Dear Forum,
I am trying to write to the CC2431 flash memory using DMA. Even though I followed the required steps as described in the datasheet closely, I didn't have success with flash writing.
My hope is that my problem is not the DMA itself but releasing the DMA-FLash-Trigger by setting FCTL Register bits.
The datasheet states:
When performing DMA flash write while
executing code from within flash memory, the
instruction that triggers the first DMA trigger
event FLASH (TRIG[4:0]=10010 DMA in
configuration) must be aligned on a 4-byte
boundary.
Some example code is also given:
#include “ioCC2430.h”
MODULE flashDmaTrigger.s51
RSEG RCODE (2)
PUBLIC halFlashDmaTrigger
FUNCTION halFlashDmaTrigger, 0203H
halFlashDmaTrigger:
ORL FCTL, #0x02;
RET;
END;
I didn't implement this because I have no experience in assembly and simply don't know how to get this piece of code to work with my sdcc compiler. I tried to find out how an inline __asm funcion could look like that first aligns the code on a word boundary and then sets the FCTL register. But here I'm completely lost...
My code so far:
// init dma
EA=0;
DMAIRQ &= ~1;
IEN1 &= ~1;
IRCON &= ~1;
DMAARM &= ~1;
dma_config.o0 = ((uint16_t)&datax) >> 8; //src high
dma_config.o1 = (uint16_t)&datax; //src low
dma_config.o2 = ((uint16_t)&FWDATA) >> 8; //dst high
dma_config.o3 = (uint16_t)&FWDATA; //dst low
dma_config.o4 = 0; //VLEN
dma_config.o5 = 4; //Transfer Count
dma_config.o6 = 18; //Flash Trigger, Byte Size Transfer, Single Mode
dma_config.o7 = 0x4A; //srcinc, dstnoinc, irq on, m8=0, prio high
DMA0CFGH = ((uint16_t)&dma_config) >> 8;
DMA0CFGL = (uint16_t)&dma_config;
IEN1 |= 0x01;
EA=1;
FADDRH = 0x7E; //0b01111110 -> 64. Flash page (last one)
FADDRL = 0x00; //0b00000000 -> 0. word (first one)
LED1_ON();
pause_us(100000);
DMAARM |= 0x01; // arm dma
pause_us(100000); //wait some time for dma_config to load..
FCTL |= 0x03; //start flash page erase and write
LED2_ON();
while(!(DMAIRQ & 0x01)){ pause_us(100000); LED2_TOGGLE();}
With this code the DMA transfer never completes, most likely it will never start due to an insufficient bit-setting of FCTL. I also wrote a DMA ISR routine that, on occurrence of a DMA interrupt, toggles LED1 (which doesn't happen).
So my question is: How could I manage to set FCTL correct? Does anybody know some examples of how to implement the code piece from the datasheet into an inline asm function that works with my sdcc compiler?
Thank you in advance,
Philipp