Subversion Repositories libSerial

Rev

Rev 9 | Rev 13 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9 Rev 10
Line 4... Line 4...
4
 *  Created on: 4 Jan 2016
4
 *  Created on: 4 Jan 2016
5
 *      Author: Mike
5
 *      Author: Mike
6
 *
6
 *
7
 *      This (ab)uses the STMCubeMX HAL declarations to implement a generic STM32F1xx
7
 *      This (ab)uses the STMCubeMX HAL declarations to implement a generic STM32F1xx
8
 *      USART driver layer
8
 *      USART driver layer
9
 *
9
 *
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
 */
Line 34... Line 34...
34
/* returns the number of characters received by the Rx USART */
34
/* returns the number of characters received by the Rx USART */
35
uint16_t
35
uint16_t
36
SerialCharsReceived(usart_ctl *instance)
36
SerialCharsReceived(usart_ctl *instance)
37
{
37
{
38
  uint16_t result = 0; // assume no characters received yet
38
  uint16_t result = 0; // assume no characters received yet
39
 
39
 
40
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
40
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
41
 
41
 
42
  if (instance->rx_usart_buffer_full)
42
  if (instance->rx_usart_buffer_full)
43
  { // buffer is full...
43
  { // buffer is full...
44
    result = RX_USART_BUFF_SIZ;
44
    result = RX_USART_BUFF_SIZ;
Line 56... Line 56...
56
  return result;
56
  return result;
57
}
57
}
58
 
58
 
59
uint16_t SerialTransmitSpace(usart_ctl *instance)
59
uint16_t SerialTransmitSpace(usart_ctl *instance)
60
{
60
{
-
 
61
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
-
 
62
  uint16_t result;
-
 
63
  if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
-
 
64
  {
-
 
65
    result = instance->tx_usart_running ? 0 : TX_USART_BUFF_SIZ;
-
 
66
  }
-
 
67
  else if (instance->tx_usart_in_Ptr > instance->tx_usart_out_Ptr)
-
 
68
  { // buffer has not wrapped...
61
  return TX_USART_BUFF_SIZ - instance->tx_usart_count;
69
    result = TX_USART_BUFF_SIZ - instance->tx_usart_in_Ptr - instance->tx_usart_out_Ptr;
-
 
70
  }
-
 
71
  else
-
 
72
  { // buffer has possibly wrapped...
-
 
73
    result = TX_USART_BUFF_SIZ - instance->tx_usart_out_Ptr + instance->tx_usart_in_Ptr;
-
 
74
  }
-
 
75
 
-
 
76
  if (instance->tx_usart_running)
-
 
77
    __HAL_UART_ENABLE_IT(instance->Handle, UART_IT_TXE);
-
 
78
  return result;
62
}
79
}
63
 
80
 
64
inline uint8_t
81
inline uint8_t
65
PollSerial(usart_ctl *instance)
82
PollSerial(usart_ctl *instance)
66
{
83
{
Line 120... Line 137...
120
PutCharSerialFIFO(usart_ctl *instance, uint8_t c)
137
PutCharSerialFIFO(usart_ctl *instance, uint8_t c)
121
{
138
{
122
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
139
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
123
 
140
 
124
  instance->tx_usart_buff[instance->tx_usart_in_Ptr++] = c;
141
  instance->tx_usart_buff[instance->tx_usart_in_Ptr++] = c;
125
  instance->tx_usart_count += 1;
-
 
126
  if (instance->tx_usart_in_Ptr >= TX_USART_BUFF_SIZ)
142
  if (instance->tx_usart_in_Ptr >= TX_USART_BUFF_SIZ)
127
  {
143
  {
128
    instance->tx_usart_in_Ptr = 0;
144
    instance->tx_usart_in_Ptr = 0;
129
  }
145
  }
130
  /* Handle overrun by losing oldest characters */
146
  /* Handle overrun by losing oldest characters */
131
  if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
147
  if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
132
  {
148
  {
-
 
149
    instance->tx_usart_overruns ++;
133
    instance->tx_usart_out_Ptr++;
150
    instance->tx_usart_out_Ptr++;
134
    if (instance->tx_usart_out_Ptr >= TX_USART_BUFF_SIZ)
151
    if (instance->tx_usart_out_Ptr >= TX_USART_BUFF_SIZ)
135
    {
152
    {
136
      instance->tx_usart_out_Ptr = 0;
153
      instance->tx_usart_out_Ptr = 0;
137
    }
154
    }
Line 143... Line 160...
143
 
160
 
144
void UART_IRQHandler(usart_ctl *instance)
161
void UART_IRQHandler(usart_ctl *instance)
145
{
162
{
146
 
163
 
147
  __disable_irq();
164
  __disable_irq();
148
  uint32_t rxStatus; // status from USART receiver
165
  // status from USART receiver
149
 
-
 
150
  rxStatus = instance->Handle->Instance->SR; // read the status bits - this resets all the hardware signalling flags
166
  uint32_t rxStatus = instance->Handle->Instance->SR; // read the status bits - this resets all the hardware signalling flags
151
 
167
 
152
  if ((rxStatus & USART_SR_LBD))
168
  if ((rxStatus & USART_SR_LBD))
153
    __HAL_UART_CLEAR_FLAG(instance->Handle, USART_SR_LBD);
169
    __HAL_UART_CLEAR_FLAG(instance->Handle, USART_SR_LBD);
154
 
170
 
155
  if ((rxStatus & USART_SR_RXNE) != RESET)
171
  if ((rxStatus & USART_SR_RXNE) != RESET)
Line 178... Line 194...
178
    /* Only enable the transmitter when baud detect has completed or check expired.
194
    /* Only enable the transmitter when baud detect has completed or check expired.
179
     * and the software is ready for it to be enabled as programming mode is wanting
195
     * and the software is ready for it to be enabled as programming mode is wanting
180
     * to receive a response and that can get blocked if we're streaming a lot of debug messages*/
196
     * to receive a response and that can get blocked if we're streaming a lot of debug messages*/
181
    if (instance->tx_usart_in_Ptr != instance->tx_usart_out_Ptr)
197
    if (instance->tx_usart_in_Ptr != instance->tx_usart_out_Ptr)
182
    {
198
    {
183
 
-
 
184
      instance->Handle->Instance->DR =
199
      instance->Handle->Instance->DR =
185
          instance->tx_usart_buff[instance->tx_usart_out_Ptr++];
200
          instance->tx_usart_buff[instance->tx_usart_out_Ptr++];
186
      if (instance->tx_usart_count != 0)
-
 
187
        instance->tx_usart_count -= 1;
-
 
188
 
201
 
189
      if (instance->tx_usart_out_Ptr >= TX_USART_BUFF_SIZ)
202
      if (instance->tx_usart_out_Ptr >= TX_USART_BUFF_SIZ)
190
      {
203
      {
191
        instance->tx_usart_out_Ptr = 0;
204
        instance->tx_usart_out_Ptr = 0;
192
      }
205
      }
193
    }
206
    }
194
    if (instance->tx_usart_count == 0)
207
    if (instance->tx_usart_in_Ptr == instance->tx_usart_out_Ptr)
195
    {
208
    {
196
      __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
209
      __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
197
      instance->tx_usart_running = 0;
210
      instance->tx_usart_running = 0;
198
    }
211
    }
199
  }
212
  }
Line 214... Line 227...
214
{
227
{
215
 
228
 
216
  instance->tx_usart_out_Ptr = 0;
229
  instance->tx_usart_out_Ptr = 0;
217
  instance->tx_usart_running = 0;
230
  instance->tx_usart_running = 0;
218
  instance->tx_usart_in_Ptr = 0; /* setup in pointer last to drop any chars come in */
231
  instance->tx_usart_in_Ptr = 0; /* setup in pointer last to drop any chars come in */
219
  instance->tx_usart_count = 0;
232
  instance->tx_usart_overruns = 0;
220
}
233
}
221
 
234
 
222
/*
235
/*
223
 * \brief
236
 * \brief
224
 * void ResetRxBuffer(void) - resets the serial receiver buffer
237
 * void ResetRxBuffer(void) - resets the serial receiver buffer
Line 244... Line 257...
244
 * @brief check if tx buffer is empty...
257
 * @brief check if tx buffer is empty...
245
 */
258
 */
246
uint8_t
259
uint8_t
247
TxBufferEmpty(usart_ctl *instance)
260
TxBufferEmpty(usart_ctl *instance)
248
{
261
{
249
  return (0 == instance->tx_usart_count);
262
  if (instance->tx_usart_running)
-
 
263
    return 0;
-
 
264
 return (instance->Handle->Instance->SR & USART_SR_TC) == 0;
250
}
265
}
251
 
266
 
252
/***!
267
/***!
253
 * @brief wait for transmission to finish
268
 * @brief wait for transmission to finish
254
 */
269
 */
255
 
270
 
256
void TxWaitEmpty(usart_ctl *instance)
271
void TxWaitEmpty(usart_ctl *instance)
257
{
272
{
-
 
273
  // no wait if not running
-
 
274
  if (!instance->tx_usart_running)
-
 
275
    return;
-
 
276
  // wait for it to finish
258
  while (instance->tx_usart_count ||
277
  while (instance->tx_usart_running ||
259
         (instance->Handle->Instance->SR & USART_SR_TC) != RESET)
278
         (instance->Handle->Instance->SR & USART_SR_TC) != RESET)
260
  {
279
  {
261
  };
280
  };
262
}
281
}
263
 
282
 
Line 271... Line 290...
271
 
290
 
272
  /* cheat here - this is a macro and I have the same Instance member as the HAL handle, with the same meaning */
291
  /* cheat here - this is a macro and I have the same Instance member as the HAL handle, with the same meaning */
273
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
292
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_TXE);
274
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
293
  __HAL_UART_DISABLE_IT(instance->Handle, UART_IT_RXNE);
275
 
294
 
276
  instance->tx_usart_in_Ptr = 0;
-
 
277
  instance->tx_usart_out_Ptr = 0;
-
 
278
  instance->tx_usart_running = 0;
-
 
279
  instance->tx_usart_count = 0;
-
 
280
 
-
 
281
  instance->rx_usart_in_Ptr = 0;
295
FlushSerial(instance);
282
  instance->rx_usart_out_Ptr = 0;
-
 
283
  instance->rx_usart_buffer_full = 0;
-
 
284
}
296
}
285
 
297
 
286
void setBaud(usart_ctl *ctl, uint32_t baud)
298
void setBaud(usart_ctl *ctl, uint32_t baud)
287
{
299
{
288
  ctl->Handle->Init.BaudRate = baud;
300
  ctl->Handle->Init.BaudRate = baud;
Line 290... Line 302...
290
  HAL_UART_Init(ctl->Handle);
302
  HAL_UART_Init(ctl->Handle);
291
  __enable_irq();
303
  __enable_irq();
292
}
304
}
293
 
305
 
294
 
306
 
295
 
-
 
296
void sendString(usart_ctl *ctl, char const * string , int length)
-
 
297
{
-
 
298
  for (int i = 0; i < length; i++)
-
 
299
    PutCharSerial(ctl, string[i]);
-
 
300
}
-
 
301
 
-
 
302
/////////////////////////////////////////////////////////
307
/////////////////////////////////////////////////////////
303
/// Moved from generated code  to avoid crappy HAL handler
308
/// Moved from generated code  to avoid crappy HAL handler
304
#if defined SERIAL_UART1
309
#if defined SERIAL_UART1
305
void USART1_IRQHandler(void)
310
void USART1_IRQHandler(void)
306
{
311
{