diff --git a/board/msb-430-common/Jamfile b/board/msb-430-common/Jamfile index 17bf86c9bb..147e49ea23 100644 --- a/board/msb-430-common/Jamfile +++ b/board/msb-430-common/Jamfile @@ -28,7 +28,7 @@ SubDir TOP board msb-430-common ; Module board : board_init.c debug_uart.c ; -Module board_config : board_config.c ; +Module board_config : board_config.c : flashrom ; UseModule board ; SubInclude TOP cpu $(CPU) ; diff --git a/cpu/msp430x16x/flashrom.c b/cpu/msp430x16x/flashrom.c new file mode 100644 index 0000000000..686e0cc3dd --- /dev/null +++ b/cpu/msp430x16x/flashrom.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +uint8_t ie1, ie2; + +static uint8_t prepare(void); +static void finish(uint8_t istate); +static inline void busy_wait(void); + +/*---------------------------------------------------------------------------*/ +uint8_t flashrom_erase(uint8_t *addr) { + uint8_t istate = prepare(); + + FCTL3 = FWKEY; /* Lock = 0 */ + busy_wait(); + FCTL1 = FWKEY | ERASE; + *addr = 0; /* erase Flash segment */ + busy_wait(); + FCTL1 = FWKEY; /* ERASE = 0 */ + FCTL3 = FWKEY | LOCK; + finish(istate); + return 1; +} + +void flashrom_write(uint8_t *dst, uint8_t *src, size_t size) { + unsigned int i; + FCTL3 = FWKEY; /* Lock = 0 */ + busy_wait(); + for (i = size; i > 0; i--) { + FCTL1 = FWKEY | WRT; + *dst = *src; /* program Flash word */ + while (!(FCTL3 & WAIT)) { + nop(); + } + } + busy_wait(); + FCTL1 = FWKEY; /* WRT = 0 */ + FCTL3 = FWKEY | LOCK; /* Lock = 1 */ +} + +/*---------------------------------------------------------------------------*/ +static uint8_t prepare(void) { + uint8_t istate; + + /* Disable all interrupts. */ + + /* Clear interrupt flag1. */ + IFG1 = 0; + + /* DCO(SMCLK) is 2,4576MHz, /6 = 409600 Hz + select SMCLK for flash timing, divider 4+1 */ + FCTL2 = FWKEY | FSSEL_3 | FN2 | FN0; + + /* disable all interrupts to protect CPU + during programming from system crash */ + istate = disableIRQ(); + + /* disable all NMI-Interrupt sources */ + ie1 = IE1; + ie2 = IE2; + IE1 = 0x00; + IE2 = 0x00; + return istate; +} +/*---------------------------------------------------------------------------*/ +void finish(uint8_t istate) { + /* Enable interrupts. */ + IE1 = ie1; + IE2 = ie2; + restoreIRQ(istate); +} + +static inline void busy_wait(void) { + /* Wait for BUSY = 0, not needed unless run from RAM */ + while(FCTL3 & 0x0001) { + nop(); + } +}