diff options
author | jaseg <git@jaseg.de> | 2020-11-27 13:38:56 +0100 |
---|---|---|
committer | jaseg <git@jaseg.de> | 2020-11-27 13:38:56 +0100 |
commit | 424310d957cb04bfacba9c711ee7f074fd41f962 (patch) | |
tree | cb7eba38c7bf5eb2c232d162f0a9dd5d7b1d5adc /prototype/fw/src | |
parent | 0a03b84e1756b36d014a83f685da1950a8e8361e (diff) | |
download | ihsm-424310d957cb04bfacba9c711ee7f074fd41f962.tar.gz ihsm-424310d957cb04bfacba9c711ee7f074fd41f962.tar.bz2 ihsm-424310d957cb04bfacba9c711ee7f074fd41f962.zip |
demo fw WIP
Diffstat (limited to 'prototype/fw/src')
-rw-r--r-- | prototype/fw/src/crc32.h | 6 | ||||
-rw-r--r-- | prototype/fw/src/main.c | 131 | ||||
-rw-r--r-- | prototype/fw/src/microcobs.c | 25 |
3 files changed, 122 insertions, 40 deletions
diff --git a/prototype/fw/src/crc32.h b/prototype/fw/src/crc32.h index 7a3a729..c115820 100644 --- a/prototype/fw/src/crc32.h +++ b/prototype/fw/src/crc32.h @@ -5,8 +5,10 @@ typedef uint32_t crc32_t; -inline static uint32_t crc32_reset() { return ~0; } +inline static uint32_t crc32_reset(void); +uint32_t crc32_reset() { return ~0; } uint32_t crc32_update(uint32_t old_state, uint8_t c); -inline static uint32_t crc32_finalize(uint32_t state) { return ~state; } +inline static uint32_t crc32_finalize(uint32_t state); +uint32_t crc32_finalize(uint32_t state) { return ~state; } #endif /* __CRC_32_H__ */ diff --git a/prototype/fw/src/main.c b/prototype/fw/src/main.c index de920eb..fb3c302 100644 --- a/prototype/fw/src/main.c +++ b/prototype/fw/src/main.c @@ -1,49 +1,128 @@ #include <global.h> +#include "microcobs.h" +#include "crc32.h" + +struct __attribute__((packed)) ll_pkt_trailer { + uint32_t crc32; +}; + +struct __attribute__((packed)) req_pkt { + uint32_t req_seq; + struct ll_pkt_trailer trailer; +}; + +struct __attribute__((packed)) res_pkt { + uint32_t req_seq; + uint32_t res_seq; + struct ll_pkt_trailer trailer; +}; + +struct tx_state { + uint8_t *tx_char; + int remaining_bytes; +}; + +static crc32_t pkt_crc(void *pkt, struct ll_pkt_trailer *trailer); +crc32_t pkt_crc(void *pkt, struct ll_pkt_trailer *trailer) { + crc32_t crc = crc32_reset(); + for (uint8_t *in = (uint8_t *)pkt; in < (uint8_t *)trailer; in++) { + crc = crc32_update(crc, *in); + } + return crc32_finalize(crc); +} + +static void packetize(void *pkt, struct ll_pkt_trailer *trailer); +void packetize(void *pkt, struct ll_pkt_trailer *trailer) { + trailer->crc32 = pkt_crc(pkt, trailer); +} + int main(void) { RCC->AHBENR |= RCC_AHBENR_GPIOAEN; RCC->APB2ENR |= RCC_APB2ENR_USART1EN; - GPIOA->MODER |= (2 << GPIO_MODER_MODER9_Pos); - GPIOA->AFR[1] = (7 << (9-8)*4); + GPIOA->MODER |= (2 << GPIO_MODER_MODER9_Pos) | (2 << GPIO_MODER_MODER10_Pos); + GPIOA->AFR[1] = (7 << (9-8)*4) | (7 << (10-8)*4); SystemCoreClockUpdate(); int apb2_clock = SystemCoreClock / APB2_PRESC; int baudrate = 115200; - USART1->CR1 = USART_CR1_MME | USART_CR1_TE; + USART1->CR1 = USART_CR1_TE | USART_CR1_RE; USART1->BRR = (apb2_clock + baudrate/2) / baudrate; + USART1->CR1 |= USART_CR2_RXINV; USART1->CR1 |= USART_CR1_UE; - char s[12] = { - '0', '0', '0', '0', '0', - ' ', 'T', 'E', 'S', 'T', - '\n', '\0'}; - int line = 0; - char *c = s; - USART1->TDR = *(c++); /* Kick off transmission */ + int req_seq = 0; + int res_seq = 0; + struct req_pkt req_buf = { 0 }; + struct tx_state tx_st = { 0 }; + struct res_pkt res_buf = { 0 }; + uint8_t rx_buf[512]; + uint8_t tx_buf[512]; + size_t rx_char = 0; + unsigned int rx_overrun = 0; + unsigned int rx_cobs_error = 0; + unsigned int rx_framing_error = 0; + unsigned int rx_crc_error = 0; + + USART1->TDR = 0; /* Kick off transmission */ while (23) { - if (USART1->ISR & USART_ISR_TXE) { + if (tx_st.remaining_bytes == 0) { + res_buf.req_seq = req_seq; + res_buf.res_seq = res_seq; + res_seq += 1; + packetize(&res_buf, &res_buf.trailer); + tx_st.tx_char = tx_buf; + tx_st.remaining_bytes = cobs_encode((uint8_t *)&res_buf, sizeof(res_buf), tx_buf, sizeof(tx_buf));; + } + + if (USART1->ISR & USART_ISR_TXE && tx_st.remaining_bytes > 0) { for (int i=0; i<100; i++) asm volatile ("nop"); - USART1->TDR = *(c++); - if (!*c) { - c = s; - line++; - int tmp = line; - tmp %= 100000; - s[0] = '0' + tmp/10000; - tmp %= 10000; - s[1] = '0' + tmp/1000; - tmp %= 1000; - s[2] = '0' + tmp/100; - tmp %= 100; - s[3] = '0' + tmp/10; - tmp %= 10; - s[4] = '0' + tmp; + USART1->TDR = *(tx_st.tx_char); + tx_st.tx_char += 1; + tx_st.remaining_bytes -= 1; + } + + if (USART1->ISR & USART_ISR_ORE) + USART1->ICR = USART_ICR_ORECF; + + if (USART1->ISR & USART_ISR_NE) + USART1->ICR = USART_ICR_NCF; + + if (USART1->ISR & USART_ISR_FE) + USART1->ICR = USART_ICR_FECF; + + if (USART1->ISR & USART_ISR_RXNE) { + uint8_t c = USART1->RDR; + if (!c) { + int rc = cobs_decode(rx_buf, rx_char, (uint8_t *)&req_buf, sizeof(req_buf)); + if (rc < 0) { + rx_cobs_error += 1; + } else { + if (rc == sizeof(req_buf)) { + crc32_t check_crc = pkt_crc(&req_buf, &req_buf.trailer); + if (check_crc != req_buf.trailer.crc32) { + rx_crc_error += 1; + } else { + req_seq = req_buf.req_seq; + } + } else { + rx_framing_error += 1; + } + } + rx_char = 0; + } else { + if (rx_char < sizeof(rx_buf)) { + rx_buf[rx_char] = c; + rx_char += 1; + } else { + rx_overrun += 1; + } } } } diff --git a/prototype/fw/src/microcobs.c b/prototype/fw/src/microcobs.c index aea199e..5007344 100644 --- a/prototype/fw/src/microcobs.c +++ b/prototype/fw/src/microcobs.c @@ -7,15 +7,15 @@ ssize_t cobs_encode_sg(const struct sg_entry input[], uint8_t *output, size_t ou { size_t idx_pos = 0; size_t out_pos = 1; - size_t sg_idx = 0; + ssize_t sg_idx = 0; const struct sg_entry *e = input; - fprintf(stderr, "\nsg_entry %016x %zd\n", e->target, e->size); + /* fprintf(stderr, "\nsg_entry %016x %zd\n", e->target, e->size); */ while (e->size >= 0) { if (sg_idx == e->size) { sg_idx = 0; e++; - fprintf(stderr, "\nsg_entry %016x %zd\n", e->target, e->size); + /* fprintf(stderr, "\nsg_entry %016x %zd\n", e->target, e->size); */ continue; } @@ -23,7 +23,7 @@ ssize_t cobs_encode_sg(const struct sg_entry input[], uint8_t *output, size_t ou return -1; uint8_t inbyte = e->target[sg_idx]; - fprintf(stderr, "%02x ", inbyte); + /* fprintf(stderr, "%02x ", inbyte); */ sg_idx += 1; if (out_pos - idx_pos >= 255) { @@ -49,8 +49,8 @@ ssize_t cobs_encode_sg(const struct sg_entry input[], uint8_t *output, size_t ou return -1; output[idx_pos] = out_pos - idx_pos; output[out_pos] = 0x00; - fprintf(stderr, "\n"); - fprintf(stderr, "Finishing %d %d %d\n", idx_pos, out_pos, out_pos - idx_pos); + /* fprintf(stderr, "\n"); */ + /* fprintf(stderr, "Finishing %d %d %d\n", idx_pos, out_pos, out_pos - idx_pos); */ return out_pos + 1; } @@ -66,7 +66,7 @@ ssize_t cobs_encode(const uint8_t *input, size_t input_len, uint8_t *output, siz return -1; uint8_t inbyte = input[in_pos]; - fprintf(stderr, "%02x ", inbyte); + /* fprintf(stderr, "%02x ", inbyte); */ in_pos += 1; if (out_pos - idx_pos >= 255) { @@ -92,12 +92,13 @@ ssize_t cobs_encode(const uint8_t *input, size_t input_len, uint8_t *output, siz return -1; output[idx_pos] = out_pos - idx_pos; output[out_pos] = 0x00; - fprintf(stderr, "\n"); - fprintf(stderr, "Finishing %d %d %d\n", idx_pos, out_pos, out_pos - idx_pos); + /* fprintf(stderr, "\n"); */ + /* fprintf(stderr, "Finishing %d %d %d\n", idx_pos, out_pos, out_pos - idx_pos); */ return out_pos + 1; } +/* input and output may overlap. */ ssize_t cobs_decode(const uint8_t *input, size_t input_len, uint8_t *output, size_t output_len) { size_t out_pos = 0; @@ -108,20 +109,20 @@ ssize_t cobs_decode(const uint8_t *input, size_t input_len, uint8_t *output, siz while (in_pos < input_len) { size_t len = input[in_pos]; - fprintf(stderr, "Length @%03d = %03d\n", in_pos, len); + /* fprintf(stderr, "Length @%03d = %03d\n", in_pos, len); */ in_pos += 1; for (size_t i=0; i<len-1; i++) { if (in_pos >= input_len) break; - fprintf(stderr, "Copy %03d -> %03d %02x\n", in_pos, out_pos, input[in_pos]); + /* fprintf(stderr, "Copy %03d -> %03d %02x\n", in_pos, out_pos, input[in_pos]); */ output[out_pos] = input[in_pos]; in_pos += 1; out_pos += 1; } if (in_pos < input_len && len < 255) { - fprintf(stderr, "Zero %03d %02x\n", out_pos); + /* fprintf(stderr, "Zero %03d %02x\n", out_pos); */ output[out_pos] = 0; out_pos += 1; } |