Andriy Makukha / Mbed 2 deprecated football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

io/MySerial.cpp

Committer:
AntonLS
Date:
2015-04-16
Revision:
4:17b8edf264c3
Parent:
2:fe1566cdb6e7
Child:
5:1b9734e68327

File content as of revision 4:17b8edf264c3:

/*
 *
 * 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"

extern "C"
{
    void pin_mode( PinName, PinMode );
}

extern int stdio_uart_inited;
extern serial_t stdio_uart;


using namespace moo;


MySerialBase::MySerialBase( PinName tx,  PinName rx,
                            PinName rts, PinName cts ) : _my_serial(), _my_baud( 9600 )
{
    my_serial_init( &_my_serial, tx, rx, rts, cts, _my_baud );
    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::my_serial_init( serial_t *obj, PinName tx, PinName rx, PinName rts, PinName cts, int baudrate )
{
    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

    if( (NC != rts) || (NC != cts) )
    {
          obj->uart->CONFIG |=  0x01;  // Enable HWFC

    } else
      {
          obj->uart->CONFIG &= ~0x01;  // Disable HWFC;
      }

    // set default baud rate and format
    serial_baud  ( obj, baudrate );
    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 (uart == STDIO_UART) {
        stdio_uart_inited = 1;
        memcpy(&stdio_uart, obj, sizeof(serial_t));
    }
}
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;
}

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;
}

/* EOF */