- fix F411 F334 systeminit when HSI used - portinout always read IDR regardless of port direction

Fork of mbed-src by mbed official

Revision:
270:e2babe29baf8
Parent:
227:7bd0639b8911
Child:
288:17565898c031
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c	Fri Aug 01 14:45:06 2014 +0100
@@ -0,0 +1,255 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2013 Nordic Semiconductor
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// math.h required for floating point operations for baud rate calculation
+//#include <math.h>
+#include <string.h>
+#include "mbed_assert.h"
+
+#include "serial_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+
+/******************************************************************************
+ * INITIALIZATION
+ ******************************************************************************/
+#define UART_NUM    1
+
+static const PinMap PinMap_UART_TX[] = {
+    {TX_PIN_NUMBER, UART_0, 1},
+    { NC  , NC    , 0}
+};
+
+static const PinMap PinMap_UART_RX[] = {
+    {RX_PIN_NUMBER, UART_0, 1},
+    {NC   , NC    , 0}
+};
+
+static uint32_t serial_irq_ids[UART_NUM] = {0};
+static uart_irq_handler irq_handler;
+static uint32_t acceptedSpeeds[16][2] = {{1200,UART_BAUDRATE_BAUDRATE_Baud1200},
+                                         {2400,UART_BAUDRATE_BAUDRATE_Baud2400},
+                                         {4800,UART_BAUDRATE_BAUDRATE_Baud4800},
+                                         {9600,UART_BAUDRATE_BAUDRATE_Baud9600},
+                                         {14400,UART_BAUDRATE_BAUDRATE_Baud14400},
+                                         {19200,UART_BAUDRATE_BAUDRATE_Baud19200},
+                                         {28800,UART_BAUDRATE_BAUDRATE_Baud28800},
+                                         {38400,UART_BAUDRATE_BAUDRATE_Baud38400},
+                                         {57600,UART_BAUDRATE_BAUDRATE_Baud57600},
+                                         {76800,UART_BAUDRATE_BAUDRATE_Baud76800},
+                                         {115200,UART_BAUDRATE_BAUDRATE_Baud115200},
+                                         {230400,UART_BAUDRATE_BAUDRATE_Baud230400},
+                                         {250000,UART_BAUDRATE_BAUDRATE_Baud250000},
+                                         {460800,UART_BAUDRATE_BAUDRATE_Baud460800},
+                                         {921600,UART_BAUDRATE_BAUDRATE_Baud921600},
+                                         {1000000,UART_BAUDRATE_BAUDRATE_Baud1M}};
+
+int stdio_uart_inited = 0;
+serial_t stdio_uart;
+
+
+void serial_init(serial_t *obj, PinName tx, PinName rx) {
+    // determine the UART to use -- for mcu's with multiple uart connections
+    UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
+    UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
+    UARTName uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
+    
+    MBED_ASSERT((int)uart != NC);
+    
+    obj->uart = (NRF_UART_Type *)uart;
+    
+    //pin configurations --
+    //outputs
+    NRF_GPIO->DIR |= (1<<tx);//TX_PIN_NUMBER);
+    NRF_GPIO->DIR |= (1<<RTS_PIN_NUMBER);
+
+    NRF_GPIO->DIR &= ~(1<<rx);//RX_PIN_NUMBER);
+    NRF_GPIO->DIR &= ~(1<<CTS_PIN_NUMBER);
+    
+    obj->uart->PSELRTS = RTS_PIN_NUMBER;
+    obj->uart->PSELTXD = tx;//TX_PIN_NUMBER;
+    
+    //inputs
+    obj->uart->PSELCTS = CTS_PIN_NUMBER;
+    obj->uart->PSELRXD = rx;//RX_PIN_NUMBER;
+    
+    
+    // set default baud rate and format
+    serial_baud  (obj, 9600);
+    serial_format(obj, 8, ParityNone, 1);
+    
+    obj->uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);;
+    obj->uart->TASKS_STARTTX = 1;
+    obj->uart->TASKS_STARTRX = 1;
+    obj->uart->EVENTS_RXDRDY =0;
+    
+    obj->index = 0;
+    
+    // set rx/tx pins in PullUp mode
+    pin_mode(tx, PullUp);
+    pin_mode(rx, PullUp);
+    
+    if (uart == STDIO_UART) {
+        stdio_uart_inited = 1;
+        memcpy(&stdio_uart, obj, sizeof(serial_t));
+    }
+}
+
+void serial_free(serial_t *obj) {
+    serial_irq_ids[obj->index] = 0;
+}
+
+// serial_baud
+// set the baud rate, taking in to account the current SystemFrequency
+void serial_baud(serial_t *obj, int baudrate) {
+    if(baudrate<=1200){
+        obj->uart->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1200;
+        return;
+    }
+    
+    for(int i=1;i<16;i++){
+        if(baudrate<acceptedSpeeds[i][0]){
+            obj->uart->BAUDRATE = acceptedSpeeds[i-1][1];
+            return;
+        }
+    }
+    obj->uart->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud1M;
+}
+
+void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
+    // 0: 1 stop bits, 1: 2 stop bits
+   // int parity_enable, parity_select;
+    switch (parity) {
+        case ParityNone:
+            obj->uart->CONFIG  = 0;
+        break;
+        default:
+            obj->uart->CONFIG  = (UART_CONFIG_PARITY_Included<<UART_CONFIG_PARITY_Pos);
+            return;
+    }
+    //no Flow Control
+}
+
+//******************************************************************************
+// * INTERRUPT HANDLING
+//******************************************************************************
+static inline void uart_irq(uint32_t iir, uint32_t index) {
+    SerialIrq irq_type;
+    switch (iir) {
+        case 1:
+            irq_type = TxIrq;
+        break;
+        case 2:
+            irq_type = RxIrq;
+        break;
+        
+        default: return;
+    }
+    
+    if (serial_irq_ids[index] != 0){
+        irq_handler(serial_irq_ids[index], irq_type);
+    }
+}
+#ifdef __cplusplus
+extern "C" {
+#endif
+void UART0_IRQHandler()
+{
+    uint32_t irtype =0;
+    
+    if(NRF_UART0->EVENTS_TXDRDY){
+        irtype =1;
+    }
+    else if(NRF_UART0->EVENTS_RXDRDY){
+        irtype =2;
+    }
+    uart_irq(irtype, 0);
+}
+#ifdef __cplusplus
+}
+#endif
+void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
+    irq_handler = handler;
+    serial_irq_ids[obj->index] = id;
+}
+
+void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
+    IRQn_Type irq_n = (IRQn_Type)0;
+
+    switch ((int)obj->uart) {
+        case UART_0: irq_n=UART0_IRQn ;
+            break;
+    }
+    
+    if (enable) {
+        switch (irq) {
+            case RxIrq: obj->uart->INTENSET |= (UART_INTENSET_RXDRDY_Msk);break;
+            case TxIrq: obj->uart->INTENSET |= (UART_INTENSET_TXDRDY_Msk);break;
+        }
+        NVIC_SetPriority(irq_n, 3);
+        NVIC_EnableIRQ(irq_n);
+    }
+    else { // disable
+        int all_disabled = 0;
+        switch (irq) {
+            case RxIrq: obj->uart->INTENSET &= ~(UART_INTENSET_RXDRDY_Msk);
+                        all_disabled = (obj->uart->INTENSET& (UART_INTENSET_TXDRDY_Msk))==0;
+            break;
+            case TxIrq: obj->uart->INTENSET &= ~(UART_INTENSET_TXDRDY_Msk);
+                        all_disabled = (obj->uart->INTENSET& (UART_INTENSET_RXDRDY_Msk))==0;
+            break;
+        }
+        
+        if (all_disabled){
+            NVIC_DisableIRQ(irq_n);
+        }
+    }
+}
+
+//******************************************************************************
+//* READ/WRITE
+//******************************************************************************
+int serial_getc(serial_t *obj) {
+    while (!serial_readable(obj));
+    
+    obj->uart->EVENTS_RXDRDY = 0;
+    
+    return (uint8_t)obj->uart->RXD;
+}
+
+void serial_putc(serial_t *obj, int c) {
+    obj->uart->TXD = (uint8_t)c;
+    
+    while (!serial_writable(obj));
+    
+    obj->uart->EVENTS_TXDRDY =0;
+}
+
+int serial_readable(serial_t *obj) {
+    return (obj->uart->EVENTS_RXDRDY == 1);
+}
+
+int serial_writable(serial_t *obj) {
+    return (obj->uart->EVENTS_TXDRDY ==1);
+}
+
+void serial_break_set(serial_t *obj) {
+    obj->uart->TASKS_SUSPEND = 1;
+}
+
+void serial_break_clear(serial_t *obj) {
+    obj->uart->TASKS_STARTTX = 1;
+    obj->uart->TASKS_STARTRX = 1;
+}