embkernel
 All Classes Functions Variables Typedefs Groups Pages
DrvUart.cpp
1 //------------------------------------------------------------------------------
2 //This file is part of embKernel.
3 //See license.txt for the full license governing this code.
4 //------------------------------------------------------------------------------
5 
6 #include "DrvUart.hpp"
7 
8 DrvUart* DrvUart::sInstances[3];
9 
10 DrvUart::DrvUart(size_t rxBufferSize, size_t txBufferSize) :
11  mBufferRx(rxBufferSize), mBufferTx(txBufferSize) {
12  mIntCallbacks = 0;
13 }
14 
15 DrvUart::~DrvUart() {
16 
17 }
18 
19 void DrvUart::init(DrvTypes::UART port, int baudrate, DrvTypes::UART_PARITY parity, DrvTypes::UART_STOP_BITS stopBits) {
20  IRQn_Type irqType;
21 
22  switch (port) {
23  case DrvTypes::DRV_UART1:
24  mUart = USART1;
25  irqType = USART1_IRQn;
26  break;
27  case DrvTypes::DRV_UART2:
28  mUart = USART2;
29  irqType = USART2_IRQn;
30  break;
31  case DrvTypes::DRV_UART3:
32  mUart = USART3;
33  irqType = USART3_IRQn;
34  break;
35  default:
36  return;
37  }
38 
39  sInstances[port - 1] = this;
40 
41  mUart->CR1 = USART_CR1_TE | USART_CR1_RXNEIE; //0x2C;
42  mUart->CR2 = 0x00;
43  mUart->CR3 = 0x00;
44  setBaudrate(baudrate);
45  setParity(parity);
46  setStopBits(stopBits);
47 
48  NVIC ->IP[irqType] = RTOS_INT_PRI;
49  NVIC_EnableIRQ(irqType);
50  mUart->CR1 |= USART_CR1_UE;
51 }
52 
53 void DrvUart::setBaudrate(int baudrate) {
54  uint16_t enableMask = mUart->CR1 & USART_CR1_UE;
55  mUart->CR1 &= ~enableMask; //Disable
56  if (mUart == USART1 ) {
57  mUart->BRR = DRV_CFG_PCLK2_FREQ / baudrate;
58  }
59  else {
60  mUart->BRR = DRV_CFG_PCLK1_FREQ / baudrate;
61  }
62  mBaudrate = baudrate;
63  mUart->CR1 |= enableMask; //Restore previous enable state
64 }
65 
66 void DrvUart::setParity(DrvTypes::UART_PARITY parity) {
67  uint16_t enableMask = mUart->CR1 & USART_CR1_UE;
68  mUart->CR1 &= ~enableMask; //Disable
69  switch (parity) {
70  case DrvTypes::DRV_UART_PARITY_NONE:
71  mUart->CR1 &= ~(USART_CR1_PCE | USART_CR1_M );
72  break;
73  case DrvTypes::DRV_UART_PARITY_EVEN:
74  mUart->CR1 |= USART_CR1_PCE | USART_CR1_M;
75  mUart->CR1 &= ~USART_CR1_PS;
76  break;
77  case DrvTypes::DRV_UART_PARITY_ODD:
78  mUart->CR1 |= USART_CR1_PCE | USART_CR1_M;
79  mUart->CR1 |= USART_CR1_PS;
80  break;
81  }
82  mUart->CR1 |= enableMask; //Restore previous enabled state
83 }
84 
85 void DrvUart::setStopBits(DrvTypes::UART_STOP_BITS stopBits) {
86  uint16_t enableMask = mUart->CR1 & USART_CR1_UE;
87  mUart->CR1 &= ~enableMask; //Disable
88  mUart->CR2 &= ~USART_CR2_STOP;
89  switch (stopBits) {
90  case DrvTypes::DRV_UART_STOP_BITS_1:
91  break;
92  case DrvTypes::DRV_UART_STOP_BITS_1_5:
93  mUart->CR2 |= USART_CR2_STOP_1 | USART_CR2_STOP_0;
94  break;
95  case DrvTypes::DRV_UART_STOP_BITS_2:
96  mUart->CR2 |= USART_CR2_STOP_1;
97  break;
98  }
99  mUart->CR1 |= enableMask; //Restore previous enable state
100 }
101 
102 int DrvUart::read(void* buffer, int len, Rtos::TICK timeout) {
103  int left = len;
104  uint8_t* p = (uint8_t*) buffer;
105  while (left > 0) {
106  int count = mBufferRx.read(p, left, timeout);
107  if (p) {
108  p += count;
109  }
110  if (!count) {
111  break;
112  }
113  left -= count;
114  }
115  return len - left;
116 }
117 
118 int DrvUart::write(const void* buffer, int len, Rtos::TICK timeout) {
119  len = mBufferTx.write((const uint8_t*) buffer, len, timeout);
120  enableTxCompletedInterrupt();
121  return len;
122 }
123 
124 void DrvUart::onInterrupt() {
125  if (mIntCallbacks) {
126  while (mUart->SR & USART_SR_RXNE ) { //RX
127  if (mUart->SR & USART_SR_PE ) {
128  mIntCallbacks->onRxParityErrorInt();
129  }
130  else {
131  mIntCallbacks->onRxInt(mUart->DR & 0xFF);
132  }
133  }
134  if (((mUart->SR & USART_SR_TC )&&(mUart->CR1 & USART_CR1_TCIE))) { //TX complete
135  uint8_t byte;
136  if(mIntCallbacks->onTxCompletedInt(&byte)) {
137  mUart->DR = byte;
138  }
139  else {
140  disableTxCompletedInterrupt();
141  }
142  }
143  }
144  else {
145  { //RX
146  int i = 0;
147  uint8_t buffer[16];
148  while (((mUart->SR & USART_SR_RXNE )&& (i < (int) sizeof(buffer)))) {
149  buffer[i++] = mUart->DR & 0xFF;
150  }
151  mBufferRx.writeFromInt(buffer, i);
152  }
153  if (((mUart->SR & USART_SR_TC )&&(mUart->CR1 & USART_CR1_TCIE))) { //TX complete
154  uint8_t buffer;
155  int len = mBufferTx.readFromInt(&buffer, 1);
156  if (len > 0) {
157  mUart->DR = buffer;
158  }
159  if (mBufferTx.getCount() == 0) {
160  disableTxCompletedInterrupt();
161  }
162  }
163  }
164 }
165 
166 extern "C" void RtosInterrupt::IRQ_USART1() {
167  DrvUart::sInstances[0]->onInterrupt();
168 }
169 
170 extern "C" void RtosInterrupt::IRQ_USART2() {
171  DrvUart::sInstances[1]->onInterrupt();
172 }
173 
174 extern "C" void RtosInterrupt::IRQ_USART3() {
175  DrvUart::sInstances[2]->onInterrupt();
176 }