summaryrefslogtreecommitdiff
path: root/gm_platform/fw/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'gm_platform/fw/serial.c')
-rw-r--r--gm_platform/fw/serial.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/gm_platform/fw/serial.c b/gm_platform/fw/serial.c
index ae639c0..468c523 100644
--- a/gm_platform/fw/serial.c
+++ b/gm_platform/fw/serial.c
@@ -31,7 +31,9 @@
volatile struct dma_tx_buf usart_tx_buf;
-static void usart_schedule_dma();
+static void usart_schedule_dma(void);
+int usart_putc_nonblocking(char c);
+int usart_putc(char c);
void usart_dma_init() {
usart_tx_buf.xfr_start = -1,
@@ -39,7 +41,7 @@ void usart_dma_init() {
usart_tx_buf.wr_pos = 0,
/* Configure DMA 1 Channel 2 to handle uart transmission */
- DMA1_Channel2->CPAR = (unsigned int)&(USART1->TDR);
+ DMA1_Channel2->CPAR = (uint32_t)&(USART1->TDR);
DMA1_Channel2->CCR = (0<<DMA_CCR_PL_Pos)
| DMA_CCR_DIR
| (0<<DMA_CCR_MSIZE_Pos) /* 8 bit */
@@ -47,6 +49,13 @@ void usart_dma_init() {
| DMA_CCR_MINC
| DMA_CCR_TCIE; /* Enable transfer complete interrupt. */
+ DMA1_Channel3->CMAR = (uint32_t)&(CRC->DR);
+ DMA1_Channel3->CCR = (1<<DMA_CCR_PL_Pos)
+ | (0<<DMA_CCR_MSIZE_Pos) /* 8 bit */
+ | (0<<DMA_CCR_PSIZE_Pos) /* 8 bit */
+ | DMA_CCR_PINC
+ | DMA_CCR_TCIE; /* Enable transfer complete interrupt. */
+
/* triggered on transfer completion. We use this to process the ADC data */
NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
NVIC_SetPriority(DMA1_Channel2_3_IRQn, 1<<5);
@@ -61,8 +70,13 @@ void usart_dma_init() {
/* other interrupts clear */
| USART_CR1_TE
| USART_CR1_RE;
- /* Set divider for 1MBd @48MHz system clock. */
- USART1->BRR = 48;
+ /* Set divider for 115.2kBd @48MHz system clock. */
+ //USART1->BRR = 417;
+
+ //USART1->BRR = 48; /* 1MBd */
+ USART1->BRR = 96; /* 500kBd */
+ USART1->BRR = 192; /* 250kBd */
+ //USART1->BRR = 208; /* 230400 */
USART1->CR2 = USART_CR2_TXINV | USART_CR2_RXINV;
@@ -112,13 +126,19 @@ int usart_dma_fifo_push(volatile struct dma_tx_buf *buf, char c) {
return 0;
}
-void usart_putc(char c) {
+int usart_putc(char c) {
/* push char to fifo, busy-loop if stalled to wait for USART to empty fifo via DMA */
while (usart_dma_fifo_push(&usart_tx_buf, c) == -EBUSY) {
/* idle */
}
+ return 0;
}
+int usart_putc_nonblocking(char c) {
+ return usart_dma_fifo_push(&usart_tx_buf, c);
+}
+
+
void DMA1_Channel2_3_IRQHandler(void) {
/* Transfer complete */
DMA1->IFCR |= DMA_IFCR_CTCIF2;
@@ -130,10 +150,28 @@ void DMA1_Channel2_3_IRQHandler(void) {
void usart_send_packet(const uint8_t *data, size_t len) {
/* ignore return value as putf is blocking and always succeeds */
- (void)cobs_encode_usart((char *)data, len);
+ (void)cobs_encode_usart(usart_putc, (char *)data, len);
/* If the DMA stream is idle right now, schedule a transfer */
if (!(DMA1_Channel2->CCR & DMA_CCR_EN))
usart_schedule_dma();
}
+int usart_send_packet_nonblocking(const uint8_t *data, size_t len) {
+ /* ignore return value as putf is blocking and always succeeds */
+ /* FIXME DEBUG */
+ //int rc = cobs_encode_usart(usart_putc_nonblocking, (char *)data, len);
+ //if (rc)
+ // return rc;
+ /* END */
+ static uint8_t x = 0;
+
+ for (size_t i=0; i<351; i++)
+ usart_putc_nonblocking(x++);
+
+ /* If the DMA stream is idle right now, schedule a transfer */
+ if (!(DMA1_Channel2->CCR & DMA_CCR_EN))
+ usart_schedule_dma();
+ return 0;
+}
+