Subversion Repositories svn.mios32

Rev

Rev 1837 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1795 tk 1
// $Id: mios32_uart.c 2312 2016-02-27 23:04:51Z tk $
2
//! \defgroup MIOS32_UART
3
//!
4
//! U(S)ART functions for MIOS32
5
//!
6
//! Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
7
//! 
8
//! \{
9
/* ==========================================================================
10
 *
11
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
12
 *  Licensed for personal non-commercial use only.
13
 *  All other rights reserved.
14
 *
15
 * ==========================================================================
16
 */
17
 
18
/////////////////////////////////////////////////////////////////////////////
19
// Include files
20
/////////////////////////////////////////////////////////////////////////////
21
 
22
#include <mios32.h>
23
 
24
// this module can be optionally disabled in a local mios32_config.h file (included from mios32.h)
25
#if !defined(MIOS32_DONT_USE_UART)
26
 
27
 
28
/////////////////////////////////////////////////////////////////////////////
29
// Pin definitions and USART mappings
30
/////////////////////////////////////////////////////////////////////////////
31
 
2312 tk 32
// how many UARTs are supported?
1801 tk 33
#if MIOS32_UART_NUM > 3
1833 tk 34
# define NUM_SUPPORTED_UARTS 4
1801 tk 35
#else
36
# define NUM_SUPPORTED_UARTS MIOS32_UART_NUM
37
#endif
1795 tk 38
 
1801 tk 39
 
1797 tk 40
#define MIOS32_UART0_TX_PORT     GPIOA
1833 tk 41
#define MIOS32_UART0_TX_PIN      GPIO_Pin_2
1797 tk 42
#define MIOS32_UART0_RX_PORT     GPIOA
1833 tk 43
#define MIOS32_UART0_RX_PIN      GPIO_Pin_3
44
#define MIOS32_UART0             USART2
45
#define MIOS32_UART0_IRQ_CHANNEL USART2_IRQn
46
#define MIOS32_UART0_IRQHANDLER_FUNC void USART2_IRQHandler(void)
47
#define MIOS32_UART0_REMAP_FUNC  { GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); }
1795 tk 48
 
1833 tk 49
#define MIOS32_UART1_TX_PORT     GPIOD
50
#define MIOS32_UART1_TX_PIN      GPIO_Pin_8
51
#define MIOS32_UART1_RX_PORT     GPIOD
52
#define MIOS32_UART1_RX_PIN      GPIO_Pin_9
1795 tk 53
#define MIOS32_UART1             USART3
54
#define MIOS32_UART1_IRQ_CHANNEL USART3_IRQn
55
#define MIOS32_UART1_IRQHANDLER_FUNC void USART3_IRQHandler(void)
1833 tk 56
#define MIOS32_UART1_REMAP_FUNC  { GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3); GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3); }
1795 tk 57
 
1837 tk 58
// Since pin PB6 is allocated by the SCL input of the Audio DAC, we've to use a TX pin of a different UART! :-/
59
#define MIOS32_UART2_TX_PORT     GPIOC
1833 tk 60
#define MIOS32_UART2_TX_PIN      GPIO_Pin_6
61
#define MIOS32_UART2_RX_PORT     GPIOB
62
#define MIOS32_UART2_RX_PIN      GPIO_Pin_7
1837 tk 63
#define MIOS32_UART2_TX             USART6
64
#define MIOS32_UART2_RX             USART1
65
#define MIOS32_UART2_TX_IRQ_CHANNEL USART6_IRQn
66
#define MIOS32_UART2_RX_IRQ_CHANNEL USART1_IRQn
67
#define MIOS32_UART2_TX_IRQHANDLER_FUNC void USART6_IRQHandler(void)
68
#define MIOS32_UART2_RX_IRQHANDLER_FUNC void USART1_IRQHandler(void)
69
#define MIOS32_UART2_REMAP_FUNC  { GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); }
1797 tk 70
 
1833 tk 71
#define MIOS32_UART3_TX_PORT     GPIOC
72
#define MIOS32_UART3_TX_PIN      GPIO_Pin_12
73
#define MIOS32_UART3_RX_PORT     GPIOD
74
#define MIOS32_UART3_RX_PIN      GPIO_Pin_2
75
#define MIOS32_UART3             UART5
76
#define MIOS32_UART3_IRQ_CHANNEL UART5_IRQn
77
#define MIOS32_UART3_IRQHANDLER_FUNC void UART5_IRQHandler(void)
78
#define MIOS32_UART3_REMAP_FUNC  { GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5); GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5); }
1795 tk 79
 
80
 
81
/////////////////////////////////////////////////////////////////////////////
82
// Local variables
83
/////////////////////////////////////////////////////////////////////////////
84
 
1801 tk 85
#if NUM_SUPPORTED_UARTS >= 1
2312 tk 86
static u8  uart_assigned_to_midi;
1801 tk 87
static u32 uart_baudrate[NUM_SUPPORTED_UARTS];
1795 tk 88
 
1801 tk 89
static u8 rx_buffer[NUM_SUPPORTED_UARTS][MIOS32_UART_RX_BUFFER_SIZE];
90
static volatile u8 rx_buffer_tail[NUM_SUPPORTED_UARTS];
91
static volatile u8 rx_buffer_head[NUM_SUPPORTED_UARTS];
92
static volatile u8 rx_buffer_size[NUM_SUPPORTED_UARTS];
1795 tk 93
 
1801 tk 94
static u8 tx_buffer[NUM_SUPPORTED_UARTS][MIOS32_UART_TX_BUFFER_SIZE];
95
static volatile u8 tx_buffer_tail[NUM_SUPPORTED_UARTS];
96
static volatile u8 tx_buffer_head[NUM_SUPPORTED_UARTS];
97
static volatile u8 tx_buffer_size[NUM_SUPPORTED_UARTS];
1795 tk 98
#endif
99
 
100
 
101
/////////////////////////////////////////////////////////////////////////////
102
//! Initializes UART interfaces
103
//! \param[in] mode currently only mode 0 supported
104
//! \return < 0 if initialisation failed
105
//! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
106
/////////////////////////////////////////////////////////////////////////////
107
s32 MIOS32_UART_Init(u32 mode)
108
{
109
  // currently only mode 0 supported
110
  if( mode != 0 )
111
    return -1; // unsupported mode
112
 
1801 tk 113
#if NUM_SUPPORTED_UARTS == 0
1795 tk 114
  return -1; // no UARTs
115
#else
116
 
117
  // map UART pins
118
#if MIOS32_UART0_ASSIGNMENT != 0
119
  MIOS32_UART0_REMAP_FUNC;
120
#endif
1801 tk 121
#if NUM_SUPPORTED_UARTS >= 2 && MIOS32_UART1_ASSIGNMENT != 0
1795 tk 122
  MIOS32_UART1_REMAP_FUNC;
123
#endif
1801 tk 124
#if NUM_SUPPORTED_UARTS >= 3 && MIOS32_UART2_ASSIGNMENT != 0
1795 tk 125
  MIOS32_UART2_REMAP_FUNC;
126
#endif
1833 tk 127
#if NUM_SUPPORTED_UARTS >= 4 && MIOS32_UART2_ASSIGNMENT != 0
128
  MIOS32_UART3_REMAP_FUNC;
129
#endif
1795 tk 130
 
2312 tk 131
  // enable all USART clocks
132
  // TODO: more generic approach for different UART selections
133
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_USART6, ENABLE);
134
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3 | RCC_APB1Periph_UART4 | RCC_APB1Periph_UART5, ENABLE);
1795 tk 135
 
2312 tk 136
  // initialize UARTs and clear buffers
137
  {
138
    u8 uart;
139
    for(uart=0; uart<NUM_SUPPORTED_UARTS; ++uart) {
140
      rx_buffer_tail[uart] = rx_buffer_head[uart] = rx_buffer_size[uart] = 0;
141
      tx_buffer_tail[uart] = tx_buffer_head[uart] = tx_buffer_size[uart] = 0;
142
 
143
      MIOS32_UART_InitPortDefault(uart);
144
    }
145
  }
146
 
147
  // configure and enable UART interrupts
1795 tk 148
#if MIOS32_UART0_ASSIGNMENT != 0
2312 tk 149
  MIOS32_IRQ_Install(MIOS32_UART0_IRQ_CHANNEL, MIOS32_IRQ_UART_PRIORITY);
150
  USART_ITConfig(MIOS32_UART0, USART_IT_RXNE, ENABLE);
1795 tk 151
#endif
152
 
1801 tk 153
#if NUM_SUPPORTED_UARTS >= 2 && MIOS32_UART1_ASSIGNMENT != 0
2312 tk 154
  MIOS32_IRQ_Install(MIOS32_UART1_IRQ_CHANNEL, MIOS32_IRQ_UART_PRIORITY);
155
  USART_ITConfig(MIOS32_UART1, USART_IT_RXNE, ENABLE);
1795 tk 156
#endif
157
 
1801 tk 158
#if NUM_SUPPORTED_UARTS >= 3 && MIOS32_UART2_ASSIGNMENT != 0
2312 tk 159
  MIOS32_IRQ_Install(MIOS32_UART2_TX_IRQ_CHANNEL, MIOS32_IRQ_UART_PRIORITY);
160
  MIOS32_IRQ_Install(MIOS32_UART2_RX_IRQ_CHANNEL, MIOS32_IRQ_UART_PRIORITY);
161
  USART_ITConfig(MIOS32_UART2_RX, USART_IT_RXNE, ENABLE);
1795 tk 162
#endif
163
 
1833 tk 164
#if NUM_SUPPORTED_UARTS >= 4 && MIOS32_UART3_ASSIGNMENT != 0
2312 tk 165
  MIOS32_IRQ_Install(MIOS32_UART3_IRQ_CHANNEL, MIOS32_IRQ_UART_PRIORITY);
166
  USART_ITConfig(MIOS32_UART3, USART_IT_RXNE, ENABLE);
1833 tk 167
#endif
168
 
2312 tk 169
  // enable UARTs
1795 tk 170
#if MIOS32_UART0_ASSIGNMENT != 0
2312 tk 171
  USART_Cmd(MIOS32_UART0, ENABLE);
1795 tk 172
#endif
1801 tk 173
#if NUM_SUPPORTED_UARTS >= 2 && MIOS32_UART1_ASSIGNMENT != 0
2312 tk 174
  USART_Cmd(MIOS32_UART1, ENABLE);
1795 tk 175
#endif
1801 tk 176
#if NUM_SUPPORTED_UARTS >= 3 && MIOS32_UART2_ASSIGNMENT != 0
2312 tk 177
  USART_Cmd(MIOS32_UART2_RX, ENABLE);
178
  USART_Cmd(MIOS32_UART2_TX, ENABLE);
1795 tk 179
#endif
1833 tk 180
#if NUM_SUPPORTED_UARTS >= 4 && MIOS32_UART3_ASSIGNMENT != 0
2312 tk 181
  USART_Cmd(MIOS32_UART3, ENABLE);
1833 tk 182
#endif
1795 tk 183
 
2312 tk 184
  return 0; // no error
185
#endif
186
}
1795 tk 187
 
2312 tk 188
 
189
/////////////////////////////////////////////////////////////////////////////
190
//! \return 0 if UART is not assigned to a MIDI function
191
//! \return 1 if UART is assigned to a MIDI function
192
/////////////////////////////////////////////////////////////////////////////
193
s32 MIOS32_UART_IsAssignedToMIDI(u8 uart)
194
{
195
#if NUM_SUPPORTED_UARTS == 0
196
  return 0; // no UART available
197
#else
198
  return (uart_assigned_to_midi & (1 << uart)) ? 1 : 0;
1795 tk 199
#endif
2312 tk 200
}
1795 tk 201
 
2312 tk 202
 
203
/////////////////////////////////////////////////////////////////////////////
204
//! Initializes a given UART interface based on given baudrate and TX output mode
205
//! \param[in] uart UART number (0..2)
206
//! \param[in] baudrate the baudrate
207
//! \param[in] tx_pin_mode the TX pin mode
208
//!   <UL>
209
//!     <LI>MIOS32_BOARD_PIN_MODE_OUTPUT_PP: TX pin configured for push-pull mode
210
//!     <LI>MIOS32_BOARD_PIN_MODE_OUTPUT_OD: TX pin configured for open drain mode
211
//!   </UL>
212
//! \param[in] is_midi MIDI or common UART interface?
213
//! \return < 0 if initialisation failed
214
/////////////////////////////////////////////////////////////////////////////
215
s32 MIOS32_UART_InitPort(u8 uart, u32 baudrate, mios32_board_pin_mode_t tx_pin_mode, u8 is_midi)
216
{
217
#if NUM_SUPPORTED_UARTS == 0
218
  return -1; // no UART available
219
#else
220
  GPIO_InitTypeDef GPIO_InitStructure;
221
  GPIO_StructInit(&GPIO_InitStructure);
222
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
223
 
224
  if( uart >= NUM_SUPPORTED_UARTS )
225
    return -1; // unsupported UART
226
 
227
  // MIDI assignment
228
  if( is_midi ) {
229
    uart_assigned_to_midi |= (1 << uart);
230
  } else {
231
    uart_assigned_to_midi &= ~(1 << uart);
232
  }
233
 
234
  switch( uart ) {
235
#if NUM_SUPPORTED_UARTS >= 1 && MIOS32_UART0_ASSIGNMENT != 0
236
  case 0: {
237
    // output
238
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART0_TX_PIN;
239
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
240
    GPIO_InitStructure.GPIO_OType = (tx_pin_mode == MIOS32_BOARD_PIN_MODE_OUTPUT_PP) ? GPIO_OType_PP : GPIO_OType_OD;
241
    GPIO_Init(MIOS32_UART0_TX_PORT, &GPIO_InitStructure);
242
 
243
    // inputs with internal pull-up
244
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
245
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
246
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART0_RX_PIN;
247
    GPIO_Init(MIOS32_UART0_RX_PORT, &GPIO_InitStructure);
248
 
249
    // UART configuration
250
    MIOS32_UART_BaudrateSet(uart, baudrate);
251
  } break;
1795 tk 252
#endif
253
 
1801 tk 254
#if NUM_SUPPORTED_UARTS >= 2 && MIOS32_UART1_ASSIGNMENT != 0
2312 tk 255
  case 1: {
256
    // output
257
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART1_TX_PIN;
258
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
259
    GPIO_InitStructure.GPIO_OType = (tx_pin_mode == MIOS32_BOARD_PIN_MODE_OUTPUT_PP) ? GPIO_OType_PP : GPIO_OType_OD;
260
    GPIO_Init(MIOS32_UART1_TX_PORT, &GPIO_InitStructure);
261
 
262
    // inputs with internal pull-up
263
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
264
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
265
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART1_RX_PIN;
266
    GPIO_Init(MIOS32_UART1_RX_PORT, &GPIO_InitStructure);
267
 
268
    // UART configuration
269
    MIOS32_UART_BaudrateSet(uart, baudrate);
270
  } break;
1795 tk 271
#endif
272
 
1801 tk 273
#if NUM_SUPPORTED_UARTS >= 3 && MIOS32_UART2_ASSIGNMENT != 0
2312 tk 274
  case 2: {
275
    // output
276
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART2_TX_PIN;
277
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
278
    GPIO_InitStructure.GPIO_OType = (tx_pin_mode == MIOS32_BOARD_PIN_MODE_OUTPUT_PP) ? GPIO_OType_PP : GPIO_OType_OD;
279
    GPIO_Init(MIOS32_UART2_TX_PORT, &GPIO_InitStructure);
280
 
281
    // inputs with internal pull-up
282
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
283
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
284
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART2_RX_PIN;
285
    GPIO_Init(MIOS32_UART2_RX_PORT, &GPIO_InitStructure);
286
 
287
    // UART configuration
288
    MIOS32_UART_BaudrateSet(uart, baudrate);
289
  } break;
1795 tk 290
#endif
291
 
1833 tk 292
#if NUM_SUPPORTED_UARTS >= 4 && MIOS32_UART3_ASSIGNMENT != 0
2312 tk 293
  case 3: {
294
    // output
295
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART3_TX_PIN;
296
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
297
    GPIO_InitStructure.GPIO_OType = (tx_pin_mode == MIOS32_BOARD_PIN_MODE_OUTPUT_PP) ? GPIO_OType_PP : GPIO_OType_OD;
298
    GPIO_Init(MIOS32_UART3_TX_PORT, &GPIO_InitStructure);
299
 
300
    // inputs with internal pull-up
301
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
302
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
303
    GPIO_InitStructure.GPIO_Pin = MIOS32_UART3_RX_PIN;
304
    GPIO_Init(MIOS32_UART3_RX_PORT, &GPIO_InitStructure);
305
 
306
    // UART configuration
307
    MIOS32_UART_BaudrateSet(uart, baudrate);
308
  } break;
1833 tk 309
#endif
310
 
2312 tk 311
  default:
312
    return -1; // unsupported UART
1795 tk 313
  }
314
 
2312 tk 315
  return 0; // no error
1795 tk 316
#endif
2312 tk 317
}
318
 
319
 
320
/////////////////////////////////////////////////////////////////////////////
321
//! Initializes a given UART interface based on default settings
322
//! \param[in] uart UART number (0..2)
323
//! \return < 0 if initialisation failed
324
/////////////////////////////////////////////////////////////////////////////
325
s32 MIOS32_UART_InitPortDefault(u8 uart)
326
{
327
#if NUM_SUPPORTED_UARTS == 0
328
  return -1; // no UART available
329
#else
330
  switch( uart ) {
331
#if NUM_SUPPORTED_UARTS >= 1 && MIOS32_UART0_ASSIGNMENT != 0
332
  case 0: {
333
# if MIOS32_UART0_TX_OD
334
    MIOS32_UART_InitPort(0, MIOS32_UART0_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_OD, MIOS32_UART0_ASSIGNMENT == 1);
335
# else
336
    MIOS32_UART_InitPort(0, MIOS32_UART0_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_PP, MIOS32_UART0_ASSIGNMENT == 1);
337
# endif
338
  } break;
339
#endif
340
 
1801 tk 341
#if NUM_SUPPORTED_UARTS >= 2 && MIOS32_UART1_ASSIGNMENT != 0
2312 tk 342
  case 1: {
343
# if MIOS32_UART1_TX_OD
344
    MIOS32_UART_InitPort(1, MIOS32_UART1_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_OD, MIOS32_UART1_ASSIGNMENT == 1);
345
# else
346
    MIOS32_UART_InitPort(1, MIOS32_UART1_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_PP, MIOS32_UART1_ASSIGNMENT == 1);
347
# endif
348
  } break;
1795 tk 349
#endif
2312 tk 350
 
1801 tk 351
#if NUM_SUPPORTED_UARTS >= 3 && MIOS32_UART2_ASSIGNMENT != 0
2312 tk 352
  case 2: {
353
# if MIOS32_UART2_TX_OD
354
    MIOS32_UART_InitPort(2, MIOS32_UART2_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_OD, MIOS32_UART2_ASSIGNMENT == 1);
355
# else
356
    MIOS32_UART_InitPort(2, MIOS32_UART2_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_PP, MIOS32_UART2_ASSIGNMENT == 1);
357
# endif
358
  } break;
1795 tk 359
#endif
2312 tk 360
 
1833 tk 361
#if NUM_SUPPORTED_UARTS >= 4 && MIOS32_UART3_ASSIGNMENT != 0
2312 tk 362
  case 3: {
363
# if MIOS32_UART3_TX_OD
364
    MIOS32_UART_InitPort(3, MIOS32_UART3_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_OD, MIOS32_UART3_ASSIGNMENT == 1);
365
# else
366
    MIOS32_UART_InitPort(3, MIOS32_UART3_BAUDRATE, MIOS32_BOARD_PIN_MODE_OUTPUT_PP, MIOS32_UART3_ASSIGNMENT == 1);
367
# endif
368
  } break;
1833 tk 369
#endif
1795 tk 370
 
2312 tk 371
  default:
372
    return -1; // unsupported UART
373
  }
374
 
1795 tk 375
  return 0; // no error
376
#endif
377
}
378
 
379
 
380
/////////////////////////////////////////////////////////////////////////////
381
//! sets the baudrate of a UART port
382
//! \param[in] uart UART number (0..2)
383
//! \param[in] baudrate the baudrate
384
//! \return 0: baudrate has been changed
385
//! \return -1: uart not available
386
//! \return -2: function not prepared for this UART
387
/////////////////////////////////////////////////////////////////////////////
388
s32 MIOS32_UART_BaudrateSet(u8 uart, u32 baudrate)
389
{
1801 tk 390
#if NUM_SUPPORTED_UARTS == 0
1795 tk 391
  return -1; // no UART available
392
#else
1801 tk 393
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 394
    return -1;
395
 
396
  // USART configuration
397
  USART_InitTypeDef USART_InitStructure;
398
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
399
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
400
  USART_InitStructure.USART_Parity = USART_Parity_No;
401
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
402
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
403
 
404
  USART_InitStructure.USART_BaudRate = baudrate;
405
 
406
  switch( uart ) {
407
  case 0: USART_Init(MIOS32_UART0, &USART_InitStructure); break;
1801 tk 408
#if NUM_SUPPORTED_UARTS >= 2
1795 tk 409
  case 1: USART_Init(MIOS32_UART1, &USART_InitStructure); break;
410
#endif
1801 tk 411
#if NUM_SUPPORTED_UARTS >= 3
1837 tk 412
  case 2: USART_Init(MIOS32_UART2_TX, &USART_InitStructure); USART_Init(MIOS32_UART2_RX, &USART_InitStructure); break;
1795 tk 413
#endif
1833 tk 414
#if NUM_SUPPORTED_UARTS >= 4
415
  case 3: USART_Init(MIOS32_UART3, &USART_InitStructure); break;
416
#endif
1795 tk 417
  default:
418
    return -2; // not prepared
419
  }
420
 
421
  // store baudrate in array
422
  uart_baudrate[uart] = baudrate;
423
 
424
  return 0;
425
#endif
426
}
427
 
428
/////////////////////////////////////////////////////////////////////////////
429
//! returns the current baudrate of a UART port
430
//! \param[in] uart UART number (0..2)
431
//! \return 0: uart not available
432
//! \return all other values: the current baudrate
433
/////////////////////////////////////////////////////////////////////////////
434
u32 MIOS32_UART_BaudrateGet(u8 uart)
435
{
1801 tk 436
#if NUM_SUPPORTED_UARTS == 0
1795 tk 437
  return 0; // no UART available
438
#else
1801 tk 439
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 440
    return 0;
441
  else
442
    return uart_baudrate[uart];
443
#endif
444
}
445
 
446
 
447
/////////////////////////////////////////////////////////////////////////////
448
//! returns number of free bytes in receive buffer
449
//! \param[in] uart UART number (0..2)
450
//! \return uart number of free bytes
451
//! \return 1: uart available
452
//! \return 0: uart not available
453
/////////////////////////////////////////////////////////////////////////////
454
s32 MIOS32_UART_RxBufferFree(u8 uart)
455
{
1801 tk 456
#if NUM_SUPPORTED_UARTS == 0
1795 tk 457
  return 0; // no UART available
458
#else
1801 tk 459
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 460
    return 0;
461
  else
462
    return MIOS32_UART_RX_BUFFER_SIZE - rx_buffer_size[uart];
463
#endif
464
}
465
 
466
 
467
/////////////////////////////////////////////////////////////////////////////
468
//! returns number of used bytes in receive buffer
469
//! \param[in] uart UART number (0..2)
470
//! \return > 0: number of used bytes
471
//! \return 0 if uart not available
472
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
473
/////////////////////////////////////////////////////////////////////////////
474
s32 MIOS32_UART_RxBufferUsed(u8 uart)
475
{
1801 tk 476
#if NUM_SUPPORTED_UARTS == 0
1795 tk 477
  return 0; // no UART available
478
#else
1801 tk 479
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 480
    return 0;
481
  else
482
    return rx_buffer_size[uart];
483
#endif
484
}
485
 
486
 
487
/////////////////////////////////////////////////////////////////////////////
488
//! gets a byte from the receive buffer
489
//! \param[in] uart UART number (0..2)
490
//! \return -1 if UART not available
491
//! \return -2 if no new byte available
492
//! \return >= 0: number of received bytes
493
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
494
/////////////////////////////////////////////////////////////////////////////
495
s32 MIOS32_UART_RxBufferGet(u8 uart)
496
{
1801 tk 497
#if NUM_SUPPORTED_UARTS == 0
1795 tk 498
  return -1; // no UART available
499
#else
1801 tk 500
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 501
    return -1; // UART not available
502
 
503
  if( !rx_buffer_size[uart] )
504
    return -2; // nothing new in buffer
505
 
506
  // get byte - this operation should be atomic!
507
  MIOS32_IRQ_Disable();
508
  u8 b = rx_buffer[uart][rx_buffer_tail[uart]];
509
  if( ++rx_buffer_tail[uart] >= MIOS32_UART_RX_BUFFER_SIZE )
510
    rx_buffer_tail[uart] = 0;
511
  --rx_buffer_size[uart];
512
  MIOS32_IRQ_Enable();
513
 
514
  return b; // return received byte
515
#endif
516
}
517
 
518
 
519
/////////////////////////////////////////////////////////////////////////////
520
//! returns the next byte of the receive buffer without taking it
521
//! \param[in] uart UART number (0..2)
522
//! \return -1 if UART not available
523
//! \return -2 if no new byte available
524
//! \return >= 0: number of received bytes
525
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
526
/////////////////////////////////////////////////////////////////////////////
527
s32 MIOS32_UART_RxBufferPeek(u8 uart)
528
{
1801 tk 529
#if NUM_SUPPORTED_UARTS == 0
1795 tk 530
  return -1; // no UART available
531
#else
1801 tk 532
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 533
    return -1; // UART not available
534
 
535
  if( !rx_buffer_size[uart] )
536
    return -2; // nothing new in buffer
537
 
538
  // get byte - this operation should be atomic!
539
  MIOS32_IRQ_Disable();
540
  u8 b = rx_buffer[uart][rx_buffer_tail[uart]];
541
  MIOS32_IRQ_Enable();
542
 
543
  return b; // return received byte
544
#endif
545
}
546
 
547
 
548
/////////////////////////////////////////////////////////////////////////////
549
//! puts a byte onto the receive buffer
550
//! \param[in] uart UART number (0..2)
551
//! \param[in] b byte which should be put into Rx buffer
552
//! \return 0 if no error
553
//! \return -1 if UART not available
554
//! \return -2 if buffer full (retry)
555
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
556
/////////////////////////////////////////////////////////////////////////////
557
s32 MIOS32_UART_RxBufferPut(u8 uart, u8 b)
558
{
1801 tk 559
#if NUM_SUPPORTED_UARTS == 0
1795 tk 560
  return -1; // no UART available
561
#else
1801 tk 562
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 563
    return -1; // UART not available
564
 
565
  if( rx_buffer_size[uart] >= MIOS32_UART_RX_BUFFER_SIZE )
566
    return -2; // buffer full (retry)
567
 
568
  // copy received byte into receive buffer
569
  // this operation should be atomic!
570
  MIOS32_IRQ_Disable();
571
  rx_buffer[uart][rx_buffer_head[uart]] = b;
572
  if( ++rx_buffer_head[uart] >= MIOS32_UART_RX_BUFFER_SIZE )
573
    rx_buffer_head[uart] = 0;
574
  ++rx_buffer_size[uart];
575
  MIOS32_IRQ_Enable();
576
 
577
  return 0; // no error
578
#endif
579
}
580
 
581
 
582
/////////////////////////////////////////////////////////////////////////////
583
//! returns number of free bytes in transmit buffer
584
//! \param[in] uart UART number (0..2)
585
//! \return number of free bytes
586
//! \return 0 if uart not available
587
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
588
/////////////////////////////////////////////////////////////////////////////
589
s32 MIOS32_UART_TxBufferFree(u8 uart)
590
{
1801 tk 591
#if NUM_SUPPORTED_UARTS == 0
1795 tk 592
  return 0; // no UART available
593
#else
1801 tk 594
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 595
    return 0;
596
  else
597
    return MIOS32_UART_TX_BUFFER_SIZE - tx_buffer_size[uart];
598
#endif
599
}
600
 
601
 
602
/////////////////////////////////////////////////////////////////////////////
603
//! returns number of used bytes in transmit buffer
604
//! \param[in] uart UART number (0..2)
605
//! \return number of used bytes
606
//! \return 0 if uart not available
607
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
608
/////////////////////////////////////////////////////////////////////////////
609
s32 MIOS32_UART_TxBufferUsed(u8 uart)
610
{
1801 tk 611
#if NUM_SUPPORTED_UARTS == 0
1795 tk 612
  return 0; // no UART available
613
#else
1801 tk 614
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 615
    return 0;
616
  else
617
    return tx_buffer_size[uart];
618
#endif
619
}
620
 
621
 
622
/////////////////////////////////////////////////////////////////////////////
623
//! gets a byte from the transmit buffer
624
//! \param[in] uart UART number (0..2)
625
//! \return -1 if UART not available
626
//! \return -2 if no new byte available
627
//! \return >= 0: transmitted byte
628
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
629
/////////////////////////////////////////////////////////////////////////////
630
s32 MIOS32_UART_TxBufferGet(u8 uart)
631
{
1801 tk 632
#if NUM_SUPPORTED_UARTS == 0
1795 tk 633
  return -1; // no UART available
634
#else
1801 tk 635
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 636
    return -1; // UART not available
637
 
638
  if( !tx_buffer_size[uart] )
639
    return -2; // nothing new in buffer
640
 
641
  // get byte - this operation should be atomic!
642
  MIOS32_IRQ_Disable();
643
  u8 b = tx_buffer[uart][tx_buffer_tail[uart]];
644
  if( ++tx_buffer_tail[uart] >= MIOS32_UART_TX_BUFFER_SIZE )
645
    tx_buffer_tail[uart] = 0;
646
  --tx_buffer_size[uart];
647
  MIOS32_IRQ_Enable();
648
 
649
  return b; // return transmitted byte
650
#endif
651
}
652
 
653
 
654
/////////////////////////////////////////////////////////////////////////////
655
//! puts more than one byte onto the transmit buffer (used for atomic sends)
656
//! \param[in] uart UART number (0..2)
657
//! \param[in] *buffer pointer to buffer to be sent
658
//! \param[in] len number of bytes to be sent
659
//! \return 0 if no error
660
//! \return -1 if UART not available
661
//! \return -2 if buffer full or cannot get all requested bytes (retry)
662
//! \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
663
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
664
/////////////////////////////////////////////////////////////////////////////
665
s32 MIOS32_UART_TxBufferPutMore_NonBlocking(u8 uart, u8 *buffer, u16 len)
666
{
1801 tk 667
#if NUM_SUPPORTED_UARTS == 0
1795 tk 668
  return -1; // no UART available
669
#else
1801 tk 670
  if( uart >= NUM_SUPPORTED_UARTS )
1795 tk 671
    return -1; // UART not available
672
 
673
  if( (tx_buffer_size[uart]+len) >= MIOS32_UART_TX_BUFFER_SIZE )
674
    return -2; // buffer full or cannot get all requested bytes (retry)
675
 
676
  // copy bytes to be transmitted into transmit buffer
677
  // this operation should be atomic!
678
  MIOS32_IRQ_Disable();
679
 
680
  u16 i;
681
  for(i=0; i<len; ++i) {
682
    tx_buffer[uart][tx_buffer_head[uart]] = *buffer++;
683
 
684
    if( ++tx_buffer_head[uart] >= MIOS32_UART_TX_BUFFER_SIZE )
685
      tx_buffer_head[uart] = 0;
686
 
687
    // enable Tx interrupt if buffer was empty
688
    if( ++tx_buffer_size[uart] == 1 ) {
689
      switch( uart ) {
690
        case 0: MIOS32_UART0->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
691
        case 1: MIOS32_UART1->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
1837 tk 692
        case 2: MIOS32_UART2_TX->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
1833 tk 693
        case 3: MIOS32_UART3->CR1 |= (1 << 7); break; // enable TXE interrupt (TXEIE=1)
1795 tk 694
        default: MIOS32_IRQ_Enable(); return -3; // uart not supported by routine (yet)
695
      }
696
    }
697
  }
698
 
699
  MIOS32_IRQ_Enable();
700
 
701
  return 0; // no error
702
#endif
703
}
704
 
705
/////////////////////////////////////////////////////////////////////////////
706
//! puts more than one byte onto the transmit buffer (used for atomic sends)<BR>
707
//! (blocking function)
708
//! \param[in] uart UART number (0..2)
709
//! \param[in] *buffer pointer to buffer to be sent
710
//! \param[in] len number of bytes to be sent
711
//! \return 0 if no error
712
//! \return -1 if UART not available
713
//! \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
714
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
715
/////////////////////////////////////////////////////////////////////////////
716
s32 MIOS32_UART_TxBufferPutMore(u8 uart, u8 *buffer, u16 len)
717
{
718
  s32 error;
719
 
720
  while( (error=MIOS32_UART_TxBufferPutMore_NonBlocking(uart, buffer, len)) == -2 );
721
 
722
  return error;
723
}
724
 
725
 
726
/////////////////////////////////////////////////////////////////////////////
727
//! puts a byte onto the transmit buffer
728
//! \param[in] uart UART number (0..2)
729
//! \param[in] b byte which should be put into Tx buffer
730
//! \return 0 if no error
731
//! \return -1 if UART not available
732
//! \return -2 if buffer full (retry)
733
//! \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
734
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
735
/////////////////////////////////////////////////////////////////////////////
736
s32 MIOS32_UART_TxBufferPut_NonBlocking(u8 uart, u8 b)
737
{
738
  // for more comfortable usage...
739
  // -> just forward to MIOS32_UART_TxBufferPutMore
740
  return MIOS32_UART_TxBufferPutMore(uart, &b, 1);
741
}
742
 
743
 
744
/////////////////////////////////////////////////////////////////////////////
745
//! puts a byte onto the transmit buffer<BR>
746
//! (blocking function)
747
//! \param[in] uart UART number (0..2)
748
//! \param[in] b byte which should be put into Tx buffer
749
//! \return 0 if no error
750
//! \return -1 if UART not available
751
//! \return -3 if UART not supported by MIOS32_UART_TxBufferPut Routine
752
//! \note Applications shouldn't call these functions directly, instead please use \ref MIOS32_COM or \ref MIOS32_MIDI layer functions
753
/////////////////////////////////////////////////////////////////////////////
754
s32 MIOS32_UART_TxBufferPut(u8 uart, u8 b)
755
{
756
  s32 error;
757
 
758
  while( (error=MIOS32_UART_TxBufferPutMore(uart, &b, 1)) == -2 );
759
 
760
  return error;
761
}
762
 
763
 
764
/////////////////////////////////////////////////////////////////////////////
765
// Interrupt handler for first UART
766
/////////////////////////////////////////////////////////////////////////////
1801 tk 767
#if NUM_SUPPORTED_UARTS >= 1
1795 tk 768
MIOS32_UART0_IRQHANDLER_FUNC
769
{
770
  if( MIOS32_UART0->SR & (1 << 5) ) { // check if RXNE flag is set
771
    u8 b = MIOS32_UART0->DR;
772
 
2312 tk 773
    s32 status = MIOS32_UART_IsAssignedToMIDI(0) ? MIOS32_MIDI_SendByteToRxCallback(UART0, b) : 0;
1795 tk 774
 
775
    if( status == 0 && MIOS32_UART_RxBufferPut(0, b) < 0 ) {
776
      // here we could add some error handling
777
    }
778
  }
779
 
780
  if( MIOS32_UART0->SR & (1 << 7) ) { // check if TXE flag is set
781
    if( MIOS32_UART_TxBufferUsed(0) > 0 ) {
782
      s32 b = MIOS32_UART_TxBufferGet(0);
783
      if( b < 0 ) {
784
    // here we could add some error handling
785
    MIOS32_UART0->DR = 0xff;
786
      } else {
787
    MIOS32_UART0->DR = b;
788
      }
789
    } else {
790
      MIOS32_UART0->CR1 &= ~(1 << 7); // disable TXE interrupt (TXEIE=0)
791
    }
792
  }
793
}
794
#endif
795
 
796
 
797
/////////////////////////////////////////////////////////////////////////////
798
// Interrupt handler for second UART
799
/////////////////////////////////////////////////////////////////////////////
1801 tk 800
#if NUM_SUPPORTED_UARTS >= 2
1795 tk 801
MIOS32_UART1_IRQHANDLER_FUNC
802
{
803
  if( MIOS32_UART1->SR & (1 << 5) ) { // check if RXNE flag is set
804
    u8 b = MIOS32_UART1->DR;
805
 
2312 tk 806
    s32 status = MIOS32_UART_IsAssignedToMIDI(1) ? MIOS32_MIDI_SendByteToRxCallback(UART1, b) : 0;
1795 tk 807
 
808
    if( status == 0 && MIOS32_UART_RxBufferPut(1, b) < 0 ) {
809
      // here we could add some error handling
810
    }
811
  }
812
 
813
  if( MIOS32_UART1->SR & (1 << 7) ) { // check if TXE flag is set
814
    if( MIOS32_UART_TxBufferUsed(1) > 0 ) {
815
      s32 b = MIOS32_UART_TxBufferGet(1);
816
      if( b < 0 ) {
817
    // here we could add some error handling
818
    MIOS32_UART1->DR = 0xff;
819
      } else {
820
    MIOS32_UART1->DR = b;
821
      }
822
    } else {
823
      MIOS32_UART1->CR1 &= ~(1 << 7); // disable TXE interrupt (TXEIE=0)
824
    }
825
  }
826
}
827
#endif
828
 
829
 
830
/////////////////////////////////////////////////////////////////////////////
831
// Interrupt handler for third UART
832
/////////////////////////////////////////////////////////////////////////////
1801 tk 833
#if NUM_SUPPORTED_UARTS >= 3
1837 tk 834
MIOS32_UART2_TX_IRQHANDLER_FUNC
1795 tk 835
{
1837 tk 836
  if( MIOS32_UART2_TX->SR & (1 << 5) ) { // check if RXNE flag is set
837
    // dummy... this UART is only used for output transfers
838
    u8 b = MIOS32_UART2_TX->DR;
839
    if( b ); // prevent "unused variable" warning
840
  }
841
 
842
  if( MIOS32_UART2_TX->SR & (1 << 7) ) { // check if TXE flag is set
843
    if( MIOS32_UART_TxBufferUsed(2) > 0 ) {
844
      s32 b = MIOS32_UART_TxBufferGet(2);
845
      if( b < 0 ) {
846
    // here we could add some error handling
847
    MIOS32_UART2_TX->DR = 0xff;
848
      } else {
849
    MIOS32_UART2_TX->DR = b;
850
      }
851
    } else {
852
      MIOS32_UART2_TX->CR1 &= ~(1 << 7); // disable TXE interrupt (TXEIE=0)
853
    }
854
  }
855
}
1795 tk 856
 
1837 tk 857
MIOS32_UART2_RX_IRQHANDLER_FUNC
858
{
859
  if( MIOS32_UART2_RX->SR & (1 << 5) ) { // check if RXNE flag is set
860
    u8 b = MIOS32_UART2_RX->DR;
861
 
2312 tk 862
    s32 status = MIOS32_UART_IsAssignedToMIDI(2) ? MIOS32_MIDI_SendByteToRxCallback(UART2, b) : 0;
1795 tk 863
 
864
    if( status == 0 && MIOS32_UART_RxBufferPut(2, b) < 0 ) {
865
      // here we could add some error handling
866
    }
867
  }
868
 
1837 tk 869
  if( MIOS32_UART2_RX->SR & (1 << 7) ) { // check if TXE flag is set
870
    // dummy... this UART is only used for output transfers
871
    MIOS32_UART2_RX->CR1 &= ~(1 << 7); // disable TXE interrupt (TXEIE=0)
1795 tk 872
  }
873
}
874
#endif
875
 
876
 
1833 tk 877
/////////////////////////////////////////////////////////////////////////////
878
// Interrupt handler for fourth UART
879
/////////////////////////////////////////////////////////////////////////////
880
#if NUM_SUPPORTED_UARTS >= 4
881
MIOS32_UART3_IRQHANDLER_FUNC
882
{
883
  if( MIOS32_UART3->SR & (1 << 5) ) { // check if RXNE flag is set
884
    u8 b = MIOS32_UART3->DR;
885
 
2312 tk 886
    s32 status = MIOS32_UART_IsAssignedToMIDI(3) ? MIOS32_MIDI_SendByteToRxCallback(UART3, b) : 0;
1833 tk 887
 
888
    if( status == 0 && MIOS32_UART_RxBufferPut(3, b) < 0 ) {
889
      // here we could add some error handling
890
    }
891
  }
892
 
893
  if( MIOS32_UART3->SR & (1 << 7) ) { // check if TXE flag is set
1837 tk 894
    if( MIOS32_UART_TxBufferUsed(3) > 0 ) {
1833 tk 895
      s32 b = MIOS32_UART_TxBufferGet(3);
896
      if( b < 0 ) {
897
    // here we could add some error handling
898
    MIOS32_UART3->DR = 0xff;
899
      } else {
900
    MIOS32_UART3->DR = b;
901
      }
902
    } else {
903
      MIOS32_UART3->CR1 &= ~(1 << 7); // disable TXE interrupt (TXEIE=0)
904
    }
905
  }
906
}
907
#endif
908
 
909
 
1795 tk 910
#endif /* MIOS32_DONT_USE_UART */