This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F6736: Accessing odd-numbered addresses

Part Number: MSP430F6736


Hi experts,

My customer is using MSP430F6736, and they are wondering about Flash on MSP430.

Q1:When accessing Flash memory, is it possible to access (read/write) odd-numbered addresses?

Q2:If so, could you tell me if there are any precautions to be taken when accessing odd-numbered addresses?

In "MSP430x5xx and MSP430x6xx Family User's Guide (Rev. Q)", I found that 1Byte access is possible, but there is no description whether it is OK to access odd-numbered address first. For example, when recording 3Byte data multiple times, if no countermeasures are taken, the odd-numbered address may be written as the first address. In this case, We are wondering if it is better to write the data in 3+1Byte units.

I checked the following thread, but in the end I could not determine if it is possible to access odd addresses.
e2e.ti.com/.../mov-b-at-odd-address-writes-the-even-address

Since we are not experiencing a specific problem, it may be difficult to answer, but it would be helpful if you could share whether Q1 is possible and some reference information.

Best regards,
O.H

  • A1: Of course you can write to odd bytes of flash. The byte write mode would be pretty useless otherwise.

    A2: The one thing to watch out for is that on some devices you can exceed the cumulative programming time before writing 128 bytes to a flash block. Check the data sheet to be sure you are OK.

  • Hi David Schultz,

    Sorry for the late response. Thanks for the reply.

    A1: Of course you can write to odd bytes of flash. The byte write mode would be pretty useless otherwise.

    I actually tested the read/write against an odd number of addresses. (The device is F6638, though...).

    One thing I noticed is that if I place a variable for an odd-numbered address as in the thread below, it seems to access from 1Byte before (even-numbered address) when accessing with 16bit pointer. In the case of 8bit pointer, the contents of the specified address can be accessed.

    I think this is the point to be noted, but if I am wrong or if there are other points to be noted, please let me know.

    A2: The one thing to watch out for is that on some devices you can exceed the cumulative programming time before writing 128 bytes to a flash block. Check the data sheet to be sure you are OK.

    I have checked the contents on the datasheet, and I understand that this is a point to be noted regardless of whether the number is odd or even.

    Best regards,
    O.H

  • Are you really attempting to access 16 bit variables at odd addresses? While that might work with things that allow an unaligned access (MC68020), the MSP430 will not split the access for you. For a 16 bit access, the lsb of the address is going to be zero. Always.

  • Hi David Schultz,

    Here are the test results. (Sorry for the complication, but I re-tested it with F67791). The compiler is v20.2.5.LTS.  There may be some rudimentary mistakes on my part...

    Best regrads,
    O.H

  • Hi O.H,

    I'm a little curious as to why you need it in the 3 Byte format. Most variable data types are already on an even byte set with the exception of the smaller data types. For example, here that unsigned int is 2 Bytes, you can even see in the expressions section that each address is starting 2 bytes from each other. It might be easier to do a long data type here as you can have your 3 bytes, but it will also be filled with a 4th byte by default.  if you were to create a 3 Byte struct, I believe the compiler would also stuff that fourth byte to maintain even addressing (I haven't verified that aspect personally). 

    But you would be able to write to 1 Byte addresses. For example a char array, would allow you to write to an odd address as the spot of arr[1] would be located in an odd address. This is just an example of general odd address writing.

    So to conclude it, you can write to odd addresses but with the 16 bit processor, memory likes being even. Your example uses an int which is 2 bytes (16 bits) here, it might be best and easiest to use a long data type so you can have 4 bytes total but you would only care about 3 of the bytes.

    Regards,

    Luke

  • Hi Luke,

    Thank you for your reply.

    In conclusion, if we have enough memory, use it so that it is placed at an even address as much as possible. For example, if we are writing 1-byte data three times, add an extra byte of dummy data. Also note that when reading to an odd-numbered address, the value to be read out may be based on the even-numbered address in some cases.

    By the way, when I created a 3-byte structure, it did not automatically fill up with 4 bytes... Attached is the CCS capture screen and the code I used for testing.

    #include <msp430.h> 
    
    //test
    unsigned char buffer[6] = {0x00,0x12,0x34,0x56,0x78,0x90};
    
    struct test{
        unsigned char Buf1;
        unsigned char Buf2;
        unsigned char Buf3;
    };
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer
    
        P1OUT &= ~BIT0;                         // Clear P1.0 output latch for a defined power-on state
        P1DIR |= BIT0;                          // Set P1.0 to output directionOUT
    
        struct test TEST[3];
        TEST[0].Buf1 =0x01;
        TEST[0].Buf2 =0x23;
        TEST[0].Buf3 =0x45;
    
        TEST[1].Buf1 =0x01;
        TEST[1].Buf2 =0x23;
        TEST[1].Buf3 =0x45;
    
        while(1)
        {
            volatile unsigned int var_uint0 = *((unsigned int *)&buffer[0]);
            volatile unsigned int var_uint1 = *((unsigned int *)&buffer[1]);
            volatile unsigned int var_uint2 = *((unsigned int *)&buffer[2]);
            volatile unsigned int var_uint3 = *((unsigned int *)&buffer[3]);
    
            volatile unsigned int var_uint0_1 = *((unsigned char *)&buffer[0]);
            volatile unsigned int var_uint1_1 = *((unsigned char *)&buffer[1]);
            volatile unsigned int var_uint2_1 = *((unsigned char *)&buffer[2]);
            volatile unsigned int var_uint3_1 = *((unsigned char *)&buffer[3]);
        }
    }

    Best regards,
    O.H

**Attention** This is a public forum