/*
*********************************************************************************************************
*                                               uC/OS-View
*
*                                 (c) Copyright 2005, Micrium, Weston, FL
*                                           All Rights Reserved
*
*                                          Philips LPC3180 (ARM9)
*                                             IAR C Compiler
*
*
* Filename   : OS_VIEWc.C
* Version    : V1.00
* Programmer : Eric Shufro
*********************************************************************************************************
*/

#include <includes.h>

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

#define  BIT0      0x01
#define  BIT1      0x02
#define  BIT2      0x04
#define  BIT3      0x08
#define  BIT4      0x10
#define  BIT5      0x20
#define  BIT6      0x40
#define  BIT7      0x80
#define  BIT8      0x100

/*$PAGE*/
/*
*********************************************************************************************************
*                                           EXIT uC/OS-View
*
* Description: This function is called if your target needs to 'uninstall' uC/OS-View.
*
* Note(s)    :
*********************************************************************************************************
*/

void  OSView_Exit (void)
{
}

/*
*********************************************************************************************************
*                                           Obtain CPU name
*********************************************************************************************************
*/

void  OSView_GetCPUName (INT8U *s)
{
    INT8U  cpu_clk_freq;


    cpu_clk_freq = (INT8U)(BSP_CPU_ClkFrq() / 1000000L);
    (void)OS_StrCopy(s, "Philips LPC3180 (--- MHz)");
    s[17] = cpu_clk_freq / 100       + '0';
    s[18] = cpu_clk_freq / 10 % 10   + '0';
    s[19] = cpu_clk_freq % 10        + '0';
}

/*
*********************************************************************************************************
*                                  Obtain Interrupt Stack information
*********************************************************************************************************
*/

INT32U  OSView_GetIntStkBase (void)
{
    return (0);                                                             /* We are not using an ISR stack                        */
}


INT32U  OSView_GetIntStkSize (void)
{
    return (0);                                                             /* We are not using an ISR stack                        */
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                    INITIALISE uC/OS-View COM PORT
*
* Description: Initialize the hardware required for the OS to run. This will work on any target hardware,
*              but may have to be tailored a little (regarding the clock frequency). Of course the same
*              holds true if for some reason you choose to use another timer.
*
* Note(s)    : 1) This function assumes that a free running timer has been initialized.  The timer can
*                 either be a 16 bits or 32 bits timer.  Your application needs to provide a function
*                 called OSView_TmrRd() that reads the current counts of this timer.  The free running
*                 timer is initialized by the BSP function OSView_TmrInit().
*********************************************************************************************************
*/

void  OSView_InitTarget (INT32U baud_rate)
{
    INT16U     div;                                                         /* Baud rate divisor                                    */
    INT8U      divlo;
    INT8U      divhi;
    INT8U      lcr;                                                         /* Line Control Register                                */
    INT32U     peripheral_clk_frq;


    divlo = 0;                                                              /* Avoid compiler warnings if high speed UART used      */
    divhi = 0;
    lcr   = 0;

    (void)divlo;                                                            /* Avoid compiler warnings if high speed UART used      */
    (void)divhi;
    (void)lcr;

    OSView_TmrInit();                                                       /* Initialize the free running timer. Since the timer   */
                                                                            /* is shared with OS Ticker. The function is left empty */

    peripheral_clk_frq =  BSP_ClkFrqPeripheral();                           /* Get the Periph. Frequency in order to calc baud div. */

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_5                                      /* Standard UART 5 selected                             */
    div                 =  (INT16U)(peripheral_clk_frq / 16 / baud_rate);   /* Compute divisor for desired baud rate                */
    divlo               =   div & 0x00FF;                                   /* Split divisor into LOW and HIGH bytes                */
    divhi               =  (div >> 8) & 0x00FF;
    lcr                 =   0x03;                                           /* 8 Bits, 1 Stop, No Parity                            */

    UARTCLK_CTRL        =   BIT2;                                           /* Enable the UART5 module clock                        */
    UART_CLKMODE        =   BIT8;                                           /* Set the UART Clock to always ON                      */
    U5CLK               =   0;                                              /* Reset the Clock Select Register to the default value */
    U5CLK              |=   BIT8 | BIT0;                                    /* Using Peripheral clock, with x div = 1, y div = 1    */
    U5LCR               =   BIT7;                                           /* Set divisor access bit                               */
    U5DLL               =   divlo;                                          /* Load divisor                                         */
    U5DLM               =   divhi;
    U5LCR               =   lcr;                                            /* Set 8 Data bits, clear 'Load Divisor' bit            */
    U5IER               =   0;                                              /* Disable both Rx and Tx interrupts                    */
    U5FCR               =   0;                                              /* Disable the FIFO                                     */

    BSP_IntEn(BSP_MAIN_INT_CTL, 9, BSP_INT_HIGH_LEVEL,                      /* Configure the interrupt for UART5                    */
              BSP_INT_LEVEL_SENSITIVE, OSView_RxTxISRHandler);
#endif

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_7                                      /* Standard UART 5 selected                             */
    div                 =  ((peripheral_clk_frq / 14 / baud_rate) - 1);     /* Compute divisor for desired baud rate                */
    HSU7_RATE           =  (INT8U)div;                                      /* UART clock divider = Peripheral_CLK / 1 / 14         */
    HSU7_CTRL           =   0x00002800;                                     /* Ensure control register starts with default value    */
    HSU7_CTRL          |=  (0x14 <<  9);                                    /* Ensure a sampling offset of 20 (default)             */
    HSU7_CTRL          |=  (3 << 16);                                       /* Set the character timeout to 16 characters           */
    HSU7_CTRL          &=  ~0x1F;                                           /* Set the Rx and Tx minimum FIFO levels to 0           */
    HSU7_CTRL          &= ~(3 <<  5);                                       /* Disable Receive and Tx Interrupts                    */
    HSU7_IIR            =   0x3F;                                           /* Clear all interrupt flags                            */

    BSP_IntEn(BSP_MAIN_INT_CTL, 24, BSP_INT_HIGH_LEVEL,                     /* Configure the interrupt for UART7                    */
              BSP_INT_LEVEL_SENSITIVE, OSView_RxTxISRHandler);
#endif
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                       Disable Rx Interrupts
*********************************************************************************************************
*/

void  OSView_RxIntDis (void)
{
#if OS_VIEW_COMM_SEL == OS_VIEW_UART_5
    U5IER     &= ~BIT0;                                                     /* Disable Receive Interrupts                           */
#endif

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_7
    HSU7_CTRL &= ~(1 << 5);                                                 /* Disable Rs Interrupts                                */
#endif
}

/*
*********************************************************************************************************
*                                       Enable Rx Interrupts
*********************************************************************************************************
*/

void  OSView_RxIntEn (void)
{
#if OS_VIEW_COMM_SEL == OS_VIEW_UART_5
    U5IER     |= BIT0;                                                      /* Enable Receive Interrupts                            */
#endif

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_7
    HSU7_CTRL |= BIT6;                                                      /* Enable Receive Interrupts                            */
#endif
}

/*
*********************************************************************************************************
*                                 Rx Communication handler for uC/OS-View
*
* Description: This function is called by OSView_RxISR (see OS_VIEWa.ASM) to process a received
*              character interrupt.
*
* Note(s)    : This adaptation of uC/OS-View assumes that a 'combined' interrupt is generated by the UART
*              and thus this function is not needed.
*********************************************************************************************************
*/

void  OSView_RxISRHandler (void)
{
}

/*
*********************************************************************************************************
*                                Rx/Tx Communication handler for uC/OS-View
*
* Description: This function is NOT called because the M16C has a separate Rx and Tx ISR.
*********************************************************************************************************
*/

void  OSView_RxTxISRHandler (void)
{
    volatile  INT8U  rx_data;
    volatile  INT8U  lsr;
    volatile  INT8U  iir;


#if OS_VIEW_COMM_SEL == OS_VIEW_UART_5
    iir = U5IIR & 0x0F;
    while (iir != 1) {
        switch (iir) {
            case  2:                                                        /* Transmitted character?                               */
                 OSView_TxHandler();                                        /* Call the Tx handler, Int. cleared by read of U5IIR   */
                 break;

            case  4:                                                        /* Received a character?                                */
                 rx_data = U5RBR;                                           /* Read the data. Int. cleared by read of U5RBR         */
                 OSView_RxHandler(rx_data);                                 /* Call the generic Rx handler                          */
                 break;

            case  6:                                                        /* Receive Line Status interrupt?                       */
                 lsr     = U5LSR;                                           /* Read the Line Status Register to clear the interrupt */
                 break;

            case 12:                                                        /* CTI interrupt?                                       */
                 rx_data = U5RBR;                                           /* Read the data register to clear the interrupt        */
                 break;
        }

        iir = U5IIR & 0x0F;
    }
#endif

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_7
    iir = (HSU7_IIR & 0x3F);                                                /* Read the interrupt status register                   */

    if ((iir & BIT0) == BIT0) {                                             /* Tx complete interrupt                                */
        HSU7_IIR |= BIT0;                                                   /* Clear the Interrupt source                           */
        OSView_TxHandler();                                                 /* Call the Tx handler, Int. cleared by read of U5IIR   */
    }

    if ((iir & BIT1) == BIT1) {                                             /* If FIFO is below threshhold                          */
        while ((HSU7_LEVEL & 0xFF) > 0) {                                   /* Read bytes from FIFO while there is data present     */
            rx_data = (HSU7_RX & 0xFF);                                     /* Read the data. Int. cleared by read of U5RBR         */
            OSView_RxHandler(rx_data);                                      /* Call the generic Rx handler                          */
        }
    }

    if ((iir & BIT3) == BIT3) {                                             /* Framing Error                                        */
        HSU7_IIR |= BIT3;                                                   /* Clear the Interrupt source                           */
    }

    if ((iir & BIT4) == BIT4) {                                             /* Break Interrupt                                      */
        HSU7_IIR |= BIT4;                                                   /* Clear the Interrupt source                           */
    }

    if ((iir & BIT5) == BIT5) {                                             /* Overrun Interrupt                                    */
        HSU7_IIR |= BIT5;                                                   /* Clear the Interrupt source                           */
    }
#endif
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                      Communication for uC/OS-View
*
* Description: Send 1 character to COM Port
*********************************************************************************************************
*/

void  OSView_Tx1 (INT8U c)
{
#if OS_VIEW_COMM_SEL == OS_VIEW_UART_5
    U5THR   = c;
#endif

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_7
    HSU7_TX = c;
#endif
}

/*$PAGE*/
/*
*********************************************************************************************************
*                                       Disable Tx Interrupts
*********************************************************************************************************
*/

void  OSView_TxIntDis (void)
{
#if OS_VIEW_COMM_SEL == OS_VIEW_UART_5
    U5IER     &= ~BIT1;                                                     /* Disable UART5 Tx interrupts                          */
#endif

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_7
    HSU7_CTRL &= ~BIT5;                                                     /* Disable UART7 Tx interrupts                          */
#endif
}

/*
*********************************************************************************************************
*                                       Enable Tx Interrupts
*********************************************************************************************************
*/

void  OSView_TxIntEn (void)
{
#if OS_VIEW_COMM_SEL == OS_VIEW_UART_5
    U5IER     |= BIT1;                                                      /* Enable Tx interrupts                                 */
#endif

#if OS_VIEW_COMM_SEL == OS_VIEW_UART_7
    HSU7_CTRL |= BIT5;                                                      /* Enable Tx interrupts                                 */
#endif
}

/*
*********************************************************************************************************
*                                 Tx Communication handler for uC/OS-View
*                                            (PORT SPECIFIC)
*
* Description: Handle transmission of a character
*
* Note(s)    : 1) This function is called by OSView_RxISR (see OS_VIEWa.ASM)
*              2) This adaptation of uC/OS-View assumes that a 'combined' interrupt is generated by the
*                 UART and thus this function is not needed.
*********************************************************************************************************
*/

void  OSView_TxISRHandler (void)
{
}


