stm32f4-uart-bootloader

Simple UART bootloader for STM32F4 MCU's
git clone git://git.mdnr.space/stm32f4-uart-bootloader
Log | Files | Refs | Submodules | README | LICENSE

update.c (7145B)


      1 #include "update.h"
      2 #include "bl/bl-packet.h"
      3 #include "bl/stimer.h"
      4 #include "shared/protocol.h"
      5 #include "shared/flash-io.h"
      6 #include "shared/drv-gpio.h"
      7 #include <string.h>
      8 
      9 typedef enum {
     10     US_INFINITE_LOOP,
     11     US_WAIT_FOR_SYNC_REQ,
     12     US_WAIT_FOR_UPDATE_REQ,
     13     US_WAIT_FOR_DEV_ID,
     14     US_WAIT_FOR_FW_LENGTH,
     15     US_ERASE_OLD_FW,
     16     US_RECEIVE_UPDATE,
     17     US_LAST_CHECK,
     18     US_DONE,
     19 } UpdateState_t;
     20 
     21 static uint8_t updateStatus = US_WAIT_FOR_SYNC_REQ;
     22 static uint8_t updateStatusLast = US_WAIT_FOR_SYNC_REQ;
     23 static uint32_t updateSize = 0;
     24 
     25 static void update_refresh_indicators(const uint8_t status) {
     26     do {
     27         res_gpio_write_pin(ST_LED0_PORT, ST_LED0_PIN, (status >> 3) & 0x01);
     28         res_gpio_write_pin(ST_LED1_PORT, ST_LED1_PIN, (status >> 2) & 0x01);
     29         res_gpio_write_pin(ST_LED2_PORT, ST_LED2_PIN, (status >> 1) & 0x01);
     30         res_gpio_write_pin(ST_LED3_PORT, ST_LED3_PIN, (status >> 0) & 0x01);
     31     } while (0);
     32 }
     33 
     34 void update_state_machine(void) {
     35     Stimer_t timeout, blink;
     36     stimer_start(&timeout, 5000, false);
     37     stimer_start(&blink, 1000, true);
     38     uint8_t *packetAddr = 0; // NULL
     39     while (updateStatus != US_DONE) {
     40         if (stimer_ping(&timeout)) updateStatus = US_LAST_CHECK;
     41         packetAddr = bl_packet_received();
     42         if (updateStatus != US_INFINITE_LOOP) update_refresh_indicators(updateStatus);
     43         switch (updateStatus) {
     44             case US_INFINITE_LOOP: {
     45                 static uint8_t ledStatus = 0x0F;
     46                 if (packetAddr != 0) {
     47                     stimer_start(&timeout, 5000, false);
     48                     updateStatusLast = updateStatus;
     49                     updateStatus++;
     50                 } else {
     51                     if (stimer_ping(&blink)) {
     52                         ledStatus ^= 0x0F;
     53                         update_refresh_indicators(ledStatus);
     54                     }
     55                 }
     56             } break;
     57             case US_WAIT_FOR_SYNC_REQ: {
     58                 if (packetAddr != 0) {
     59                     ProtocolPacketAttr_t attr = protocol_extract_packet_attr(packetAddr, false);
     60                     if (attr.tag == PROTOCOL_TAG_SYNC_REQ) {
     61                         packet_send_ack();
     62                         updateStatusLast = updateStatus;
     63                         updateStatus++;
     64                         stimer_reload(&timeout);
     65                     } else if (attr.tag == PROTOCOL_TAG_RST) packet_send_ack();
     66                     else packet_send_nack();
     67                 }
     68             } break;
     69             case US_WAIT_FOR_UPDATE_REQ: {
     70                 if (packetAddr != 0) {
     71                     ProtocolPacketAttr_t attr = protocol_extract_packet_attr(packetAddr, false);
     72                     if (attr.tag == PROTOCOL_TAG_UPDATE_REQ) {
     73                         packet_send_ack();
     74                         updateStatusLast = updateStatus;
     75                         updateStatus++;
     76                         stimer_reload(&timeout);
     77                     }
     78                 }
     79             } break;
     80             case US_WAIT_FOR_DEV_ID: {
     81                 if (packetAddr != 0) {
     82                     ProtocolPacketAttr_t attr = protocol_extract_packet_attr(packetAddr, false);
     83                     if (attr.tag == PROTOCOL_TAG_DEV_ID_CHECK &&
     84                         flash_io_check_dev_id((uint32_t *)(packetAddr + PACK_DATA_INDEX))) {
     85                         packet_send_ack();
     86                         updateStatusLast = updateStatus;
     87                         updateStatus++;
     88                         stimer_reload(&timeout);
     89                     } else packet_send_nack();
     90                 }
     91             } break;
     92             case US_WAIT_FOR_FW_LENGTH: {
     93                 if (packetAddr != 0) {
     94                     ProtocolPacketAttr_t attr = protocol_extract_packet_attr(packetAddr, false);
     95                     if (attr.tag == PROTOCOL_TAG_FW_UPDATE_SIZE) {
     96                         updateSize = flash_io_check_update_size((uint32_t *)(packetAddr + PACK_DATA_INDEX));
     97                         if (updateSize != 0) {
     98                             packet_send_ack();
     99                             updateStatusLast = updateStatus;
    100                             updateStatus++;
    101                             stimer_reload(&timeout);
    102                         } else packet_send_nack();
    103                     } else packet_send_nack();
    104                 }
    105             } break;
    106             case US_ERASE_OLD_FW: {
    107                 if (packetAddr != 0) {
    108                     ProtocolPacketAttr_t attr = protocol_extract_packet_attr(packetAddr, false);
    109                     if (attr.tag == PROTOCOL_TAG_ERASE_REQ) {
    110                         if (flash_io_erase_fw_partition()) {
    111                             packet_send_ack();
    112                             updateStatusLast = updateStatus;
    113                             updateStatus++;
    114                             stimer_start(&timeout, 10000, false);
    115                         } else packet_send_nack();
    116                     }
    117                 }
    118             } break;
    119             case US_RECEIVE_UPDATE: {
    120                 static uint32_t writtenBytesNo = 0;
    121                 static bool lastWriteSuccess = false;
    122                 if (updateStatusLast == updateStatus - 1) {
    123                     updateStatusLast = updateStatus;
    124                     writtenBytesNo = 0;
    125                     lastWriteSuccess = false;
    126                 }
    127                 if (packetAddr != 0 && writtenBytesNo < updateSize) {
    128                     ProtocolPacketAttr_t attr = protocol_extract_packet_attr(packetAddr, true);
    129                     if (attr.tag == PROTOCOL_TAG_FW_NEW) {
    130                         if ((lastWriteSuccess = (flash_io_write_new_firmware(packetAddr + 2, attr.length) == attr.length))) {
    131                             writtenBytesNo += attr.length;
    132                             packet_send_ack();
    133                             stimer_reload(&timeout);
    134                         } else packet_send_nack();
    135                     } else if (attr.tag == PROTOCOL_TAG_FW_REP) {
    136                         if (lastWriteSuccess) {
    137                             packet_send_ack();
    138                             stimer_reload(&timeout);
    139                         } else if ((lastWriteSuccess =
    140                                     (flash_io_write_new_firmware(packetAddr + 2, attr.length) == attr.length))) {
    141                             writtenBytesNo += attr.length;
    142                             packet_send_ack();
    143                             stimer_reload(&timeout);
    144                         } else packet_send_nack();
    145                     } else packet_send_nack();
    146                 } else if (writtenBytesNo == updateSize) {
    147                     flash_io_write_main_entry();
    148                     updateStatusLast = updateStatus;
    149                     updateStatus++;
    150                 }
    151             } break;
    152             case US_LAST_CHECK: {
    153                 if (!flash_io_check_fw_integrity()) {
    154                     updateStatus = US_INFINITE_LOOP;
    155                 } else updateStatus++;
    156             } break;
    157             case US_DONE: {
    158             } break;
    159         }
    160     }
    161     gpio_clear(ST_LED0_PORT, ST_LED0_PIN | ST_LED1_PIN);
    162     gpio_clear(ST_LED2_PORT, ST_LED2_PIN | ST_LED3_PIN);
    163 }