Skip to content

Instantly share code, notes, and snippets.

@lrodorigo
Last active April 3, 2020 07:59
Show Gist options
  • Save lrodorigo/3b975205962e403b50c647728d4cef6f to your computer and use it in GitHub Desktop.
Save lrodorigo/3b975205962e403b50c647728d4cef6f to your computer and use it in GitHub Desktop.
static xmodem_status xmodem_handle_packet(uint8_t header) {
/* Contains received data and 2 bytes CRC16 */
uint8_t received_data[X_PACKET_1024_SIZE + X_PACKET_CRC_SIZE];
/* Contains the remaining part of the header: the packet number and the 1-complement of the packet number
Note: does not contains the first-byte of the header (which is passed to this function) */
uint8_t received_header[X_PACKET_HEADER_SIZE];
xmodem_status status = X_OK;
uint16_t size = 0u;
if (X_SOH == header) {
size = X_PACKET_128_SIZE;
} else if (X_STX == header) {
size = X_PACKET_1024_SIZE;
} else {
/* Wrong header type. */
status = X_ERROR;
}
uint16_t length = size + X_PACKET_CRC_SIZE;
/* Get the packet (except for the header) from UART. */
uart_status header_status = uart_receive(&received_header[0u], X_PACKET_HEADER_SIZE);
uart_status packet_status = uart_receive(&received_data[0u], length);
uart_status comm_status = UART_OK;
/* If header or packet rx are not fine set comm_status */
if (header_status != UART_OK || packet_status != UART_OK)
comm_status = UART_ERROR;
/* The last two bytes are the CRC from the host. */
uint16_t crc_received = ((uint16_t) received_data[length - 2u] << 8u) | ((uint16_t) received_data[length - 1u]);
/* We calculate it too. */
uint16_t crc_calculated = xmodem_calc_crc(received_data, size);
/* If it is the first packet, then erase the memory. */
if (FALSE == x_first_packet_received) {
if (FLASH_OK == flash_erase(FLASH_APP_START_ADDRESS))
{
x_first_packet_received = true;
}
else
{
status |= X_ERROR_FLASH;
}
}
/* Error handling and flashing. */
if (X_OK == status) {
if (UART_OK != comm_status) {
/* UART error. */
status |= X_ERROR_UART;
}
if (xmodem_packet_number != received_header[X_PACKET_NUMBER_INDEX]) {
/* Packet number counter mismatch. */
status |= X_ERROR_NUMBER;
}
if (255u != (received_header[X_PACKET_NUMBER_INDEX] + received_header[X_PACKET_NUMBER_COMPLEMENT_INDEX])) {
/* The sum of the packet number and packet number complement aren't 255. */
/* The sum always has to be 255. */
status |= X_ERROR_NUMBER;
}
if (crc_calculated != crc_received) {
/* The calculated and received CRC are different. */
status |= X_ERROR_CRC;
}
/* Do the actual flashing. */
if (FLASH_OK != flash_write(xmodem_actual_flash_address, (uint32_t*) &received_data[0], (uint32_t)size/4u))
{
/* Flashing error. */
status |= X_ERROR_FLASH;
}
}
/* Raise the packet number and the address counters (if there wasn't any error). */
if (X_OK == status) {
xmodem_packet_number++;
xmodem_actual_flash_address += size;
}
return status;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment