summaryrefslogtreecommitdiffstats
path: root/radiator-plc/stm32/app/usart.c
diff options
context:
space:
mode:
Diffstat (limited to 'radiator-plc/stm32/app/usart.c')
-rw-r--r--radiator-plc/stm32/app/usart.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/radiator-plc/stm32/app/usart.c b/radiator-plc/stm32/app/usart.c
new file mode 100644
index 0000000..52866b7
--- /dev/null
+++ b/radiator-plc/stm32/app/usart.c
@@ -0,0 +1,149 @@
+#include "project.h"
+
+#define BUFFER_SIZE 768
+
+ring_t rx1_ring;
+static uint8_t rx1_ring_buf[BUFFER_SIZE];
+
+ring_t tx1_ring;
+static uint8_t tx1_ring_buf[BUFFER_SIZE];
+
+//unsigned locked = 25000;
+unsigned locked = 0;
+
+
+
+
+
+void usart_ticker (void)
+{
+ if (locked) locked--;
+}
+
+
+
+static char unlock[] = "octopus banana";
+static int unlock_ptr = 0;
+
+
+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);
+
+ if (locked) {
+ if (unlock[unlock_ptr] == data)
+ unlock_ptr++;
+ else
+ unlock_ptr = 0;
+
+ if (!unlock[unlock_ptr]) {
+ printf ("Unlocked!\r\n");
+ unlock_ptr = 0;
+ locked = 0;
+ }
+ }
+
+
+ if (!locked)
+ 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);
+ }
+
+}
+
+
+int
+_write (int file, char *ptr, int len)
+{
+ int ret = len;
+
+ if (file == 1) {
+ while (len--) {
+ if (*ptr == '\n')
+ ring_write_byte (&tx1_ring, '\r');
+
+ ring_write_byte (&tx1_ring, * (ptr++));
+ }
+
+ 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
+usart1_queue_buf (void *buf, size_t len)
+{
+ ring_write (&tx1_ring, buf, len);
+ USART_CR1 (USART1) |= USART_CR1_TXEIE;
+}
+
+
+
+void
+usart1_drain (void)
+{
+ while (!ring_empty (&tx1_ring));
+}
+
+
+
+void
+usart_init (void)
+{
+ rcc_periph_clock_enable (RCC_USART1);
+
+ ring_init (&rx1_ring, rx1_ring_buf, sizeof (rx1_ring_buf));
+ ring_init (&tx1_ring, tx1_ring_buf, sizeof (tx1_ring_buf));
+
+
+ /* Enable the USART1,2 interrupt. */
+ nvic_enable_irq (NVIC_USART1_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);
+
+ /* 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);
+
+
+ /* Enable USART1 Receive interrupt. */
+ USART_CR1 (USART1) |= USART_CR1_RXNEIE;
+
+ /* Finally enable the USARTs. */
+ usart_enable (USART1);
+}