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 }