Test code for Grove Node BLE

Dependencies:   BLE_API nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Committer:
yihui
Date:
Thu Nov 27 09:30:36 2014 +0000
Revision:
10:22480ac31879
Parent:
9:05f0b5a3a70a
change to new revision hardware

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 9:05f0b5a3a70a 1 /* mbed Microcontroller Library
yihui 9:05f0b5a3a70a 2 * Copyright (c) 2013 Nordic Semiconductor
yihui 9:05f0b5a3a70a 3 *
yihui 9:05f0b5a3a70a 4 * Licensed under the Apache License, Version 2.0 (the "License");
yihui 9:05f0b5a3a70a 5 * you may not use this file except in compliance with the License.
yihui 9:05f0b5a3a70a 6 * You may obtain a copy of the License at
yihui 9:05f0b5a3a70a 7 *
yihui 9:05f0b5a3a70a 8 * http://www.apache.org/licenses/LICENSE-2.0
yihui 9:05f0b5a3a70a 9 *
yihui 9:05f0b5a3a70a 10 * Unless required by applicable law or agreed to in writing, software
yihui 9:05f0b5a3a70a 11 * distributed under the License is distributed on an "AS IS" BASIS,
yihui 9:05f0b5a3a70a 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
yihui 9:05f0b5a3a70a 13 * See the License for the specific language governing permissions and
yihui 9:05f0b5a3a70a 14 * limitations under the License.
yihui 9:05f0b5a3a70a 15 */
yihui 9:05f0b5a3a70a 16 // math.h required for floating point operations for baud rate calculation
yihui 9:05f0b5a3a70a 17 //#include <math.h>
yihui 9:05f0b5a3a70a 18 #include <string.h>
yihui 9:05f0b5a3a70a 19 #include "mbed_assert.h"
yihui 9:05f0b5a3a70a 20
yihui 9:05f0b5a3a70a 21 #include "serial_api.h"
yihui 9:05f0b5a3a70a 22 #include "cmsis.h"
yihui 9:05f0b5a3a70a 23 #include "pinmap.h"
yihui 9:05f0b5a3a70a 24
yihui 9:05f0b5a3a70a 25 /******************************************************************************
yihui 9:05f0b5a3a70a 26 * INITIALIZATION
yihui 9:05f0b5a3a70a 27 ******************************************************************************/
yihui 9:05f0b5a3a70a 28 #define UART_NUM 1
yihui 9:05f0b5a3a70a 29
yihui 9:05f0b5a3a70a 30 static uint32_t serial_irq_ids[UART_NUM] = {0};
yihui 9:05f0b5a3a70a 31 static uart_irq_handler irq_handler;
yihui 9:05f0b5a3a70a 32 static uint32_t acceptedSpeeds[16][2] = {{1200, UART_BAUDRATE_BAUDRATE_Baud1200},
yihui 9:05f0b5a3a70a 33 {2400, UART_BAUDRATE_BAUDRATE_Baud2400},
yihui 9:05f0b5a3a70a 34 {4800, UART_BAUDRATE_BAUDRATE_Baud4800},
yihui 9:05f0b5a3a70a 35 {9600, UART_BAUDRATE_BAUDRATE_Baud9600},
yihui 9:05f0b5a3a70a 36 {14400, UART_BAUDRATE_BAUDRATE_Baud14400},
yihui 9:05f0b5a3a70a 37 {19200, UART_BAUDRATE_BAUDRATE_Baud19200},
yihui 9:05f0b5a3a70a 38 {28800, UART_BAUDRATE_BAUDRATE_Baud28800},
yihui 9:05f0b5a3a70a 39 {38400, UART_BAUDRATE_BAUDRATE_Baud38400},
yihui 9:05f0b5a3a70a 40 {57600, UART_BAUDRATE_BAUDRATE_Baud57600},
yihui 9:05f0b5a3a70a 41 {76800, UART_BAUDRATE_BAUDRATE_Baud76800},
yihui 9:05f0b5a3a70a 42 {115200, UART_BAUDRATE_BAUDRATE_Baud115200},
yihui 9:05f0b5a3a70a 43 {230400, UART_BAUDRATE_BAUDRATE_Baud230400},
yihui 9:05f0b5a3a70a 44 {250000, UART_BAUDRATE_BAUDRATE_Baud250000},
yihui 9:05f0b5a3a70a 45 {460800, UART_BAUDRATE_BAUDRATE_Baud460800},
yihui 9:05f0b5a3a70a 46 {921600, UART_BAUDRATE_BAUDRATE_Baud921600},
yihui 9:05f0b5a3a70a 47 {1000000, UART_BAUDRATE_BAUDRATE_Baud1M}};
yihui 9:05f0b5a3a70a 48
yihui 9:05f0b5a3a70a 49 int stdio_uart_inited = 0;
yihui 9:05f0b5a3a70a 50 serial_t stdio_uart;
yihui 9:05f0b5a3a70a 51
yihui 9:05f0b5a3a70a 52
yihui 9:05f0b5a3a70a 53 void serial_init(serial_t *obj, PinName tx, PinName rx) {
yihui 9:05f0b5a3a70a 54 UARTName uart = UART_0;
yihui 9:05f0b5a3a70a 55
yihui 9:05f0b5a3a70a 56 MBED_ASSERT((int)uart != NC);
yihui 9:05f0b5a3a70a 57
yihui 9:05f0b5a3a70a 58 obj->uart = (NRF_UART_Type *)uart;
yihui 9:05f0b5a3a70a 59
yihui 9:05f0b5a3a70a 60 //pin configurations --
yihui 9:05f0b5a3a70a 61 //outputs
yihui 9:05f0b5a3a70a 62 NRF_GPIO->DIR |= (1 << tx); //TX_PIN_NUMBER);
yihui 9:05f0b5a3a70a 63 NRF_GPIO->DIR |= (1 << RTS_PIN_NUMBER);
yihui 9:05f0b5a3a70a 64
yihui 9:05f0b5a3a70a 65 NRF_GPIO->DIR &= ~(1 << rx); //RX_PIN_NUMBER);
yihui 9:05f0b5a3a70a 66 NRF_GPIO->DIR &= ~(1 << CTS_PIN_NUMBER);
yihui 9:05f0b5a3a70a 67
yihui 9:05f0b5a3a70a 68 obj->uart->PSELRTS = RTS_PIN_NUMBER;
yihui 9:05f0b5a3a70a 69 obj->uart->PSELTXD = tx; //TX_PIN_NUMBER;
yihui 9:05f0b5a3a70a 70
yihui 9:05f0b5a3a70a 71 //inputs
yihui 9:05f0b5a3a70a 72 obj->uart->PSELCTS = CTS_PIN_NUMBER;
yihui 9:05f0b5a3a70a 73 obj->uart->PSELRXD = rx; //RX_PIN_NUMBER;
yihui 9:05f0b5a3a70a 74
yihui 9:05f0b5a3a70a 75
yihui 9:05f0b5a3a70a 76 // set default baud rate and format
yihui 9:05f0b5a3a70a 77 serial_baud (obj, 9600);
yihui 9:05f0b5a3a70a 78 serial_format(obj, 8, ParityNone, 1);
yihui 9:05f0b5a3a70a 79
yihui 9:05f0b5a3a70a 80 obj->uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
yihui 9:05f0b5a3a70a 81 obj->uart->TASKS_STARTTX = 1;
yihui 9:05f0b5a3a70a 82 obj->uart->TASKS_STARTRX = 1;
yihui 9:05f0b5a3a70a 83 obj->uart->EVENTS_RXDRDY = 0;
yihui 9:05f0b5a3a70a 84
yihui 9:05f0b5a3a70a 85 obj->index = 0;
yihui 9:05f0b5a3a70a 86
yihui 9:05f0b5a3a70a 87 // set rx/tx pins in PullUp mode
yihui 9:05f0b5a3a70a 88 if (tx != NC) {
yihui 9:05f0b5a3a70a 89 pin_mode(tx, PullUp);
yihui 9:05f0b5a3a70a 90 }
yihui 9:05f0b5a3a70a 91 if (rx != NC) {
yihui 9:05f0b5a3a70a 92 pin_mode(rx, PullUp);
yihui 9:05f0b5a3a70a 93 }
yihui 9:05f0b5a3a70a 94
yihui 9:05f0b5a3a70a 95 if (uart == STDIO_UART) {
yihui 9:05f0b5a3a70a 96 stdio_uart_inited = 1;
yihui 9:05f0b5a3a70a 97 memcpy(&stdio_uart, obj, sizeof(serial_t));
yihui 9:05f0b5a3a70a 98 }
yihui 9:05f0b5a3a70a 99 }
yihui 9:05f0b5a3a70a 100
yihui 9:05f0b5a3a70a 101 void serial_free(serial_t *obj)
yihui 9:05f0b5a3a70a 102 {
yihui 9:05f0b5a3a70a 103 serial_irq_ids[obj->index] = 0;
yihui 9:05f0b5a3a70a 104 }
yihui 9:05f0b5a3a70a 105
yihui 9:05f0b5a3a70a 106 // serial_baud
yihui 9:05f0b5a3a70a 107 // set the baud rate, taking in to account the current SystemFrequency
yihui 9:05f0b5a3a70a 108 void serial_baud(serial_t *obj, int baudrate)
yihui 9:05f0b5a3a70a 109 {
yihui 9:05f0b5a3a70a 110 if (baudrate<=1200) {
yihui 9:05f0b5a3a70a 111 obj->uart->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1200;
yihui 9:05f0b5a3a70a 112 return;
yihui 9:05f0b5a3a70a 113 }
yihui 9:05f0b5a3a70a 114
yihui 9:05f0b5a3a70a 115 for (int i = 1; i<16; i++) {
yihui 9:05f0b5a3a70a 116 if (baudrate<acceptedSpeeds[i][0]) {
yihui 9:05f0b5a3a70a 117 obj->uart->BAUDRATE = acceptedSpeeds[i - 1][1];
yihui 9:05f0b5a3a70a 118 return;
yihui 9:05f0b5a3a70a 119 }
yihui 9:05f0b5a3a70a 120 }
yihui 9:05f0b5a3a70a 121 obj->uart->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1M;
yihui 9:05f0b5a3a70a 122 }
yihui 9:05f0b5a3a70a 123
yihui 9:05f0b5a3a70a 124 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
yihui 9:05f0b5a3a70a 125 {
yihui 9:05f0b5a3a70a 126 // 0: 1 stop bits, 1: 2 stop bits
yihui 9:05f0b5a3a70a 127 // int parity_enable, parity_select;
yihui 9:05f0b5a3a70a 128 switch (parity) {
yihui 9:05f0b5a3a70a 129 case ParityNone:
yihui 9:05f0b5a3a70a 130 obj->uart->CONFIG = 0;
yihui 9:05f0b5a3a70a 131 break;
yihui 9:05f0b5a3a70a 132 default:
yihui 9:05f0b5a3a70a 133 obj->uart->CONFIG = (UART_CONFIG_PARITY_Included << UART_CONFIG_PARITY_Pos);
yihui 9:05f0b5a3a70a 134 return;
yihui 9:05f0b5a3a70a 135 }
yihui 9:05f0b5a3a70a 136 //no Flow Control
yihui 9:05f0b5a3a70a 137 }
yihui 9:05f0b5a3a70a 138
yihui 9:05f0b5a3a70a 139 //******************************************************************************
yihui 9:05f0b5a3a70a 140 // * INTERRUPT HANDLING
yihui 9:05f0b5a3a70a 141 //******************************************************************************
yihui 9:05f0b5a3a70a 142 static inline void uart_irq(uint32_t iir, uint32_t index)
yihui 9:05f0b5a3a70a 143 {
yihui 9:05f0b5a3a70a 144 SerialIrq irq_type;
yihui 9:05f0b5a3a70a 145 switch (iir) {
yihui 9:05f0b5a3a70a 146 case 1:
yihui 9:05f0b5a3a70a 147 irq_type = TxIrq;
yihui 9:05f0b5a3a70a 148 break;
yihui 9:05f0b5a3a70a 149 case 2:
yihui 9:05f0b5a3a70a 150 irq_type = RxIrq;
yihui 9:05f0b5a3a70a 151 break;
yihui 9:05f0b5a3a70a 152
yihui 9:05f0b5a3a70a 153 default:
yihui 9:05f0b5a3a70a 154 return;
yihui 9:05f0b5a3a70a 155 }
yihui 9:05f0b5a3a70a 156
yihui 9:05f0b5a3a70a 157 if (serial_irq_ids[index] != 0) {
yihui 9:05f0b5a3a70a 158 irq_handler(serial_irq_ids[index], irq_type);
yihui 9:05f0b5a3a70a 159 }
yihui 9:05f0b5a3a70a 160 }
yihui 9:05f0b5a3a70a 161
yihui 9:05f0b5a3a70a 162 #ifdef __cplusplus
yihui 9:05f0b5a3a70a 163 extern "C" {
yihui 9:05f0b5a3a70a 164 #endif
yihui 9:05f0b5a3a70a 165 void UART0_IRQHandler()
yihui 9:05f0b5a3a70a 166 {
yihui 9:05f0b5a3a70a 167 uint32_t irtype = 0;
yihui 9:05f0b5a3a70a 168
yihui 9:05f0b5a3a70a 169 if((NRF_UART0->INTENSET & 0x80) && NRF_UART0->EVENTS_TXDRDY) {
yihui 9:05f0b5a3a70a 170 irtype = 1;
yihui 9:05f0b5a3a70a 171 } else if((NRF_UART0->INTENSET & 0x04) && NRF_UART0->EVENTS_RXDRDY) {
yihui 9:05f0b5a3a70a 172 irtype = 2;
yihui 9:05f0b5a3a70a 173 }
yihui 9:05f0b5a3a70a 174 uart_irq(irtype, 0);
yihui 9:05f0b5a3a70a 175 }
yihui 9:05f0b5a3a70a 176
yihui 9:05f0b5a3a70a 177 #ifdef __cplusplus
yihui 9:05f0b5a3a70a 178 }
yihui 9:05f0b5a3a70a 179 #endif
yihui 9:05f0b5a3a70a 180 void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
yihui 9:05f0b5a3a70a 181 {
yihui 9:05f0b5a3a70a 182 irq_handler = handler;
yihui 9:05f0b5a3a70a 183 serial_irq_ids[obj->index] = id;
yihui 9:05f0b5a3a70a 184 }
yihui 9:05f0b5a3a70a 185
yihui 9:05f0b5a3a70a 186 void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
yihui 9:05f0b5a3a70a 187 {
yihui 9:05f0b5a3a70a 188 IRQn_Type irq_n = (IRQn_Type)0;
yihui 9:05f0b5a3a70a 189
yihui 9:05f0b5a3a70a 190 switch ((int)obj->uart) {
yihui 9:05f0b5a3a70a 191 case UART_0:
yihui 9:05f0b5a3a70a 192 irq_n = UART0_IRQn;
yihui 9:05f0b5a3a70a 193 break;
yihui 9:05f0b5a3a70a 194 }
yihui 9:05f0b5a3a70a 195
yihui 9:05f0b5a3a70a 196 if (enable) {
yihui 9:05f0b5a3a70a 197 switch (irq) {
yihui 9:05f0b5a3a70a 198 case RxIrq:
yihui 9:05f0b5a3a70a 199 obj->uart->INTENSET |= (UART_INTENSET_RXDRDY_Msk);
yihui 9:05f0b5a3a70a 200 break;
yihui 9:05f0b5a3a70a 201 case TxIrq:
yihui 9:05f0b5a3a70a 202 obj->uart->INTENSET |= (UART_INTENSET_TXDRDY_Msk);
yihui 9:05f0b5a3a70a 203 break;
yihui 9:05f0b5a3a70a 204 }
yihui 9:05f0b5a3a70a 205 NVIC_SetPriority(irq_n, 3);
yihui 9:05f0b5a3a70a 206 NVIC_EnableIRQ(irq_n);
yihui 9:05f0b5a3a70a 207 } else { // disable
yihui 9:05f0b5a3a70a 208 int all_disabled = 0;
yihui 9:05f0b5a3a70a 209 switch (irq) {
yihui 9:05f0b5a3a70a 210 case RxIrq:
yihui 9:05f0b5a3a70a 211 obj->uart->INTENSET &= ~(UART_INTENSET_RXDRDY_Msk);
yihui 9:05f0b5a3a70a 212 all_disabled = (obj->uart->INTENSET & (UART_INTENSET_TXDRDY_Msk))==0;
yihui 9:05f0b5a3a70a 213 break;
yihui 9:05f0b5a3a70a 214 case TxIrq:
yihui 9:05f0b5a3a70a 215 obj->uart->INTENSET &= ~(UART_INTENSET_TXDRDY_Msk);
yihui 9:05f0b5a3a70a 216 all_disabled = (obj->uart->INTENSET & (UART_INTENSET_RXDRDY_Msk))==0;
yihui 9:05f0b5a3a70a 217 break;
yihui 9:05f0b5a3a70a 218 }
yihui 9:05f0b5a3a70a 219
yihui 9:05f0b5a3a70a 220 if (all_disabled) {
yihui 9:05f0b5a3a70a 221 NVIC_DisableIRQ(irq_n);
yihui 9:05f0b5a3a70a 222 }
yihui 9:05f0b5a3a70a 223 }
yihui 9:05f0b5a3a70a 224 }
yihui 9:05f0b5a3a70a 225
yihui 9:05f0b5a3a70a 226 //******************************************************************************
yihui 9:05f0b5a3a70a 227 //* READ/WRITE
yihui 9:05f0b5a3a70a 228 //******************************************************************************
yihui 9:05f0b5a3a70a 229 int serial_getc(serial_t *obj)
yihui 9:05f0b5a3a70a 230 {
yihui 9:05f0b5a3a70a 231 while (!serial_readable(obj)) {
yihui 9:05f0b5a3a70a 232 }
yihui 9:05f0b5a3a70a 233
yihui 9:05f0b5a3a70a 234 obj->uart->EVENTS_RXDRDY = 0;
yihui 9:05f0b5a3a70a 235
yihui 9:05f0b5a3a70a 236 return (uint8_t)obj->uart->RXD;
yihui 9:05f0b5a3a70a 237 }
yihui 9:05f0b5a3a70a 238
yihui 9:05f0b5a3a70a 239 void serial_putc(serial_t *obj, int c)
yihui 9:05f0b5a3a70a 240 {
yihui 9:05f0b5a3a70a 241 obj->uart->TXD = (uint8_t)c;
yihui 9:05f0b5a3a70a 242
yihui 9:05f0b5a3a70a 243 while (!serial_writable(obj)) {
yihui 9:05f0b5a3a70a 244 }
yihui 9:05f0b5a3a70a 245
yihui 9:05f0b5a3a70a 246 obj->uart->EVENTS_TXDRDY = 0;
yihui 9:05f0b5a3a70a 247 }
yihui 9:05f0b5a3a70a 248
yihui 9:05f0b5a3a70a 249 int serial_readable(serial_t *obj)
yihui 9:05f0b5a3a70a 250 {
yihui 9:05f0b5a3a70a 251 return (obj->uart->EVENTS_RXDRDY == 1);
yihui 9:05f0b5a3a70a 252 }
yihui 9:05f0b5a3a70a 253
yihui 9:05f0b5a3a70a 254 int serial_writable(serial_t *obj)
yihui 9:05f0b5a3a70a 255 {
yihui 9:05f0b5a3a70a 256 return (obj->uart->EVENTS_TXDRDY ==1);
yihui 9:05f0b5a3a70a 257 }
yihui 9:05f0b5a3a70a 258
yihui 9:05f0b5a3a70a 259 void serial_break_set(serial_t *obj)
yihui 9:05f0b5a3a70a 260 {
yihui 9:05f0b5a3a70a 261 obj->uart->TASKS_SUSPEND = 1;
yihui 9:05f0b5a3a70a 262 }
yihui 9:05f0b5a3a70a 263
yihui 9:05f0b5a3a70a 264 void serial_break_clear(serial_t *obj)
yihui 9:05f0b5a3a70a 265 {
yihui 9:05f0b5a3a70a 266 obj->uart->TASKS_STARTTX = 1;
yihui 9:05f0b5a3a70a 267 obj->uart->TASKS_STARTRX = 1;
yihui 9:05f0b5a3a70a 268 }
yihui 9:05f0b5a3a70a 269
yihui 9:05f0b5a3a70a 270 void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
yihui 9:05f0b5a3a70a 271 {
yihui 9:05f0b5a3a70a 272
yihui 9:05f0b5a3a70a 273 if (type == FlowControlRTSCTS || type == FlowControlRTS) {
yihui 9:05f0b5a3a70a 274 NRF_GPIO->DIR |= (1<<rxflow);
yihui 9:05f0b5a3a70a 275 pin_mode(rxflow, PullUp);
yihui 9:05f0b5a3a70a 276 obj->uart->PSELRTS = rxflow;
yihui 9:05f0b5a3a70a 277
yihui 9:05f0b5a3a70a 278 obj->uart->CONFIG |= 0x01; // Enable HWFC
yihui 9:05f0b5a3a70a 279 }
yihui 9:05f0b5a3a70a 280
yihui 9:05f0b5a3a70a 281 if (type == FlowControlRTSCTS || type == FlowControlCTS) {
yihui 9:05f0b5a3a70a 282 NRF_GPIO->DIR &= ~(1<<txflow);
yihui 9:05f0b5a3a70a 283 pin_mode(txflow, PullUp);
yihui 9:05f0b5a3a70a 284 obj->uart->PSELCTS = txflow;
yihui 9:05f0b5a3a70a 285
yihui 9:05f0b5a3a70a 286 obj->uart->CONFIG |= 0x01; // Enable HWFC;
yihui 9:05f0b5a3a70a 287 }
yihui 9:05f0b5a3a70a 288
yihui 9:05f0b5a3a70a 289 if (type == FlowControlNone) {
yihui 9:05f0b5a3a70a 290 obj->uart->PSELRTS = 0xFFFFFFFF; // Disable RTS
yihui 9:05f0b5a3a70a 291 obj->uart->PSELCTS = 0xFFFFFFFF; // Disable CTS
yihui 9:05f0b5a3a70a 292
yihui 9:05f0b5a3a70a 293 obj->uart->CONFIG &= ~0x01; // Enable HWFC;
yihui 9:05f0b5a3a70a 294 }
yihui 9:05f0b5a3a70a 295 }
yihui 9:05f0b5a3a70a 296
yihui 9:05f0b5a3a70a 297 void serial_clear(serial_t *obj) {
yihui 9:05f0b5a3a70a 298 }
yihui 9:05f0b5a3a70a 299