Facebook
From Emerald Crocodile, 6 Years ago, written in C.
Embed
Download Paste or View Raw
Hits: 356
  1. #include <gpio.h>
  2. #include <delay.h>
  3. #include <irq.h>
  4. #include <stm32.h>
  5. #include <string.h>
  6. #include "queue.h"
  7. #include "uart.h"
  8. #include "leds.h"
  9.  
  10. #define RED_LED_GPIO GPIOA
  11. #define RED_LED_PIN 6
  12.  
  13. #define RedLEDon() RED_LED_GPIO->BSRRH = 1 << RED_LED_PIN
  14. #define RedLEDoff() RED_LED_GPIO->BSRRL = 1 << RED_LED_PIN
  15.  
  16. #define USART_Mode_Rx_Tx (USART_CR1_RE | USART_CR1_TE)
  17. #define USART_Enable USART_CR1_UE
  18. #define USART_WordLength_8b 0x0000
  19. #define USART_Parity_No 0x0000
  20. #define USART_StopBits_1 0x0000
  21. #define USART_FlowControl_None 0x0000
  22.  
  23. #define HSI_HZ 16000000U
  24. #define PCLK2_HZ HSI_HZ
  25.  
  26. #define USART1_GPIO GPIOA
  27. #define USART1_TXD_PIN 9
  28. #define USART1_RXD_PIN 10
  29.  
  30. #define BUFF_SIZE 100
  31.  
  32. char buffer[BUFF_SIZE];
  33. Queue queue;
  34. char buff[2] = "\0";
  35.  
  36. static void enableUSART() { USART1->CR1 |= USART_CR1_UE; }
  37.  
  38. static void initDMA2() {
  39.   RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
  40.  
  41.   DMA2_Stream7->CR =
  42.       4U << 25 | DMA_SxCR_PL_1 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_TCIE;
  43.   DMA2_Stream7->PAR = (uint32_t)&USART1->DR;
  44.  
  45.   DMA2_Stream5->CR = 4U << 25 | DMA_SxCR_PL_1 | DMA_SxCR_MINC | DMA_SxCR_TCIE;
  46.   DMA2_Stream5->PAR = (uint32_t)&USART1->DR;
  47.  
  48.   DMA2->HIFCR = DMA_HIFCR_CTCIF7 | DMA_HIFCR_CTCIF5;
  49.   NVIC_EnableIRQ(DMA2_Stream5_IRQn);
  50.   // DMA2->HIFCR = DMA_HIFCR_CTCIF7;
  51.   NVIC_EnableIRQ(DMA2_Stream7_IRQn);
  52. }
  53.  
  54. static int busyDMA() { return (DMA2_Stream7->CR & DMA_SxCR_EN); }
  55.  
  56. static void sendDMA(char *msg, uint32_t len) {
  57.   DMA2_Stream7->M0AR = (uint32_t)msg;
  58.   DMA2_Stream7->NDTR = len;
  59.   DMA2_Stream7->CR |= DMA_SxCR_EN;
  60. }
  61.  
  62. static void recvDMA(char *msg) {
  63.   DMA2_Stream5->M0AR = (uint32_t)msg;
  64.   DMA2_Stream5->NDTR = 2;
  65.   DMA2_Stream5->CR |= DMA_SxCR_EN;
  66. }
  67.  
  68. void initUSART1() {
  69.   uint32_t const baudrate = 9600U;
  70.  
  71.   RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
  72.   RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
  73.  
  74.   USART1->BRR = (PCLK2_HZ + (baudrate / 2U)) / baudrate;
  75.   USART1->CR1 = USART_Mode_Rx_Tx | USART_WordLength_8b | USART_Parity_No;
  76.   USART1->CR2 = USART_StopBits_1;
  77.   USART1->CR3 = USART_CR3_DMAT | USART_CR3_DMAR;
  78.  
  79.   GPIOafConfigure(USART1_GPIO, USART1_TXD_PIN, GPIO_OType_PP, GPIO_Fast_Speed,
  80.                   GPIO_PuPd_NOPULL, GPIO_AF_USART1);
  81.  
  82.   GPIOafConfigure(USART1_GPIO, USART1_RXD_PIN, GPIO_OType_PP, GPIO_Fast_Speed,
  83.                   GPIO_PuPd_UP, GPIO_AF_USART1);
  84.  
  85.   initDMA2();
  86.   enableUSART();
  87.   initQueue(&queue);
  88.   recvDMA(buff);
  89. }
  90.  
  91. void DMA2_Stream7_IRQHandler() {
  92.   uint32_t isr = DMA2->HISR;
  93.   if (isr & DMA_HISR_TCIF7) {
  94.     DMA2->HIFCR = DMA_HIFCR_CTCIF7;
  95.  
  96.     if (!isEmptyQueue(&queue)) {
  97.       uint32_t len = getStrQueue(&queue, buffer, BUFF_SIZE);
  98.       sendDMA(buffer, len);
  99.     }
  100.   }
  101. }
  102.  
  103. void DMA2_Stream5_IRQHandler() {
  104.   uint32_t isr = DMA2->HISR;
  105.   if (isr & DMA_HISR_TCIF5) {
  106.     DMA2->HIFCR = DMA_HIFCR_CTCIF5;
  107.     sendUSART(buff);
  108.     parseCmdLed(buff);
  109.     recvDMA(buff);
  110.   }
  111. }
  112.  
  113. void sendUSART(char *msg) {
  114.   // toggleLed(RED);
  115.   if (busyDMA()) {
  116.     putStrQueue(&queue, msg);
  117.   } else {
  118.     sendDMA(msg, strlen(msg));
  119.   }
  120. }
  121.