/*
 * SCIC.cpp
 *
 *      Author: Aleksey Gerasimenko
 *      gerasimenko.aleksey.n@gmail.com
 */

#include "DSP28335/SCIC.h"

namespace DSP28335
{
//CONSTRUCTOR
SCIC::SCIC(volatile struct SCI_REGS& SciRegs):
        DSP28335::SCIBase(SciRegs)
{
    // set default
    settings.config.baudrate = SCIC_BAUDRATE_DEFAULT;
    settings.config.parity = SCIC_PARITY_DEFAULT;
    settings.config.stopbits = SCIC_STOPBITS_DEFAULT;
    settings.config.lenght = SCIC_LENGHT_DEFAULT;
    settings.gpio_setup = SCIC_GPIO_SETUP_DEFAULT;
    //
}//CONSTRUCTOR


void SCIC::setup()
{
    //
    get_default_configuration(settings.config);
    _configure(settings.config);
    //
    _gpio_setup = settings.gpio_setup;
    (*_gpio_setup)();
    //
}//
//
void SCIC::setup(DSP28335::SCISetup& setup)
{
    settings = setup;
    _configure(settings.config);
    //
    _gpio_setup = settings.gpio_setup;
    (*_gpio_setup)();
    //
}//
//
void SCIC::get_default_configuration(DSP28335::SCIConfiguration& config)
{
    config.baudrate = SCIC_BAUDRATE_DEFAULT;
    config.parity   = SCIC_PARITY_DEFAULT;
    config.stopbits = SCIC_STOPBITS_DEFAULT;
    config.lenght   = SCIC_LENGHT_DEFAULT;
    //
}//
//
void SCIC::get_configuration(DSP28335::SCIConfiguration& config)
{
    config = settings.config;
    //
}//
//
void SCIC::set_configuration(DSP28335::SCIConfiguration& config)
{
    settings.config = config;
    _configure(settings.config);
    //
}//
//
bool SCIC::compare_configuration(DSP28335::SCIConfiguration& config)
{

    return (settings.config.baudrate == config.baudrate)
            & (settings.config.parity == config.parity)
            & (settings.config.stopbits == config.stopbits)
            & (settings.config.lenght == config.lenght);
    //
}//
//
void SCIC::_configure(DSP28335::SCIConfiguration& config)
{
    //
    // SCICTL1.5 - Software reset 0/1-reset/active state
    SciRegs.SCICTL1.bit.SWRESET = 0x000;
    //
    // Reset FIFO's
    SciRegs.SCIFFTX.all=0x8000;
    //
    // SCICCR.7 - Number of stop bits
    if(config.stopbits == DSP28335::ONE){ SciRegs.SCICCR.bit.STOPBITS = 0x00;}
    if(config.stopbits == DSP28335::TWO){ SciRegs.SCICCR.bit.STOPBITS = 0x01;}
    //
    // SCICCR.5 - Parity enable
    // SCICCR.6 - Parity odd/even
    if(config.parity == DSP28335::NO){   SciRegs.SCICCR.bit.PARITYENA = 0x00; SciRegs.SCICCR.bit.PARITY = 0x00;}
    if(config.parity == DSP28335::ODD){  SciRegs.SCICCR.bit.PARITYENA = 0x01; SciRegs.SCICCR.bit.PARITY = 0x00;}
    if(config.parity == DSP28335::EVEN){ SciRegs.SCICCR.bit.PARITYENA = 0x01; SciRegs.SCICCR.bit.PARITY = 0x01;}
    //
    // SCICCR.4 - Loop Back test mode enable
    SciRegs.SCICCR.bit.LOOPBKENA = 0x00;
    //
    // SCICCR.3 - Idle - Address mode protocol
    SciRegs.SCICCR.bit.ADDRIDLE_MODE = 0x00;
    //
    // SCICCR.2-0 - Character-length
    if(config.lenght == DSP28335::LEN1){ SciRegs.SCICCR.bit.SCICHAR = 0x00;}
    if(config.lenght == DSP28335::LEN2){ SciRegs.SCICCR.bit.SCICHAR = 0x01;}
    if(config.lenght == DSP28335::LEN3){ SciRegs.SCICCR.bit.SCICHAR = 0x02;}
    if(config.lenght == DSP28335::LEN4){ SciRegs.SCICCR.bit.SCICHAR = 0x03;}
    if(config.lenght == DSP28335::LEN5){ SciRegs.SCICCR.bit.SCICHAR = 0x04;}
    if(config.lenght == DSP28335::LEN6){ SciRegs.SCICCR.bit.SCICHAR = 0x05;}
    if(config.lenght == DSP28335::LEN7){ SciRegs.SCICCR.bit.SCICHAR = 0x06;}
    if(config.lenght == DSP28335::LEN8){ SciRegs.SCICCR.bit.SCICHAR = 0x07;}
    //
    // SCICTL1.6 - Receive error interrupt enable
    SciRegs.SCICTL1.bit.RXERRINTENA =0x000;
    //
    SciRegs.SCICTL1.bit.RXENA =0x001;          // Receiver enable
    SciRegs.SCICTL1.bit.TXENA =0x001;          // Transmitter enable
    SciRegs.SCICTL1.bit.SLEEP =0x000;          // Sleep 0/1 - disable/enable
    SciRegs.SCICTL1.bit.TXWAKE =0x000;         // Transmitter wake-up method select

    SciRegs.SCICTL2.bit.TXINTENA =0x000;      // SCITXBUF-register interrupt enable
    SciRegs.SCICTL2.bit.RXBKINTENA =0x00;         // Receiver-buffer/break interrupt enable

    // Ideal Baud       BRR             Actual Baud     Error, %
    //  2400            1952(07A0h)     2400            0
    //  4800            976(03D0h)      4798            -0,04
    //  9600            487(01E7h)      9606            0.06
    //  19200           243(00F3h)      19211           0.06
    //  38400           121(0079h)      38422           0.006

    if(config.baudrate == DSP28335::BR2400){ SciRegs.SCIHBAUD = 0x0007; SciRegs.SCILBAUD = 0x00A0;}
    if(config.baudrate == DSP28335::BR4800){ SciRegs.SCIHBAUD = 0x0003; SciRegs.SCILBAUD = 0x00D0;}
    if(config.baudrate == DSP28335::BR9600){ SciRegs.SCIHBAUD = 0x0001; SciRegs.SCILBAUD = 0x00E7;}
    if(config.baudrate == DSP28335::BR19200){ SciRegs.SCIHBAUD = 0x0000; SciRegs.SCILBAUD = 0x00F3;}
    if(config.baudrate == DSP28335::BR38400){ SciRegs.SCIHBAUD = 0x0000; SciRegs.SCILBAUD = 0x0079;}

    // SCICTL1.5 - Relinquish SCI from Reset
    SciRegs.SCICTL1.bit.SWRESET =0x001;
    //
}//
//
} /* namespace DSP28335 */