/***********************************************************************************
  Filename:     uart_isr.c

  Description:  This example sends/receives data on UART0, using interrupt method.

  Comments:     To execute this example, compile one SmartRF05EB unit as transmitter,
                by activating the UART_TST_MODE_TX definition, then compile another
                unit as receiver, by activating the UART_TST_MODE_RX definition.
                Pressing S1 makes the transmitter send its allocated uartTxBuffer[]
                to the receiver. The transferred data will arrive at uartRxBuffer[]
                and can be verified using the debugger.

  Note:         Once the UART receiver has been enabled (U0CSR.RE = 1) it will
                automatically trigger data reception as soon the Start bit is
                detected. The transmitter I/O should therefore be configured
                before the receiver, such that potential pin toggling (during
                I/O configuration of the transmitter) does not trigger data
                reception at the receiver side. Also, remember to use common
                ground for the TX unit and RX unit!

***********************************************************************************/

/***********************************************************************************
* INCLUDES
*/

#include <hal_types.h>
#include <string.h>
#include <stdbool.h>
#include <dma.h>
#include "OSAL.h"
#include <ioCC254x_bitdef.h>
#include "ioCC2541.h"

/***********************************************************************************
* CONSTANTS
*/

// Size of allocated UART RX/TX buffer (just an example)
#define SIZE_OF_UART_RX_BUFFER   50
#define SIZE_OF_UART_TX_BUFFER   50

// UART test characters
#define UART_TEST_DATA "Texas Instruments LPRF!\r\n"

// Test definitions
//#define UART_TST_MODE_RX
#define UART_TST_MODE_TX

// Baudrate = 115200 kbps (U0BAUD.BAUD_M = 216, U0GCR.BAUD_E = 10), given 32 MHz system clock
#define UART_BAUD_M  216
#define UART_BAUD_E  11


// ------Bits definitions
#define PERCFG_U0CFG                  0x01               // USART 0 I/O location
#define PERCFG_U0CFG_ALT1             0x00          // Alternative 1 location

/***********************************************************************************
* LOCAL VARIABLES
*/

// Buffer+index for UART RX/TX.
//static uint8 __xdata uartRxBuffer[SIZE_OF_UART_RX_BUFFER];
static uint8 __xdata uartTxBuffer[SIZE_OF_UART_TX_BUFFER] = UART_TEST_DATA;
static uint16 __xdata uartTxIndex;
//static uint16 __xdata uartRxIndex;

// Variable for UART packet monitoring.
//static uint8 __xdata uartPktReceived = 1;
static uint8 __xdata charsToSend;
static bool __xdata busy=false;
// Prototype for local functions.
void uart0StartRxForIsr(void);
void uart0StartTxForIsr(void);
//-------------------------------------------------




/***********************************************************************************
* @fn          serial_debug_irq_Init()
*
* @brief       initit UART0, for using Tx interrupt.
*
* @param       void
*
* @return      void
*/
void serial_debugInit(void)
{
  
  
    /***************************************************************************
    * Setup I/O ports
    *
    * Port and pins used by USART0 operating in UART-mode, at the Alternative 1
    * location are:
    * RX     : P0_2
    * TX     : P0_3
    * CT/CTS : P0_4
    * RT/RTS : P0_5
    *
    * These pins must be set to function as peripheral I/O to be used by UART0.
    * The TX pin on the transmitter must be connected to the RX pin on the receiver.
    * If enabling hardware flow control (U0UCR.FLOW = 1) the CT/CTS (Clear-To-Send)
    * on the transmitter must be connected to the RS/RTS (Ready-To-Send) pin on the
    * receiver.
    */ 
    // Configure USART0 for Alternative 1 => Port P0 (PERCFG.U0CFG = 0).
    PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U0CFG_ALT1;    
    // Give priority to USART 0 over Timer 1 for port 0 pins.
    P2DIR &= P2DIR_PRIP0_USART0;
    // Set pins 2, 3 and 5 as peripheral I/O and pin 4 as GPIO output.
    P0SEL |= BIT5 | BIT4 | BIT3 | BIT2;
    // Initialize P0_1 for SRF05EB S1 button.
    P0SEL &= ~BIT1;           // Function as General Purpose I/O.
    P0DIR &= ~BIT1;           // Input.
  
    /***************************************************************************
    * Configure UART
    *
    */

    // Initialise bitrate = 115200 kbps.
    U0BAUD = UART_BAUD_M;
    U0GCR = (U0GCR&~U0GCR_BAUD_E) | UART_BAUD_E;

    // Initialise UART protocol (start/stop bit, data bits, parity, etc.):
    // USART mode = UART (U0CSR.MODE = 1).
    U0CSR |= U0CSR_MODE;

    // Start bit level = low => Idle level = high  (U0UCR.START = 0).
    U0UCR &= ~U0UCR_START;

    // Stop bit level = high (U0UCR.STOP = 1).
    U0UCR |= U0UCR_STOP;

    // Number of stop bits = 1 (U0UCR.SPB = 0).
    U0UCR &= ~U0UCR_SPB;

    // Parity = disabled (U0UCR.PARITY = 0).
    U0UCR &= ~U0UCR_PARITY;

    // 9-bit data enable = 8 bits transfer (U0UCR.BIT9 = 0).
    U0UCR &= ~U0UCR_BIT9;

    // Level of bit 9 = 0 (U0UCR.D9 = 0), used when U0UCR.BIT9 = 1.
    // Level of bit 9 = 1 (U0UCR.D9 = 1), used when U0UCR.BIT9 = 1.
    // Parity = Even (U0UCR.D9 = 0), used when U0UCR.PARITY = 1.
    // Parity = Odd (U0UCR.D9 = 1), used when U0UCR.PARITY = 1.
    U0UCR &= ~U0UCR_D9;

    // Flow control = disabled (U0UCR.FLOW = 0).
    U0UCR &= ~U0UCR_FLOW;

    // Bit order = LSB first (U0GCR.ORDER = 0).
    U0GCR &= ~U0GCR_ORDER;
} /* serial_debug_irq_Init */

   


/***********************************************************************************
* LOCAL FUNCTIONS
*/

/***********************************************************************************
* @fn          uart0StartTxForIsr
*
* @brief       Function which starts/initiates the transmission of byte sequence
*              on UART0.
*
* @param       void
*
* @return      void
*/
static void uart0StartTxForIsr(void)
{
    // Initialize the UART TX buffer index.
    uartTxIndex = 0;
  
    // Clear any pending UART TX Interrupt Flag (IRCON2.UTXxIF = 0, UxCSR.TX_BYTE = 0).
    UTX0IF = 0;
    U0CSR &= ~U0CSR_TX_BYTE;
  
    // Enable global interrupt (IEN0.EA = 1) and UART TX Interrupt (IEN2.UTXxIE = 1).
    IEN2 |= IEN2_UTX0IE;
    EA = 1;
  
    // Trigger TX interrupt to start transmitting.
    UTX0IF = 1;
}


/***********************************************************************************
* @fn          uart0StartRxForIsr
*
* @brief       Function which starts/initiates the receive of a byte sequence
*              on UART0.
*
* @param       void
*
* @return      void
*/
//void uart0StartRxForIsr(void)
//{
//    // Ready for new packet.
//    uartPktReceived = 0;
//    
//    // Initialize the UART RX buffer index.
//    uartRxIndex = 0;
//
//    // Clear any pending UART RX Interrupt Flag (TCON.URXxIF = 0, UxCSR.RX_BYTE = 0).
//    URX0IF = 0;
//
//    // Enable UART RX (UxCSR.RE = 1).
//    U0CSR |= U0CSR_RE;
//
//    // Enable global Interrupt (IEN0.EA = 1) and UART RX Interrupt (IEN0.URXxIE = 1).
//    URX0IE = 1;
//    EA = 1; 
//}

//----------------------------------
 /***************************************************************************
    * transmit  data
*/
void serial_debugPrint(uint8 *buf){
    
  //charsToSend= strlen((char *)buf); 
  while(busy);
  busy=true;
   charsToSend = (uint8)osal_strlen( (char*)buf);
  //osal_memcpy( buf, title, tmpLen );
  //memcpy(uartTxBuffer,buf,charsToSend);
  osal_memcpy(uartTxBuffer,buf,charsToSend);
  uart0StartTxForIsr();
    
    
}
//--------------------- add new line
void serial_debugPrintln(uint8 *buf){
    
  while(busy);
  busy=true;
  charsToSend= (uint8)osal_strlen((char *)buf); 
  memcpy(uartTxBuffer,buf,charsToSend);
  osal_memcpy(uartTxBuffer,buf,charsToSend);
  *(uartTxBuffer+charsToSend)=0x0d;
  *(uartTxBuffer+charsToSend+1)=0x0a;
  charsToSend+=2;
  uart0StartTxForIsr();
    
    
}
 //--------------------- string and value
void serial_debugPrintValueLn(uint8 *buf, uint16 value){
  
  uint8 *p=uartTxBuffer;
  while(busy);
  busy=true;
  charsToSend= (uint8)osal_strlen((char *)buf); 
  osal_memcpy(uartTxBuffer,buf,charsToSend);
  p+=charsToSend;
  *p =' ';
  p++;
  _ltoa( value, p, 10 );
  p+=osal_strlen((char *)p); ;
  *p++=0x0d;
  *p=0x0a;
  charsToSend=p-uartTxBuffer;
  uart0StartTxForIsr();
}



//    while(1)
//    {
//#ifdef UART_TST_MODE_RX
//        // Use debugger to check received UART packet.
//        if(uartPktReceived)
//        {
//            uart0StartRxForIsr();
//        }
//#else 
//        // Start UART TX when S1 pressed (S1 is high when pushed).
//        if (P0 & BIT1)
//        {
//            halMcuWaitMs(200);      // Button debouncing delay
//            uart0StartTxForIsr();
//        }
//#endif
//    }
//}



/***********************************************************************************
* @fn          UART0_TX_ISR
*
* @brief       Function which completes the UART transmit session, that is it
*              sends the rest of the UART0 packet.
*
* @param       void
*
*/
#pragma vector = UTX0_VECTOR
__interrupt void UART0_TX_ISR(void)
{
    // Clear UART0 TX Interrupt Flag (IRCON2.UTX0IF = 0).
    UTX0IF = 0;

    // Send next UART byte.
    U0DBUF = uartTxBuffer[uartTxIndex++];

    // If no UART byte left to transmit, stop this UART TX session
    if (uartTxIndex >= charsToSend)
    {
    // Note:
    // In order to start another UART TX session the application just needs
    // to prepare the source buffer, and trigger the TX isr.
    uartTxIndex = 0;
    busy=false;
    IEN2 &= ~IEN2_UTX0IE;
    }
}



/***********************************************************************************
* @fn          UART0_RX_ISR
*
* @brief       Function which completes the UART receive session.
*
* @param       void
*
*/
//#pragma vector = URX0_VECTOR
//__interrupt void UART0_RX_ISR(void)
//{
//    // Clear UART0 RX Interrupt Flag (TCON.URX0IF = 0).
//    URX0IF = 0;
//
//    // Read UART0 RX buffer.
//    uartRxBuffer[uartRxIndex++] = U0DBUF;
//
//    // If all UART data received, stop this UART RX session.
//    if (uartRxIndex >= SIZE_OF_UART_RX_BUFFER)
//    {
//        uartRxIndex = 0;
//        uartPktReceived = 1;
//    }
//}
//--------------------------------- EOF