char BSL430_unlock_BSL(char* data) { int i; int retValue = 0; char *interrupts = (char*)INTERRUPT_VECTOR_START; for (i = 0; i <= (INTERRUPT_VECTOR_END - INTERRUPT_VECTOR_START); i++, interrupts++) { retValue |= *interrupts ^ data[i]; } if (retValue == 0) { #ifndef RAM_WRITE_ONLY_BSL volatile int i; for (i = MASS_ERASE_DELAY - 1; i > 0; i--) ; #endif LockedStatus = UNLOCKED; return SUCCESSFUL_OPERATION; } else { BSL430_massErase(); return BSL_PASSWORD_ERROR; } }
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; }