Subversion Repositories libSerial

Rev

Rev 13 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 13 Rev 15
Line 10... Line 10...
10
 * Note - this requires the UART interrupt to be globally enabled in STM32CubeMX,
10
 * Note - this requires the UART interrupt to be globally enabled in STM32CubeMX,
11
 * but not to generate IRQ handler or HAL driver for the UART.
11
 * but not to generate IRQ handler or HAL driver for the UART.
12
 *
12
 *
13
 *
13
 *
14
 */
14
 */
-
 
15
 
15
#include "libSerial/serial.h"
16
#include "libSerial/serial.h"
16
 
17
 
17
/* workspaces for the USARTS being used */
18
/* workspaces for the USARTS being used */
18
#if defined SERIAL_UART1
19
#if defined SERIAL_UART1
19
usart_ctl uc1;
20
struct usart_ctl uc1;
20
#endif
21
#endif
21
#if defined SERIAL_UART2
22
#if defined SERIAL_UART2
22
usart_ctl uc2;
23
struct usart_ctl uc2;
23
#endif
24
#endif
24
#if defined SERIAL_UART3
25
#if defined SERIAL_UART3
25
usart_ctl uc3;
26
struct usart_ctl uc3;
26
#endif
27
#endif
27
#if defined SERIAL_UART4
28
#if defined SERIAL_UART4
28
usart_ctl uc4;
29
struct usart_ctl uc4;
29
#endif
30
#endif
30
#if defined SERIAL_UART5
31
#if defined SERIAL_UART5
31
usart_ctl uc5;
32
struct usart_ctl uc5;
32
#endif
33
#endif
33
 
34
 
34
uint16_t
35
uint16_t
35
SerialCharsReceived(usart_ctl *instance)
36
SerialCharsReceived(struct usart_ctl *instance)
36
{
37
{
37
  uint16_t result = 0; // assume no characters received yet
38
  uint16_t result = 0; // assume no characters received yet
38
 
39
 
39
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
40
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
40
 
41
 
41
  if (instance->rx_usart_buffer_full)
42
  if (instance->rx_usart_buffer_full)
42
  { // buffer is full...
43
  { // buffer is full...
43
    result = RX_USART_BUFF_SIZ;
44
    result = instance->rx_usart_buff_size;
44
  }
45
  }
45
  else if (instance->rx_usart_in_Ptr >= instance->rx_usart_out_Ptr)
46
  else if (instance->rx_usart_in_Ptr >= instance->rx_usart_out_Ptr)
46
  { // buffer has not wrapped...
47
  { // buffer has not wrapped...
47
    result = instance->rx_usart_in_Ptr - instance->rx_usart_out_Ptr;
48
    result = instance->rx_usart_in_Ptr - instance->rx_usart_out_Ptr;
48
  }
49
  }
49
  else
50
  else
50
  { // buffer has possibly wrapped...
51
  { // buffer has possibly wrapped...
51
    result = RX_USART_BUFF_SIZ - instance->rx_usart_out_Ptr + instance->rx_usart_in_Ptr;
52
    result = instance->rx_usart_buff_size - instance->rx_usart_out_Ptr + instance->rx_usart_in_Ptr;
52
  }
53
  }
53
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
54
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
54
 
55
 
55
  return result;
56
  return result;
56
}
57
}
57
 
58
 
58
uint16_t SerialTransmitSpace(usart_ctl *instance)
59
uint16_t SerialTransmitSpace(struct usart_ctl *instance)
59
{
60
{
60
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
61
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
61
  uint16_t result;
62
  uint16_t result;
62
  if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
63
  if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
63
  {
64
  {
64
    result = instance->tx_usart_running ? 0 : TX_USART_BUFF_SIZ;
65
    result = instance->tx_usart_running ? 0 : instance->tx_usart_buff_size;
65
  }
66
  }
66
  else if (instance->tx_usart_in_Ptr > instance->tx_usart_out_Ptr)
67
  else if (instance->tx_usart_in_Ptr > instance->tx_usart_out_Ptr)
67
  { // buffer has not wrapped...
68
  { // buffer has not wrapped...
68
    result = TX_USART_BUFF_SIZ - instance->tx_usart_in_Ptr - instance->tx_usart_out_Ptr;
69
    result = instance->tx_usart_buff_size - instance->tx_usart_in_Ptr - instance->tx_usart_out_Ptr;
69
  }
70
  }
70
  else
71
  else
71
  { // buffer has possibly wrapped...
72
  { // buffer has possibly wrapped...
72
    result = TX_USART_BUFF_SIZ - instance->tx_usart_out_Ptr + instance->tx_usart_in_Ptr;
73
    result = instance->tx_usart_buff_size - instance->tx_usart_out_Ptr + instance->tx_usart_in_Ptr;
73
  }
74
  }
74
 
75
 
75
  if (instance->tx_usart_running)
76
  if (instance->tx_usart_running)
76
    __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_TXE);
77
    __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_TXE);
77
  return result;
78
  return result;
78
}
79
}
79
 
80
 
80
inline uint8_t
81
inline uint8_t
81
PollSerial(usart_ctl *instance)
82
PollSerial(struct usart_ctl *instance)
82
{
83
{
83
  uint8_t rc;
84
  uint8_t rc;
84
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
85
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
85
  rc = (instance->rx_usart_buffer_full || (instance->rx_usart_in_Ptr != instance->rx_usart_out_Ptr));
86
  rc = (instance->rx_usart_buffer_full || (instance->rx_usart_in_Ptr != instance->rx_usart_out_Ptr));
86
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
87
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
87
 
88
 
88
  return rc;
89
  return rc;
89
}
90
}
90
 
91
 
91
inline uint8_t
92
inline uint8_t
92
GetCharSerial(usart_ctl *instance)
93
GetCharSerial(struct usart_ctl *instance)
93
{
94
{
94
  uint8_t c;
95
  uint8_t c;
95
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
96
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
96
  while (!instance->rx_usart_buffer_full && (instance->rx_usart_in_Ptr == instance->rx_usart_out_Ptr))
97
  while (!instance->rx_usart_buffer_full && (instance->rx_usart_in_Ptr == instance->rx_usart_out_Ptr))
97
  {
98
  {
Line 101... Line 102...
101
  }
102
  }
102
 
103
 
103
  c = instance->rx_usart_buff[instance->rx_usart_out_Ptr];
104
  c = instance->rx_usart_buff[instance->rx_usart_out_Ptr];
104
  instance->rx_usart_buffer_full = 0; /* removed character */
105
  instance->rx_usart_buffer_full = 0; /* removed character */
105
  instance->rx_usart_out_Ptr++;
106
  instance->rx_usart_out_Ptr++;
106
  if (instance->rx_usart_out_Ptr >= RX_USART_BUFF_SIZ)
107
  if (instance->rx_usart_out_Ptr >= instance->rx_usart_buff_size)
107
  {
108
  {
108
    instance->rx_usart_out_Ptr = 0;
109
    instance->rx_usart_out_Ptr = 0;
109
  }
110
  }
110
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
111
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
111
  return c;
112
  return c;
Line 115... Line 116...
115
 * \brief
116
 * \brief
116
 * void EnableSerialRxInterrupt(void) - this function is used from the interrupt handler and the main scheduler loop
117
 * void EnableSerialRxInterrupt(void) - this function is used from the interrupt handler and the main scheduler loop
117
 * to enable the serial rx interrupt after resetting the serial rx buffer...
118
 * to enable the serial rx interrupt after resetting the serial rx buffer...
118
 */
119
 */
119
inline void
120
inline void
120
EnableSerialRxInterrupt(usart_ctl *instance)
121
EnableSerialRxInterrupt(struct usart_ctl *instance)
121
{
122
{
122
  /* cheat here - this is a macro and I have the same Instance member as the HAL handle, with the same meaning */
123
  /* cheat here - this is a macro and I have the same Instance member as the HAL handle, with the same meaning */
123
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
124
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_RXNE);
124
}
125
}
125
 
126
 
Line 127... Line 128...
127
 * @brief send a character to the serial USART via placing it in the serial buffer
128
 * @brief send a character to the serial USART via placing it in the serial buffer
128
 *
129
 *
129
 */
130
 */
130
 
131
 
131
static void
132
static void
132
PutCharSerialFIFO(usart_ctl *instance, uint8_t c)
133
PutCharSerialFIFO(struct usart_ctl *instance, uint8_t c)
133
{
134
{
134
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
135
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
135
 
136
 
136
  instance->tx_usart_buff[instance->tx_usart_in_Ptr++] = c;
137
  instance->tx_usart_buff[instance->tx_usart_in_Ptr++] = c;
137
  if (instance->tx_usart_in_Ptr >= TX_USART_BUFF_SIZ)
138
  if (instance->tx_usart_in_Ptr >= instance->tx_usart_buff_size)
138
  {
139
  {
139
    instance->tx_usart_in_Ptr = 0;
140
    instance->tx_usart_in_Ptr = 0;
140
  }
141
  }
141
  /* Handle overrun by losing oldest characters */
142
  /* Handle overrun by losing oldest characters */
142
  if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
143
  if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
143
  {
144
  {
144
    instance->tx_usart_overruns++;
145
    instance->tx_usart_overruns++;
145
    instance->tx_usart_out_Ptr++;
146
    instance->tx_usart_out_Ptr++;
146
    if (instance->tx_usart_out_Ptr >= TX_USART_BUFF_SIZ)
147
    if (instance->tx_usart_out_Ptr >= instance->tx_usart_buff_size)
147
    {
148
    {
148
      instance->tx_usart_out_Ptr = 0;
149
      instance->tx_usart_out_Ptr = 0;
149
    }
150
    }
150
  }
151
  }
151
 
152
 
152
  instance->tx_usart_running = 1;
153
  instance->tx_usart_running = 1;
153
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_TXE);
154
  __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_TXE);
154
}
155
}
155
 
156
 
156
void UART_IRQHandler(usart_ctl *instance)
157
void UART_IRQHandler(struct usart_ctl *instance)
157
{
158
{
158
 
159
 
159
  __disable_irq();
160
  __disable_irq();
160
  // status from USART receiver
161
  // status from USART receiver
161
  uint32_t rxStatus = instance->Handle->Instance->SR; // read the status bits - this resets all the hardware signalling flags
162
  uint32_t rxStatus = instance->Handle->Instance->SR; // read the status bits - this resets all the hardware signalling flags
Line 170... Line 171...
170
 
171
 
171
    if (!instance->rx_usart_buffer_full)
172
    if (!instance->rx_usart_buffer_full)
172
    {
173
    {
173
      instance->rx_usart_buff[instance->rx_usart_in_Ptr++] = rxChar;
174
      instance->rx_usart_buff[instance->rx_usart_in_Ptr++] = rxChar;
174
 
175
 
175
      if (instance->rx_usart_in_Ptr >= RX_USART_BUFF_SIZ)
176
      if (instance->rx_usart_in_Ptr >= instance->rx_usart_buff_size)
176
      {
177
      {
177
        instance->rx_usart_in_Ptr = 0;
178
        instance->rx_usart_in_Ptr = 0;
178
      }
179
      }
179
      if (instance->rx_usart_in_Ptr == instance->rx_usart_out_Ptr)
180
      if (instance->rx_usart_in_Ptr == instance->rx_usart_out_Ptr)
180
      {
181
      {
Line 192... Line 193...
192
    if (instance->tx_usart_in_Ptr != instance->tx_usart_out_Ptr)
193
    if (instance->tx_usart_in_Ptr != instance->tx_usart_out_Ptr)
193
    {
194
    {
194
      instance->Handle->Instance->DR =
195
      instance->Handle->Instance->DR =
195
          instance->tx_usart_buff[instance->tx_usart_out_Ptr++];
196
          instance->tx_usart_buff[instance->tx_usart_out_Ptr++];
196
 
197
 
197
      if (instance->tx_usart_out_Ptr >= TX_USART_BUFF_SIZ)
198
      if (instance->tx_usart_out_Ptr >= instance-> tx_usart_buff_size)
198
      {
199
      {
199
        instance->tx_usart_out_Ptr = 0;
200
        instance->tx_usart_out_Ptr = 0;
200
      }
201
      }
201
    }
202
    }
202
    if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
203
    if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
Line 206... Line 207...
206
    }
207
    }
207
  }
208
  }
208
  __enable_irq();
209
  __enable_irq();
209
}
210
}
210
 
211
 
211
void PutCharSerial(usart_ctl *instance, uint8_t c)
212
void PutCharSerial(struct usart_ctl *instance, uint8_t c)
212
{
213
{
213
  PutCharSerialFIFO(instance, c);
214
  PutCharSerialFIFO(instance, c);
214
}
215
}
215
 
216
 
216
void ResetTxBuffer(usart_ctl *instance)
217
void ResetTxBuffer(struct usart_ctl *instance)
217
{
218
{
218
 
219
 
219
  instance->tx_usart_out_Ptr = 0;
220
  instance->tx_usart_out_Ptr = 0;
220
  instance->tx_usart_running = 0;
221
  instance->tx_usart_running = 0;
221
  instance->tx_usart_in_Ptr = 0; /* setup in pointer last to drop any chars come in */
222
  instance->tx_usart_in_Ptr = 0; /* setup in pointer last to drop any chars come in */
Line 224... Line 225...
224
 
225
 
225
/*
226
/*
226
 * \brief
227
 * \brief
227
 * void ResetRxBuffer(void) - resets the serial receiver buffer
228
 * void ResetRxBuffer(void) - resets the serial receiver buffer
228
 */
229
 */
229
void ResetRxBuffer(usart_ctl *instance)
230
void ResetRxBuffer(struct usart_ctl *instance)
230
{
231
{
231
 
232
 
232
  instance->rx_usart_out_Ptr = 0;
233
  instance->rx_usart_out_Ptr = 0;
233
  instance->rx_usart_buffer_full = 0;
234
  instance->rx_usart_buffer_full = 0;
234
  instance->rx_usart_in_Ptr = 0; /* setup in pointer last to drop any chars come in */
235
  instance->rx_usart_in_Ptr = 0; /* setup in pointer last to drop any chars come in */
235
}
236
}
236
 
237
 
237
/***!
238
/***!
238
 * @brief Flush Serial input and output buffers
239
 * @brief Flush Serial input and output buffers
239
 */
240
 */
240
void FlushSerial(usart_ctl *instance)
241
void FlushSerial(struct usart_ctl *instance)
241
{
242
{
242
  ResetRxBuffer(instance);
243
  ResetRxBuffer(instance);
243
  ResetTxBuffer(instance);
244
  ResetTxBuffer(instance);
244
}
245
}
245
 
246
 
246
/***!
247
/***!
247
 * @brief check if tx buffer is empty...
248
 * @brief check if tx buffer is empty...
248
 */
249
 */
249
uint8_t
250
uint8_t
250
TxBufferEmpty(usart_ctl *instance)
251
TxBufferEmpty(struct usart_ctl *instance)
251
{
252
{
252
  if (instance->tx_usart_running)
253
  if (instance->tx_usart_running)
253
    return 0;
254
    return 0;
254
  return (instance->Handle->Instance->SR & USART_SR_TC) == 0;
255
  return (instance->Handle->Instance->SR & USART_SR_TC) == 0;
255
}
256
}
256
 
257
 
257
/***!
258
/***!
258
 * @brief wait for transmission to finish
259
 * @brief wait for transmission to finish
259
 */
260
 */
260
 
261
 
261
void TxWaitEmpty(usart_ctl *instance)
262
void TxWaitEmpty(struct usart_ctl *instance)
262
{
263
{
263
  // no wait if not running
264
  // no wait if not running
264
  if (!instance->tx_usart_running)
265
  if (!instance->tx_usart_running)
265
    return;
266
    return;
266
  // wait for it to finish
267
  // wait for it to finish
Line 271... Line 272...
271
}
272
}
272
 
273
 
273
/****
274
/****
274
 * @brief Initialise control structure
275
 * @brief Initialise control structure
275
 */
276
 */
276
void init_usart_ctl(usart_ctl *instance, UART_HandleTypeDef *handle)
277
void init_usart_ctl(struct usart_ctl *instance, UART_HandleTypeDef *handle,
-
 
278
                                   volatile uint8_t * tx_buffer,
-
 
279
                                                   volatile uint8_t * rx_buffer,
-
 
280
                                                   uint16_t tx_buffer_size,
-
 
281
                                                   uint16_t rx_buffer_size)
277
{
282
{
278
 
283
 
279
  instance->Handle = handle;
284
  instance->Handle = handle;
-
 
285
  instance->tx_usart_buff = tx_buffer;
-
 
286
  instance->rx_usart_buff = rx_buffer;
-
 
287
  instance->tx_usart_buff_size = tx_buffer_size;
-
 
288
  instance->rx_usart_buff_size = rx_buffer_size;
280
 
289
 
281
  /* cheat here - this is a macro and I have the same Instance member as the HAL handle, with the same meaning */
290
  /* cheat here - this is a macro and I have the same Instance member as the HAL handle, with the same meaning */
282
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
291
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
283
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
292
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
284
 
293
 
285
  FlushSerial(instance);
294
  FlushSerial(instance);
286
}
295
}
287
 
296
 
288
void setBaud(usart_ctl *ctl, uint32_t baud)
297
void setBaud(struct usart_ctl *ctl, uint32_t baud)
289
{
298
{
290
  ctl->Handle->Init.BaudRate = baud;
299
  ctl->Handle->Init.BaudRate = baud;
291
  __disable_irq();
300
  __disable_irq();
292
  HAL_UART_Init(ctl->Handle);
301
  HAL_UART_Init(ctl->Handle);
293
  __enable_irq();
302
  __enable_irq();
294
}
303
}
295
 
304
 
296
/////////////////////////////////////////////////////////
-
 
297
/// Moved from generated code  to avoid crappy HAL handler
-
 
298
#if defined SERIAL_UART1
-
 
299
void USART1_IRQHandler(void)
-
 
300
{
-
 
301
  UART_IRQHandler(&uc1);
-
 
302
}
-
 
303
#endif
-
 
304
#if defined SERIAL_UART2
-
 
305
void USART2_IRQHandler(void)
-
 
306
{
-
 
307
  UART_IRQHandler(&uc2);
-
 
308
}
-
 
309
#endif
-
 
310
#if defined SERIAL_UART3
-
 
311
void USART3_IRQHandler(void)
-
 
312
{
-
 
313
  UART_IRQHandler(&uc3);
-
 
314
}
-
 
315
#endif
-
 
316
#if defined SERIAL_UART4
-
 
317
void UART4_IRQHandler(void)
-
 
318
{
-
 
319
  UART_IRQHandler(&uc4);
-
 
320
}
-
 
321
#endif
-
 
322
#if defined SERIAL_UART5
-
 
323
void UART5_IRQHandler(void)
-
 
324
{
-
 
325
  UART_IRQHandler(&uc5);
-
 
326
}
-
 
327
#endif
-