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.

DMA during Flash write

Other Parts Discussed in Thread: MSP430F2618

Hi, I'm using a timer-triggered DMA to transfer a byte once every 3 ms from an array in RAM to UCA0TXBUF, but I'd like to write 128 bytes to flash memory with the CPU at the same time. The user guide says that interrupts are automatically disabled during any flash operation, but the DMA should still make the transfers even if DMAIE and the timer interrupts are disabled, right? I believe all I need is for the DMA itself to be enabled, and to set the timer as its trigger source.

Also, in case that won't work, and I need to move my code into RAM, how can I go about finding where my code is located in memory? I'm using IAR and outputting the module map as an HTML file, but I'm having a hard time distinguishing between data and code.

Thanks!

  • Interrupts are not automatically disabled during flash operation. But you better disable them before you start flash operations.
    Yes, the Timer, DMA, and UCA can still operate as long as they do not need to involve flash memory cycles.
  • Thanks for the reply, but from p. 320 of the MSP430F2618 user guide:

    "Interrupts are automatically disabled during any flash operation when EEI = 0 and EEIEX = 0 and on
    MSP430x20xx and MSP430G2xx devices where EEI and EEIEX are not present. After the flash operation
    has completed, interrupts are automatically re-enabled. Any interrupt that occurred during the operation
    has its associated flag set and generates an interrupt request when re-enabled."

    Also, any thoughts on figuring out where exactly in memory my code resides?

    Thanks again

  • Edit: Sorry, my previous response was cut short.

    I should have said: "... not always automatically disabled ...". I was referring to F1xx,F2xx, Gxxs chip and also other chips with FLASH31 error.(;  It is prodent not to point you gun and pull the trigger even when you have the safety latched ;)

    As for the Map File in IAR, you can use "Text" mode under [Project] => [Options] => [Linker] => [List] => [List] tab under [File Format]

    Normally, Link will put all you code in Flash.To run some of your code in RAM, you need to (a) tell Linker to link that part of the code in the RAM addresses but load them in Flash first, and (b) copy that part from Flash into RAM yourself at run time. See IAR instructions.

  • Section 6.2.3.3 of the User's Guide mentions using DMA to write to flash memory, so it appears that DMA triggers are not disabled.

  • And what is the problem if you write a byte every 3 ms from RAM to TXBUF without DMA? Copy part of your program during runtime to RAM and execute it from there (flash block write up to 50 KByte/s). Don't use any interrupts. There will be plenty of free CPU cycles for manual testing of interrupt flags during flash write waiting for BUSY /  WAIT bits.

  • Thanks for all of your replies, I will respond to all of them in one place to hopefully decrease the chance that some of these questions get overlooked:

    old_cow_yellow:

    Thanks for the help with the memory mapping, and I'm outputting that file, but I'm having a little difficulty interpreting it; I've got a bunch of DATA16 segments, some <CODE> segments, some ISR_CODE segments, and then some miscellaneous stuff, e.g. INTVEC, CSTACK, CSTART, DATA20, RESET, etc.


    Does all of that have to get copied over to RAM? If my code references variables, and I move code + variables into RAM, will the program know to read the variables in RAM, or do I have to update the pointers?

    Lastly, when you say "See IAR instructions," can I find that on IAR's website somewhere?
    I found this: https://e2e.ti.com/support/microcontrollers/msp430/f/166/p/72156/262251#262251
    which seems to have some sample code.

    Thanks so much for all the help, and sorry for the onslaught of questions

    Clemens Ladisch:

    Thanks, that's reassuring

    :

    Without the DMA, I'd need timer-triggered interrupts to control the 3 ms timing of the transmissions from RAM to TXBUF. Also, if I don't use a DMA, I'd have to interleave writing to TXBUF with writing to flash, and even at 50 kB/s, I can transfer 128 bytes in 2.56 ms, which is cutting it pretty close.

  • The compiler/linker is designed to put code and constants in Flash and execute them in place (i.e., in Flash). If you want to put part of the code and constants in Flash (as storage) but later at run time to execute them in RAM, you have to “twist their arms” to do so and you have to copy them from Flash to RAM.

    People have done so and there are examples and documents about this. But I have not used that and do not know how to do it.

    Someone else please help!
  • The __ramfunc keyword makes a function execute in RAM.
    The function is copied from ROM to RAM by cstartup

    The keyword is specified before the return type:
    __ramfunc void foo(void);

    If the whole memory area used for code and constants is disabled—for example,
    when the whole flash memory is being erased—only functions and data stored in RAM can be used.
    Interrupts must be disabled unless the interrupt vector and the interrupt service routines are also stored in RAM

    On the 5xx/6xx family devices, it is possible to re-allocate the interrupt vectors to the RAM by setting the SYSRIVECT of the SYSCTL register.

  • Peter McMenamin said:
    Without the DMA, I'd need timer-triggered interrupts to control the 3 ms timing of the transmissions from RAM to TXBUF. Also, if I don't use a DMA, I'd have to interleave writing to TXBUF with writing to flash, and even at 50 kB/s, I can transfer 128 bytes in 2.56 ms, which is cutting it pretty close.

    During flash write executed from RAM, there are plenty of free / spare CPU cycles between each double word flash write. Check flash writing function executed from RAM in 2xx family datasheet. BTW, maybe that his 3 ms can be also calculated on executed CPU cycles, without timer.  

  • Thanks everyone, this has all been very helpful, I just have two lingering questions:

    1. Tony explained how to copy functions over to RAM, but how do I copy (possibly global) variables?

    2. If I do copy a variable, and one of my functions modifies it, how do I make sure that the function modifies the variable that is located in RAM and not the original variable, which is still in Flash?

    Thanks!

    EDIT: Oh, and "RTFM" is also an acceptable answer

  • Global and static variables already are located in RAM (if they aren't read only).
  • Ohh, right, of course. Thank you

**Attention** This is a public forum