Skip to content

Commit 486ebec

Browse files
committed
[NUCLEO_F030R8] Add serial api
1 parent a5726b8 commit 486ebec

File tree

1 file changed

+280
-0
lines changed
  • libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8

1 file changed

+280
-0
lines changed
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
/* mbed Microcontroller Library
2+
*******************************************************************************
3+
* Copyright (c) 2014, STMicroelectronics
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright notice,
10+
* this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following disclaimer in the documentation
13+
* and/or other materials provided with the distribution.
14+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
15+
* may be used to endorse or promote products derived from this software
16+
* without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*******************************************************************************
29+
*/
30+
#include "serial_api.h"
31+
#include "cmsis.h"
32+
#include "pinmap.h"
33+
#include "error.h"
34+
#include <string.h>
35+
36+
static const PinMap PinMap_UART_TX[] = {
37+
{PA_9, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)},
38+
{PA_2, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)},
39+
{NC, NC, 0}
40+
};
41+
42+
static const PinMap PinMap_UART_RX[] = {
43+
{PA_10, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)},
44+
{PA_3, UART_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_1)},
45+
{NC, NC, 0}
46+
};
47+
48+
#define UART_NUM (2)
49+
50+
static uint32_t serial_irq_ids[UART_NUM] = {0};
51+
52+
static uart_irq_handler irq_handler;
53+
54+
int stdio_uart_inited = 0;
55+
serial_t stdio_uart;
56+
57+
static void init_usart(serial_t *obj) {
58+
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
59+
USART_InitTypeDef USART_InitStructure;
60+
61+
USART_Cmd(usart, DISABLE);
62+
63+
USART_InitStructure.USART_BaudRate = obj->baudrate;
64+
USART_InitStructure.USART_WordLength = obj->databits;
65+
USART_InitStructure.USART_StopBits = obj->stopbits;
66+
USART_InitStructure.USART_Parity = obj->parity;
67+
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
68+
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
69+
USART_Init(usart, &USART_InitStructure);
70+
71+
USART_Cmd(usart, ENABLE);
72+
}
73+
74+
void serial_init(serial_t *obj, PinName tx, PinName rx) {
75+
// Determine the UART to use (UART_1, UART_2, ...)
76+
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
77+
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
78+
79+
// Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
80+
obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
81+
82+
if (obj->uart == (UARTName)NC) {
83+
error("Serial pinout mapping failed");
84+
}
85+
86+
// Enable USART clock
87+
if (obj->uart == UART_1) {
88+
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
89+
}
90+
if (obj->uart == UART_2) {
91+
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
92+
}
93+
94+
// Configure the UART pins
95+
pinmap_pinout(tx, PinMap_UART_TX);
96+
pinmap_pinout(rx, PinMap_UART_RX);
97+
pin_mode(tx, PullUp);
98+
pin_mode(rx, PullUp);
99+
100+
// Configure UART
101+
obj->baudrate = 9600;
102+
obj->databits = USART_WordLength_8b;
103+
obj->stopbits = USART_StopBits_1;
104+
obj->parity = USART_Parity_No;
105+
106+
init_usart(obj);
107+
108+
// The index is used by irq
109+
if (obj->uart == UART_1) obj->index = 0;
110+
if (obj->uart == UART_2) obj->index = 1;
111+
112+
// For stdio management
113+
if (obj->uart == STDIO_UART) {
114+
stdio_uart_inited = 1;
115+
memcpy(&stdio_uart, obj, sizeof(serial_t));
116+
}
117+
118+
}
119+
120+
void serial_free(serial_t *obj) {
121+
serial_irq_ids[obj->index] = 0;
122+
}
123+
124+
void serial_baud(serial_t *obj, int baudrate) {
125+
obj->baudrate = baudrate;
126+
init_usart(obj);
127+
}
128+
129+
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
130+
if (data_bits == 8) {
131+
obj->databits = USART_WordLength_8b;
132+
}
133+
else {
134+
obj->databits = USART_WordLength_9b;
135+
}
136+
137+
switch (parity) {
138+
case ParityOdd:
139+
case ParityForced0:
140+
obj->parity = USART_Parity_Odd;
141+
break;
142+
case ParityEven:
143+
case ParityForced1:
144+
obj->parity = USART_Parity_Even;
145+
break;
146+
default: // ParityNone
147+
obj->parity = USART_Parity_No;
148+
break;
149+
}
150+
151+
if (stop_bits == 2) {
152+
obj->stopbits = USART_StopBits_2;
153+
}
154+
else {
155+
obj->stopbits = USART_StopBits_1;
156+
}
157+
158+
init_usart(obj);
159+
}
160+
161+
/******************************************************************************
162+
* INTERRUPTS HANDLING
163+
******************************************************************************/
164+
165+
// not api
166+
static void uart_irq(USART_TypeDef* usart, int id) {
167+
if (serial_irq_ids[id] != 0) {
168+
if (USART_GetITStatus(usart, USART_IT_TC) != RESET) {
169+
irq_handler(serial_irq_ids[id], TxIrq);
170+
USART_ClearITPendingBit(usart, USART_IT_TC);
171+
}
172+
if (USART_GetITStatus(usart, USART_IT_RXNE) != RESET) {
173+
irq_handler(serial_irq_ids[id], RxIrq);
174+
USART_ClearITPendingBit(usart, USART_IT_RXNE);
175+
}
176+
}
177+
}
178+
179+
static void uart1_irq(void) {uart_irq((USART_TypeDef*)UART_1, 0);}
180+
static void uart2_irq(void) {uart_irq((USART_TypeDef*)UART_2, 1);}
181+
182+
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
183+
irq_handler = handler;
184+
serial_irq_ids[obj->index] = id;
185+
}
186+
187+
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
188+
IRQn_Type irq_n = (IRQn_Type)0;
189+
uint32_t vector = 0;
190+
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
191+
192+
if (obj->uart == UART_1) {
193+
irq_n = USART1_IRQn;
194+
vector = (uint32_t)&uart1_irq;
195+
}
196+
197+
if (obj->uart == UART_2) {
198+
irq_n = USART2_IRQn;
199+
vector = (uint32_t)&uart2_irq;
200+
}
201+
202+
if (enable) {
203+
204+
if (irq == RxIrq) {
205+
USART_ITConfig(usart, USART_IT_RXNE, ENABLE);
206+
}
207+
else { // TxIrq
208+
USART_ITConfig(usart, USART_IT_TC, ENABLE);
209+
}
210+
211+
NVIC_SetVector(irq_n, vector);
212+
NVIC_EnableIRQ(irq_n);
213+
214+
} else { // disable
215+
216+
int all_disabled = 0;
217+
218+
if (irq == RxIrq) {
219+
USART_ITConfig(usart, USART_IT_RXNE, DISABLE);
220+
// Check if TxIrq is disabled too
221+
if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
222+
}
223+
else { // TxIrq
224+
USART_ITConfig(usart, USART_IT_TXE, DISABLE);
225+
// Check if RxIrq is disabled too
226+
if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
227+
}
228+
229+
if (all_disabled) NVIC_DisableIRQ(irq_n);
230+
231+
}
232+
}
233+
234+
/******************************************************************************
235+
* READ/WRITE
236+
******************************************************************************/
237+
238+
int serial_getc(serial_t *obj) {
239+
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
240+
while (!serial_readable(obj));
241+
return (int)(USART_ReceiveData(usart));
242+
}
243+
244+
void serial_putc(serial_t *obj, int c) {
245+
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
246+
while (!serial_writable(obj));
247+
USART_SendData(usart, (uint16_t)c);
248+
}
249+
250+
int serial_readable(serial_t *obj) {
251+
int status;
252+
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
253+
// Check if data is received
254+
status = ((USART_GetFlagStatus(usart, USART_FLAG_RXNE) != RESET) ? 1 : 0);
255+
return status;
256+
}
257+
258+
int serial_writable(serial_t *obj) {
259+
int status;
260+
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
261+
// Check if data is transmitted
262+
status = ((USART_GetFlagStatus(usart, USART_FLAG_TXE) != RESET) ? 1 : 0);
263+
return status;
264+
}
265+
266+
void serial_clear(serial_t *obj) {
267+
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
268+
USART_ClearFlag(usart, USART_FLAG_TXE);
269+
USART_ClearFlag(usart, USART_FLAG_RXNE);
270+
}
271+
272+
void serial_pinout_tx(PinName tx) {
273+
pinmap_pinout(tx, PinMap_UART_TX);
274+
}
275+
276+
void serial_break_set(serial_t *obj) {
277+
}
278+
279+
void serial_break_clear(serial_t *obj) {
280+
}

0 commit comments

Comments
 (0)