Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of football_project by
io/MySerial.cpp@9:95dc84e9fb7f, 2015-04-19 (annotated)
- Committer:
- AntonLS
- Date:
- Sun Apr 19 19:59:46 2015 +0000
- Revision:
- 9:95dc84e9fb7f
- Parent:
- 8:d5d055be2bb8
- Child:
- 15:b86c4b798aa1
RTS HWFC now working.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| AntonLS | 1:0ba687d4196f | 1 | /* |
| AntonLS | 1:0ba687d4196f | 2 | * |
| AntonLS | 1:0ba687d4196f | 3 | * Replacement for Serial, so UART flow control is inited properly. ALS 20150412 |
| AntonLS | 1:0ba687d4196f | 4 | * |
| AntonLS | 1:0ba687d4196f | 5 | * MySerialBase is a replacement for SerialBase, to prevent it from calling |
| AntonLS | 1:0ba687d4196f | 6 | * the faulty-for-nRF51822-uart-init serial_init() |
| AntonLS | 1:0ba687d4196f | 7 | * in mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c |
| AntonLS | 1:0ba687d4196f | 8 | * |
| AntonLS | 1:0ba687d4196f | 9 | */ |
| AntonLS | 1:0ba687d4196f | 10 | |
| AntonLS | 1:0ba687d4196f | 11 | #include "MySerial.h" |
| AntonLS | 1:0ba687d4196f | 12 | |
| AntonLS | 1:0ba687d4196f | 13 | extern "C" |
| AntonLS | 1:0ba687d4196f | 14 | { |
| AntonLS | 1:0ba687d4196f | 15 | void pin_mode( PinName, PinMode ); |
| AntonLS | 6:ef758ac3c928 | 16 | |
| AntonLS | 8:d5d055be2bb8 | 17 | void UART0_IRQHandler(); // Make sure UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 8:d5d055be2bb8 | 18 | // TODO Maybe move all serial_api.c workarounds into serial_api.c |
| AntonLS | 1:0ba687d4196f | 19 | } |
| AntonLS | 1:0ba687d4196f | 20 | |
| AntonLS | 1:0ba687d4196f | 21 | extern int stdio_uart_inited; |
| AntonLS | 1:0ba687d4196f | 22 | extern serial_t stdio_uart; |
| AntonLS | 1:0ba687d4196f | 23 | |
| AntonLS | 6:ef758ac3c928 | 24 | // Our versions of serial_api.c's... |
| AntonLS | 8:d5d055be2bb8 | 25 | // (serial_free(), etc. in serial_api.c won't work when use our own copy.) TODO Maybe make one in serial_api.c accessible. |
| AntonLS | 6:ef758ac3c928 | 26 | #define UART_NUM 1 |
| AntonLS | 6:ef758ac3c928 | 27 | static uint32_t serial_irq_ids[UART_NUM] = {0}; |
| AntonLS | 6:ef758ac3c928 | 28 | static uart_irq_handler irq_handler; |
| AntonLS | 6:ef758ac3c928 | 29 | |
| AntonLS | 1:0ba687d4196f | 30 | |
| AntonLS | 1:0ba687d4196f | 31 | using namespace moo; |
| AntonLS | 1:0ba687d4196f | 32 | |
| AntonLS | 1:0ba687d4196f | 33 | |
| AntonLS | 1:0ba687d4196f | 34 | MySerialBase::MySerialBase( PinName tx, PinName rx, |
| AntonLS | 1:0ba687d4196f | 35 | PinName rts, PinName cts ) : _my_serial(), _my_baud( 9600 ) |
| AntonLS | 1:0ba687d4196f | 36 | { |
| AntonLS | 2:fe1566cdb6e7 | 37 | my_serial_init( &_my_serial, tx, rx, rts, cts, _my_baud ); |
| AntonLS | 8:d5d055be2bb8 | 38 | // serial_irq_handler( &_my_serial, _irq_handler, (uint32_t)this ); // serial_api.c only calls handler for Tx & Rx. |
| AntonLS | 7:205ef63d311a | 39 | |
| AntonLS | 8:d5d055be2bb8 | 40 | // Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 8:d5d055be2bb8 | 41 | my_serial_irq_handler( &_my_serial, _irq_handler, (uint32_t)this ); |
| AntonLS | 5:1b9734e68327 | 42 | |
| AntonLS | 8:d5d055be2bb8 | 43 | // For uart errors -- Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 8:d5d055be2bb8 | 44 | attach( this, &MySerialBase::error_handler, (Serial::IrqType)ErrIrq ); |
| AntonLS | 8:d5d055be2bb8 | 45 | // For cts -- Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 8:d5d055be2bb8 | 46 | attach( this, &MySerialBase::ncts_handler, (Serial::IrqType)NctsIrq ); |
| AntonLS | 8:d5d055be2bb8 | 47 | attach( this, &MySerialBase::cts_handler, (Serial::IrqType)CtsIrq ); |
| AntonLS | 1:0ba687d4196f | 48 | } |
| AntonLS | 1:0ba687d4196f | 49 | void MySerialBase::baud( int baudrate ) |
| AntonLS | 1:0ba687d4196f | 50 | { |
| AntonLS | 1:0ba687d4196f | 51 | serial_baud( &_my_serial, baudrate ); |
| AntonLS | 1:0ba687d4196f | 52 | _my_baud = baudrate; |
| AntonLS | 1:0ba687d4196f | 53 | } |
| AntonLS | 1:0ba687d4196f | 54 | void MySerialBase::format( int bits, SerialBase::Parity parity, int stop_bits ) |
| AntonLS | 1:0ba687d4196f | 55 | { |
| AntonLS | 1:0ba687d4196f | 56 | serial_format( &_my_serial, bits, (SerialParity)parity, stop_bits ); |
| AntonLS | 1:0ba687d4196f | 57 | } |
| AntonLS | 1:0ba687d4196f | 58 | int MySerialBase::readable() |
| AntonLS | 1:0ba687d4196f | 59 | { |
| AntonLS | 1:0ba687d4196f | 60 | return serial_readable( &_my_serial ); |
| AntonLS | 1:0ba687d4196f | 61 | } |
| AntonLS | 1:0ba687d4196f | 62 | int MySerialBase::writeable() |
| AntonLS | 1:0ba687d4196f | 63 | { |
| AntonLS | 1:0ba687d4196f | 64 | return serial_writable( &_my_serial ); |
| AntonLS | 1:0ba687d4196f | 65 | } |
| AntonLS | 5:1b9734e68327 | 66 | void MySerialBase::attach( void (*fptr)(void), Serial::IrqType type ) |
| AntonLS | 1:0ba687d4196f | 67 | { |
| AntonLS | 1:0ba687d4196f | 68 | if( fptr ) |
| AntonLS | 1:0ba687d4196f | 69 | { |
| AntonLS | 1:0ba687d4196f | 70 | _my_irq[type].attach( fptr ); |
| AntonLS | 5:1b9734e68327 | 71 | my_serial_irq_set( &_my_serial, (IrqType)type, 1 ); |
| AntonLS | 5:1b9734e68327 | 72 | |
| AntonLS | 1:0ba687d4196f | 73 | } else |
| AntonLS | 5:1b9734e68327 | 74 | { |
| AntonLS | 5:1b9734e68327 | 75 | my_serial_irq_set( &_my_serial, (IrqType)type, 0 ); |
| AntonLS | 5:1b9734e68327 | 76 | } |
| AntonLS | 1:0ba687d4196f | 77 | } |
| AntonLS | 2:fe1566cdb6e7 | 78 | void MySerialBase::my_serial_init( serial_t *obj, PinName tx, PinName rx, PinName rts, PinName cts, int baudrate ) |
| AntonLS | 2:fe1566cdb6e7 | 79 | { |
| AntonLS | 2:fe1566cdb6e7 | 80 | UARTName uart = UART_0; |
| AntonLS | 2:fe1566cdb6e7 | 81 | obj->uart = (NRF_UART_Type *)uart; |
| AntonLS | 2:fe1566cdb6e7 | 82 | |
| AntonLS | 2:fe1566cdb6e7 | 83 | // pin configurations -- |
| AntonLS | 2:fe1566cdb6e7 | 84 | NRF_GPIO->DIR |= (1 << tx); // TX_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 85 | NRF_GPIO->DIR |= ((NC == rts) ? 0 : (1 << rts)); // RTS_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 86 | |
| AntonLS | 2:fe1566cdb6e7 | 87 | NRF_GPIO->DIR &= ~(1 << rx); // RX_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 88 | NRF_GPIO->DIR &= ~((NC == cts) ? 0 : (1 << cts)); // CTS_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 89 | |
| AntonLS | 2:fe1566cdb6e7 | 90 | obj->uart->PSELRTS = ((NC == rts) ? 0xFFFFFFFF : rts); // RTS_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 91 | obj->uart->PSELTXD = tx; // TX_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 92 | obj->uart->PSELCTS = ((NC == cts) ? 0xFFFFFFFF : cts); // CTS_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 93 | obj->uart->PSELRXD = rx; // RX_PIN_NUMBER |
| AntonLS | 2:fe1566cdb6e7 | 94 | |
| AntonLS | 9:95dc84e9fb7f | 95 | // set default baud rate and format |
| AntonLS | 9:95dc84e9fb7f | 96 | serial_baud ( obj, baudrate ); |
| AntonLS | 9:95dc84e9fb7f | 97 | serial_format( obj, 8, ParityNone, 1 ); |
| AntonLS | 9:95dc84e9fb7f | 98 | |
| AntonLS | 2:fe1566cdb6e7 | 99 | if( (NC != rts) || (NC != cts) ) |
| AntonLS | 2:fe1566cdb6e7 | 100 | { |
| AntonLS | 9:95dc84e9fb7f | 101 | obj->uart->CONFIG |= UART_CONFIG_HWFC_Msk; // Enable HWFC |
| AntonLS | 2:fe1566cdb6e7 | 102 | |
| AntonLS | 2:fe1566cdb6e7 | 103 | } else |
| AntonLS | 2:fe1566cdb6e7 | 104 | { |
| AntonLS | 9:95dc84e9fb7f | 105 | obj->uart->CONFIG &= ~UART_CONFIG_HWFC_Msk; // Disable HWFC; |
| AntonLS | 2:fe1566cdb6e7 | 106 | } |
| AntonLS | 2:fe1566cdb6e7 | 107 | |
| AntonLS | 2:fe1566cdb6e7 | 108 | obj->uart->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); |
| AntonLS | 2:fe1566cdb6e7 | 109 | obj->uart->TASKS_STARTTX = 1; |
| AntonLS | 2:fe1566cdb6e7 | 110 | obj->uart->TASKS_STARTRX = 1; |
| AntonLS | 2:fe1566cdb6e7 | 111 | obj->uart->EVENTS_RXDRDY = 0; |
| AntonLS | 2:fe1566cdb6e7 | 112 | // dummy write needed or TXDRDY trails write rather than leads write. |
| AntonLS | 2:fe1566cdb6e7 | 113 | // pins are disconnected so nothing is physically transmitted on the wire |
| AntonLS | 2:fe1566cdb6e7 | 114 | obj->uart->TXD = 0; |
| AntonLS | 2:fe1566cdb6e7 | 115 | |
| AntonLS | 2:fe1566cdb6e7 | 116 | obj->index = 0; |
| AntonLS | 9:95dc84e9fb7f | 117 | |
| AntonLS | 2:fe1566cdb6e7 | 118 | // set rx/tx pins in PullUp mode |
| AntonLS | 2:fe1566cdb6e7 | 119 | if (tx != NC) { |
| AntonLS | 2:fe1566cdb6e7 | 120 | pin_mode(tx, PullUp); |
| AntonLS | 2:fe1566cdb6e7 | 121 | } |
| AntonLS | 2:fe1566cdb6e7 | 122 | if (rx != NC) { |
| AntonLS | 2:fe1566cdb6e7 | 123 | pin_mode(rx, PullUp); |
| AntonLS | 2:fe1566cdb6e7 | 124 | } |
| AntonLS | 2:fe1566cdb6e7 | 125 | |
| AntonLS | 2:fe1566cdb6e7 | 126 | // Set CTS pin to PullDown mode if used. |
| AntonLS | 2:fe1566cdb6e7 | 127 | if( cts != NC ) |
| AntonLS | 2:fe1566cdb6e7 | 128 | { |
| AntonLS | 2:fe1566cdb6e7 | 129 | pin_mode( cts, PullDown ); |
| AntonLS | 2:fe1566cdb6e7 | 130 | } |
| AntonLS | 2:fe1566cdb6e7 | 131 | |
| AntonLS | 2:fe1566cdb6e7 | 132 | |
| AntonLS | 2:fe1566cdb6e7 | 133 | if (uart == STDIO_UART) { |
| AntonLS | 2:fe1566cdb6e7 | 134 | stdio_uart_inited = 1; |
| AntonLS | 2:fe1566cdb6e7 | 135 | memcpy(&stdio_uart, obj, sizeof(serial_t)); |
| AntonLS | 2:fe1566cdb6e7 | 136 | } |
| AntonLS | 2:fe1566cdb6e7 | 137 | } |
| AntonLS | 7:205ef63d311a | 138 | |
| AntonLS | 8:d5d055be2bb8 | 139 | // Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 6:ef758ac3c928 | 140 | void MySerialBase::my_serial_irq_handler( serial_t *obj, uart_irq_handler handler, uint32_t id ) |
| AntonLS | 6:ef758ac3c928 | 141 | { |
| AntonLS | 6:ef758ac3c928 | 142 | irq_handler = handler; |
| AntonLS | 6:ef758ac3c928 | 143 | serial_irq_ids[obj->index] = id; |
| AntonLS | 6:ef758ac3c928 | 144 | } |
| AntonLS | 8:d5d055be2bb8 | 145 | // |
| AntonLS | 6:ef758ac3c928 | 146 | |
| AntonLS | 8:d5d055be2bb8 | 147 | // Replacement for serial_irq_set() in serial_api.c so we can grab uart errors. |
| AntonLS | 5:1b9734e68327 | 148 | void MySerialBase::my_serial_irq_set( serial_t *obj, IrqType irq, uint32_t enable ) |
| AntonLS | 5:1b9734e68327 | 149 | { |
| AntonLS | 5:1b9734e68327 | 150 | IRQn_Type irq_n = (IRQn_Type)0; |
| AntonLS | 5:1b9734e68327 | 151 | |
| AntonLS | 5:1b9734e68327 | 152 | switch( (int)obj->uart ) |
| AntonLS | 5:1b9734e68327 | 153 | { |
| AntonLS | 5:1b9734e68327 | 154 | case UART_0: |
| AntonLS | 5:1b9734e68327 | 155 | irq_n = UART0_IRQn; |
| AntonLS | 5:1b9734e68327 | 156 | break; |
| AntonLS | 5:1b9734e68327 | 157 | } |
| AntonLS | 5:1b9734e68327 | 158 | |
| AntonLS | 5:1b9734e68327 | 159 | if( enable ) |
| AntonLS | 5:1b9734e68327 | 160 | { |
| AntonLS | 5:1b9734e68327 | 161 | switch( irq ) |
| AntonLS | 5:1b9734e68327 | 162 | { |
| AntonLS | 5:1b9734e68327 | 163 | case RxIrq: |
| AntonLS | 8:d5d055be2bb8 | 164 | obj->uart->INTENSET = UART_INTENSET_RXDRDY_Msk; |
| AntonLS | 5:1b9734e68327 | 165 | break; |
| AntonLS | 5:1b9734e68327 | 166 | case TxIrq: |
| AntonLS | 8:d5d055be2bb8 | 167 | obj->uart->INTENSET = UART_INTENSET_TXDRDY_Msk; |
| AntonLS | 5:1b9734e68327 | 168 | break; |
| AntonLS | 5:1b9734e68327 | 169 | case ErrIrq: |
| AntonLS | 8:d5d055be2bb8 | 170 | obj->uart->INTENSET = UART_INTENSET_ERROR_Msk; |
| AntonLS | 5:1b9734e68327 | 171 | break; |
| AntonLS | 7:205ef63d311a | 172 | case CtsIrq: |
| AntonLS | 8:d5d055be2bb8 | 173 | obj->uart->INTENSET = UART_INTENSET_CTS_Msk; |
| AntonLS | 7:205ef63d311a | 174 | break; |
| AntonLS | 7:205ef63d311a | 175 | case NctsIrq: |
| AntonLS | 8:d5d055be2bb8 | 176 | obj->uart->INTENSET = UART_INTENSET_NCTS_Msk; |
| AntonLS | 7:205ef63d311a | 177 | break; |
| AntonLS | 7:205ef63d311a | 178 | case RxtoIrq: |
| AntonLS | 8:d5d055be2bb8 | 179 | obj->uart->INTENSET = UART_INTENSET_RXTO_Msk; |
| AntonLS | 7:205ef63d311a | 180 | break; |
| AntonLS | 5:1b9734e68327 | 181 | } |
| AntonLS | 5:1b9734e68327 | 182 | NVIC_SetPriority( irq_n, 3 ); |
| AntonLS | 5:1b9734e68327 | 183 | NVIC_EnableIRQ( irq_n ); |
| AntonLS | 5:1b9734e68327 | 184 | |
| AntonLS | 5:1b9734e68327 | 185 | } else |
| AntonLS | 8:d5d055be2bb8 | 186 | { // Disable |
| AntonLS | 5:1b9734e68327 | 187 | switch( irq ) |
| AntonLS | 5:1b9734e68327 | 188 | { |
| AntonLS | 5:1b9734e68327 | 189 | case RxIrq: |
| AntonLS | 8:d5d055be2bb8 | 190 | obj->uart->INTENCLR = UART_INTENCLR_RXDRDY_Msk; |
| AntonLS | 5:1b9734e68327 | 191 | break; |
| AntonLS | 5:1b9734e68327 | 192 | case TxIrq: |
| AntonLS | 8:d5d055be2bb8 | 193 | obj->uart->INTENCLR = UART_INTENCLR_TXDRDY_Msk; |
| AntonLS | 5:1b9734e68327 | 194 | break; |
| AntonLS | 5:1b9734e68327 | 195 | case ErrIrq: |
| AntonLS | 8:d5d055be2bb8 | 196 | obj->uart->INTENCLR = UART_INTENCLR_ERROR_Msk; |
| AntonLS | 5:1b9734e68327 | 197 | break; |
| AntonLS | 7:205ef63d311a | 198 | case CtsIrq: |
| AntonLS | 8:d5d055be2bb8 | 199 | obj->uart->INTENCLR = UART_INTENCLR_CTS_Msk; |
| AntonLS | 7:205ef63d311a | 200 | break; |
| AntonLS | 7:205ef63d311a | 201 | case NctsIrq: |
| AntonLS | 8:d5d055be2bb8 | 202 | obj->uart->INTENCLR = UART_INTENCLR_NCTS_Msk; |
| AntonLS | 7:205ef63d311a | 203 | break; |
| AntonLS | 7:205ef63d311a | 204 | case RxtoIrq: |
| AntonLS | 8:d5d055be2bb8 | 205 | obj->uart->INTENCLR = UART_INTENCLR_RXTO_Msk; |
| AntonLS | 7:205ef63d311a | 206 | break; |
| AntonLS | 5:1b9734e68327 | 207 | } |
| AntonLS | 5:1b9734e68327 | 208 | |
| AntonLS | 5:1b9734e68327 | 209 | if( 0 == obj->uart->INTENCLR ) |
| AntonLS | 5:1b9734e68327 | 210 | { |
| AntonLS | 5:1b9734e68327 | 211 | NVIC_DisableIRQ( irq_n ); |
| AntonLS | 5:1b9734e68327 | 212 | } |
| AntonLS | 5:1b9734e68327 | 213 | } |
| AntonLS | 5:1b9734e68327 | 214 | } |
| AntonLS | 1:0ba687d4196f | 215 | void MySerialBase::_irq_handler( uint32_t id, SerialIrq irq_type ) |
| AntonLS | 1:0ba687d4196f | 216 | { |
| AntonLS | 1:0ba687d4196f | 217 | MySerialBase *handler = (MySerialBase*)id; |
| AntonLS | 1:0ba687d4196f | 218 | handler->_my_irq[irq_type].call(); |
| AntonLS | 1:0ba687d4196f | 219 | } |
| AntonLS | 6:ef758ac3c928 | 220 | |
| AntonLS | 8:d5d055be2bb8 | 221 | // Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 5:1b9734e68327 | 222 | void MySerialBase::error_handler() |
| AntonLS | 5:1b9734e68327 | 223 | { |
| AntonLS | 8:d5d055be2bb8 | 224 | // Apparently handler will be continuously called until [error] condition is gone even though cleared. |
| AntonLS | 5:1b9734e68327 | 225 | |
| AntonLS | 5:1b9734e68327 | 226 | if( (UART_ERRORSRC_OVERRUN_Present << UART_ERRORSRC_OVERRUN_Pos) == (UART_ERRORSRC_OVERRUN_Msk & _my_serial.uart->ERRORSRC) ) |
| AntonLS | 5:1b9734e68327 | 227 | { |
| AntonLS | 5:1b9734e68327 | 228 | puts( "\r\n[ERR: OVERRUN]\r\n" ); |
| AntonLS | 5:1b9734e68327 | 229 | |
| AntonLS | 5:1b9734e68327 | 230 | // Clear the error |
| AntonLS | 5:1b9734e68327 | 231 | _my_serial.uart->ERRORSRC = (UART_ERRORSRC_OVERRUN_Clear << UART_ERRORSRC_OVERRUN_Pos); |
| AntonLS | 8:d5d055be2bb8 | 232 | |
| AntonLS | 8:d5d055be2bb8 | 233 | } else if( (UART_ERRORSRC_PARITY_Present << UART_ERRORSRC_PARITY_Pos) == (UART_ERRORSRC_PARITY_Msk & _my_serial.uart->ERRORSRC) ) |
| AntonLS | 8:d5d055be2bb8 | 234 | { |
| AntonLS | 8:d5d055be2bb8 | 235 | puts( "\r\n[ERR: PARITY]\r\n" ); |
| AntonLS | 8:d5d055be2bb8 | 236 | |
| AntonLS | 8:d5d055be2bb8 | 237 | // Clear the error |
| AntonLS | 8:d5d055be2bb8 | 238 | _my_serial.uart->ERRORSRC = (UART_ERRORSRC_PARITY_Clear << UART_ERRORSRC_PARITY_Pos); |
| AntonLS | 8:d5d055be2bb8 | 239 | |
| AntonLS | 8:d5d055be2bb8 | 240 | } else if( (UART_ERRORSRC_FRAMING_Present << UART_ERRORSRC_FRAMING_Pos) == (UART_ERRORSRC_FRAMING_Msk & _my_serial.uart->ERRORSRC) ) |
| AntonLS | 8:d5d055be2bb8 | 241 | { |
| AntonLS | 8:d5d055be2bb8 | 242 | puts( "\r\n[ERR: FRAMING]\r\n" ); |
| AntonLS | 8:d5d055be2bb8 | 243 | |
| AntonLS | 8:d5d055be2bb8 | 244 | // Clear the error |
| AntonLS | 8:d5d055be2bb8 | 245 | _my_serial.uart->ERRORSRC = (UART_ERRORSRC_FRAMING_Clear << UART_ERRORSRC_FRAMING_Pos); |
| AntonLS | 8:d5d055be2bb8 | 246 | |
| AntonLS | 8:d5d055be2bb8 | 247 | } else if( (UART_ERRORSRC_BREAK_Present << UART_ERRORSRC_BREAK_Pos) == (UART_ERRORSRC_BREAK_Msk & _my_serial.uart->ERRORSRC) ) |
| AntonLS | 8:d5d055be2bb8 | 248 | { |
| AntonLS | 8:d5d055be2bb8 | 249 | puts( "\r\n[ERR: BREAK]\r\n" ); |
| AntonLS | 8:d5d055be2bb8 | 250 | |
| AntonLS | 8:d5d055be2bb8 | 251 | // Clear the error |
| AntonLS | 8:d5d055be2bb8 | 252 | _my_serial.uart->ERRORSRC = (UART_ERRORSRC_BREAK_Clear << UART_ERRORSRC_BREAK_Pos); |
| AntonLS | 8:d5d055be2bb8 | 253 | |
| AntonLS | 8:d5d055be2bb8 | 254 | } else |
| AntonLS | 8:d5d055be2bb8 | 255 | { |
| AntonLS | 8:d5d055be2bb8 | 256 | // Clear the error interrupt... |
| AntonLS | 8:d5d055be2bb8 | 257 | _my_serial.uart->EVENTS_ERROR = 0; |
| AntonLS | 8:d5d055be2bb8 | 258 | } |
| AntonLS | 5:1b9734e68327 | 259 | } |
| AntonLS | 6:ef758ac3c928 | 260 | |
| AntonLS | 8:d5d055be2bb8 | 261 | // Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 6:ef758ac3c928 | 262 | void MySerialBase::cts_handler() |
| AntonLS | 6:ef758ac3c928 | 263 | { |
| AntonLS | 8:d5d055be2bb8 | 264 | // Clear interrupt. |
| AntonLS | 8:d5d055be2bb8 | 265 | _my_serial.uart->EVENTS_CTS = 0; |
| AntonLS | 8:d5d055be2bb8 | 266 | |
| AntonLS | 8:d5d055be2bb8 | 267 | // puts( "\r\n[CTS: Clear]\r\n" ); |
| AntonLS | 8:d5d055be2bb8 | 268 | } |
| AntonLS | 8:d5d055be2bb8 | 269 | |
| AntonLS | 8:d5d055be2bb8 | 270 | // Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 8:d5d055be2bb8 | 271 | void MySerialBase::ncts_handler() |
| AntonLS | 8:d5d055be2bb8 | 272 | { |
| AntonLS | 8:d5d055be2bb8 | 273 | // Attempt to clear interrupt. |
| AntonLS | 8:d5d055be2bb8 | 274 | _my_serial.uart->EVENTS_NCTS = 0; |
| AntonLS | 8:d5d055be2bb8 | 275 | |
| AntonLS | 6:ef758ac3c928 | 276 | puts( "\r\n[CTS: High]\r\n" ); |
| AntonLS | 6:ef758ac3c928 | 277 | } |
| AntonLS | 6:ef758ac3c928 | 278 | |
| AntonLS | 1:0ba687d4196f | 279 | int MySerialBase::_base_getc() |
| AntonLS | 1:0ba687d4196f | 280 | { |
| AntonLS | 1:0ba687d4196f | 281 | return serial_getc( &_my_serial ); |
| AntonLS | 1:0ba687d4196f | 282 | } |
| AntonLS | 1:0ba687d4196f | 283 | int MySerialBase::_base_putc( int c ) |
| AntonLS | 1:0ba687d4196f | 284 | { |
| AntonLS | 1:0ba687d4196f | 285 | serial_putc( &_my_serial, c ); |
| AntonLS | 1:0ba687d4196f | 286 | return c; |
| AntonLS | 1:0ba687d4196f | 287 | } |
| AntonLS | 8:d5d055be2bb8 | 288 | |
| AntonLS | 1:0ba687d4196f | 289 | void MySerialBase::send_break() |
| AntonLS | 1:0ba687d4196f | 290 | { |
| AntonLS | 1:0ba687d4196f | 291 | // Wait for 1.5 frames before clearing the break condition |
| AntonLS | 1:0ba687d4196f | 292 | // This will have different effects on our platforms, but should |
| AntonLS | 1:0ba687d4196f | 293 | // ensure that we keep the break active for at least one frame. |
| AntonLS | 1:0ba687d4196f | 294 | // We consider a full frame (1 start bit + 8 data bits bits + |
| AntonLS | 1:0ba687d4196f | 295 | // 1 parity bit + 2 stop bits = 12 bits) for computation. |
| AntonLS | 1:0ba687d4196f | 296 | // One bit time (in us) = 1000000/_my_baud |
| AntonLS | 1:0ba687d4196f | 297 | // Twelve bits: 12000000/baud delay |
| AntonLS | 1:0ba687d4196f | 298 | // 1.5 frames: 18000000/baud delay |
| AntonLS | 1:0ba687d4196f | 299 | serial_break_set( &_my_serial ); |
| AntonLS | 1:0ba687d4196f | 300 | wait_us( 18000000/_my_baud ); |
| AntonLS | 1:0ba687d4196f | 301 | serial_break_clear( &_my_serial ); |
| AntonLS | 1:0ba687d4196f | 302 | } |
| AntonLS | 1:0ba687d4196f | 303 | |
| AntonLS | 1:0ba687d4196f | 304 | |
| AntonLS | 1:0ba687d4196f | 305 | MySerial::MySerial( PinName tx, PinName rx, const char *name, |
| AntonLS | 1:0ba687d4196f | 306 | PinName rts, PinName cts ) : MySerialBase( tx, rx, rts, cts ), Stream( name ) |
| AntonLS | 1:0ba687d4196f | 307 | { |
| AntonLS | 1:0ba687d4196f | 308 | } |
| AntonLS | 1:0ba687d4196f | 309 | int MySerial::_getc() |
| AntonLS | 1:0ba687d4196f | 310 | { |
| AntonLS | 1:0ba687d4196f | 311 | return _base_getc(); |
| AntonLS | 1:0ba687d4196f | 312 | } |
| AntonLS | 1:0ba687d4196f | 313 | int MySerial::_putc( int c ) |
| AntonLS | 1:0ba687d4196f | 314 | { |
| AntonLS | 1:0ba687d4196f | 315 | return _base_putc( c ); |
| AntonLS | 1:0ba687d4196f | 316 | } |
| AntonLS | 1:0ba687d4196f | 317 | int MySerial::puts( const char *str ) |
| AntonLS | 1:0ba687d4196f | 318 | { |
| AntonLS | 1:0ba687d4196f | 319 | while( *str ) |
| AntonLS | 1:0ba687d4196f | 320 | putc( *str ++ ); |
| AntonLS | 1:0ba687d4196f | 321 | |
| AntonLS | 1:0ba687d4196f | 322 | return 0; |
| AntonLS | 1:0ba687d4196f | 323 | } |
| AntonLS | 4:17b8edf264c3 | 324 | |
| AntonLS | 1:0ba687d4196f | 325 | int MySerial::printf( const char *format, ... ) |
| AntonLS | 1:0ba687d4196f | 326 | { |
| AntonLS | 1:0ba687d4196f | 327 | va_list arg; |
| AntonLS | 1:0ba687d4196f | 328 | va_start( arg, format ); |
| AntonLS | 1:0ba687d4196f | 329 | |
| AntonLS | 1:0ba687d4196f | 330 | int len = MySerial::vprintf( format, arg ); |
| AntonLS | 1:0ba687d4196f | 331 | |
| AntonLS | 1:0ba687d4196f | 332 | va_end( arg ); |
| AntonLS | 1:0ba687d4196f | 333 | |
| AntonLS | 1:0ba687d4196f | 334 | return len; |
| AntonLS | 1:0ba687d4196f | 335 | } |
| AntonLS | 1:0ba687d4196f | 336 | int MySerial::vprintf( const char *format, va_list arg ) |
| AntonLS | 1:0ba687d4196f | 337 | { |
| AntonLS | 1:0ba687d4196f | 338 | int len = vsnprintf( NULL, 0, format, arg ); |
| AntonLS | 1:0ba687d4196f | 339 | if( len < STRING_STACK_LIMIT ) |
| AntonLS | 1:0ba687d4196f | 340 | { |
| AntonLS | 1:0ba687d4196f | 341 | char temp[STRING_STACK_LIMIT]; |
| AntonLS | 1:0ba687d4196f | 342 | vsprintf( temp, format, arg ); |
| AntonLS | 1:0ba687d4196f | 343 | puts( temp ); |
| AntonLS | 1:0ba687d4196f | 344 | |
| AntonLS | 1:0ba687d4196f | 345 | } else |
| AntonLS | 1:0ba687d4196f | 346 | { |
| AntonLS | 1:0ba687d4196f | 347 | char *temp = new char[len + 1]; |
| AntonLS | 1:0ba687d4196f | 348 | vsprintf( temp, format, arg ); |
| AntonLS | 1:0ba687d4196f | 349 | puts( temp ); |
| AntonLS | 1:0ba687d4196f | 350 | delete[] temp; |
| AntonLS | 1:0ba687d4196f | 351 | } |
| AntonLS | 1:0ba687d4196f | 352 | |
| AntonLS | 1:0ba687d4196f | 353 | return len; |
| AntonLS | 1:0ba687d4196f | 354 | } |
| AntonLS | 1:0ba687d4196f | 355 | |
| AntonLS | 8:d5d055be2bb8 | 356 | // Won't work unless UART0_IRQHandler is commented-out in serial_api.c (rebuild mbed lib.) |
| AntonLS | 6:ef758ac3c928 | 357 | #ifdef __cplusplus |
| AntonLS | 6:ef758ac3c928 | 358 | extern "C" |
| AntonLS | 6:ef758ac3c928 | 359 | { |
| AntonLS | 6:ef758ac3c928 | 360 | #endif |
| AntonLS | 8:d5d055be2bb8 | 361 | void UART0_IRQHandler() |
| AntonLS | 6:ef758ac3c928 | 362 | { |
| AntonLS | 6:ef758ac3c928 | 363 | MySerial::IrqType irq_type; |
| AntonLS | 6:ef758ac3c928 | 364 | |
| AntonLS | 6:ef758ac3c928 | 365 | if( (NRF_UART0->INTENSET & UART_INTENSET_TXDRDY_Msk) && NRF_UART0->EVENTS_TXDRDY ) |
| AntonLS | 6:ef758ac3c928 | 366 | { |
| AntonLS | 6:ef758ac3c928 | 367 | irq_type = MySerial::TxIrq; |
| AntonLS | 6:ef758ac3c928 | 368 | |
| AntonLS | 6:ef758ac3c928 | 369 | } else if( (NRF_UART0->INTENSET & UART_INTENSET_RXDRDY_Msk) && NRF_UART0->EVENTS_RXDRDY ) |
| AntonLS | 6:ef758ac3c928 | 370 | { |
| AntonLS | 6:ef758ac3c928 | 371 | irq_type = MySerial::RxIrq; |
| AntonLS | 6:ef758ac3c928 | 372 | |
| AntonLS | 6:ef758ac3c928 | 373 | } else if( (NRF_UART0->INTENSET & UART_INTENSET_ERROR_Msk) && NRF_UART0->EVENTS_ERROR ) |
| AntonLS | 6:ef758ac3c928 | 374 | { |
| AntonLS | 6:ef758ac3c928 | 375 | irq_type = MySerial::ErrIrq; |
| AntonLS | 6:ef758ac3c928 | 376 | |
| AntonLS | 6:ef758ac3c928 | 377 | } else if( (NRF_UART0->INTENSET & UART_INTENSET_CTS_Msk) && NRF_UART0->EVENTS_CTS ) |
| AntonLS | 6:ef758ac3c928 | 378 | { |
| AntonLS | 6:ef758ac3c928 | 379 | irq_type = MySerial::CtsIrq; |
| AntonLS | 6:ef758ac3c928 | 380 | |
| AntonLS | 6:ef758ac3c928 | 381 | } else if( (NRF_UART0->INTENSET & UART_INTENSET_NCTS_Msk) && NRF_UART0->EVENTS_NCTS ) |
| AntonLS | 6:ef758ac3c928 | 382 | { |
| AntonLS | 6:ef758ac3c928 | 383 | irq_type = MySerial::NctsIrq; |
| AntonLS | 6:ef758ac3c928 | 384 | |
| AntonLS | 6:ef758ac3c928 | 385 | } else if( (NRF_UART0->INTENSET & UART_INTENSET_RXTO_Msk) && NRF_UART0->EVENTS_RXTO ) |
| AntonLS | 6:ef758ac3c928 | 386 | { |
| AntonLS | 6:ef758ac3c928 | 387 | irq_type = MySerial::RxtoIrq; |
| AntonLS | 6:ef758ac3c928 | 388 | |
| AntonLS | 6:ef758ac3c928 | 389 | } else |
| AntonLS | 6:ef758ac3c928 | 390 | { |
| AntonLS | 6:ef758ac3c928 | 391 | return; |
| AntonLS | 6:ef758ac3c928 | 392 | } |
| AntonLS | 6:ef758ac3c928 | 393 | |
| AntonLS | 6:ef758ac3c928 | 394 | if( serial_irq_ids[0] != 0 ) |
| AntonLS | 6:ef758ac3c928 | 395 | { |
| AntonLS | 6:ef758ac3c928 | 396 | irq_handler( serial_irq_ids[0], (SerialIrq)irq_type ); |
| AntonLS | 6:ef758ac3c928 | 397 | } |
| AntonLS | 6:ef758ac3c928 | 398 | } |
| AntonLS | 6:ef758ac3c928 | 399 | #ifdef __cplusplus |
| AntonLS | 6:ef758ac3c928 | 400 | } |
| AntonLS | 6:ef758ac3c928 | 401 | #endif |
| AntonLS | 8:d5d055be2bb8 | 402 | // |
| AntonLS | 7:205ef63d311a | 403 | |
| AntonLS | 1:0ba687d4196f | 404 | /* EOF */ |
