Hello,
My application needs a custom function which can update the cc2530F256's firmware during runtime, but I'm having a problem getting the function to work.
My program code resides in pages 0-8 of the flash memory. My firmware updating function is placed in a separate segment of memory on page 9 (created by adding the line "-P(CODE)updateFirmwareCodespace=0x4800-0x5000" to the linker command file) - so it can erase and re-program the program code without erasing itself.
When my program receives new program code, it's stored in flash pages 118-126. When the firmware updating function is called, it's supposed to erase pages 0-8, transfer the new code from pages 118-126 to pages 0-8, then restart with the new program. Specifically, I map the upper flash bank into XDATA, then use DMA to read the new code from XDATA and write it to the lower flash pages. Here's the C code:
void updateFirmware(void) @ "updateFirmwareCodespace"
{
// disable interrupts
IEN0 = 0;
// map the FLASH bank containing new code into XDATA
MEMCTR = (MEMCTR & 0xF8) | 7;
// clear existing firmware
for(uint8 pg = 0; pg<9; pg++)
{
FADDRH = pg<<1; FCTL |= 0x01;
while(FCTL&0x80);
}
// set up DMA transfer of new firmware to 0x0000-0x47FF - this code borrowed from TI's hal_flash.c
HAL_DMA_SET_ADDR_DESC0( &dmaCh0 );
HAL_DMA_SET_ADDR_DESC1234( dmaCh1234 );
halDMADesc_t *ch = &dmaCh0;
HAL_DMA_SET_DEST(ch, &FWDATA);
HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_USE_LEN);
HAL_DMA_SET_LEN(ch, 16);
HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE);
HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE);
HAL_DMA_SET_TRIG_SRC(ch, HAL_DMA_TRIG_FLASH);
HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1);
HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0);
// The DMA is to be polled and shall not issue an IRQ upon completion.
HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_DISABLE);
HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS);
HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH);
HAL_DMA_CLEAR_IRQ(HAL_NV_DMA_CH);
HAL_DMA_ARM_CH(HAL_NV_DMA_CH);
// transfer new firmware 16 bytes at a time
for(uint16 i = 0; i<1152; i+=16)
{
// set source of DMA transfer
HAL_DMA_SET_SOURCE(ch, (0xB000 + i));
// set destination of DMA transfer
FADDRL = (uint8)i;
FADDRH = (uint8)(i >> 8);
// Trigger the DMA writes
FCTL |= 0x02;
// Wait until writing is done.
while (FCTL & 0x80);
}
// restart the new program
asm("LJMP 0x0000");
}
After running the program, I read the cc2530's flash and see that pages 0-8 have been cleared to 0xFF, the updater function code still resides in page 9, and the new code is in pages 118-126. That is, the function clears pages 0-8 but does not re-write them successfully. Can you give any insight into what I might be doing wrong?
Thanks very much!
Eric