Sunday, July 5, 2015

Phase 1: core

/*
 **********************************************************************
 *name:         IE_EGWU_IVT.S
 *author:       Samuel Igwe
 *date:         06/30/2015
 *description:  Igbo Embedded EGWU_IVT.S source
 *              the interrupt vector table starts with the initial 
 *              stack address followed by the addresses of the function
 *              and ISR's. just allocate the space - leave it vacant
 *note:  this must be linked in first when building the .out file
 *              since i plan on remmapping VTOR to point to the IVT at
 *  the start of SRAM memory
 **********************************************************************
 */


#ifndef IE_EGWU_IVT_H

.global EGWU_IVT
.global EGWU_IVT_END
.extern main
.equ LPC177X_SRAM_BASE, 0x10000000
.equ    LPC177X_NUM_INT  , 40
.data
.align 4
EGWU_IVT:       .word   LPC177X_SRAM_BASE + (64 * 1024)
                .word   (main + 1)
                .skip   (14 * 4)
                .skip   (LPC177X_NUM_INT * 4)
EGWU_IVT_END:
#endif

 
 
 
 
/*
 ****************************************************************************
 *name:         IE_egwu_setup.h
 *author:       Samuel Igwe
 *date:         06/30/2015
 *description:  pll/clock/iopin initialization
 ****************************************************************************
 */
#ifndef IE_EGWU_SETUP_H
    #define     LPC177X_NUM_INT                 40
    #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



    #include "chip.h"
    #include "chip_lpc177x_8x.h"


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

    

    #define     EGWU_UART_BUFFER_SIZE           64
    struct      STR_EGWU_UART           {
        volatile unsigned int  wdMutex;
        volatile unsigned int  wdCount;
        volatile unsigned int  wdIndex;
        volatile unsigned char sbBuf[EGWU_UART_BUFFER_SIZE];
        }strUart;

 
    extern      int     EGWU_IVT;
    const       uint32_t OscRateIn;


    void        egwu_setup_pll(void);
    void        egwu_setup_nvic(void);
    void        egwu_setup_gpio(void);
    void        egwu_setup_uart(void);

    void        egwu_nvic_systick_isr(void);
    void        egwu_nvic_fault_isr(void);
    void        egwu_nvic_user_isr(void);

    void        egwu_set_lpc_biled(unsigned int wdLedMask);

#endif
 
 
 
 
 
/*
 ****************************************************************************
 *name:         IE_egwu_setup.c
 *author:       Samuel Igwe
 *date:         06/30/2015
 *description:  pll/clock/iopin/nvic initialization
 ****************************************************************************
 */
#ifndef 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
egwu_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 "egwu_ivt"
 *              skip stack and reset positions
 *              default isrs
 *              egwu_nvic_fault_isr()
 *              egwu_nvic_systic_isr()
 *              egwu_nvic_user_isr()
 ****************************************************************************
 */
void
egwu_setup_nvic(void)
{
    volatile unsigned int wdTemp, *ptrTemp, wdCount;


    ptrTemp = (volatile unsigned int *)&EGWU_IVT;
    for(wdCount = 2; wdCount < (LPC177X_NUM_INT + 16); wdCount++)
        {
        if(wdCount < 15)                        /*faults*/
                wdTemp  = (int) egwu_nvic_fault_isr;
        else
                {
                if(wdCount == 15)               /*systick*/
                        wdTemp  = (int) egwu_nvic_systick_isr;
                else
                        wdTemp  = (int) egwu_nvic_user_isr;
                }

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


    /*
     ************************************************************************
     *selecting nvic priority group 1  (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 
     *4 + 5 + 6 to priority level 0
     *11+14     to priority level 1
     *15 (timer)to priority level 2
     *interrupts 1 through 3 are fixed (reset to fault)
     ************************************************************************
     */
    NVIC_SetPriorityGrouping(1);
    for (wdCount = 4; wdCount <= 15; wdCount++)
        {
        if(wdCount <= 6)
                wdTemp = NVIC_EncodePriority(1, 0, (wdCount - 4));

        if(wdCount == 11 || wdCount == 14)
                wdTemp = NVIC_EncodePriority(1, 1, (wdCount - 11));

        if(wdCount == 15)
                wdTemp = NVIC_EncodePriority(1, 1, 0);


        NVIC_SetPriority(wdCount, wdTemp);
        }


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


    /*
     ************************************************************************
     *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
egwu_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);
                        }
                }
        }


    /*
     ************************************************************************
     *port 1
     ************************************************************************
     */
    for(wdCount = 0; wdCount < 32; wdCount++)
        {
        if((wdCount >= 2  && wdCount <= 10) ||
           (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);

    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    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
egwu_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     <= 16
     *                  0 <= DivAddVal  <= 14
     *                  DivAddVal       <  MulVal
     ************************************************************************
     *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)
     ************************************************************************
     *many fractional dividers can work so I chose FRest = 1.1 from table 398
     *FRest =  1.1
     ************************************************************************
     *DLest =  INT(40Mhz/(16 x 115200 x 1.1) = 19
     *FRest =  40Mhz/(16 x 115200 x 19)      = 1.142
     *this satisfies the condition 1.1 < Frest < 1.9
     ************************************************************************
     *DivAdd  = 1
     *MulVal  = 7
     ************************************************************************
     *technical baud rate = 40Mhz/(16 x 115200 x z) z = 21 
     ************************************************************************
     */

    Chip_UART_EnableDivisorAccess(LPC_UART0);
    Chip_UART_SetDivisorLatches(LPC_UART0, 21, 0);
    Chip_UART_DisableDivisorAccess(LPC_UART0);


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

    LPC_UART0->FDR = (UART_FDR_MULVAL(7) | UART_FDR_DIVADDVAL(1)); 


    /*
     ************************************************************************
     *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;
    Chip_UART_SetupFIFOS(LPC_UART0, wdTemp);

    Chip_UART_TXEnable(LPC_UART0);
 

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



 

/*
 ****************************************************************************
 *description:  nvic systic handler
 *inputs:       none
 *note:         toggle P1[8] = 190 uC led used as heartbeat monitor
 ****************************************************************************
 */
void
egwu_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);  
        }
}





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





/*
 ****************************************************************************
 *description:  nvic user handler
 *inputs:       none
 ****************************************************************************
 */
void
egwu_nvic_user_isr(void)
{
egwu_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
egwu_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));
}




#endif

Phase 1: tclib

/*
 *****************************************************************
 *name:         tclib.h
 *author:       Samuel Igwe
 *date:         06/07/2015 (c) copyright
 *description:  tclib (my thumb) library header.
 *****************************************************************
 */
#ifndef TCLIB_H
#define TCLIB_H


    extern  int     IE_tclib_atoi(unsigned char *ptrAscStr);
    extern  void    IE_tclib_itoa(unsigned int wdValue,\
                                  unsigned char *ptrAscStr);
    extern  int     IE_tclib_bswap(unsigned int wdValue);
    extern  int     IE_tclib_swap(unsigned int wdValue);
    extern  int     IE_tclib_strlen(unsigned char *ptrStrSrc);
    extern  int     IE_tclib_strcmp(unsigned char *ptrStrSrc,\
                                    unsigned char *ptrStrDst);
    extern  void    IE_tclib_memset(unsigned char *ptrString,\
                                    unsigned int wdValue,\
                                    unsigned int wdSize);
    extern  void    IE_tclib_memcpy(unsigned char *ptrDstStr,\
                                    unsigned char *ptrSrcStr,\
                                    unsigned int wdSize);
    extern  int     IE_tclib_acquire_semaphore(unsigned int *ptrWord);
    extern  int     IE_tclib_release_semaphore(unsigned int *ptrWord);


#endif
 



 
 
 
 

/*
 *****************************************************************
 *name:         tclib.S
 *author:       Samuel Igwe
 *date:         06/07/2015
 *description:  my thumb2 library. asm optimized generic routines
 *
 *notes:        from ARM technical reference manual
 *              instructions are conditional
 *              eq/ne (eq = 0, ne = not 0)
 *              ge/gt/le/lt
 *              memory addressing formats ldr(s)/str
 *              pre-index with writeback   ldr r0, [r1,#4]!
 *                              data = mem[base+offset] 
 *                      base addr reg= base+offset
 *              pre-index                  ldr r0, [r1,#4]
 *                              data = mem[base+offset]
 *                      base addr reg= not updated
 *              post-index                 ldr r0, [r1],#4
 *                              data = mem[base]
 *                      base addr reg= base+offset 
 *
 *              #4 above could be replaced by another register
 *****************************************************************
 */
#ifndef TCLIB_S
    .thumb
    .text
    .syntax unified


/*
 *****************************************************************
 *description:  C initializer. basically just setups up the stack
 *note:         not really needed since offset 0 of the ivt setups
 *              up the main stack pointer. this routine exists for
 *              when i want to change it which is UNLIKELY
 *****************************************************************
 */
    .align      2
    .global tclib_cinit
    .thumb_func
    .equ        LPC177X_SRAM_BASE, 0x10000000
    .equ        SRAM_TOP, (LPC177X_SRAM_BASE + (64*1024))
    tclib_cinit:
    ldr sp, =SRAM_TOP
    mov pc, lr





/*
 *****************************************************************
 *description:  software divider. meanth to be called from asm
 *              takes 
 *inputs:       r0 = dividend
 *              r1 = divisor
 *outputs:      r0 = quotient
 *              r1 = remainder
 *output:       0 on error 1 on success
 *****************************************************************
 */
    .align  2
    .global tclib_softdiv
    .thumb_func
    tclib_softdiv:
    push    {r2, lr}

    mov r2, r0                                  /*put r0 in r2*/
    mov r0, #0                                  /*zero out quotient*/

    tclib_softdiv_loop:
    cmp r2, r1
    blt tclib_softdiv_exit
    sub r2, r2, r1
    add r0, r0, #1
    b tclib_softdiv_loop

    tclib_softdiv_exit:
    mov r1, r2                                  /*r1 remainder*/

    pop {r2, lr}
    mov pc, lr





/*
 *****************************************************************
 *description:  acquire semaphore
 *input:        char *ptrWord   = pointer to memory word
 *output:       0 on error 1 on success
 *void
 *tclib_acquire_semaphore(unsigned char *ptrWord)
 *****************************************************************
 */
    .align  2
    .global tclib_acquire_semaphore
/*
 *****************************************************************
 *r0 = ptrWord
 *****************************************************************
 */
    .thumb_func
    tclib_acquire_semaphore:
    push    {r1-r2}


    mov     r1, #1
    mov     r2, r0

    ldrexb  r0, [r2]                        /*get value*/
    cmp     r0, #0
    itt     ne
    eorne   r0, #1
    bne     tclib_get_mutex_exit

    strexb  r0, r1, [r2]
    eor     r0, #1

    tclib_get_mutex_exit:
    clrex

    pop     {r1-r2}
    mov     pc, lr





/*
 *****************************************************************
 *description:  release semaphore
 *input:        char *ptrWord   = pointer to memory word
 *output:       0 on error 1 on success
 *void
 *tclib_release_semaphore(unsigned char *ptrWord)
 *****************************************************************
 */
    .align  2
    .global tclib_release_semaphore
/*
 *****************************************************************
 *r0 = ptrWord
 *****************************************************************
 */
    .thumb_func
    tclib_release_semaphore:
    push    {r1-r2}


    mov     r1, #0
    mov     r2, r0

    ldrexb  r0, [r2]                        /*get value*/
    cmp     r0, #0
    ite     ne
    eorne   r0, #1
    beq     tclib_release_mutex_exit

    strexb  r0, r1, [r2]
    eor     r0, #1

    tclib_release_mutex_exit:
    clrex

    pop     {r1-r2}
    mov     pc, lr





/*
 *****************************************************************
 *description:  sets a string buffer to a certain value
 *input:        char *ptrString =pointer to string
 *              int  wdValue    =value
 *              int  wdSize     =maximum length of string
 *void
 *tclib_memset(unsigned char *ptrString, int wdValue, int wdSize)
 *{
 *while ((wdSize--) >0)
 *       *(ptrString++) = (char)wdValue;
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_memset
/*
 *****************************************************************
 *r0 = ptrString
 *r1 = wdValue
 *r2 = wdSize
 *r3 = scratch
 *****************************************************************
 */
    .thumb_func
    tclib_memset:
    push    {r0-r3, lr}

    mov     r3, r1, lsl #8
    orr     r1, r1, r3                      /*put byte into word*/
    mov     r3, r1, lsl #16
    orr     r1, r1, r3                      /*put word into dword*/

/*
 *****************************************************************
 *the instructions below
 orr     r1, r1, lsl #8                 
 orr     r1, r1, lsl #16
 *
 *generate the error
 tclib/tclib.S: Assembler messages:
 tclib/tclib.S:203: Error: garbage following instruction -- `orr r1,r1,lsl#8'
 tclib/tclib.S:204: Error: garbage following instruction -- `orr r1,r1,lsl#16'
 *under arm-linux-gnueabi-gcc version 4.4.5
 *so I revised it to the instructions above this comment
 *****************************************************************
 */

    andS    r3, r0, #0x3                /*determine dword alignment*/
    beq     tclib_memset_loop        /*take action if aligned*/


        tclib_memset_align:
        strb    r1, [r0], #1            /*store one byte - autoincr*/
        subS    r2, r2, #1              /*decrement counter*/
        itt     EQ
        popeq   {r0-r3, lr}             /*exit*/
        moveq   pc, lr                  /*exit*/

        andS    r3, r0, #0x3            /*determine dword alignment*/
        bne     tclib_memset_align


        tclib_memset_loop:           /*optimization*/
        cmp     r2, #4                  /*r2 >= 4*/
        blt     tclib_memset_align
                                        /*else*/
        str     r1, [r0], #4            /*dword*/
        subS    r2, #4                  /*decrement counter*/
        bne     tclib_memset_loop      
        pop     {r0-r3, lr}             /*exit*/
        mov     pc, lr                  /*exit*/




/*
 *****************************************************************
 *description:  copy from source to destination buffer
 *input:        char *ptrDstStr =pointer to dst string
 *              char *ptrSrcStr =pointer to src string
 *              int  wdSize     =max length of string
 *void
 *tclib_memcpy(unsigned char *ptrDstStr,\
 *              unsigned char *ptrSrcStr, \
 *              int wdSize)
 *{
 *while ((wdSize--) >0)
 *       *(ptrDstStr++) = *(ptrSrcStr++);
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_memcpy
/*
 *****************************************************************
 *r0 = ptrDst
 *r1 = ptrSrc
 *r2 = wdSize
 *r3 = scratch
 *****************************************************************
 */
    .thumb_func
    tclib_memcpy:
    push    {r0-r3, lr}

    andS    r3, r0, #0x3                /*check if dst aligned*/                        
    bne     tclib_memcpy_bcopy
    andS    r3, r1, #0x3                /*check if src aligned*/
    bne     tclib_memcpy_bcopy


        tclib_memcpy_loop:           /*optimization*/
        cmp     r2, #4                  /*check if size >= 4*/
        blt     tclib_memcpy_bcopy
                                        /*else*/
        ldr     r3, [r1], #4            /*get from src*/
        str     r3, [r0], #4            /*put in   dst*/
        subS    r2, #4                  /*decrement counter*/
        bne     tclib_memcpy_loop
        pop     {r0-r3, lr}             /*exit*/
        mov     pc, lr                  /*exit*/


        tclib_memcpy_bcopy:
        ldrb    r3, [r1], #1            /*get from src*/
        strb    r3, [r0], #1            /*put in   dst*/
        subS    r2, #1                  /*decrement counter*/
        bne     tclib_memcpy_bcopy
        pop     {r0-r3, lr}             /*exit*/
        mov     pc, lr                  /*exit*/





/*
 *****************************************************************
 *description:  ascii to integer
 *input:        char *ptrAscStr =pointer to string
 *output:       int             =value
 *int
 *tclib_atoi(unsigned char *ptrAscStr)
 *{
 *unsigned char     *ptrTemp;
 *volatile int wdValue,wdWeight,wdTemp;
 *
 *wdValue =0;
 *wdWeight=1;
 *ptrTemp =ptrAscStr;
 *
 *while ((*ptrTemp) != NULL)
 *       ptrTemp++;
 *
 *while ((--ptrTemp) >= ptrAscStr)
 *       {
 *       wdTemp = *ptrTemp;
 *       if (wdTemp >= '0' && wdTemp <='9')
 *               wdTemp-= '0';
 *       else
 *               {
 *               if (wdTemp >='a' && wdTemp <='f')
 *                       {
 *                       wdTemp-= 'a';
 *                       wdTemp+= 10;
 *                       }
 *               else
 *                       {
 *                       if (wdTemp >= 'A' && wdTemp <= 'F')
 *                               {
 *                               wdTemp-= 'A';
 *                               wdTemp+= 10;
 *                               }
 *                       else
 *                               return 0;
 *                       }
 *               }
 *
 *       wdValue  += wdTemp * wdWeight;
 *       wdWeight<<= 4;
 *       }
 *
 *return wdValue;
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_atoi
/*
 *****************************************************************
 *r0 = ptrString
 *returns r0
 *r1 = r0 - address
 *r2 = scratch - wdValue
 *r3 = scratch - wdWeight
 *r4 = scratch
 *****************************************************************
 */
    .thumb_func
    tclib_atoi:
    push    {r1-r4, lr}

    mov     r1, r0                      /*to be return value*/
    bl      tclib_strlen                /*of strlen()*/
    cmp     r0, #0                      /*is it zero?*/
    itt     EQ
    popeq   {r1-r4, lr}
    moveq   pc, lr

    mov     r3, #1                      /*init wdWeight*/
    mov     r2, #0                      /*zero out*/


        tclib_atoi_loop:
        subS    r0, r0, #1              /*decrement loop*/
        ittt    LT
        movlt   r0, r2                  /*copy out arg when done*/
        poplt   {r1-r4, lr}
        movlt   pc, lr

        ldrb    r4, [r1,r0]             /*preindex without update*/
        and     r4, r4, #0x0ff          /*clear upper bits*/

        cmp     r4, #'0'
        ittt    LT
        movlt   r0, #0                  /*zero out before exiting*/
        poplt   {r1-r4, lr}             /*exit if less than '0'*/
        movlt   pc, lr                  /*exit*/

        cmp     r4, #'9'
        bgt     tclib_atoi_lcase
        sub     r4, r4, #'0'
        mla     r2, r4, r3, r2          /*r2=(r3*r4)+r2*/
        mov     r3, r3, lsl #4          /*adjust 16^x*/
        b       tclib_atoi_loop


        tclib_atoi_lcase:
        cmp     r4, #'a'
        blt     tclib_atoi_ucase
        cmp     r4, #'f'
        ittt    GT
        movgt   r0, #0                  /*zero out before exiting*/
        popgt   {r1-r4, lr}             /*exit if greater than 'f'*/
        movgt   pc, lr                  /*exit*/

        sub     r4, r4, #'a'
        add     r4, r4, #10
        mla     r2, r4, r3, r2          /*r2=(r3*r4)+r2*/
        mov     r3, r3, lsl #4
        b       tclib_atoi_loop

                
        tclib_atoi_ucase:
        cmp     r4, #'A'
        ittt    LT
        movlt   r0, #0                  /*zero out before exiting*/
        poplt   {r1-r4, lr}
        movlt   pc, lr

        cmp     r4, #'F'
        ittt    GT
        movgt   r0, #0                  /*zero out before exiting*/
        popgt   {r1-r4, lr}             /*exit if greater than 'F'*/
        movgt   pc, lr                  /*exit*/

        sub     r4, r4, #'A'
        add     r4, r4, #10
        mla     r2, r4, r3, r2          /*r2=(r3*r4)+r2*/
        mov     r3, r3, lsl #4
        b       tclib_atoi_loop
        




/*
 *****************************************************************
 *description:  integer to ascii. convert nibbles
 *input:        int     wdValue     =value
 *              char    *ptrAscStr  =pointer to string
 *void
 *tclib_itoa(int wdValue, unsigned char *ptrAscStr)
 *{
 *volatile int wdIndex,wdTemp;
 *
 *if (wdValue < 0)
 *       wdIndex =8;
 *else
 *       {
 *       if (wdValue < (1 << 8))
 *               wdIndex =2;
 *       else
 *               {
 *               if (wdValue < (1 << 16))
 *                       wdIndex =4;
 *               else
 *                       {
 *                       if (wdValue < (1 << 24))
 *                               wdIndex =6;
 *                       else
 *                               wdIndex =8;
 *                       }
 *               }
 *       }
 *
 *ptrAscStr[wdIndex--] =NULL;
 *while (wdIndex >=0)
 *       {
 *       wdTemp   = wdValue;
 *       wdTemp  &= 0x0f;
 *       wdValue>>= 4;
 *
 *       if (wdTemp >=0 && wdTemp < 10)
 *               ptrAscStr[wdIndex--] = wdTemp +'0';
 *       else
 *               {
 *               wdTemp -=10;
 *               ptrAscStr[wdIndex--] = wdTemp +'A';     
 *               }
 *       }
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_itoa
/*
 *****************************************************************
 *r0 = value
 *r1 = ptrString
 *r2 = scratch - index
 *r3 = scratch
 *r4 = 1
 *****************************************************************
 */
    .thumb_func
    tclib_itoa:
    push    {r0-r4, lr}

    mov     r4, #1
    mov     r3, r4, lsl #8              /*(wdValue< (1<<8))*/
    cmp     r0, r3
    itt     LO
    movlo   r2, #2
    blo     tclib_itoa_prep_loop

    mov     r3, r4, lsl #16             /*(wdValue< (1<<16))*/
    cmp     r0, r3
    itt     LO
    movlo   r2, #4
    blo     tclib_itoa_prep_loop

    mov     r3, r4, lsl #24             /*(wdValue< (1<<24))*/
    cmp     r0, r3
    ite     LO
    movlo   r2, #6
    movhs   r2, #8


    tclib_itoa_prep_loop:
    add     r1, r1, r2                  /*setup addresses*/
    mov     r3, #0
    strb    r3, [r1],#-1                /*nullify string*/


        tclib_itoa_loop:
        sub     r2, r2, #1              /*decrement counter*/
        cmp     r2, #0
        itt     LT
        poplt   {r0-r4, lr}             /*exit*/
        movlt   pc, lr                  /*exit*/

        mov     r3, r0                  /*save r0 temporarily*/
        mov     r0, r0, lsr #4          /*new value to work on*/
        and     r3, r3, #0x0f           /*nibble*/

        cmp     r3, #10                 /*prepare to adjust*/
        itee    LT
        addlt   r3, r3, #'0'
        subge   r3, r3, #10
        addge   r3, r3, #'A'
        
        strb    r3, [r1],#-1            /*store with auto-decr*/
        b       tclib_itoa_loop





/*
 *****************************************************************
 *description:  word swap
 *input:        int wdValue = value 
 *output:       int
 *int
 *tclib_word_swap(int wdValue)
 *{
 *unsigned int dwTemp;
 *
 *(dwTemp = 0;
 *dwTemp|= (wdValue << 24) & 0xff000000;
 *dwTemp|= (wdValue << 8 ) & 0x00ff0000;
 *dwTemp|= (wdValue >> 24) & 0x0ff;
 *dwTemp|= (wdValue >> 8 ) & 0x0ffff;
 *
 *return dwTemp;
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_swap
/*
 *****************************************************************
 *r0 = value
 *returns r0 = word swapped value
 *r1 = scratch
 *r2 = scratch
 *r3 = 0x0ff
 *****************************************************************
 */
    .thumb_func
    tclib_swap:
    push    {r1, lr}

    mov     r1, r0                      /*safe keep - r0 = return*/
    rev     r0, r1                      /*theres a single thumb ins*/
                                        /*for this now*/
    pop     {r1, lr}                    /*exit*/
    mov     pc, lr                      /*exit*/





/*
 *****************************************************************
 *description:  byte swap
 *input:        int wdValue = value 
 *output:       int
 *int
 *tclib_byte_swap(int wdValue)
 *{
 *unsigned int dwTemp;
 *
 *dwTemp = 0;
 *dwTemp|= (wdValue << 8 ) & 0xff00;
 *dwTemp|= (wdValue >> 8 ) & 0x0ff;
 *
 *return dwTemp;
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_bswap
/*
 *****************************************************************
 *r0 = value
 *returns r0 = byte swapped value
 *r1 = scratch
 *r2 = scratch old value
 *****************************************************************
 */
    .thumb_func
    tclib_bswap:
    push    {r1, lr}

    mov     r1, r0
    rev     r0, r1                          /*save original value*/
    mov     r0, r0, lsl #16

    pop     {r1, lr}                        /*exit*/
    mov     pc, lr                          /*exit*/
 




/*
 *****************************************************************
 *description:  string len computation function
 *inputs:       char *ptrStrSrc
 *output:       int  = lenght of string
 *int
 *tclib_strlen(unsigned char *ptrStrSrc)
 *{
 *unsigned int wdCount;
 *for (wdCount=0; ptrStrSrc[wdCount]!=NULL; wdCount++)
 *      ;
 *
 *return wdCount;
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_strlen
/*
 *****************************************************************
 *r0 = ptrString
 *returns r0 = byte length
 *r1 = ptrString
 *r2 = scratch
 *****************************************************************
 */
    .thumb_func
    tclib_strlen:
    push    {r1-r2, lr}

    mov     r1, r0                      /*put pointer in r1*/
    mov     r0, #0                      /*zero out r0*/


        tclib_strlen_loop:
        ldrb    r2, [r1], #1            
        andS    r2, r2, #0x0ff          /*clear lower bits*/
            
        itee    NE
        addne   r0, r0, #1              /*track strlen results*/

        popeq   {r1-r2, lr}             /*exit*/
        moveq   pc, lr                  /*exit*/

        b       tclib_strlen_loop              





/*
 *****************************************************************
 *description:  string comparison 
 *inputs:       char *ptrStrSrc=string 1
 *              char *ptrStrDst=string 2
 *              int  wdCount   =number of characters to compare 
 *output:       int = 0 on success failing index on error
 *int
 *tclib_strcmp(unsigned char *ptrStrSrc,\
 *             unsigned char *ptrStrDst,\
 *             int wdCount)
 *{
 *unsigned int wdIndex;
 *
 *for(wdIndex=0; wdIndex <wdCount; wdIndex++)
 *      {
 *      if (ptrStrSrc[wdIndex] == NULL || \
 *           ptrStrDst[wdIndex] == NULL || \
 *          (ptrStrSrc[wdIndex] - ptrStrDst[wdIndex]) !=0)
 *              return wdIndex;
 *      }
 *
 *return 0;          
 *}
 *****************************************************************
 */
    .align  2
    .global tclib_strcmp
/*
 *****************************************************************
 *r0 = ptrDst
 *r1 = ptrSrc
 *returns r0 strcmp value
 *r1 = src1
 *r2 = src2
 *r3 = scratch
 *r4 = scratch
 *r0 = cmp
 *****************************************************************
 */
    .thumb_func
    tclib_strcmp:
    push    {r1-r4, lr}

    mov     r2, r0                      /*save src1 in r2*/
    mov     r0, #0                      /*zero out r0*/


        tclib_strcmp_loop:
        ldrb    r3, [r1], #1            
        andS    r3, r3, #0x0ff          /*clear upper bits*/
        orrS    r3, r3, #0              /*end of string?*/
        beq     tclib_strcmp_exit

        ldrb    r4, [r2], #1
        andS    r4, r4, #0x0ff          /*clear upper bits*/
        orrS    r4, r4, #0              /*end of string?*/
        beq     tclib_strcmp_exit

        cmp     r4, r3
        it      EQ
        beq     tclib_strcmp_loop
                                        /*else*/
        ite     HI
        addhi   r0, r0, #1              /*track strcmp results*/
        subls   r0, r0, #1              /*ditto*/

        itt     NE
        popne   {r1-r4, lr}             /*exit*/
        movne   pc, lr                  /*exit*/
        
        
        tclib_strcmp_exit:
        itt     EQ
        popeq   {r1-r4, lr}             /*exit*/
        moveq   pc, lr                  /*exit*/

        b       tclib_strcmp_loop





    .end
#endif

Phase 1: Script files

$HOME/.gdbinit
set history filename ~/.gdb_history
set history save
set architecture arm
target remote localhost:3333
monitor reset halt 
 
 
 
$HOME/.bashrc
alias openocd_ft2232='sudo /usr/local/bin/openocd -s /home/rombios/DEVEL/EGWU/openocd/scripts -f interface/egwu_interface_usb.cfg -f board/egwu_board.cfg'
alias openocd_ftdi='sudo /usr/bin/openocd -s /home/rombios/DEVEL/EGWU/openocd/scripts -f interface/ftdi/egwu_interface_usb.cfg -f board/egwu_board.cfg' 
 
 
 
$HOME/DEVEL/EGWU/openocd/scripts/board
# egwu_board.cfg

set WORKAREASIZE 0x10000
source [find target/egwu_target_1788.cfg] 
 
 
  
$HOME/DEVEL/EGWU/openocd/scripts/interface
#
# embedded projects openocd usb adapter v3
#
# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14
#

#gdb_port        10000
interface  ft2232
ft2232_vid_pid  0x0403 0x6010
ft2232_device_desc "Dual RS232-HS"
ft2232_layout  "usbjtag"
ft2232_latency  2  
 
 
 
$HOME/DEVEL/EGWU/openocd/scripts/interface/ftdi
#
# embedded projects openocd usb adapter v3
#
# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14
#

interface   ftdi
ftdi_vid_pid   0x0403 0x6010
#ftdi_channel     0
ftdi_layout_init 0x1000 0x3d1b 
 
 
 
$HOME/DEVEL/EGWU/openocd/scripts/target
# egwu_target_1788.cfg

set CHIPNAME  lpc1788
set CPUTAPID  0x4ba00477
set CPURAMSIZE  0x10000
set CPUROMSIZE  0x80000

# CCLK is the core clock frequency in KHz

set CCLK 8000
source [find target/egwu_target_17xx.cfg];
cortex_m reset_config sysresetreq
 
 
 
# egwu_target_17xx.cfg

if { [info exists CHIPNAME] } {
 set _CHIPNAME $CHIPNAME
} else {
 error "_CHIPNAME not set. Please do not include lpc17xx.cfg directly, but the specific chip configuration file (lpc1751.cfg, lpc1764.cfg, etc)."
}

# After reset the chip is clocked by the ~4MHz internal RC oscillator.
# When board-specific code (reset-init handler or device firmware)
# configures another oscillator and/or PLL0, set CCLK to match; if
# you don't, then flash erase and write operations may misbehave.
# (The ROM code doing those updates cares about core clock speed...)
#
# CCLK is the core clock frequency in KHz
if { [info exists CCLK] } {
 set _CCLK $CCLK
} else {
 set _CCLK 12000
}

if { [info exists CPUTAPID] } {
 set _CPUTAPID $CPUTAPID
} else {
 error "_CPUTAPID not set. Please do not include lpc17xx.cfg directly, but the specific chip configuration file (lpc1751.cfg, lpc1764.cfg, etc)."
}

if { [info exists CPURAMSIZE] } {
  set _CPURAMSIZE $CPURAMSIZE
} else {
 error "_CPURAMSIZE not set. Please do not include lpc17xx.cfg directly, but the specific chip configuration file (lpc1751.cfg, lpc1764.cfg, etc)."
}

if { [info exists CPUROMSIZE] } {
  set _CPUROMSIZE $CPUROMSIZE
} else {
 error "_CPUROMSIZE not set. Please do not include lpc17xx.cfg directly, but the specific chip configuration file (lpc1751.cfg, lpc1764.cfg, etc)."
}

jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME

# The LPC17xx devices have 8/16/32kB of SRAM In the ARMv7-M "Code" area (at 0x10000000)
$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_CPURAMSIZE

# The LPC17xx devies have 32/64/128/256/512kB of flash memory, managed by ROM code
# (including a boot loader which verifies the flash exception table's checksum).
# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum]
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME lpc2000 0x0 $_CPUROMSIZE 0 0 $_TARGETNAME \
 lpc1700 $_CCLK calc_checksum

# Run with *real slow* clock by default since the
# boot rom could have been playing with the PLL, so
# we have no idea what clock the target is running at.
adapter_khz 2000
#adapter_khz 1000

# delays on reset lines
adapter_nsrst_assert_width 50
adapter_nsrst_delay  100

jtag_ntrst_assert_width  50
jtag_ntrst_delay   100

$_TARGETNAME configure -event reset-init {
 mww 0x400FC040 0x01
 mww 0xe000ed08 0x10000000
}

# perform a soft reset
#cortex_m reset_config sysresetreq
cortex_m reset_config trst_only
 
 
 
$HOME/DEVEL/EGWU/linker/IE_lpc17xx.ld
/*
 ***********************************************************************
 *name:         IE_lpc177x.ld
 *author:       Samuel Igwe
 *date:         06/10/2015
 *description:  linker script that I have created for use in egwu
 *              development related matters on this board
 *
 *  first this is the memory map I had decided on 
 *    
 *         0xa1ff ffff  +++++++++++++++++++++++++++++++
 *                  +ext sdram  = 64Mb            +
 *              0xa000 0000   +++++++++++++++++++++++++++++++
 *                 +                             +
 *         0x8001 ffff  +++++++++++++++++++++++++++++++
 *                  +ext sram   = 128k            +
 *              0x8000 0000   +++++++++++++++++++++++++++++++
 *                 +                             +
 *         0x1000 ffff  +++++++++++++++++++++++++++++++
 *                  +int sram   = 64k             +
 *              0x1000 0000   +++++++++++++++++++++++++++++++
 *                 +                             +
 *  0x0007 ffff  +++++++++++++++++++++++++++++++
 *                 +int flash  = 512k            +
 *  0x0000 0000  +++++++++++++++++++++++++++++++
 *
 *
 *              for now I will be debugging from SRAM until the code 
 *  matures
 *
 *  adding the variable _loadaddr_data_section_ to the end
 *  of the .text along with the AT> directive places a copy
 *  of the .data right after .text but leaves the virtual
 *  addresses pointing at .data in ram
 *  
 *  in the assembler initialization file I can copy .data 
 *  from bottom of .text into .data in sram
 ***********************************************************************
 */
MEMORY  {
        LPC177X_RAM    : ORIGIN = 0x10000000,   LENGTH = (64K - 1024)
        }



SECTIONS
        {
        .data :   
                {
                *(.data);
                } > LPC177X_RAM

        .text :   
  {
                *(.text);
                *(.rodata);
                } > LPC177X_RAM

        .bss :
                {
                *(.bss);
                } > LPC177X_RAM
        }




  
 

Phase 1: Makefile

########################################################################
#name:          Makefile
#description:   IgboEmbedded' EGWU Makefile
#date:          06/09/2015
#author:        Samuel Igwe
########################################################################

CC     = arm-linux-gnueabi-gcc
LD     = arm-linux-gnueabi-ld
OBJCPY = arm-linux-gnueabi-objcopy

AR     = arm-linux-gnueabi-ar
RM     = rm -f
MV     = mv -f


#CFLAGS = -g -c -Wall -nostdlib -mcpu=cortex-m3 -mlittle-endian -mthumb -mabi=atpcs -O0 -DDEBUG
CFLAGS = -g -c -Wall -nostdlib -mcpu=cortex-m3 -mlittle-endian -mthumb  -mabi=atpcs -DDEBUG -fno-inline\
         -fno-inline-small-functions -O0
LDFLAGS= -nostdlib -e main  -Map flash.map -L linker -T IE_lpc177x.ld --cref 
ARFLAGS= -r



all:
        make lpcopen.lib
        make egwu_core
        make egwu_app
        make clean


        
lpcopen.lib:
        $(CC)   $(CFLAGS) -DCORE_M3 -I lpcopen/include lpcopen/source/*.c
        $(AR)   $(ARFLAGS) lpcopen.lib *.o
        $(RM)   *.o



egwu_core:      
        $(CC)   $(CFLAGS)                                                -o ivt.o    core/IE_egwu_ivt.S
        $(CC)   $(CFLAGS) -DCORE_M3  -I core -I lpcopen/include -I tclib -o setup.o  core/IE_egwu_setup.c
        $(CC)   $(CFLAGS) -DCORE_M3  -I core -I lpcopen/include -I tclib -o uartio.o core/IE_egwu_uartio.c
        $(CC)   $(CFLAGS)                                       -I tclib -o tclib.o  tclib/IE_tclib.S
        


egwu_app:
        $(CC)   $(CFLAGS) -DCORE_M3  -I core -I lpcopen/include -I tclib -o main.o   app/main.c
        $(LD)   $(LDFLAGS)                                               -o app.out  ivt.o\
                                                                                     setup.o\
                                                                                     uartio.o\
                                                                                     tclib.o\
                                                                                     main.o\
                                                                                     lpcopen.lib


clean:
        $(RM)   *.o
        $(RM)   lpcopen.lib
     

binimage: 
        $(OBJCPY) -O binary flash.out flash.bin




Wednesday, March 18, 2015

EGWU arm-linux-gnueabi-gdb $HOME/.gdbinit

$HOME/.gdbinit
set history filename ~/.gdb_history
set history save
target remote localhost:3333
monitor reset halt



Decided to dump the CPUID register which should read back
0x412fc230 



arm-linux-gnueabi-gdb
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i486-linux-gnu --target=arm-linux-gnueabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
0x00000000 in ?? ()
JTAG tap: lpc1788.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)

target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc
(gdb)
(gdb) monitor reset halt
JTAG tap: lpc1788.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc
(gdb) monitor mdw 0xe000ed00
0xe000ed00: 412fc230
(gdb)

EGWU openocd 0.7.0 connection established

Finally!!!
So
sudo openocd -f interface/egwu_interface.cfg -f board/egwu_board.cfg


Open On-Chip Debugger 0.7.0 (2015-03-16-10:11)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter_nsrst_delay: 200
jtag_ntrst_delay: 200
adapter speed: 10 kHz
cortex_m3 reset_config vectreset
cortex_m3 reset_config sysresetreq
Info : max TCK change to: 30000 kHz
Info : clock speed 10 kHz
Info : JTAG tap: lpc1788.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : lpc1788.cpu: hardware has 6 breakpoints, 4 watchpoints

EGWU openocd 0.7.0 egwu_interface_usb.cfg

I grabbed the first fully assembled board from storage to test this morning and got the same results. very disheartening. I thought then I should focus on the ft2232_layout. I couldnt find "oocdlink" pin layouts in the first few google searches. But I found the one for "usbjtag" in the openocd thesis on www.openocd.org/files/thesis.pdf on page 6.

This of course matched the FTDI application note AN_129 (Interfacing FTDI USB Hi-Speed Devices to a JTAG TAP) which I based my design on.










cd /usr/local/share/openocd/scripts/interface
cp openocd-usb-hs.cfg egwu_interface_usb.cfg
change oocdlink to usbjtag below



#
# embedded projects openocd usb adapter v3
#
# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14
#

interface ft2232
ft2232_vid_pid 0x0403 0x6010
ft2232_device_desc "Dual RS232-HS"
ft2232_layout "usbjtag"
ft2232_latency 2