Advertisement
teplofizik

uart.c (DMX)

May 27th, 2013
690
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.78 KB | None | 0 0
  1. //
  2. // Драйвер UART
  3. //
  4.  
  5. #include "uart.h"
  6. #include "gpio.h"
  7. #include "clock.h"
  8. #include <stm32f4xx.h>
  9. #include <string.h>
  10.  
  11. #define BUFFER_SIZE   16
  12.  
  13. typedef struct
  14. {
  15.     USART_TypeDef * USART;
  16.    
  17.     uint32_t (*     GetClock)(void);
  18.    
  19.     volatile uint32_t * RCCRegister;
  20.     uint32_t            RCCMask;
  21.  
  22.     IRQn_Type           IRQn;
  23.    
  24.     uint32_t        AlternateFunction;
  25.     TPin            TX;
  26.     TPin            RX;
  27. } TUartPort;
  28.  
  29. typedef struct
  30. {
  31.     void (* onBreak)(uint32_t);
  32.     void (* onReceive)(uint32_t, uint8_t);
  33.     void (* onTransmitted)(uint32_t);
  34.     void (* onTransmitCompleted)(uint32_t);
  35.    
  36.     uint32_t Index;
  37.    
  38.     uint8_t  Buffer[BUFFER_SIZE];
  39.     uint32_t IndexToSend;
  40.     uint32_t IndexToAdd;
  41.    
  42.     bool     Completed;
  43. } TUartState;
  44.  
  45. // Таблица UART'ов
  46. static const TUartPort Ports[] = {
  47.     { USART1, &clock_GetAPB2, &RCC->APB2ENR, RCC_APB2ENR_USART1EN, USART1_IRQn, 7, {PA, 9}, {PA, 10} },
  48.     { USART2, &clock_GetAPB1, &RCC->APB1ENR, RCC_APB1ENR_USART2EN, USART2_IRQn, 7, {PD, 5}, {PD, 6} },
  49.     { USART3, &clock_GetAPB1, &RCC->APB1ENR, RCC_APB1ENR_USART3EN, USART3_IRQn, 7, {PB, 10}, {PB, 11} },
  50. };
  51.  
  52. static TUartState States[sizeof(Ports) / sizeof(Ports[0])];
  53. static const int PortCount = sizeof(Ports) / sizeof(Ports[0]);
  54.  
  55. // Оповестить о Break
  56. static void uart_onBreak(TUart Uart)
  57. {
  58.     if(States[Uart].onBreak) States[Uart].onBreak(States[Uart].Index);
  59. }
  60.  
  61. // Принять байт
  62. static void uart_onReceive(TUart Uart, uint8_t Data)
  63. {
  64.     if(States[Uart].onReceive) States[Uart].onReceive(States[Uart].Index, Data);
  65. }
  66.  
  67. // Оповестить о опустошении передающего буфера
  68. static void uart_onTransmitted(TUart Uart)
  69. {
  70.     if(States[Uart].onTransmitted) States[Uart].onTransmitted(States[Uart].Index);
  71. }
  72.  
  73. // Оповестить о завершении передачи
  74. static void uart_onTransmitCompleted(TUart Uart)
  75. {
  76.     if(States[Uart].onTransmitCompleted) States[Uart].onTransmitCompleted(States[Uart].Index);
  77. }
  78.  
  79. void USART_IRQHandler(TUart Uart)
  80. {
  81.     USART_TypeDef * USART = Ports[Uart].USART;
  82.     uint32_t Status = USART->SR;
  83.    
  84.     // Принят байт
  85.     if(Status & USART_SR_RXNE)
  86.     {
  87.         uint8_t Data = USART->DR;
  88.        
  89.         if(Status & USART_SR_FE)
  90.         {
  91.             uart_onBreak(Uart);
  92.         }
  93.         else
  94.         {
  95.             uart_onReceive(Uart, Data);
  96.         }
  97.     }
  98.     // Буфер пуст
  99.     if(Status & USART_SR_TXE)
  100.     {
  101.         if(States[Uart].IndexToSend != States[Uart].IndexToAdd)
  102.         {
  103.             uart_SendByte(Uart, States[Uart].Buffer[States[Uart].IndexToSend]);
  104.            
  105.             States[Uart].IndexToSend++;
  106.             if(States[Uart].IndexToSend >= BUFFER_SIZE) States[Uart].IndexToSend = 0;
  107.         }
  108.         else
  109.         {
  110.             States[Uart].Completed = true;
  111.             uart_onTransmitted(Uart);
  112.         }
  113.     }
  114.    
  115.     if(Status & USART_SR_TC)
  116.     {
  117.         if(States[Uart].IndexToSend == States[Uart].IndexToAdd)
  118.         {
  119.             USART->CR1 &= ~(USART_CR1_TXEIE | USART_CR1_TCIE);  // Transmitter empty interrupt enable
  120.             uart_onTransmitCompleted(Uart);
  121.         }
  122.     }
  123. }
  124.  
  125. // Прерывание от USART
  126. void USART1_IRQHandler(void) { USART_IRQHandler(UART1); }
  127. void USART2_IRQHandler(void) { USART_IRQHandler(UART2); }
  128. void USART3_IRQHandler(void) { USART_IRQHandler(UART3); }
  129.  
  130. // Инициализация модуля USART
  131. // Аргументы: 2
  132. //  Index - номер модуля
  133. //  BaudRate - скорость
  134. // Результаты: нет
  135. void uart_Init(TUart Uart, uint32_t BaudRate)
  136. {
  137.     if(Uart >= PortCount) return;
  138.  
  139.     memset(&States[0], 0, sizeof(States));
  140.    
  141.     {
  142.         USART_TypeDef * USART = Ports[Uart].USART;
  143.        
  144.         // Тактирование
  145.         *Ports[Uart].RCCRegister |= Ports[Uart].RCCMask;
  146.        
  147.         USART->CR1 = USART_CR1_UE |     // USART Enable
  148.                      0;
  149.        
  150.         uart_SetBaudrate(Uart, BaudRate);
  151.        
  152.         NVIC_EnableIRQ(Ports[Uart].IRQn);
  153.     }
  154.    
  155.     // Выводы - режим альтернативной функции
  156.     gpio_HighLevel(&Ports[Uart].TX);
  157.     gpio_SetAlternateFunction(&Ports[Uart].TX, Ports[Uart].AlternateFunction);
  158.     gpio_SetAlternateFunction(&Ports[Uart].RX, Ports[Uart].AlternateFunction);
  159. }
  160.  
  161. // Установить номер порта (для обратной связи)
  162. void uart_SetPortIndex(TUart Uart, uint32_t Index)
  163. {
  164.     if(Uart >= PortCount) return;
  165.    
  166.     States[Uart].Index = Index;
  167. }
  168.  
  169. // Режим GPIO при передаче (заданное состояние линии)
  170. void uart_GPIOMode(TUart Uart, bool Value)
  171. {
  172.     if(Uart >= PortCount) return;
  173.    
  174.     if(Value)
  175.     {
  176.         gpio_HighLevel(&Ports[Uart].TX);
  177.     }
  178.     else
  179.     {
  180.         gpio_LowLevel(&Ports[Uart].TX);
  181.     }
  182.    
  183.     gpio_DigitalOutput(&Ports[Uart].TX);
  184. }
  185.  
  186. // Количество стоповых бит
  187. void uart_StopBits(TUart Uart, TUartStopBits StopBits)
  188. {
  189.     USART_TypeDef * USART;
  190.     if(Uart >= PortCount) return;
  191.    
  192.     USART = Ports[Uart].USART;
  193.    
  194.     USART->CR2 &= ~USART_CR2_STOP;
  195.     switch(StopBits)
  196.     {
  197.     case STOP_BITS_0_5: // 0b01
  198.         USART->CR2 |= USART_CR2_STOP_0;
  199.         break;
  200.     case STOP_BITS_1:   // 0b00
  201.         break;
  202.     case STOP_BITS_1_5: // 0b11
  203.         USART->CR2 |= USART_CR2_STOP_0 | USART_CR2_STOP_1;
  204.         break;
  205.     case STOP_BITS_2:   // 0b10
  206.         USART->CR2 |= USART_CR2_STOP_1;
  207.         break;
  208.     }
  209. }
  210.  
  211. // Разрешить прим
  212. void uart_ReceiveEnable(TUart Uart, bool Enable)
  213. {
  214.     USART_TypeDef * USART;
  215.     if(Uart >= PortCount) return;
  216.    
  217.     USART = Ports[Uart].USART;
  218.    
  219.     if(Enable)
  220.     {
  221.         USART->CR1 |= USART_CR1_RXNEIE | // RXNE interrupt enable
  222.                       USART_CR1_RE |     // Receiver enable
  223.                       0;
  224.     }
  225.     else
  226.     {
  227.         USART->CR1 &= ~(USART_CR1_RXNEIE | // RXNE interrupt enable
  228.                         USART_CR1_RE |     // Receiver enable
  229.                         0);
  230.     }
  231. }
  232.  
  233. // Разрешить передачу
  234. void uart_TransmitEnable(TUart Uart, bool Enable)
  235. {
  236.     USART_TypeDef * USART;
  237.     if(Uart >= PortCount) return;
  238.    
  239.     USART = Ports[Uart].USART;
  240.    
  241.     if(Enable)
  242.     {
  243.         USART->CR1 |= USART_CR1_TCIE |   // Transmission complete interrupt enable
  244.                       USART_CR1_TE |     // Transmitter enable
  245.                       0;
  246.     }
  247.     else
  248.     {
  249.         USART->CR1 &= ~(USART_CR1_TCIE |   // Transmission complete interrupt enable
  250.                         USART_CR1_TE |     // Transmitter enable
  251.                         0);
  252.     }
  253. }
  254.  
  255. // Режим передачи данных
  256. void uart_UARTMode(TUart Uart)
  257. {
  258.     if(Uart >= PortCount) return;
  259.    
  260.     gpio_SetAlternateFunction(&Ports[Uart].TX, Ports[Uart].AlternateFunction);
  261. }
  262.  
  263. // Отправка байта
  264. void uart_SendByte(TUart Uart, uint8_t Data)
  265. {
  266.     if(Uart >= PortCount) return;
  267.    
  268.     States[Uart].Completed = false;
  269.     Ports[Uart].USART->DR = Data;
  270.    
  271.     if(!(Ports[Uart].USART->CR1 & USART_CR1_TXEIE))
  272.         Ports[Uart].USART->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;  // Transmitter empty interrupt enable
  273. }
  274.  
  275. static int32_t uart_GetFreeBytesCount(TUart Uart)
  276. {
  277.     if(States[Uart].IndexToAdd >= States[Uart].IndexToSend)
  278.     {
  279.         return BUFFER_SIZE - (States[Uart].IndexToAdd - States[Uart].IndexToSend);
  280.     }
  281.     else
  282.     {
  283.         return BUFFER_SIZE - (BUFFER_SIZE + States[Uart].IndexToAdd - States[Uart].IndexToSend);
  284.     }
  285. }
  286.  
  287. // Отправка буфера
  288. void uart_Send(TUart Uart, uint8_t * Data, int32_t BytesToSend, int32_t * BytesSended)
  289. {
  290.     int32_t Sended = 0;
  291.     int32_t FreeBytes = 0;
  292.     int i;
  293.    
  294.     if(BytesSended) *BytesSended = 0;
  295.     if(Uart >= PortCount) return;
  296.    
  297.     FreeBytes = uart_GetFreeBytesCount(Uart);
  298.    
  299.     {
  300.         uint8_t * Buffer = &States[Uart].Buffer[0];
  301.         uint32_t  Index  = States[Uart].IndexToAdd;
  302.        
  303.         if(BytesToSend > FreeBytes - 1) BytesToSend = FreeBytes - 1;
  304.        
  305.         // Добавим
  306.         for(i = 0; i < BytesToSend; i++)
  307.         {
  308.             Buffer[Index] = Data[i];
  309.            
  310.             Sended++;
  311.             Index++;
  312.             if(Index >= BUFFER_SIZE) Index = 0;
  313.         }
  314.        
  315.         States[Uart].IndexToAdd = Index;
  316.     }
  317.    
  318.     // Если ждМ, то отправим
  319.     if(States[Uart].Completed && Sended)
  320.     {
  321.         uart_SendByte(Uart, States[Uart].Buffer[States[Uart].IndexToSend]);
  322.        
  323.         States[Uart].IndexToSend++;
  324.         if(States[Uart].IndexToSend >= BUFFER_SIZE) States[Uart].IndexToSend = 0;
  325.     }
  326.    
  327.     *BytesSended = Sended;
  328. }
  329.  
  330. // Установить скорость передачи
  331. void uart_SetBaudrate(TUart Uart, uint32_t Baudrate)
  332. {
  333.     USART_TypeDef * USART;
  334.     if(Uart >= PortCount) return;
  335.    
  336.     USART = Ports[Uart].USART;
  337.    
  338.     // Ждм завершения передачи
  339.     while(!(USART->SR & USART_SR_TC)) {}
  340.    
  341.     Ports[Uart].USART->BRR = Ports[Uart].GetClock() / Baudrate;
  342. }
  343.  
  344. // Установить обработчик
  345. void uart_SetHandler(TUart Uart, TUartEvent Event, void * Handler)
  346. {
  347.     if(Uart >= PortCount) return;
  348.    
  349.     switch(Event)
  350.     {
  351.     case UART_EVENT_ONBREAK:             States[Uart].onBreak = (void(*)(uint32_t))Handler; break;
  352.     case UART_EVENT_ONRECEIVE:           States[Uart].onReceive = (void(*)(uint32_t, uint8_t))Handler; break;
  353.     case UART_EVENT_ONTRANSMITTED:       States[Uart].onTransmitted = (void(*)(uint32_t))Handler; break;
  354.     case UART_EVENT_ONTRANSMITCOMPLETED: States[Uart].onTransmitCompleted = (void(*)(uint32_t))Handler; break;
  355.     }
  356. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement