mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-28 16:34:14 +01:00
76 lines
2.2 KiB
C
76 lines
2.2 KiB
C
|
#include <stdbool.h>
|
||
|
#include <string.h>
|
||
|
#include "hw.h"
|
||
|
#include "vendor.h"
|
||
|
|
||
|
|
||
|
static const uint8_t cmd_token[3] = { 'C', 'M', 'D' };
|
||
|
static const uint8_t rsp_token[3] = { 'R', 'S', 'P' };
|
||
|
static const uint8_t err_token[3] = { 'E', 'R', 'R' };
|
||
|
|
||
|
|
||
|
static void primer_get_and_calculate_crc32 (uint8_t *buffer, uint8_t rx_length, uint32_t *crc32) {
|
||
|
hw_uart_read(buffer, rx_length);
|
||
|
*crc32 = hw_crc32_calculate(buffer, rx_length);
|
||
|
}
|
||
|
|
||
|
static uint8_t primer_get_command (uint8_t *buffer, uint8_t *rx_length) {
|
||
|
uint32_t calculated_crc32;
|
||
|
uint32_t received_crc32;
|
||
|
uint8_t token[4];
|
||
|
|
||
|
while (1) {
|
||
|
hw_crc32_reset();
|
||
|
|
||
|
primer_get_and_calculate_crc32(token, 4, &calculated_crc32);
|
||
|
if (memcmp(token, cmd_token, 3) != 0) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
primer_get_and_calculate_crc32(rx_length, 1, &calculated_crc32);
|
||
|
|
||
|
if (*rx_length > 0) {
|
||
|
primer_get_and_calculate_crc32(buffer, *rx_length, &calculated_crc32);
|
||
|
}
|
||
|
|
||
|
hw_uart_read((uint8_t *) (&received_crc32), sizeof(received_crc32));
|
||
|
if (calculated_crc32 == received_crc32) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return token[3];
|
||
|
}
|
||
|
|
||
|
static void primer_send_and_calculate_crc32 (uint8_t *buffer, uint8_t tx_length, uint32_t *crc32) {
|
||
|
hw_uart_write(buffer, tx_length);
|
||
|
*crc32 = hw_crc32_calculate(buffer, tx_length);
|
||
|
}
|
||
|
|
||
|
static void primer_send_response (uint8_t cmd, uint8_t *buffer, uint8_t tx_length, bool error) {
|
||
|
uint32_t calculated_crc32;
|
||
|
uint8_t *token = (uint8_t *) (error ? err_token : rsp_token);
|
||
|
uint8_t length = (error ? 0 : tx_length);
|
||
|
|
||
|
hw_crc32_reset();
|
||
|
|
||
|
primer_send_and_calculate_crc32(token, 3, &calculated_crc32);
|
||
|
primer_send_and_calculate_crc32(&cmd, 1, &calculated_crc32);
|
||
|
|
||
|
primer_send_and_calculate_crc32(&length, 1, &calculated_crc32);
|
||
|
|
||
|
if ((!error) && (tx_length > 0)) {
|
||
|
primer_send_and_calculate_crc32(buffer, tx_length, &calculated_crc32);
|
||
|
}
|
||
|
|
||
|
hw_uart_write((uint8_t *) (&calculated_crc32), sizeof(calculated_crc32));
|
||
|
}
|
||
|
|
||
|
|
||
|
void primer (void) {
|
||
|
hw_primer_init();
|
||
|
vendor_initial_configuration(primer_get_command, primer_send_response);
|
||
|
hw_uart_wait_busy();
|
||
|
hw_reset(NULL);
|
||
|
}
|