Tuesday, August 25, 2015

Phase 2: IE_egwu_setup

/*
 ****************************************************************************
 *name:         IE_egwu_setup.h
 *author:       Samuel Igwe
 *date:         06/30/2015
 *description:  pll/clock/iopin initialization
 ****************************************************************************
 */
#ifndef IE_EGWU_SETUP_H
#define IE_EGWU_SETUP_H
    #include "chip.h"
    #include "chip_lpc177x_8x.h"
    #include "gpdma_17xx_40xx.h"
    #include "IE_egwu_uartio.h"

   /*
    *************************************************************************
    *#defines
    *************************************************************************
    */
    #define     EGWU_ONBOARD_UART               LPC_UART1
    #define     EGWU_UART_BAUD_RATE             115200
    #define     LPC177X_NUM_INT                 40
    #define     LPC177X_PREEMPT_PRIO_GROUP      2
    #define     EGWU_CPU_CLK_RATE               120000000
    #define     EGWU_CPU_OSC_RATE               24000000
    #define     EGWU_SYSTICK_RATE               (EGWU_CPU_CLK_RATE/1000)

    #define     LPC177X_SRAM_BASE               0x10000000


    #define     LPC_BILED_PORT                  1
    #define     LPC_BILED_PIN1                  23
    #define     LPC_BILED_PIN2                  24

    #define     LPC_LED_PORT                    1
    #define     LPC_LED_PIN                     8

    #define     EGWU_NVIC_USER_BILED_MASK       0x1
    #define     EGWU_NVIC_FAULT_BILED_MASK      0x2



    struct      STR_EGWU_SYSTICK        {
        volatile unsigned int wdSeconds;
        volatile unsigned int wdTicks;
        }strSysTick;


    #define     MINIMUM_PERIPHERAL_IRQ_PRIORITY 3
    enum        egwu_int_pl     {
        USB_INT_PL=MINIMUM_PERIPHERAL_IRQ_PRIORITY,
        UART_INT_PL,
        DMA_INT_PL,
        GPIO_INT_PL,
        WD_INT_PL};


    extern      int     EGWU_IVT;
    const       uint32_t OscRateIn;

    void        (*ptrGpDmaUserIsr[GPDMA_NUMBER_CHANNELS])(void);
    unsigned int wdEnableGpDmaInt;


   /*
    *************************************************************************
    *routines
    *************************************************************************
    */
    void        setup_pll(void);
    void        setup_nvic(void);
    void        setup_gpio(void);
    void        setup_uart(void);

    void        nvic_systick_isr(void);
    void        nvic_fault_isr(void);
    void        nvic_user_isr(void);

    void        gpio_set_lpc_biled(unsigned int wdLedMask);

    void        setup_gpdma(void);
    void        nvic_dma_isr(void);
    void        gpdma_hook_chan_isr(int  wdChannel,\
                                       void (*ptrFunc)(void));  
    void        gpdma_unhook_chan_isr(int wdChannel);
    void        timer_delay_mS(int wdMs);

#endif 
 
 
 
 
 
 
/*
 ****************************************************************************
 *name:         IE_egwu_setup.c
 *author:       Samuel Igwe
 *date:         06/30/2015
 *description:  pll/clock/iopin initialization
 ****************************************************************************
 */
#ifndef IE_EGWU_SETUP_C
#define IE_EGWU_SETUP_C

#include "IE_egwu_setup.h"





/*
 ****************************************************************************
 *description:  pll/clock.
 *inputs:       none
 *note:         main pll (0)        m=5        p=1    
 *                              pllin=24  pllout=120  fcco=240  
 *               alt pll (1)        m=2        p=2
 *                              pllin=24  pllout48    fcco=192
 *
 *              the condition pllin  = 1 < 25Mhz and fcco = 156 -> 320 has 
 *              has been satisfied
 *              cpu = 120Mhz
 *              emc =  60Mhz
 *              gpio=  40Mhz
 *
 *              when using the internal oscillator aim for 120Mhz as well
 *              main pll (0)        m=10       p=1
 *                              pllin=12  pllout=120  fcco=240
 ****************************************************************************
 */
void
setup_pll(void)
{
    /*
     ************************************************************************
     *switch to using default clock source
     ************************************************************************
     */
    Chip_Clock_SetMainPLLSource(SYSCTL_PLLCLKSRC_IRC);
    Chip_Clock_SetCPUClockSource(SYSCTL_CCLKSRC_SYSCLK);
    Chip_Clock_DisablePLL(SYSCTL_MAIN_PLL, SYSCTL_PLL_ENABLE);
    Chip_Clock_DisablePLL(SYSCTL_USB_PLL,  SYSCTL_PLL_ENABLE);


    /*
     ************************************************************************
     *use the internal rc clock for phase 1 and 2, while await replacement
     *caps for the crystal oscillator driver
     ************************************************************************
     */
#ifdef  EXT_CLK
    Chip_Clock_SetCrystalRangeHi();
    Chip_Clock_EnableCrystal();

    if((Chip_Clock_IsCrystalEnabled()) == TRUE)
        Chip_Clock_SetCPUClockSource(SYSCTL_CCLKSRC_MAINPLL);

    Chip_Clock_SetupPLL(SYSCTL_MAIN_PLL, 5, 1);
    Chip_Clock_SetupPLL(SYSCTL_USB_PLL,  2, 2);

    Chip_Clock_EnablePLL(SYSCTL_MAIN_PLL, SYSCTL_PLL_ENABLE);
    Chip_Clock_EnablePLL(SYSCTL_USB_PLL,  SYSCTL_PLL_ENABLE);
#else
    Chip_Clock_SetupPLL(SYSCTL_MAIN_PLL, 10, 1);
    Chip_Clock_EnablePLL(SYSCTL_MAIN_PLL, SYSCTL_PLL_ENABLE);
#endif


    /*
     ************************************************************************
     *delay a bit to let the logic do its thing
     ************************************************************************
     */
    while(Chip_Clock_IsMainPLLLocked() == 0)
        ;

#ifdef  EXT_CLK
    Chip_Clock_SetMainPLLSource(SYSCTL_PLLCLKSRC_MAINOSC);
    while(Chip_Clock_IsUSBPLLLocked() == 0)
        ;
#endif


    /*
     ************************************************************************
     *resume initialization
     ************************************************************************
     */
    Chip_Clock_SetCPUClockDiv(1);
    Chip_Clock_SetCPUClockSource(SYSCTL_CCLKSRC_MAINPLL);

#ifdef  EXT_CLK
    Chip_Clock_SetUSBClockDiv(1);
    Chip_Clock_SetUSBClockSource(SYSCTL_USBCLKSRC_USBPLL);
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USB);
#endif

    Chip_Clock_SetPCLKDiv(3);


    /*
     ************************************************************************
     *enable all the peripherals
     ************************************************************************
     */
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_TIMER0);
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_TIMER1);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_UART0);
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_UART1);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_RTC);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_EMC);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2C0);
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2C1);
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2C2);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SSP0);
    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SSP1);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USB);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPDMA);

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_GPIO);


    /*
     ************************************************************************
     *enable emc and clkout
     ************************************************************************
     */
    Chip_Clock_SetEMCClockDiv(SYSCTL_EMC_DIV2); 
    Chip_Clock_SetCLKOUTSource(SYSCTL_CLKOUTSRC_MAINOSC, 3);
    Chip_Clock_EnableCLKOUT();
}





/*
 ****************************************************************************
 *description:  configure nvic
 *inputs:       none
 *notes:        assume vector table is the global "ivt"
 *              skip stack and reset positions
 *              default isrs
 *              nvic_fault_isr()
 *              nvic_systic_isr()
 *              nvic_user_isr()
 ****************************************************************************
 */
void
setup_nvic(void)
{
    volatile unsigned int wdTemp, *ptrTemp;
    volatile int wdCount;


    ptrTemp = (volatile unsigned int *)&EGWU_IVT;
    for(wdCount = 2; wdCount < (LPC177X_NUM_INT + 16); wdCount++)
        {
        if(wdCount < 15)                        /*faults*/
                wdTemp  = (int) nvic_fault_isr;
        else
                {
                switch(wdCount)
                        {
                        case    15:             /*systick*/
                                wdTemp  = (int) nvic_systick_isr;
                                break;
                        case    42:             /*dma*/
                                wdTemp  = (int) nvic_dma_isr;
                                break;
                        default:
                                wdTemp  = (int) nvic_user_isr;
                                break;
                        }
                }

        wdTemp |= 1;                            /*thumb - mandatory*/
        *(ptrTemp + wdCount) = wdTemp;
        }


    /*
     ************************************************************************
     *selecting nvic priority group 2  (there are 32 pre-rempt priority 
     *levels on the lpc17xx)
     *[7:3]     = preempt priority field (5 bits)
     *[2:0]     = sub priority field     (3 bits)
     *
     *this allows me to allocate 32 interrupt priority levels thought I doubt
     *Id use that many interrupts in this project but one never knows
     *
     *for now set interrupts (system handler priority)
     *4 + 5 + 6   to priority level 0
     *11+14       to priority level 1
     *15 (systick)to priority level 2
     *(peripherals interrupt)
     *26 (dma)    to priority level 3
     *interrupts 1 through 3 are fixed (reset to fault)
     *set to rest to maximum priority (0xff)
     ************************************************************************
     */
    NVIC_SetPriorityGrouping(LPC177X_PREEMPT_PRIO_GROUP);
    for (wdCount = MemoryManagement_IRQn; wdCount < (LPC177X_NUM_INT); wdCount++)
        {
        switch(wdCount)
                {
                case    UsageFault_IRQn:
                        wdTemp = NVIC_EncodePriority(LPC177X_PREEMPT_PRIO_GROUP, 0, 0);
                        break;
                case    SVCall_IRQn:
                case    PendSV_IRQn:
                        wdTemp = NVIC_EncodePriority(LPC177X_PREEMPT_PRIO_GROUP, 1, 0);
                        break;
                case    SysTick_IRQn:
                        wdTemp = NVIC_EncodePriority(LPC177X_PREEMPT_PRIO_GROUP, 2, 0);
                        break;
                case    DMA_IRQn:
                        wdTemp = NVIC_EncodePriority(LPC177X_PREEMPT_PRIO_GROUP, 3, 0);
                        break;
                default:
                        wdTemp = NVIC_EncodePriority(LPC177X_PREEMPT_PRIO_GROUP, 9, 0);
                        break;
                }

        NVIC_SetPriority(wdCount, wdTemp);
        }


    /*
     ************************************************************************
     *setup systick timer for 1mS tick
     *configure variables
     ************************************************************************
     */
    strSysTick.wdSeconds = 0;
    strSysTick.wdTicks   = 0;
    SysTick_Config(EGWU_CPU_CLK_RATE/1000);


    /*
     ************************************************************************
     *cpu synchronization
     ************************************************************************
     */
    asm("dsb");
    asm("isb");


    /*
     ************************************************************************
     *enable mem/bus/usage fault interrupts
     ************************************************************************
     */
    wdTemp  = SCB_SHCSR_MEMFAULTENA_Msk;
    wdTemp |= SCB_SHCSR_BUSFAULTENA_Msk;
    wdTemp |= SCB_SHCSR_USGFAULTENA_Msk;
    SCB->SHCSR = wdTemp;


    /*
     ************************************************************************
     *remap vector table
     *enable interrupts on the processor level
     ************************************************************************
     */
    SCB->VTOR = LPC177X_SRAM_BASE;
    asm("cpsie i");
}





/*
 ****************************************************************************
 *description:  gpio configuration
 *inputs:       none
 *note:         mapping is as follows
 *              p0[00] - p0[01] =       fx4     =uart0
 *              p0[02] - p0[11] =       fx2     =sspi + i2c
 *              p0[12] - p0[13] =       fx1     =usb
 *              p0[15] - p0[18] =       fx2     =spi
 *              p0[23] - p0[25] =       fx1     =adc
 *              p0[26]          =       fx2     =dac
 *              p0[30]          =       fx0     =gpio1
 *              p0[31]          =       fx1     =usb
 *
 *              p1[02] - p1[10] =       fx0     =gpio
 *              p1[11] - p1[12] =       fx3     =pwm
 *              p1[14]          =       fx0     =gpio
 *              p1[18] - p1[19] =       fx0     =gpio3 and gpio4
 *              p1[23] - p1[24] =       fx0     =gpio (bi-led anode)
 *              p1[27]          =       fx4     =clkout
 *              p1[30] - p1[31] =       fx1     =usb
 *
 *              p2[00] - p[01]  =       fx1     =uart1
 *
 *              p2[10]          =       fx0     =isp_mode (dont use)
 *              p2[11]          =       fx1     =gbl_int
 *
 *              p2[14] - p2[31] =       fx1     =emc
 *
 *              p3[00] - p3[31] =       fx0     =emc
 *
 *              p4[00] - p4[31] =       fx0     =emc
 *
 *              p5[00] - p5[01] =       fx0     =emc
 ****************************************************************************
 */
void
setup_gpio(void)
{
    volatile unsigned int wdCount;


    /*
     ************************************************************************
     *port 3 and port 4 to function 1 and port 2 (14-31)
     ************************************************************************
     */
    for(wdCount = 0; wdCount < 32; wdCount++)
        {
        Chip_IOCON_PinMuxSet(LPC_IOCON, 3, wdCount, IOCON_FUNC1);
        Chip_IOCON_PinMuxSet(LPC_IOCON, 4, wdCount, IOCON_FUNC1);
        if(wdCount >= 14)
                Chip_IOCON_PinMuxSet(LPC_IOCON, 2, wdCount, IOCON_FUNC1);
        }


    /*
     ************************************************************************
     *port 0
     ************************************************************************
     */
    for(wdCount = 0; wdCount < 32; wdCount++)
        {
        if(wdCount <= 1)
                Chip_IOCON_PinMuxSet(LPC_IOCON, 0, wdCount, IOCON_FUNC4);
        else
                {
                if((wdCount >= 6  && wdCount <= 11) ||
                   (wdCount >= 15 && wdCount <= 18) ||
                   (wdCount == 26))
                        Chip_IOCON_PinMuxSet(LPC_IOCON, 0, wdCount, IOCON_FUNC2);
                else
                        {
                        if((wdCount >= 12 && wdCount <= 13) ||
                           (wdCount >= 23 && wdCount <= 25) ||
                           (wdCount == 31))
                                Chip_IOCON_PinMuxSet(LPC_IOCON, 0, wdCount, IOCON_FUNC1);
                        else
                                {
                                if(wdCount == 30)
                                        Chip_IOCON_PinMuxSet(LPC_IOCON, 0, wdCount, IOCON_FUNC0);
                                }
                        }
                }
        }


    /*
     ************************************************************************
     *port 1
     ************************************************************************
     */
    for(wdCount = 0; wdCount < 32; wdCount++)
        {
        if((wdCount >= 2  && wdCount <= 10) ||
           (wdCount >= 18 && wdCount <= 19) ||
           (wdCount >= 23 && wdCount <= 24) ||
           (wdCount == 14))
                Chip_IOCON_PinMuxSet(LPC_IOCON, 1, wdCount, IOCON_FUNC0);
        else
                {
                if(wdCount >= 11 &&  wdCount <= 12)
                        Chip_IOCON_PinMuxSet(LPC_IOCON, 1, wdCount, IOCON_FUNC3);
                else
                        {
                        if(wdCount  >= 30 && wdCount <= 31)
                                Chip_IOCON_PinMuxSet(LPC_IOCON, 1, wdCount, IOCON_FUNC1);
                        else
                                {
                                if(wdCount == 27)
                                        Chip_IOCON_PinMuxSet(LPC_IOCON, 1, wdCount, IOCON_FUNC4);
                                }
                        }
                }
        }


    /*
     ************************************************************************
     *port 2
     ************************************************************************
     */
    for(wdCount = 0; wdCount < 14; wdCount++)
        {
        if(wdCount <= 1)
                Chip_IOCON_PinMuxSet(LPC_IOCON, 2, wdCount, IOCON_FUNC2);
        else
                {
                if(wdCount >= 14)
                        Chip_IOCON_PinMuxSet(LPC_IOCON, 2, wdCount, IOCON_FUNC1);
                }
        }


    /*
     ************************************************************************
     *set direction for ports configured as gpio
     ************************************************************************
     */
    //Chip_GPIO_SetPinDIRInput(LPC_GPIO, 0, 30);
    Chip_GPIO_SetPinDIROutput(LPC_GPIO, 0, 30);

    for(wdCount =0; wdCount < 32; wdCount++)
        {
        switch(wdCount)
                {
                case    2:
                case    5:
                case    9:
                case    10:
                case    14:
                        {
                        Chip_GPIO_SetPinDIRInput(LPC_GPIO, 1, wdCount);
                        break;
                        }
                case    3:
                case    4:
                case    6:
                case    7:
                case    8:
                case    18:
                case    19:
                case    23:
                case    24:
                        {
                        Chip_GPIO_SetPinDIROutput(LPC_GPIO, 1, wdCount);
                        break;
                        }
                }
        }
}





/*
 ****************************************************************************
 *description:  uart configuration
 *inputs:       none
 *notes:        using 40Mhz peripheral clock (cpuclock/3) to derive 115200 baud
 ****************************************************************************
 */
void
setup_uart(void)
{
    volatile unsigned int wdTemp;


    /*
     ************************************************************************
     *governing formula is as follows:
     *Uart(baudrate) =  PCLK (40Mhz)/16 x (256 x DLM) + DLL x (1 + DivVal/MulVal)
     *constraints
     *                  1 <= MulVal     <= 15
     *                  0 <= DivAddVal  <= 14
     *                  DivAddVal       <  MulVal
     *[for 115200]
     ************************************************************************
     *115200 = 40Mhz/16 x [(256 x DLM) + DLL x (1 + D/M)
     *115200 = 40Mhz/16 x DLest
     *DLest  = 21.7
     *FRest  = 1.5
     ************************************************************************
     *DLest  = INT(40Mhz/(16 x 115200 x FRest)
     *FRest  = 40Mhz/(16 x 115200 x DLest)
     ************************************************************************
     *DLest  = INT(14.46) = 14
     *FRest  = 1.55
     ************************************************************************
     *this satisfies the condition 1.1 < Frest < 1.9
     *DL     = INT(40Mhz/(16 x 115200 x 1.55) = 14
     *DL*FR  = 14 x 1.55 =  21.7
     ************************************************************************
     *from the table
     *DivAdd = 5
     *MulVal = 9
     * 
     *determined later that the values 6/7 work best for this osc and board
     ************************************************************************
     *[for 9600]
     ************************************************************************
     *9600   = 40Mhz/16 x [(256 x DLM) + DLL x (1 + D/M)
     *9600   = 40Mhz/16 x DLest
     *DLest  = 260.41
     *FRest  = 1.5
     ************************************************************************
     *DLest  = INT(40Mhz/(16 x 9600 x FRest)
     *FRest  = 40Mhz/(16 x 9600 x DLest)
     ************************************************************************
     *DLest  = INT(173.61) = 173
     *FRest  = 1.505
     ************************************************************************
     *this satisfies the condition 1.1 < Frest < 1.9
     *DL     = INT(40Mhz/(16 x 9600 x 1.505) = 173.03
     *DL*FR  = 173 x 1.505 =  260.365
     ************************************************************************
     *from the table
     *DivAdd = 5
     *MulVal = 9
     ************************************************************************
     */
#if (EGWU_UART_BAUD_RATE == 115200)
    Chip_UART_EnableDivisorAccess(EGWU_ONBOARD_UART);
    Chip_UART_SetDivisorLatches(EGWU_ONBOARD_UART, 14, 0);
    Chip_UART_DisableDivisorAccess(EGWU_ONBOARD_UART);


    /*
     ************************************************************************
     *8-N-1
     ************************************************************************
     */
    wdTemp  = UART_LCR_WLEN8;
    wdTemp |= UART_LCR_SBS_1BIT;
    wdTemp |= UART_LCR_PARITY_DIS;
    Chip_UART_ConfigData(EGWU_ONBOARD_UART, wdTemp);

    EGWU_ONBOARD_UART->FDR = (UART_FDR_MULVAL(7) | UART_FDR_DIVADDVAL(6)); 
#else
    Chip_UART_EnableDivisorAccess(EGWU_ONBOARD_UART);
    Chip_UART_SetDivisorLatches(EGWU_ONBOARD_UART, 173, 0);
    Chip_UART_DisableDivisorAccess(EGWU_ONBOARD_UART);


    /*
     ************************************************************************
     *8-N-1
     ************************************************************************
     */
    wdTemp  = UART_LCR_WLEN8;
    wdTemp |= UART_LCR_SBS_1BIT;
    wdTemp |= UART_LCR_PARITY_DIS;
    Chip_UART_ConfigData(EGWU_ONBOARD_UART, wdTemp);

    //EGWU_ONBOARD_UART->FDR = (UART_FDR_MULVAL(1) | UART_FDR_DIVADDVAL(0)); 
    #ifdef      DIVADDVAL
        EGWU_ONBOARD_UART->FDR = (UART_FDR_MULVAL(MULVAL) | UART_FDR_DIVADDVAL(DIVADDVAL)); 
    #else
        EGWU_ONBOARD_UART->FDR = (UART_FDR_MULVAL(9) | UART_FDR_DIVADDVAL(5)); 
    #endif
#endif


    /*
     ************************************************************************
     *reset RX and TX blocks and enable fifos
     ************************************************************************
     */
    wdTemp  = UART_FCR_FIFO_EN;
    wdTemp |= UART_FCR_RX_RS;
    wdTemp |= UART_FCR_TX_RS;
    wdTemp |= UART_FCR_TRG_LEV1;
    wdTemp |= UART_FCR_DMAMODE_SEL;
    Chip_UART_SetupFIFOS(EGWU_ONBOARD_UART, wdTemp);

    Chip_UART_TXEnable(EGWU_ONBOARD_UART);
 

    /*
     ************************************************************************
     *enable interrupts
     ************************************************************************
     */
    wdTemp  = UART_IER_RBRINT;
    Chip_UART_IntEnable(EGWU_ONBOARD_UART, wdTemp);
}



 

/*
 ****************************************************************************
 *description:  nvic systic handler
 *inputs:       none
 *note:         toggle P1[8] = 190 uC led used as heartbeat monitor
 ****************************************************************************
 */
void
nvic_systick_isr(void)
{
    volatile unsigned int wdTemp;

    strSysTick.wdTicks++;
    if(strSysTick.wdTicks == 1000)
        {
        strSysTick.wdTicks = 0;
        strSysTick.wdSeconds++;

        //wdTemp = Chip_GPIO_GetPinState(LPC_GPIO1, LPC_LED_PORT, LPC_LED_PIN);
        //Chip_GPIO_SetPinState(LPC_GPIO1, LPC_LED_PORT, LPC_LED_PIN, wdTemp);

        wdTemp = (((LPC_GPIO1->PIN) >> LPC_LED_PIN) & 0x1);
        wdTemp ^= 0x1;
        if(wdTemp == 0)
                (LPC_GPIO1->CLR) = (1 << LPC_LED_PIN);  
        else
                (LPC_GPIO1->SET) = (1 << LPC_LED_PIN);  

        uartio_tx_flush();
        }
}





/*
 ****************************************************************************
 *description:  nvic fault handler
 *inputs:       none
 ****************************************************************************
 */
void
nvic_fault_isr(void)
{
    gpio_set_lpc_biled(EGWU_NVIC_FAULT_BILED_MASK);
}





/*
 ****************************************************************************
 *description:  nvic user handler
 *inputs:       none
 ****************************************************************************
 */
void
nvic_user_isr(void)
{
    gpio_set_lpc_biled(EGWU_NVIC_USER_BILED_MASK);
}





/*
 ****************************************************************************
 *description:  set the bi-led connected to the LPC
 *inputs:       unsigned int wdLedMask = led mask only lower two bits matter
 ****************************************************************************
 */
void
gpio_set_lpc_biled(unsigned int wdLedMask)
{
    wdLedMask &= 0x3;

    Chip_GPIO_SetPinState(LPC_GPIO, LPC_BILED_PORT, LPC_BILED_PIN1, wdLedMask);
    Chip_GPIO_SetPinState(LPC_GPIO, LPC_BILED_PORT, LPC_BILED_PIN2, (wdLedMask >> 1));
}





/*
 *****************************************************************
 *description:  configure the gpdma peripheral
 *              set array of pointers to int to 0 then init gpdma
 *****************************************************************
 */
void
setup_gpdma(void)
{
    volatile unsigned int wdCount;

    for(wdCount=0; wdCount < GPDMA_NUMBER_CHANNELS; wdCount++)
        *(ptrGpDmaUserIsr + wdCount) = 0;

    wdEnableGpDmaInt = 0;
    Chip_GPDMA_Init(LPC_GPDMA);
}





/*
 *****************************************************************
 *description:  channel isr call back
 *****************************************************************
 */
void
nvic_dma_isr(void)
{
    volatile unsigned int wdCount;

    for(wdCount=0; wdCount <GPDMA_NUMBER_CHANNELS; wdCount++)
        {
        if((Chip_GPDMA_Interrupt(LPC_GPDMA, wdCount) == SUCCESS) &&\
                ptrGpDmaUserIsr[wdCount] != NULL)
                ptrGpDmaUserIsr[wdCount]();
        }
}





/*
 *****************************************************************
 *description:  hook channel ISR
 *inputs:       int  wdChannel        = 0 to GPDMA_NUMBER_CHANNELS 
 *              void (*ptrFunc)(void) = pointer to callback function
 *****************************************************************
 */
void
gpdma_hook_chan_isr(int  wdChannel, \
                    void (*ptrFunc)(void))
{
    if(ptrGpDmaUserIsr[wdChannel] == NULL)
        {
        ptrGpDmaUserIsr[wdChannel] = ptrFunc;
        wdEnableGpDmaInt++;

        NVIC_EnableIRQ(DMA_IRQn);
        }
}





/*
 *****************************************************************
 *description:  unhook channel ISR
 *input:        int  wdChannel        = 0 to GPDMA_NUMBER_CHANNELS 
 *****************************************************************
 */
void
gpdma_unhook_chan_isr(int wdChannel)
{
    if(wdChannel >= GPDMA_NUMBER_CHANNELS)
        return;

    ptrGpDmaUserIsr[wdChannel] = 0;
    wdEnableGpDmaInt--;
    if(wdEnableGpDmaInt == 0)
        NVIC_DisableIRQ(DMA_IRQn);
}





/*
 *****************************************************************
 *description:  mS delay using TIMER0
 *input:        int  wdMs = number of milliseconds to delay
 *note:         peripheral clock is 40Mhz
 *****************************************************************
 */
void
timer_delay_mS(int wdMs)
{
    volatile unsigned int wdTemp;
    
    Chip_TIMER_Reset(LPC_TIMER0);
    Chip_TIMER_Disable(LPC_TIMER0);
    Chip_TIMER_PrescaleSet(LPC_TIMER0, 40000);
    Chip_TIMER_SetMatch(LPC_TIMER0, 0, wdMs);
    Chip_TIMER_StopOnMatchEnable(LPC_TIMER0, 0);

    Chip_TIMER_Enable(LPC_TIMER0);
    do
        {
        wdTemp = Chip_TIMER_ReadCount(LPC_TIMER0);
        }while(wdTemp != wdMs);

}





#endif
 

No comments:

Post a Comment