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
Diff: io/MySerial.cpp
- Revision:
- 1:0ba687d4196f
- Child:
- 2:fe1566cdb6e7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/io/MySerial.cpp Mon Apr 13 12:23:44 2015 +0000
@@ -0,0 +1,208 @@
+/*
+ *
+ * Replacement for Serial, so UART flow control is inited properly. ALS 20150412
+ *
+ * MySerialBase is a replacement for SerialBase, to prevent it from calling
+ * the faulty-for-nRF51822-uart-init serial_init()
+ * in mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c
+ *
+ */
+
+#include "MySerial.h"
+
+#define STRING_STACK_LIMIT 120
+
+extern "C"
+{
+ void pin_mode( PinName, PinMode );
+}
+
+extern int stdio_uart_inited;
+extern serial_t stdio_uart;
+
+
+using namespace moo;
+
+void my_serial_init( serial_t *obj, PinName tx, PinName rx, PinName rts, PinName cts );
+
+
+MySerialBase::MySerialBase( PinName tx, PinName rx,
+ PinName rts, PinName cts ) : _my_serial(), _my_baud( 9600 )
+{
+// my_serial_init( &_my_serial, tx, rx, rts, cts );
+ serial_irq_handler( &_my_serial, _irq_handler, (uint32_t)this );
+}
+void MySerialBase::baud( int baudrate )
+{
+ serial_baud( &_my_serial, baudrate );
+ _my_baud = baudrate;
+}
+void MySerialBase::format( int bits, SerialBase::Parity parity, int stop_bits )
+{
+ serial_format( &_my_serial, bits, (SerialParity)parity, stop_bits );
+}
+int MySerialBase::readable()
+{
+ return serial_readable( &_my_serial );
+}
+int MySerialBase::writeable()
+{
+ return serial_writable( &_my_serial );
+}
+void MySerialBase::attach( void (*fptr)(void), SerialBase::IrqType type )
+{
+ if( fptr )
+ {
+ _my_irq[type].attach( fptr );
+ serial_irq_set( &_my_serial, (SerialIrq)type, 1 );
+ } else
+ {
+ serial_irq_set( &_my_serial, (SerialIrq)type, 0 );
+ }
+}
+void MySerialBase::_irq_handler( uint32_t id, SerialIrq irq_type )
+{
+ MySerialBase *handler = (MySerialBase*)id;
+ handler->_my_irq[irq_type].call();
+}
+int MySerialBase::_base_getc()
+{
+ return serial_getc( &_my_serial );
+}
+int MySerialBase::_base_putc( int c )
+{
+ serial_putc( &_my_serial, c );
+ return c;
+}
+void MySerialBase::send_break()
+ {
+ // Wait for 1.5 frames before clearing the break condition
+ // This will have different effects on our platforms, but should
+ // ensure that we keep the break active for at least one frame.
+ // We consider a full frame (1 start bit + 8 data bits bits +
+ // 1 parity bit + 2 stop bits = 12 bits) for computation.
+ // One bit time (in us) = 1000000/_my_baud
+ // Twelve bits: 12000000/baud delay
+ // 1.5 frames: 18000000/baud delay
+ serial_break_set( &_my_serial );
+ wait_us( 18000000/_my_baud );
+ serial_break_clear( &_my_serial );
+}
+
+
+MySerial::MySerial( PinName tx, PinName rx, const char *name,
+ PinName rts, PinName cts ) : MySerialBase( tx, rx, rts, cts ), Stream( name )
+{
+}
+int MySerial::_getc()
+{
+ return _base_getc();
+}
+int MySerial::_putc( int c )
+{
+ return _base_putc( c );
+}
+int MySerial::puts( const char *str )
+{
+ while( *str )
+ putc( *str ++ );
+
+ return 0;
+}
+// Experimental support for printf in MySerial. No Stream inheritance
+// means we can't call printf() directly, so we use sprintf() instead.
+// We only call malloc() for the sprintf() buffer if the buffer
+// length is above a certain threshold, otherwise we use just the stack.
+int MySerial::printf( const char *format, ... )
+{
+ va_list arg;
+ va_start( arg, format );
+
+ int len = MySerial::vprintf( format, arg );
+
+ va_end( arg );
+
+ return len;
+}
+int MySerial::vprintf( const char *format, va_list arg )
+{
+ int len = vsnprintf( NULL, 0, format, arg );
+ if( len < STRING_STACK_LIMIT )
+ {
+ char temp[STRING_STACK_LIMIT];
+ vsprintf( temp, format, arg );
+ puts( temp );
+
+ } else
+ {
+ char *temp = new char[len + 1];
+ vsprintf( temp, format, arg );
+ puts( temp );
+ delete[] temp;
+ }
+
+ return len;
+}
+
+void my_serial_init( serial_t *obj, PinName tx, PinName rx, PinName rts, PinName cts )
+{
+ UARTName uart = UART_0;
+ obj->uart = (NRF_UART_Type *)uart;
+
+ // pin configurations --
+ NRF_GPIO->DIR |= (1 << tx); // TX_PIN_NUMBER
+ NRF_GPIO->DIR |= ((NC == rts) ? 0 : (1 << rts)); // RTS_PIN_NUMBER
+
+ NRF_GPIO->DIR &= ~(1 << rx); // RX_PIN_NUMBER
+ NRF_GPIO->DIR &= ~((NC == cts) ? 0 : (1 << cts)); // CTS_PIN_NUMBER
+
+ obj->uart->PSELRTS = ((NC == rts) ? 0xFFFFFFFF : rts); // RTS_PIN_NUMBER
+ obj->uart->PSELTXD = tx; // TX_PIN_NUMBER
+ obj->uart->PSELCTS = ((NC == cts) ? 0xFFFFFFFF : cts); // 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;
+ // dummy write needed or TXDRDY trails write rather than leads write.
+ // pins are disconnected so nothing is physically transmitted on the wire
+ obj->uart->TXD = 0;
+
+ obj->index = 0;
+
+ // set rx/tx pins in PullUp mode
+ if (tx != NC) {
+ pin_mode(tx, PullUp);
+ }
+ if (rx != NC) {
+ pin_mode(rx, PullUp);
+ }
+
+ // Set CTS pin to PullDown mode if used.
+ if( cts != NC )
+ {
+ pin_mode( cts, PullDown );
+ }
+
+ if( (NC != rts) || (NC != cts) )
+ {
+ obj->uart->CONFIG |= 0x01; // Enable HWFC
+
+ } else
+ {
+ obj->uart->CONFIG &= ~0x01; // Disable HWFC;
+ }
+
+
+ if (uart == STDIO_UART) {
+ stdio_uart_inited = 1;
+ memcpy(&stdio_uart, obj, sizeof(serial_t));
+ }
+}
+
+/* EOF */
