diff options
Diffstat (limited to 'fw/fe310/phone/flash.c')
-rw-r--r-- | fw/fe310/phone/flash.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/fw/fe310/phone/flash.c b/fw/fe310/phone/flash.c new file mode 100644 index 0000000..e78576a --- /dev/null +++ b/fw/fe310/phone/flash.c @@ -0,0 +1,160 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <encoding.h> +#include <platform.h> + +#include <eos.h> + +#include <soc/timer.h> +#include <dev/flash.h> +#include <eve/eve.h> +#include <eve/eve_kbd.h> +#include <eve/eve_font.h> + +#include <eve/screen/window.h> +#include <eve/screen/page.h> +#include <eve/screen/form.h> + +#include "app/app.h" +#include "app/status.h" + +#include "flash.h" + +static const uint8_t magic[] = + {0x2D, 0xC0, 0x3B, 0x5F, 0xEA, 0xE3, 0x1A, 0x3A, 0x83, 0x11, 0x6A, 0x33, 0x98, 0x46, 0x1C, 0x47}; + +#define ACK 0x05 +#define NACK 0x0A +#define BLK_SIZE 256 + +__attribute__ ((section (".itim"))) +static uint32_t crc32x(unsigned char *buf, size_t len, uint32_t crc) { + int i; + + crc = ~crc; + while (len--) { + crc ^= *buf++; + for (i=0; i<8; i++) { + uint32_t t = ~((crc & 1) - 1); + crc = (crc >> 1) ^ (0xEDB88320 & t); + } + } + + return ~crc; +} + +__attribute__ ((section (".itim"))) +void flash_write(void) { + volatile uint32_t r; + uint32_t crc32, crc32_b; + uint32_t addr; + uint8_t buf[BLK_SIZE + 2 * sizeof(uint32_t)]; + int i; + + clear_csr(mstatus, MSTATUS_MIE); + SPI0_REG(SPI_REG_FCTRL) = 0; + SPI0_REG(SPI_REG_FMT) &= ~SPI_FMT_DIR(SPI_DIR_TX); + + do { + for (i=0; i<sizeof(buf); i++) { + while ((r = UART0_REG(UART_REG_RXFIFO)) & 0x80000000); + buf[i] = r; + } + + addr = 0; + addr |= (uint32_t)buf[0] << 24; + addr |= (uint32_t)buf[1] << 16; + addr |= (uint32_t)buf[2] << 8; + addr |= (uint32_t)buf[3]; + + crc32_b = 0; + crc32_b |= (uint32_t)buf[BLK_SIZE + 4] << 24; + crc32_b |= (uint32_t)buf[BLK_SIZE + 5] << 16; + crc32_b |= (uint32_t)buf[BLK_SIZE + 6] << 8; + crc32_b |= (uint32_t)buf[BLK_SIZE + 7]; + crc32 = crc32x(buf, BLK_SIZE + sizeof(uint32_t), 0xffffffff); + if (crc32 != crc32_b) { + *buf = NACK; + goto write_rep; + } + + if (addr != -1) { + if (addr % 4096 == 0) { + eos_flash_wren(); + eos_flash_ser(addr); + eos_flash_wip(); + } + eos_flash_wren(); + eos_flash_pp(addr, buf + sizeof(uint32_t)); + eos_flash_wip(); + } + *buf = ACK; +write_rep: + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000); + UART0_REG(UART_REG_TXFIFO) = *buf; + } while (addr != -1); + + while(1); +} + +void flash_write_init(void) { + volatile uint32_t r; + uint8_t buf[sizeof(magic)]; + int i; + + while (!(UART0_REG(UART_REG_RXFIFO) & 0x80000000)); + app_status_set_msg("READY!"); + eve_window_root_draw(app_root()); + + for (i=0; i<sizeof(magic); i++) { + while ((r = UART0_REG(UART_REG_RXFIFO)) & 0x80000000); + buf[i] = r; + } + if (memcmp(buf, magic, sizeof(magic)) == 0) { + *buf = ACK; + app_status_set_msg("FLASH START"); + } else { + *buf = NACK; + app_status_set_msg("FLASH FAIL"); + } + eve_window_root_draw(app_root()); + + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000); + UART0_REG(UART_REG_TXFIFO) = *buf; +} + +int flash_app(EVEWindow *window, EVEViewStack *stack) { + EVEFormSpec spec[] = { + APP_SPACERW(1,1), + }; + EVEPage *page = eve_form_create(window, stack, spec, APP_SPEC_SIZE(spec), flash_uievt, flash_close); + if (page == NULL) return EVE_ERR_NOMEM; + + return EVE_OK; +} + +int flash_uievt(EVEPage *page, uint16_t evt, void *param) { + int ret = 0; + + switch (evt) { + case EVE_UIEVT_GEST_TOUCH: { + flash_write_init(); + flash_write(); + break; + } + + default: { + ret = eve_form_uievt(page, evt, param); + break; + } + } + + return ret; +} + +void flash_close(EVEPage *page) { + eve_form_destroy(page); +} |