summaryrefslogtreecommitdiffstats
path: root/app/usart.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/usart.c')
-rw-r--r--app/usart.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/app/usart.c b/app/usart.c
new file mode 100644
index 0000000..e0a80b1
--- /dev/null
+++ b/app/usart.c
@@ -0,0 +1,191 @@
+#include "project.h"
+
+#define BUFFER_SIZE 256
+#define BIG_BUFFER_SIZE 600
+
+ring_t rx1_ring;
+static uint8_t rx1_ring_buf[BUFFER_SIZE];
+
+ring_t tx1_ring;
+static uint8_t tx1_ring_buf[BUFFER_SIZE];
+
+ring_t rx2_ring;
+static uint8_t rx2_ring_buf[BUFFER_SIZE];
+
+ring_t tx2_ring;
+static uint8_t tx2_ring_buf[BIG_BUFFER_SIZE];
+
+void
+usart1_isr (void)
+{
+ uint8_t data;
+
+ /* Check if we were called because of RXNE. */
+ if (((USART_CR1 (USART1) & USART_CR1_RXNEIE) != 0) &&
+ ((USART_SR (USART1) & USART_SR_RXNE) != 0))
+ {
+
+ /* Retrieve the data from the peripheral. */
+ data = usart_recv (USART1);
+
+
+ ring_write_byte (&rx1_ring, data);
+ }
+
+ /* Check if we were called because of TXE. */
+ if (((USART_CR1 (USART1) & USART_CR1_TXEIE) != 0) &&
+ ((USART_SR (USART1) & USART_SR_TXE) != 0))
+ {
+
+ if (ring_read_byte (&tx1_ring, &data))
+ {
+ /*No more data, Disable the TXE interrupt, it's no longer needed. */
+ USART_CR1 (USART1) &= ~USART_CR1_TXEIE;
+ }
+ else
+ {
+ usart_send (USART1, data);
+ }
+ }
+
+}
+
+void
+usart2_isr (void)
+{
+ uint8_t data;
+
+ /* Check if we were called because of RXNE. */
+ if (((USART_CR1 (USART2) & USART_CR1_RXNEIE) != 0) &&
+ ((USART_SR (USART2) & USART_SR_RXNE) != 0))
+ {
+
+ /* Retrieve the data from the peripheral. */
+ data = usart_recv (USART2);
+
+ ring_write_byte (&rx2_ring, data);
+ }
+
+ /* Check if we were called because of TXE. */
+ if (((USART_CR1 (USART2) & USART_CR1_TXEIE) != 0) &&
+ ((USART_SR (USART2) & USART_SR_TXE) != 0))
+ {
+
+ if (ring_read_byte (&tx2_ring, &data))
+ {
+ /*No more data, Disable the TXE interrupt, it's no longer needed. */
+ USART_CR1 (USART2) &= ~USART_CR1_TXEIE;
+ }
+ else
+ {
+ usart_send_blocking (USART2, data);
+ }
+ }
+
+}
+
+int
+_write (int file, char *ptr, int len)
+{
+ int ret;
+
+ if (file == 1)
+ {
+ ret = ring_write (&tx1_ring, (uint8_t *) ptr, len);
+
+ if (ret < 0)
+ ret = -ret;
+
+ USART_CR1 (USART1) |= USART_CR1_TXEIE;
+ return ret;
+ }
+
+ errno = EIO;
+ return -1;
+}
+
+void
+usart1_queue (uint8_t d)
+{
+ ring_write_byte (&tx1_ring, d);
+ USART_CR1 (USART1) |= USART_CR1_TXEIE;
+}
+
+
+void
+usart2_queue (uint8_t d)
+{
+ ring_write_byte (&tx2_ring, d);
+ USART_CR1 (USART2) |= USART_CR1_TXEIE;
+}
+
+void
+usart2_drain (void)
+{
+ while (!ring_empty (&tx2_ring));
+}
+
+void
+usart1_drain (void)
+{
+ while (!ring_empty (&tx1_ring));
+}
+
+
+
+void
+usart_init (void)
+{
+ rcc_periph_clock_enable (RCC_USART1);
+ rcc_periph_clock_enable (RCC_USART2);
+ rcc_periph_clock_enable (RCC_USART3);
+
+ ring_init (&rx1_ring, rx1_ring_buf, sizeof (rx1_ring_buf));
+ ring_init (&tx1_ring, tx1_ring_buf, sizeof (tx1_ring_buf));
+
+ ring_init (&rx2_ring, rx2_ring_buf, sizeof (rx2_ring_buf));
+ ring_init (&tx2_ring, tx2_ring_buf, sizeof (tx2_ring_buf));
+
+
+ /* Enable the USART1,2 interrupt. */
+ nvic_enable_irq (NVIC_USART1_IRQ);
+ nvic_enable_irq (NVIC_USART2_IRQ);
+
+ /* Map pins, and set usart2 to have pull ups */
+ gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART1_TX);
+ gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT,
+ GPIO_USART1_RX);
+
+ gpio_set_mode (GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);
+ gpio_set_mode (GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN,
+ GPIO_USART2_RX);
+ gpio_set (GPIOA, GPIO_USART2_RX);
+
+
+ /* Setup UART1 parameters. */
+ usart_set_baudrate (USART1, 38400);
+ usart_set_databits (USART1, 8);
+ usart_set_stopbits (USART1, USART_STOPBITS_1);
+ usart_set_parity (USART1, USART_PARITY_NONE);
+ usart_set_flow_control (USART1, USART_FLOWCONTROL_NONE);
+ usart_set_mode (USART1, USART_MODE_TX_RX);
+
+ /* Setup UART2 parameters. */
+ usart_set_baudrate (USART2, 9600);
+ usart_set_databits (USART2, 8);
+ usart_set_stopbits (USART2, USART_STOPBITS_1);
+ usart_set_parity (USART2, USART_PARITY_NONE);
+ usart_set_flow_control (USART2, USART_FLOWCONTROL_NONE);
+ usart_set_mode (USART2, USART_MODE_TX_RX);
+
+
+ /* Enable USART1,2 Receive interrupt. */
+ USART_CR1 (USART1) |= USART_CR1_RXNEIE;
+ USART_CR1 (USART2) |= USART_CR1_RXNEIE;
+
+ /* Finally enable the USARTs. */
+ usart_enable (USART1);
+ usart_enable (USART2);
+}