Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Reading flash of MSP430G2553

Status
Not open for further replies.

maxeen

Member level 1
Member level 1
Joined
Jul 26, 2012
Messages
36
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,288
Activity points
1,559
Hello.

I am trying to read the flash memory of a MSP430G2553. I have read that data bus is 16bit, therefore whenever I read a byte, the CPU reads two bytes and discard one of them. The problem is that the operation can only be performed if I read a even address. If I try to read a odd address, I get a zero.

How can I read a odd address then?
 

It's a bit unclear as to what exactly your are attempting to accomplish, perhaps posting your code, using proper CODE or SYNTAX tags, might clarify the desire task.

Typically, when access data stored in the flash storage of a device, the task is accomplished by accessing the data through the use of an identifier/variable name or possibly an initial pointer containing the starting address of the data block of interest.

If the data to be retrieved is of byte size, when it was originally stored as a multiple byte value, an appropriate pointer can be defined of type unsigned char and initialized to the starting address of the data block. And then accessed/read by using the pointer as a const array of type unsigned char or through standard pointer arithmetic.

As it is unclear of the specific task required, it is difficult to offer any meaningful advice.


BigDog
 

I'm sorry if I was not clear enough.

Say I want to read the address 0x1000. Then I can creat a pointer, associate it with the address 0x1000 and read its value. But when I try to read the address 0x1001, I always read zero.

After doing some research on the web, I have found that whenever I try to read the address 0x1000, the MCU reads both 0x1000 and 0x1001, but discards the latter. It only works with even address, so if I read the address 0x1002, the MCU reads both 0x1002 and 0x1003. What I could not find is how to read the address 0x1001 (or any odd address).

I have tried creating a char, but no sucess.

Thanks for your reply
 

Please post your code, it's difficult to troubleshoot such an issue with a description alone.

When you defined the pointer, how was its pointer type defined?

What is the specific data located at the starting address 0x1000, that you are attempting to access?


BigDog
 

The code is as follows:
Code:
unsigned char buffer_flash[64] 
unsigned int i

int *p_flash = (int *)0x1000;
for (i=0; i<64; i++) buffer_flash[i] = *p_flash++;
Whenever I increment the pointer, its address goes from 0x1000 to 0x1002 directly.

Then I tried the following code:
Code:
p_flash = (int *)0x1000;
buffer_flash[0] = *p_flash;
p_flash = (int *)0x1001;
buffer_flash[0] = *p_flash;

The pointer does point to 0x1001, but I read zero always..

The data located is a password that opens a door. But even when I erase the flash, I read zero..

Thanks for the help
 
Last edited by a moderator:

After doing some research on the web, I have found that whenever I try to read the address 0x1000, the MCU reads both 0x1000 and 0x1001, but discards the latter. It only works with even address, so if I read the address 0x1002, the MCU reads both 0x1002 and 0x1003. What I could not find is how to read the address 0x1001 (or any odd address).

As literal and const char strings are routinely stored in Flash memory and accessed as a type char or unsigned char, a single byte, from Flash memory, I find that rather hard to believe. As I suspected your implementation of the pointer is incorrect, as the following pointer definition in your code is incorrect for accessing a single byte:

Code:
[COLOR="#FF0000"]int[/COLOR] *p_flash = ([COLOR="#FF0000"]int[/COLOR] *)0x1000;

Defining the pointer variable as a pointer to type int, will retrieve or write two bytes and any associated pointer arithmetic will increment the address contained in the pointer by multiples of two.

Try something along these lines:

Code:
unsigned char * p_flash = (unsigned char *) 0x1000;

You may need to define the pointer as a const unsigned char as the contents of Flash are essentially read only during normal runtime.

The data located is a password that opens a door. But even when I erase the flash, I read zero..

Your above statement may present several additional issues and certainly some questions.

1. Is the Flash contents you are attempting to access, some type of bootloader?

2. If code protection is enabled on the device, you will not be able to read the flash directly nor read it's contents using an in-circuit programmer or debugger. Which may explain why you are have issues reading the Flash contents directly. In fact if code protection is enabled, you maybe essentially dead in the water. Do you have the firmware image file of the area you are attempting to read?

3. Are you sure the password is stored in Flash and not in EEPROM or another storage device connected to the MSP430?

Typically passwords are not stored in Flash, unless they are a master password of sorts never to be changed, as updating the Flash during runtime requires the microcontroller have In Application Programming (IAP) capabilities and is a relatively a very slow task.

4. Do you have a schematic of the device's circuit design? If not, can you check for any other storage devices connected to the MSP430?

I'll examine the MSP430G2553 datasheet to see if it yields any other insight into the issue.


BigDog
 

Well, it is only a project for my class, in which one can open a door using a password or a magnetic card. I thought of storing these values in the flash memory so I could sign more cards or passwords without having to program the microcontroller again. Again, it is only a class project, and there aren't really any schematics. The card reader (ID20LA) is connected to the microcontroller's pins (which is actually a launchpad, pretty similar to those of Arduino), there is a matrix keyboard (16 characters), also connected directly to the microcontroller's pins and a 2x16 display.

If the address is 0x1000 (2 bytes) would a char be not enough to store the whole address? By accident I tried to create a char pointer, and the compilar gave me a warning, but I will try again.

Answering your questions:

1. There is not any kind of bootloader. I only read some bytes of the flash memory that are available for users. There is nothing store in those addresses, and the main program is stored elsewhere.

2. I do not intend to use code protection. Since it is a class project, don't want to lose my launchpad.

3. Yes, the password is in the microcontrollers flash. I forgot to mention that I wrote the password in the flash memory.

4. The schematic is pretty simple. It consists of a magnetic card reader (ID20LA), 16-character matrix keyboard and 2x16 LCD.

I kindly appreciate your concern. I have already presented the project to my professor, and I used only even address (which cut half of the possible data to be stored).
 

I appreciate you clarifying the nature of your project, which answers the questions I previously posed.

I needed to ensure we were not attempting to circumvent a third party's password system, which would have most likely had the code protection feature enabled.

However, you need to be more specific in the method you are using to store the passwords initially in your code.

Please post or upload your code in its entirety, using the proper CODE tags or if you wish to upload it as a zip file, use the Manage Attachment feature.

The method used to initially define and store the passwords is of most importance.

BigDog

- - - Updated - - -

Update:

Also which compiler/IDE toolset are you utilized to develop your code?

I have several TI MSP430 Launchpads available, although I will not complete your assignment for you, I will troubleshoot the issue and provide some advice on how to accomplish your task.
 

I will not post the entire code, most commentaries are in portuguese and the flash part is actually short.

So, to write in the flash memory, the code is the following:

Code:
void write_flash(char data, int *addr){	//writes data in addr
	while(BUSY & FCTL3);                  //wait for flash memory to be ready
	FCTL1 = 0xA500 | WRT;               //enable write
	FCTL2 = 0xA500 | FSSEL1 | 0x0D; //select proper clock and divider
	FCTL3 = 0xA500 | LOCKA;            //locks segment A, which contain important information
	while(BUSY & FCTL3);                 //wait for flash memory to be ready                
	*addr = data;                           //write data in addr
	addr++;                                  //increment pointer (which isnt really necessary)
	while(BUSY & FCTL3);                 //wait for flash memory to be ready
	FCTL1 = 0xA500;                      //lock writing
	FCTL3 = 0xA500 | LOCK;
}

It is based on the microcontrollers user guide.

Code:
void inicializa_flash(void){
	int *p = (int *)0x103A;			//points to 0x103A (which is the number o passwords)
	char aux;			               //"work" variable
	save_flash((int*)0x1000);	      //saves the content of the flash (for debugging purposes)
//	erase_flash((int*)0x1000);          //erase flash 
	aux = *p;                                 
	if(aux == 0xFF) write_password();	  //if aux == 0xFF, then flash memory is empty and 
                                                         //password is saved
		
}

The function write_password is as follows:

Code:
void write_password(void){
	write_flash(0x01, (int *)0x101A);
	write_flash(0x02, (int *)0x101C);
	write_flash(0x03, (int *)0x101E);		//saves the master password
	write_flash(0x04, (int *)0x1020);

	write_flash(0x01, (int *)0x103A);		//saves the number of passwords (1 now)
	write_flash(0x00, (int *)0x103C);		//saves the number of magnetic cards (0)
}


Here, I have saved the password in even addresses only, since I can't get to read odd adresses.

Whenever I try to read a address, I use the code posted before. If I define a char pointer, I get warning because the address is 2-byte long.

I hope this can clarify things.

----

I am using Code Composer Studio.

Please, don't worry about that. My code works, it sucessfully reads magnetic cards, passwords and store new magnetic cards ans passwords (I developed it with other friends). I just can't read odd addresses from the flash memory, which should be pretty straightfoward :bang:
 

I'll experiment around with the MSP430 Launchpad and perhaps shed some light on the issue of accessing odd addresses.

It's been quite a while since I last used a MSP430 for a client project, so I'm a little rusty in that area.

After reviewing the associated datasheets, the Flash storage in question is referred to as information memory with a segment size of only 64 bytes, it seems the intention was to provide an alternative for an on-board EEPROM.

The only other question I have at this time, what is the specifications and format of the passwords.

An alphanumeric character string of some N length? Or are you storing it as a numerical value, RFID, of the card? If so, what is the maximum number of digits per password?

So check back late tomorrow, I may have some answers and advice for you.

BigDog

- - - Updated - - -

Update:

After reviewing your code it appears the passwords are a series of N digits, what is the maximum value of N? Only four digits?
 

Yes, we chose to make it 4 digits long. We also store the magnetic card's ID, which is 3 byte long.

The microcontrollers flash memory contain 4 segments (A, B, C, D) for storing data (each 64 byte long), and segment A contain some information about internal clock calibration. We chose to store data only in segment D (as far as possible from segment A).

Again, thanks for the help.
 

Hello!

I did a short experiment with a G 2452, and I have no problem reading bytes anywhere.
Writing also works well. You may want to have a lool at TI's soucrce code for teh G series.
There is a msp430g2xx2_flashwrite_01.c which explains it all. As it writes a complete sector,
I have just changed the code to write a single byte at 0x1041 and read it back, It works.

Dora.
 
  • Like
Reactions: maxeen

    maxeen

    Points: 2
    Helpful Answer Positive Rating
Where do I find this code? Most codes I found on the web was pretty similar to mine, so I did not run them..

Thanks for your answer..
 

Thank you Dora for you time and effort.



The source file in question appears to be included in the following GitHub ZIP file:

https://github.com/clayrichardson/MSP430G2xx2

The contained source files appear to be TI Launchpad example code, the msp430g2xx2_flashwrite_01.c file is located in the C directory.


Notice they appear to utilize pointers of type char * to read and write values, as previously discussed.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//******************************************************************************
//  MSP430G2xx2 Demo - Flash In-System Programming, Copy SegC to SegD
//
//  Description: This program first erases flash seg C, then it increments all
//  values in seg C, then it erases seg D, then copies seg C to seg D.
//  Assumed MCLK 771kHz - 1428kHz.
//  //* Set Breakpoint on NOP in the Mainloop to avoid Stressing Flash *//
//
//               MSP430G2xx2
//            -----------------
//        /|\|              XIN|-
//         | |                 |
//         --|RST          XOUT|-
//           |                 |
//
//  D. Dang
//  Texas Instruments Inc.
//  December 2010
//  Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
 
#include <msp430g2452.h>
 
char  value;                                // 8-bit value to write to segment A
 
// Function prototypes
void write_SegC (char value);
void copy_C2D (void);
 
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
  {  
    while(1);                               // If calibration constants erased
                                            // do not load, trap CPU!!
  } 
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz
  DCOCTL = CALDCO_1MHZ;
  FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
  value = 0;                                // initialize value
 
  while(1)                                  // Repeat forever
  {
    write_SegC(value++);                    // Write segment C, increment value
    copy_C2D();                             // Copy segment C to D
    _NOP();                                 // SET BREAKPOINT HERE
  }
}
 
void write_SegC (char value)
{
  char *Flash_ptr;                          // Flash pointer
  unsigned int i;
 
  Flash_ptr = (char *) 0x1040;              // Initialize Flash pointer
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  FCTL3 = FWKEY;                            // Clear Lock bit
  *Flash_ptr = 0;                           // Dummy write to erase Flash segment
 
  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
 
  for (i=0; i<64; i++)
  {
    *Flash_ptr++ = value;                   // Write value to flash
  }
 
  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
}
 
void copy_C2D (void)
{
  char *Flash_ptrC;                         // Segment C pointer
  char *Flash_ptrD;                         // Segment D pointer
  unsigned int i;
 
  Flash_ptrC = (char *) 0x1040;             // Initialize Flash segment C pointer
  Flash_ptrD = (char *) 0x1000;             // Initialize Flash segment D pointer
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  FCTL3 = FWKEY;                            // Clear Lock bit
  *Flash_ptrD = 0;                          // Dummy write to erase Flash segment D
  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
 
  for (i=0; i<64; i++)
  {
    *Flash_ptrD++ = *Flash_ptrC++;          // copy value segment C to segment D
  }
 
  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
}





BigDog
 
  • Like
Reactions: maxeen

    maxeen

    Points: 2
    Helpful Answer Positive Rating
It worked! Honestly, I can't understand why the pointer has to be char, but it worked! Thank you for all your time!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top