Friday, December 4, 2015

Phase 2: IE_egwu_monitor

/*
 *****************************************************************
 *name:         IE_egwu_monitor.h
 *author:       Samuel Igwe
 *date:         12/03/2015
 *description:  IE_egwu_monitor program/command interpreter header.
 *****************************************************************
 */
#ifndef IE_EGWU_MONITOR_H
#define IE_EGWU_MONITOR_H

    #include "chip.h"
    #include "chip_lpc177x_8x.h"
    #include "uart_17xx_40xx.h"
    #include "IE_egwu_uartio.h"


    /*
     *************************************************************
     *support variables
     *************************************************************
     */
    enum        {
        MON_ERROR_CMD=0,
        MON_ERROR_ADDRESS,
        MON_ERROR_TOKEN,
        MON_ERROR_COMMANDS};

    enum        {
        MON_CMD_GO=0,
        MON_CMD_HELP,
        MON_CMD_LDUSB,
        MON_CMD_LDXMODEM,
        MON_CMD_MDB,
        MON_CMD_MDH,
        MON_CMD_MDW,
        MON_CMD_MWB,
        MON_CMD_MWH,
        MON_CMD_MWW,
        MON_CMD_RESET,
        NUM_MONITOR_COMMANDS};


    union       UN_ADDR {
        volatile unsigned int   *ptrInt;
        volatile unsigned short *ptrShort;
        volatile unsigned char  *ptrChar;
        }unAddr;

        
    struct MONITOR_CMDLINE      {
        volatile int wdCmd;
        volatile int wdAddr;
        volatile int wdOpSize;
        volatile int wdVallen;
        }strCmdline;

        
    /*
     *************************************************************
     *routines
     *************************************************************
     */
    void monitor_assist_reset(struct MONITOR_CMDLINE *ptrStrCmdline);
    void monitor_assist_go(struct MONITOR_CMDLINE  *ptrStrCmdline);
    void monitor_assist_ldxmodem(struct MONITOR_CMDLINE  *ptrStrCmdline);
    void monitor_assist_ldusb(struct MONITOR_CMDLINE  *ptrStrCmdline);
    void monitor_assist_mwx(struct MONITOR_CMDLINE  *ptrStrCmdline);
    void monitor_assist_mdx(struct MONITOR_CMDLINE  *ptrStrCmdline);
    void monitor_assist_help(struct MONITOR_CMDLINE  *ptrStrCmdline);
    void monitor_execution(struct MONITOR_CMDLINE *ptrStrCmdline);
    void monitor_flag_error(int wdErrorNum);
    
    int  monitor_parse_cmdline(unsigned char *ptrCmdString, struct MONITOR_CMDLINE *ptrStrCmdline);
    int  monitor_get_next_token(unsigned char *ptrSrc, unsigned char *ptrDst, int DstSize);
    int  monitor_search_table(unsigned char *ptrString, char *ptrTable[], int wdSize);
  

#endif 
 
 
 
 
 
 
/*
 *****************************************************************
 *name:         IE_egwu_monitor.c
 *author:       Samuel Igwe
 *date:         12/03/2015
 *description:  monitor program/command interpreter and support 
 *              functions. 
 *****************************************************************
 */
#ifndef IE_EGWU_MONITOR_C
#define IE_EGWU_MONITOR_C

#include "IE_egwu_monitor.h"

    void (*ptrMonCmdFuncTable[NUM_MONITOR_COMMANDS])(struct \
                              MONITOR_CMDLINE *ptrStrCmdline) ={
        monitor_assist_go,
        monitor_assist_help,
        monitor_assist_ldusb,
        monitor_assist_ldxmodem,
        monitor_assist_mdx,
        monitor_assist_mdx,
        monitor_assist_mdx,
        monitor_assist_mwx,
        monitor_assist_mwx,
        monitor_assist_mwx,
        monitor_assist_reset};


    char *ptrMonErrorStrings[] = {
        "\r\ncommand error",
        "\r\ninvalid or non existent address",
        "\r\ntoken error"};


    char *ptrMonCmdStrings[] = {
        "go",
        "help",
        "ldusb",
        "ldxmodem",
        "mdb",
        "mdh",
        "mdw",
        "mwb",
        "mwh",
        "mww",
        "reset"};


    char *ptrBanner = {
       "\r\n..ie........\
        \r\n..ieieie....\
        \r\n..ie........\
        \r\n..ieieie....\
        \r\n..ie........\tIgbo Embedded\
        \r\n..ieieie....\tEGWU v1,1 (c) 2015\
        \r\n..ie........\tSamuel Igwe\n\n"};


    char *ptrPrompt = "\r\negwu-> ";


    char *ptrMonUsage = {
        "\r\ngo address           :\t jump to address\
         \r\nldusb address        :\t load file to address using USB\
         \r\nldxmodem address     :\t load file to address using xmodem+serial port\
         \r\nhelp                 :\t display command table\
         \r\nmdb|mdh|mdw addr len :\t display byte|word|dword at address\
         \r\nmwb|mwh|mww addr val :\t write byte|word|dword to address\
         \r\nreset                :\t reset the lpc1778\n\n"};



/*
 *****************************************************************
 *description:  monitor executioner
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *note:         clear screen
 *              print banner
 *              loop:
 *                      get string
 *                      call monitor_parse_string()
 *                      check result != -1
 *                      take action
 *                      loop loop
 *............
 *..ie........
 *..ieieie....
 *..ie........
 *..ieieie....
 *..ie........
 *..ie........
 *..ieieie....
 *..ie........
 *............
 *****************************************************************
 */
void
monitor_execution(struct MONITOR_CMDLINE *ptrStrCmdline)
{
    volatile unsigned int wdTemp;
    unsigned char     sbTemp[80+1];


    uartio_printf("%s", (unsigned int)ptrBanner);
    while(1)
        {
        tclib_memset((unsigned char *)ptrStrCmdline, 0, sizeof(struct MONITOR_CMDLINE));
        uartio_printf("%s", (unsigned int)ptrPrompt);

        if((uartio_gets((char *)sbTemp, 80)) < 4)
                continue;

        wdTemp = monitor_parse_cmdline(sbTemp, ptrStrCmdline);
        if(wdTemp >= MON_CMD_GO && wdTemp <= MON_CMD_RESET)
                ptrMonCmdFuncTable[wdTemp](ptrStrCmdline);
        }       


     
    
}
 



/*
 *****************************************************************
 *description:  "reset" command
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *****************************************************************
 */
void
monitor_assist_reset(struct MONITOR_CMDLINE *ptrStrCmdline)
{
    uartio_printf("\n\rpreparing to reset board \n", 0);
    timer_delay_mS(1000);
    /*NVIC_SystemReset();
      asm ("ldr r0, =0x10000004");
      asm ("mov pc, [r0]"); Error: r15 not allowed here -- `mov pc,[r0]'
      */

    /*do something with a register write to the FPGA that resets the
      entire system ... although this is only useful for rom code
      for now just jump to main*/ 

      main();
}
 




/*
 *****************************************************************
 *description:  "go" command
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *****************************************************************
 */
void
monitor_assist_go(struct MONITOR_CMDLINE *ptrStrCmdline)
{
    unsigned int wdTemp = ptrStrCmdline->wdAddr;
    
    uartio_printf("preparing to jump to address %x\n", wdTemp);
    timer_delay_mS(1000);

//    asm ("ldr r0, =wdTemp");
    asm ("ldr sp, =0x10010000");
    asm ("mov pc, r0");

}





/*
 *****************************************************************
 *description:  "ldxmodem" command
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *****************************************************************
 */
void
monitor_assist_ldxmodem(struct MONITOR_CMDLINE *ptrStrCmdline)
{
}





/*
 *****************************************************************
 *description:  "ldusb" command
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *****************************************************************
 */
void
monitor_assist_ldusb(struct MONITOR_CMDLINE *ptrStrCmdline)
{
}





/*
 *****************************************************************
 *description:  "mwb/mwh/mww" commands
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *****************************************************************
 */
void
monitor_assist_mwx(struct MONITOR_CMDLINE *ptrStrCmdline)
{
    unsigned int wdTemp;
    union    UN_ADDR *ptrAddr = &unAddr;

    ptrAddr->ptrInt = (volatile unsigned int *)ptrStrCmdline->wdAddr;
    if(ptrStrCmdline->wdOpSize == 1)
        {
        *ptrAddr->ptrChar = ptrStrCmdline->wdVallen;
        wdTemp = *ptrAddr->ptrChar;
        }
    else
        {
        if(ptrStrCmdline->wdOpSize == 2)
                {
                *ptrAddr->ptrShort = ptrStrCmdline->wdVallen;
                wdTemp = *ptrAddr->ptrShort;
                }
        else
                {
                *ptrAddr->ptrInt = ptrStrCmdline->wdVallen;
                wdTemp = *ptrAddr->ptrInt;
                }
        }

        uartio_printf("\n\r%x", wdTemp);
}





/*
 *****************************************************************
 *description:  "mdb/mdh/mdw" commands
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *****************************************************************
 */
void
monitor_assist_mdx(struct MONITOR_CMDLINE *ptrStrCmdline)
{
    volatile unsigned int wdRow, wdMaxRow, wdTemp, wdValPerRow = 8;
    volatile unsigned int wdCol, wdMaxCol, wdLastCol;
    volatile union    UN_ADDR *ptrAddr = &unAddr;


    if(ptrStrCmdline->wdAddr== 0)
        {
        monitor_flag_error(MON_ERROR_ADDRESS);
        return;
        }
    else
        ptrAddr->ptrInt = (volatile unsigned int *)ptrStrCmdline->wdAddr;

     
    if(ptrStrCmdline->wdVallen == 0)
        ptrStrCmdline->wdVallen++;

    wdMaxRow = (ptrStrCmdline->wdVallen)/wdValPerRow;
    if(wdMaxRow == 0)
        wdMaxRow++;

    wdLastCol= (ptrStrCmdline->wdVallen)%16;

    for(wdRow = 0; wdRow < wdMaxRow; wdRow++)
        {
        uartio_printf("\r\n%x:\t", (unsigned int)ptrAddr->ptrInt);

        if(wdRow == (wdMaxRow - 1))
                wdMaxCol = wdLastCol;
        else
                wdMaxCol = wdValPerRow;

        for(wdCol = 0; wdCol < wdMaxCol; wdCol++)
                {
                if(ptrStrCmdline->wdOpSize == 1)
                        {
                        wdTemp = *ptrAddr->ptrChar;
                        ptrAddr->ptrChar++;
                        wdTemp &= 0x0ff;
                        }
                else
                        {
                        if(ptrStrCmdline->wdOpSize == 2)
                                {
                                wdTemp = *ptrAddr->ptrShort;
                                ptrAddr->ptrShort++;
                                wdTemp &= 0x0ffff;
                                }
                        else
                                {
                                wdTemp = *ptrAddr->ptrInt;
                                ptrAddr->ptrInt++;
                                }
                        }


                switch(ptrStrCmdline->wdOpSize)
                        {
                        case    4:
                                {
                                uartio_printf("%x", ((wdTemp >> 24)&0x0ff));
                                uartio_printf("%x", ((wdTemp >> 16)&0x0ff));
                                wdTemp &= 0x0ffff;
                                /*slide down to code below*/
                                }
                        case    2:
                                {
                                uartio_printf("%x", ((wdTemp >>  8)&0x0ff));
                                wdTemp &= 0x0ff;
                                /*slide down to code below*/
                                }
                        case    1:
                                {
                                uartio_printf("%x  ",(wdTemp));
                                break;
                                }
                        default:
                                {
                                }
                        }
                }

        }

        uartio_printf("\n", 0);
}





/*
 *****************************************************************
 *description:  "help" command
 *inputs:       struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *****************************************************************
 */
void
monitor_assist_help(struct MONITOR_CMDLINE *ptrStrCmdline)
{
    uartio_printf("%s", (unsigned int)ptrMonUsage);
}





/*
 *****************************************************************
 *description:  command line parsing routine
 *inputs:       char   *ptrString     = pointer to input string
 *              struct MONITOR_CMDLINE *ptrStrCmdline = pointer to
 *                                      cmdline structure
 *output:       int                   = 0 on success 
 *****************************************************************
 */
int
monitor_parse_cmdline(unsigned char   *ptrString,\
                      struct MONITOR_CMDLINE *ptrStrCmdline)
{
    int  wdTemp, wdArgCnt = 0;
    unsigned char sbToken[80+1];


    tclib_memset((unsigned char *)ptrStrCmdline, 0, sizeof(struct MONITOR_CMDLINE));
    ptrStrCmdline->wdCmd = -1;          /*0 is a valid cmd index*/

    while(1)
        {
        if((wdTemp = monitor_get_next_token(ptrString, sbToken, 80))  == 0)
                return (ptrStrCmdline->wdCmd);
                
        wdArgCnt++;
        switch(wdArgCnt)
                {
                case    1:      /*command*/
                        {
                        if((wdTemp = monitor_search_table(sbToken, ptrMonCmdStrings, NUM_MONITOR_COMMANDS)) == -1)
                                {
                                monitor_flag_error(MON_ERROR_CMD);
                                return -1;
                                }
                
                        ptrStrCmdline->wdCmd = wdTemp;
                        switch(wdTemp)
                                {
                                case    MON_CMD_HELP:
                                case    MON_CMD_RESET:
                                        {
                                        ptrStrCmdline->wdOpSize = 0;
                                        break;
                                        }
                                case    MON_CMD_MDB:
                                case    MON_CMD_MWB:
                                        {
                                        ptrStrCmdline->wdOpSize = 1;
                                        break;
                                        }
                                case    MON_CMD_MDH:
                                case    MON_CMD_MWH:
                                        {
                                        ptrStrCmdline->wdOpSize = 2;
                                        break;
                                        }
                                case    MON_CMD_MDW:
                                case    MON_CMD_MWW:
                                case    MON_CMD_GO:
                                case    MON_CMD_LDXMODEM:
                                case    MON_CMD_LDUSB:
                                default:
                                        {
                                        ptrStrCmdline->wdOpSize = 4;
                                        break;
                                        }
                                }
                        break;
                        }
                case 2:                 /*address*/
                        {
                        if(sbToken[1] == 'x' || sbToken[1] == 'X')
                                ptrStrCmdline->wdAddr = tclib_atoi(sbToken+2);
                        else
                                ptrStrCmdline->wdAddr = tclib_atoi(sbToken);
                        break;
                        }
                case 3:                 /*value or length*/
                        {
                        if(sbToken[1] == 'x' || sbToken[1] == 'X')
                                ptrStrCmdline->wdVallen = tclib_atoi(sbToken+2);
                        else
                                ptrStrCmdline->wdVallen = tclib_atoi(sbToken);
                        break;
                        }
                default:
                        {
                        monitor_flag_error(MON_ERROR_TOKEN);
                        return -1;
                        }
                }
        }

    if(wdArgCnt < 4)
        return ptrStrCmdline->wdCmd;
    else
        return -1;
}





/*
 *****************************************************************
 *description:  token extraction routine
 *inputs:       char *ptrSrc  = pointer to input string
 *              char *ptrDst  = pointer to destination buffer
 *              int   wdSize  = size of destination buffer
 *output:       int           = string length on success or 0
 *operation:    a) scan through ptrSrc extracting a string
 *              b) see a non space char extract into ptrDst and
 *                 replace with space (convert to lower)
 *              c) when space or NULL is encountered exit
 *              d) return 0 on error or string lenght on success
 *****************************************************************
 */
int
monitor_get_next_token(unsigned char *ptrSrc,\
                       unsigned char *ptrDst,\
                       int   wdSize)
{
    int  wdCount;
    char byValue;
    while(((*ptrSrc) != 0) && (*(ptrSrc) == ' '))
        ptrSrc++;

    if((*ptrSrc) == 0)
        return 0;

    //for(wdCount = 0; ((*ptrSrc) != 0 && (*ptrSrc) != ' '); wdCount++)
    for(wdCount = 0; wdCount <wdSize; wdCount++)
        {
        if((*ptrSrc) == 0 || (*ptrSrc) == ' ')
                break;

        byValue = (*ptrSrc);
        *(ptrSrc++) = ' ';

        if(byValue >='A' && byValue <='Z')
                {
                byValue  =('Z'- byValue);
                byValue += 'a';
                }

        *(ptrDst++) = byValue;
        }

    (*ptrDst) = 0;

    return wdCount;
}





/*
 *****************************************************************
 *description:  error routine
 *inputs:       int wdErrorNum = index into error table
 *****************************************************************
 */
void
monitor_flag_error(int wdErrorNum)
{
    unsigned int wdAddr;

    if(wdErrorNum >= MON_ERROR_COMMANDS)
        return;
    else
        wdAddr = (unsigned int)ptrMonErrorStrings[wdErrorNum];

    uartio_printf("%s\n", wdAddr);
}





/*
 *****************************************************************
 *description:  table search routine 
 *inputs:       char *ptrString  = pointer to input string
 *              char *ptrTable[] = pointer to MonCmdStrings table
 *              int   wdSize     = NUM_MONITOR_COMMANDS
 *output:       int              = enum index into *ptrMonCmdStrings
 *****************************************************************
 */
int
monitor_search_table(unsigned char *ptrString,\
                     char *ptrTable[],\
                     int   wdSize)
{
    short wdTop    = wdSize - 1;
    short wdMiddle = 0;
    short wdBottom = 0;
    short wdResult = 0;

    while(wdBottom <= wdTop)
        {
        wdMiddle   = (wdTop + wdBottom);
        wdMiddle >>= 1;
        wdResult = tclib_strcmp(ptrString, (unsigned char *)ptrTable[wdMiddle]);
        if(wdResult == 0)
                return wdMiddle;

        if(wdResult < 0)
                wdTop = (wdMiddle - 1);
        else
                wdBottom = (wdMiddle + 1);
        }

    return -1;
}



#endif
 

No comments:

Post a Comment