mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Mon Dec 09 11:15:04 2013 +0000
Revision:
55:3b765ca737a5
Parent:
52:a51c77007319
Child:
56:99eb381a3269
Synchronized with git revision faee2bf073820222f14e0baf95ec002e8cfec21e

Full URL: https://github.com/mbedmicro/mbed/commit/faee2bf073820222f14e0baf95ec002e8cfec21e/

- use TC flag instead of TXE for TX interrupt
- clear interrupt flags to prevent possible interrupt storm

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 52:a51c77007319 1 /* mbed Microcontroller Library
mbed_official 52:a51c77007319 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 52:a51c77007319 3 *
mbed_official 52:a51c77007319 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 52:a51c77007319 5 * you may not use this file except in compliance with the License.
mbed_official 52:a51c77007319 6 * You may obtain a copy of the License at
mbed_official 52:a51c77007319 7 *
mbed_official 52:a51c77007319 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 52:a51c77007319 9 *
mbed_official 52:a51c77007319 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 52:a51c77007319 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 52:a51c77007319 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 52:a51c77007319 13 * See the License for the specific language governing permissions and
mbed_official 52:a51c77007319 14 * limitations under the License.
mbed_official 52:a51c77007319 15 */
mbed_official 52:a51c77007319 16 //==============================================================================
mbed_official 52:a51c77007319 17 // STM32F103
mbed_official 52:a51c77007319 18 //==============================================================================
mbed_official 52:a51c77007319 19 #include "serial_api.h"
mbed_official 52:a51c77007319 20 #include "cmsis.h"
mbed_official 52:a51c77007319 21 #include "pinmap.h"
mbed_official 52:a51c77007319 22 #include "error.h"
mbed_official 52:a51c77007319 23 #include <string.h>
mbed_official 52:a51c77007319 24
mbed_official 52:a51c77007319 25 /******************************************************************************
mbed_official 52:a51c77007319 26 * INITIALIZATION
mbed_official 52:a51c77007319 27 ******************************************************************************/
mbed_official 52:a51c77007319 28
mbed_official 52:a51c77007319 29 static const PinMap PinMap_UART_TX[] = {
mbed_official 52:a51c77007319 30 {PA_9, UART_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)},
mbed_official 52:a51c77007319 31 {PA_2, UART_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)},
mbed_official 52:a51c77007319 32 {NC, NC, 0}
mbed_official 52:a51c77007319 33 };
mbed_official 52:a51c77007319 34
mbed_official 52:a51c77007319 35 static const PinMap PinMap_UART_RX[] = {
mbed_official 52:a51c77007319 36 {PA_10, UART_1, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)},
mbed_official 52:a51c77007319 37 {PA_3, UART_2, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)},
mbed_official 52:a51c77007319 38 {NC, NC, 0}
mbed_official 52:a51c77007319 39 };
mbed_official 52:a51c77007319 40
mbed_official 52:a51c77007319 41 #define UART_NUM (2)
mbed_official 52:a51c77007319 42
mbed_official 52:a51c77007319 43 static uint32_t serial_irq_ids[UART_NUM] = {0};
mbed_official 52:a51c77007319 44
mbed_official 52:a51c77007319 45 static uart_irq_handler irq_handler;
mbed_official 52:a51c77007319 46
mbed_official 52:a51c77007319 47 int stdio_uart_inited = 0;
mbed_official 52:a51c77007319 48 serial_t stdio_uart;
mbed_official 52:a51c77007319 49
mbed_official 52:a51c77007319 50 void serial_init(serial_t *obj, PinName tx, PinName rx) {
mbed_official 52:a51c77007319 51
mbed_official 52:a51c77007319 52 USART_TypeDef *usart;
mbed_official 52:a51c77007319 53 USART_InitTypeDef USART_InitStructure;
mbed_official 52:a51c77007319 54
mbed_official 52:a51c77007319 55 // Determine the UART to use (UART_1, UART_2, ...)
mbed_official 52:a51c77007319 56 UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
mbed_official 52:a51c77007319 57 UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
mbed_official 52:a51c77007319 58
mbed_official 52:a51c77007319 59 // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
mbed_official 52:a51c77007319 60 obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
mbed_official 52:a51c77007319 61
mbed_official 52:a51c77007319 62 if (obj->uart == (UARTName)NC) {
mbed_official 52:a51c77007319 63 error("Serial pinout mapping failed");
mbed_official 52:a51c77007319 64 }
mbed_official 52:a51c77007319 65
mbed_official 52:a51c77007319 66 // Get UART registers structure address
mbed_official 52:a51c77007319 67 usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 68
mbed_official 52:a51c77007319 69 // Enable USART clock
mbed_official 52:a51c77007319 70 if (obj->uart == UART_1) {
mbed_official 52:a51c77007319 71 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
mbed_official 52:a51c77007319 72 }
mbed_official 52:a51c77007319 73 if (obj->uart == UART_2) {
mbed_official 52:a51c77007319 74 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
mbed_official 52:a51c77007319 75 }
mbed_official 52:a51c77007319 76
mbed_official 52:a51c77007319 77 // Configure the UART pins
mbed_official 52:a51c77007319 78 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 52:a51c77007319 79 pinmap_pinout(rx, PinMap_UART_RX);
mbed_official 52:a51c77007319 80
mbed_official 52:a51c77007319 81 // Configure UART
mbed_official 52:a51c77007319 82 obj->baudrate = 9600;
mbed_official 52:a51c77007319 83 obj->databits = USART_WordLength_8b;
mbed_official 52:a51c77007319 84 obj->stopbits = USART_StopBits_1;
mbed_official 52:a51c77007319 85 obj->parity = USART_Parity_No;
mbed_official 52:a51c77007319 86
mbed_official 52:a51c77007319 87 USART_InitStructure.USART_BaudRate = obj->baudrate;
mbed_official 52:a51c77007319 88 USART_InitStructure.USART_WordLength = obj->databits;
mbed_official 52:a51c77007319 89 USART_InitStructure.USART_StopBits = obj->stopbits;
mbed_official 52:a51c77007319 90 USART_InitStructure.USART_Parity = obj->parity;
mbed_official 52:a51c77007319 91 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
mbed_official 52:a51c77007319 92 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
mbed_official 52:a51c77007319 93 USART_Init(usart, &USART_InitStructure);
mbed_official 52:a51c77007319 94
mbed_official 52:a51c77007319 95 USART_Cmd(usart, ENABLE);
mbed_official 52:a51c77007319 96
mbed_official 52:a51c77007319 97 // The index is used by irq
mbed_official 52:a51c77007319 98 if (obj->uart == UART_1) obj->index = 0;
mbed_official 52:a51c77007319 99 if (obj->uart == UART_2) obj->index = 1;
mbed_official 52:a51c77007319 100
mbed_official 52:a51c77007319 101 // For stdio management
mbed_official 52:a51c77007319 102 if (obj->uart == STDIO_UART) {
mbed_official 52:a51c77007319 103 stdio_uart_inited = 1;
mbed_official 52:a51c77007319 104 memcpy(&stdio_uart, obj, sizeof(serial_t));
mbed_official 52:a51c77007319 105 }
mbed_official 52:a51c77007319 106
mbed_official 52:a51c77007319 107 }
mbed_official 52:a51c77007319 108
mbed_official 52:a51c77007319 109 void serial_free(serial_t *obj) {
mbed_official 52:a51c77007319 110 serial_irq_ids[obj->index] = 0;
mbed_official 52:a51c77007319 111 }
mbed_official 52:a51c77007319 112
mbed_official 52:a51c77007319 113 void serial_baud(serial_t *obj, int baudrate) {
mbed_official 52:a51c77007319 114 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 115 USART_InitTypeDef USART_InitStructure;
mbed_official 52:a51c77007319 116
mbed_official 52:a51c77007319 117 // Save new value
mbed_official 52:a51c77007319 118 obj->baudrate = baudrate;
mbed_official 52:a51c77007319 119
mbed_official 52:a51c77007319 120 USART_Cmd(usart, DISABLE);
mbed_official 52:a51c77007319 121
mbed_official 52:a51c77007319 122 USART_InitStructure.USART_BaudRate = obj->baudrate;
mbed_official 52:a51c77007319 123 USART_InitStructure.USART_WordLength = obj->databits;
mbed_official 52:a51c77007319 124 USART_InitStructure.USART_StopBits = obj->stopbits;
mbed_official 52:a51c77007319 125 USART_InitStructure.USART_Parity = obj->parity;
mbed_official 52:a51c77007319 126 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
mbed_official 52:a51c77007319 127 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
mbed_official 52:a51c77007319 128 USART_Init(usart, &USART_InitStructure);
mbed_official 52:a51c77007319 129
mbed_official 52:a51c77007319 130 USART_Cmd(usart, ENABLE);
mbed_official 52:a51c77007319 131 }
mbed_official 52:a51c77007319 132
mbed_official 52:a51c77007319 133 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
mbed_official 52:a51c77007319 134 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 135 USART_InitTypeDef USART_InitStructure;
mbed_official 52:a51c77007319 136
mbed_official 52:a51c77007319 137 // Save new values
mbed_official 52:a51c77007319 138
mbed_official 52:a51c77007319 139 if (data_bits == 8) {
mbed_official 52:a51c77007319 140 obj->databits = USART_WordLength_8b;
mbed_official 52:a51c77007319 141 }
mbed_official 52:a51c77007319 142 else {
mbed_official 52:a51c77007319 143 obj->databits = USART_WordLength_9b;
mbed_official 52:a51c77007319 144 }
mbed_official 52:a51c77007319 145
mbed_official 52:a51c77007319 146 switch (parity) {
mbed_official 52:a51c77007319 147 case ParityOdd:
mbed_official 52:a51c77007319 148 case ParityForced0:
mbed_official 52:a51c77007319 149 obj->parity = USART_Parity_Odd;
mbed_official 52:a51c77007319 150 break;
mbed_official 52:a51c77007319 151 case ParityEven:
mbed_official 52:a51c77007319 152 case ParityForced1:
mbed_official 52:a51c77007319 153 obj->parity = USART_Parity_Even;
mbed_official 52:a51c77007319 154 break;
mbed_official 52:a51c77007319 155 default: // ParityNone
mbed_official 52:a51c77007319 156 obj->parity = USART_Parity_No;
mbed_official 52:a51c77007319 157 break;
mbed_official 52:a51c77007319 158 }
mbed_official 52:a51c77007319 159
mbed_official 52:a51c77007319 160 if (stop_bits == 2) {
mbed_official 52:a51c77007319 161 obj->stopbits = USART_StopBits_2;
mbed_official 52:a51c77007319 162 }
mbed_official 52:a51c77007319 163 else {
mbed_official 52:a51c77007319 164 obj->stopbits = USART_StopBits_1;
mbed_official 52:a51c77007319 165 }
mbed_official 52:a51c77007319 166
mbed_official 52:a51c77007319 167 USART_Cmd(usart, DISABLE);
mbed_official 52:a51c77007319 168
mbed_official 52:a51c77007319 169 USART_InitStructure.USART_BaudRate = obj->baudrate;
mbed_official 52:a51c77007319 170 USART_InitStructure.USART_WordLength = obj->databits;
mbed_official 52:a51c77007319 171 USART_InitStructure.USART_StopBits = obj->stopbits;
mbed_official 52:a51c77007319 172 USART_InitStructure.USART_Parity = obj->parity;
mbed_official 52:a51c77007319 173 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
mbed_official 52:a51c77007319 174 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
mbed_official 52:a51c77007319 175 USART_Init(usart, &USART_InitStructure);
mbed_official 52:a51c77007319 176
mbed_official 52:a51c77007319 177 USART_Cmd(usart, ENABLE);
mbed_official 52:a51c77007319 178 }
mbed_official 52:a51c77007319 179
mbed_official 52:a51c77007319 180 /******************************************************************************
mbed_official 52:a51c77007319 181 * INTERRUPTS HANDLING
mbed_official 52:a51c77007319 182 ******************************************************************************/
mbed_official 52:a51c77007319 183
mbed_official 52:a51c77007319 184 // not api
mbed_official 55:3b765ca737a5 185 static void uart_irq(USART_TypeDef* usart, int id) {
mbed_official 55:3b765ca737a5 186 if (serial_irq_ids[id] != 0) {
mbed_official 55:3b765ca737a5 187 if (USART_GetITStatus(usart, USART_IT_TC) != RESET) {
mbed_official 55:3b765ca737a5 188 irq_handler(serial_irq_ids[id], TxIrq);
mbed_official 55:3b765ca737a5 189 USART_ClearITPendingBit(usart, USART_IT_TC);
mbed_official 52:a51c77007319 190 }
mbed_official 52:a51c77007319 191 if (USART_GetITStatus(usart, USART_IT_RXNE) != RESET) {
mbed_official 55:3b765ca737a5 192 irq_handler(serial_irq_ids[id], RxIrq);
mbed_official 55:3b765ca737a5 193 USART_ClearITPendingBit(usart, USART_IT_RXNE);
mbed_official 52:a51c77007319 194 }
mbed_official 52:a51c77007319 195 }
mbed_official 52:a51c77007319 196 }
mbed_official 52:a51c77007319 197
mbed_official 55:3b765ca737a5 198 static void uart1_irq(void) {uart_irq((USART_TypeDef*)UART_1, 0);}
mbed_official 55:3b765ca737a5 199 static void uart2_irq(void) {uart_irq((USART_TypeDef*)UART_2, 1);}
mbed_official 52:a51c77007319 200
mbed_official 52:a51c77007319 201 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
mbed_official 52:a51c77007319 202 irq_handler = handler;
mbed_official 52:a51c77007319 203 serial_irq_ids[obj->index] = id;
mbed_official 52:a51c77007319 204 }
mbed_official 52:a51c77007319 205
mbed_official 52:a51c77007319 206 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
mbed_official 52:a51c77007319 207 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 52:a51c77007319 208 uint32_t vector = 0;
mbed_official 52:a51c77007319 209 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 210
mbed_official 52:a51c77007319 211 if (obj->uart == UART_1) {
mbed_official 52:a51c77007319 212 irq_n = USART1_IRQn;
mbed_official 52:a51c77007319 213 vector = (uint32_t)&uart1_irq;
mbed_official 52:a51c77007319 214 }
mbed_official 52:a51c77007319 215
mbed_official 52:a51c77007319 216 if (obj->uart == UART_2) {
mbed_official 52:a51c77007319 217 irq_n = USART2_IRQn;
mbed_official 52:a51c77007319 218 vector = (uint32_t)&uart2_irq;
mbed_official 52:a51c77007319 219 }
mbed_official 52:a51c77007319 220
mbed_official 52:a51c77007319 221 if (enable) {
mbed_official 52:a51c77007319 222
mbed_official 52:a51c77007319 223 if (irq == RxIrq) {
mbed_official 52:a51c77007319 224 USART_ITConfig(usart, USART_IT_RXNE, ENABLE);
mbed_official 52:a51c77007319 225 }
mbed_official 52:a51c77007319 226 else { // TxIrq
mbed_official 55:3b765ca737a5 227 USART_ITConfig(usart, USART_IT_TC, ENABLE);
mbed_official 52:a51c77007319 228 }
mbed_official 52:a51c77007319 229
mbed_official 52:a51c77007319 230 NVIC_SetVector(irq_n, vector);
mbed_official 52:a51c77007319 231 NVIC_EnableIRQ(irq_n);
mbed_official 52:a51c77007319 232
mbed_official 52:a51c77007319 233 } else { // disable
mbed_official 52:a51c77007319 234
mbed_official 52:a51c77007319 235 int all_disabled = 0;
mbed_official 52:a51c77007319 236
mbed_official 52:a51c77007319 237 if (irq == RxIrq) {
mbed_official 52:a51c77007319 238 USART_ITConfig(usart, USART_IT_RXNE, DISABLE);
mbed_official 52:a51c77007319 239 // Check if TxIrq is disabled too
mbed_official 52:a51c77007319 240 if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
mbed_official 52:a51c77007319 241 }
mbed_official 52:a51c77007319 242 else { // TxIrq
mbed_official 52:a51c77007319 243 USART_ITConfig(usart, USART_IT_TXE, DISABLE);
mbed_official 52:a51c77007319 244 // Check if RxIrq is disabled too
mbed_official 52:a51c77007319 245 if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
mbed_official 52:a51c77007319 246 }
mbed_official 52:a51c77007319 247
mbed_official 52:a51c77007319 248 if (all_disabled) NVIC_DisableIRQ(irq_n);
mbed_official 52:a51c77007319 249
mbed_official 52:a51c77007319 250 }
mbed_official 52:a51c77007319 251 }
mbed_official 52:a51c77007319 252
mbed_official 52:a51c77007319 253 /******************************************************************************
mbed_official 52:a51c77007319 254 * READ/WRITE
mbed_official 52:a51c77007319 255 ******************************************************************************/
mbed_official 52:a51c77007319 256
mbed_official 52:a51c77007319 257 int serial_getc(serial_t *obj) {
mbed_official 52:a51c77007319 258 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 259 while (!serial_readable(obj));
mbed_official 52:a51c77007319 260 return (int)(USART_ReceiveData(usart));
mbed_official 52:a51c77007319 261 }
mbed_official 52:a51c77007319 262
mbed_official 52:a51c77007319 263 void serial_putc(serial_t *obj, int c) {
mbed_official 52:a51c77007319 264 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 265 while (!serial_writable(obj));
mbed_official 52:a51c77007319 266 USART_SendData(usart, (uint16_t)c);
mbed_official 52:a51c77007319 267 }
mbed_official 52:a51c77007319 268
mbed_official 52:a51c77007319 269 int serial_readable(serial_t *obj) {
mbed_official 52:a51c77007319 270 int status;
mbed_official 52:a51c77007319 271 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 272 // Check if data is received
mbed_official 52:a51c77007319 273 status = ((USART_GetFlagStatus(usart, USART_FLAG_RXNE) != RESET) ? 1 : 0);
mbed_official 52:a51c77007319 274 return status;
mbed_official 52:a51c77007319 275 }
mbed_official 52:a51c77007319 276
mbed_official 52:a51c77007319 277 int serial_writable(serial_t *obj) {
mbed_official 52:a51c77007319 278 int status;
mbed_official 52:a51c77007319 279 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 280 // Check if data is transmitted
mbed_official 52:a51c77007319 281 status = ((USART_GetFlagStatus(usart, USART_FLAG_TXE) != RESET) ? 1 : 0);
mbed_official 52:a51c77007319 282 return status;
mbed_official 52:a51c77007319 283 }
mbed_official 52:a51c77007319 284
mbed_official 52:a51c77007319 285 void serial_clear(serial_t *obj) {
mbed_official 52:a51c77007319 286 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 287 USART_ClearFlag(usart, USART_FLAG_TXE);
mbed_official 52:a51c77007319 288 USART_ClearFlag(usart, USART_FLAG_RXNE);
mbed_official 52:a51c77007319 289 }
mbed_official 52:a51c77007319 290
mbed_official 52:a51c77007319 291 void serial_pinout_tx(PinName tx) {
mbed_official 52:a51c77007319 292 pinmap_pinout(tx, PinMap_UART_TX);
mbed_official 52:a51c77007319 293 }
mbed_official 52:a51c77007319 294
mbed_official 52:a51c77007319 295 void serial_break_set(serial_t *obj) {
mbed_official 52:a51c77007319 296 USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
mbed_official 52:a51c77007319 297 USART_SendBreak(usart);
mbed_official 52:a51c77007319 298 }
mbed_official 52:a51c77007319 299
mbed_official 52:a51c77007319 300 void serial_break_clear(serial_t *obj) {
mbed_official 52:a51c77007319 301 }