char BSL430_writeMemory(unsigned long startAddr, unsigned int size, char* data) { unsigned long i; char exceptions = SUCCESSFUL_OPERATION; for (i = startAddr; i < startAddr + size; i++) { #ifndef RAM_WRITE_ONLY_BSL if ((startAddr & 0x01) || i == startAddr + size - 1) #endif { exceptions = BSL430_writeByte(i, *data); data += 1; } #ifndef RAM_WRITE_ONLY_BSL else { exceptions = BSL430_writeWord(i, *(int *)data); data += 2; i++; } if (exceptions != SUCCESSFUL_OPERATION) { return exceptions; } // if #endif } // for return exceptions; }
char flushBuffer(void) { unsigned long i; char exceptions = SUCCESSFUL_OPERATION; unsigned char* data = &BlockBuffer[0]; if (LockedStatus == UNLOCKED) { if (((BlockBufferStart & 0x7F) == 0) && (BlockBufferPtr == 128)) //Buffer is full and // aligned { while (FCTL3 & BUSY) ; FCTL3 = FWKEY; // Clear Lock bit FCTL1 = FWKEY + BLKWRT + WRT; // Set write/block bit for (i = BlockBufferStart; i < BlockBufferStart + 128; i += 4) { __data20_write_long(i, *((long*)data)); data += 4; while ((FCTL3 & WAIT) == 0) ; } // for FCTL1 = FwRamKey; while (FCTL3 & BUSY) ; FCTL3 = FwRamKey + LOCK; } // if else { FCTL3 = FwRamKey; // Clear Lock bit FCTL1 = FwRamKey + WRT; // Set write bit for (i = BlockBufferStart; i < BlockBufferStart + BlockBufferPtr; i++) { if ((BlockBufferStart & 0x01) || i == BlockBufferStart + BlockBufferPtr - 1) { exceptions = BSL430_writeByte(i, *data); data += 1; } else { exceptions = BSL430_writeWord(i, *(int *)data); data += 2; i++; } if (exceptions != SUCCESSFUL_OPERATION) { return exceptions; } // if } // for } // else BlockBufferStart = 0; BlockBufferNext = 0; BlockBufferPtr = 0; } else { exceptions = BSL_LOCKED; } return exceptions; }
void FlashFirmware() { unsigned int i; char *pBuffer; WriteState state; uint16_t NumByteToRead; uint32_t NumByteToWrite; uint32_t write_ptr; uint32_t buffer[32]; // 32 * 4 = 128 __disable_interrupt(); // 5xx Workaround: Disable global // interrupt while erasing. Re-Enable // GIE if needed state = STATE_NEEDSIGNATURE; // Start the loop while(state != STATE_DONE) { putchar_('a' + state); switch(state) { case STATE_NEEDSIGNATURE: NumByteToRead = 10; // the size of file header, sync with main.c under convert tool src SPI_FLASH_CS_LOW(); SPI_FLASH_SendCommandAddress(W25X_ReadData, FIRMWARE_BASE); break; case STATE_NEEDADDR: NumByteToRead = 8; // one address and one break; case STATE_WRITE: if (NumByteToWrite > 128) NumByteToRead = 128; else NumByteToRead = NumByteToWrite; break; } pBuffer = (char*)&buffer[0];; for(int i = 0; i < NumByteToRead; i++) { *pBuffer = ~SPI_FLASH_SendByte(Dummy_Byte); pBuffer++; } switch(state) { case STATE_NEEDSIGNATURE: { if (buffer[0] != SIGNATURE) { SPI_FLASH_CS_HIGH(); state = STATE_DONE; // error continue; } // Erase Flash BSL430_massErase(); state = STATE_NEEDADDR; } break; case STATE_NEEDADDR: { if (buffer[0] == 0 || buffer[0] == SIGNATURE) // hit the end { state = STATE_DONE; continue; } // first uint32 is start address, second uint32 is length write_ptr = buffer[0]; NumByteToWrite = buffer[1]; //putx_(write_ptr); //putx_(NumByteToWrite); state = STATE_WRITE; } break; case STATE_WRITE: { while(BUSY & FCTL3); // Test wait until ready for next byte // Write Flash FCTL1 = FWKEY+WRT; // Enable block write FCTL3 = FWKEY; // Set LOCK char* src = (char*)&buffer[0]; for(i = 0; i < NumByteToRead; i++) { BSL430_writeByte(write_ptr++, *src++); } FCTL1 = FWKEY; FCTL3 = FWKEY+LOCK; // Set LOCK while(BUSY & FCTL3); // Check for write completion NumByteToWrite -= NumByteToRead; if (NumByteToWrite == 0) state = STATE_NEEDADDR; } break; } } // reboot WDTCTL = 0; }
char BSL430_writeMemory(unsigned long startAddr, unsigned int size, char* data) { unsigned long i; char exceptions = SUCCESSFUL_OPERATION; // Note: this function compiles quite differently based on whether the // BSL is based out of RAM, or not. RAM based BSLs can use buffering // and perform a block long word write. This is primarily used for // USB BSLs for performance increase. // Flash based BSLs will use the second second of code, below #ifdef RAM_BASED_BSL if (LockedStatus == UNLOCKED) { if ((BlockBufferStart == 0) || BlockBufferNext == startAddr) { // if we are starting, or continuing a block... if (BlockBufferStart == 0) { BlockBufferStart = startAddr; // if starting a new block, reset // start addr } BlockBufferNext = startAddr + size; // always update the next addr for // streaming for (i = 0; i < size;) { BlockBuffer[BlockBufferPtr++] = *data; // add the incoming data to the buffer data++; startAddr++; i++; // i incrimented here for check below if (((startAddr) & 0x7F) == 0x00) // we've crossed a 128 byte block // boundary { flushBuffer(); // flush out old buffer, writing... // begin write on block boundary return BSL430_writeMemory(startAddr, (size - i), data); } // if } // for } // if buffer start else { // for when data exists in the buffer, but we are jumping to a new place to write... flushBuffer(); // flush out old buffer, writing.. return BSL430_writeMemory(startAddr, size, data); // begin buffering new data } } // if unlocked else { exceptions = BSL_LOCKED; } // Below is the writeMemory function compiled with Flash based BSLs. #else for (i = startAddr; i < startAddr + size; i++) { # ifndef RAM_WRITE_ONLY_BSL // if the start address is odd, or we're 1 byte from end... if ((startAddr & 0x01) || i == startAddr + size - 1) # endif { exceptions = BSL430_writeByte(i, *data); data += 1; } # ifndef RAM_WRITE_ONLY_BSL // else, we're on an even addr, and have at least 1 word left.. else { exceptions = BSL430_writeWord(i, *(int *)data); data += 2; i++; } if (exceptions != SUCCESSFUL_OPERATION) { return exceptions; } // if # endif } // for #endif return exceptions; }