Monday, November 11, 2013

peekstm32.c

/*
 ***********************************************************************
 *name:         peekstm32
 *author:       Samuel Igwe
 *date:         11/11/2013 A.D
 *description:  stm32 host to usb peek and poke routine. 
 *note:         peekstm32 address               = read address
 *              peekstm32 address  value        = write value to address
 *compiled as:  gcc -o peekstm32.out -lusb-1.0  linux/peekstm32.c
 ***********************************************************************
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>



/*#define constants*/
#define STMUSB_VENDOR_ID                                0xc0de
#define STMUSB_PRODUCT_ID                               0xfeed

#define STMUSB_BULK_ENDP_OUT                            0x1
#define STMUSB_BULK_ENDP_IN                             0x81

#define STMUSB_CMD_PEEK                                 0
#define STMUSB_CMD_POKE                                 1

#define STMUSB_TIMEOUT                                  1000



/*structure*/
struct  STR_PEEKSTM32
        {
        unsigned int                    wdAddress;
        unsigned int                    wdValue;
        unsigned int                    wdMaxPktSize;
        
        struct  libusb_device_handle    *ptrHandle;
        struct  libusb_device           *ptrDevice;

        }strPeekStm32;



void    func_atexit(void);



/*
 ***********************************************************************
 *description:  main routine    
 *inputs:       int     argc    = count
 *              char    *argv[] = pointer to command line parameters
 ***********************************************************************
 */
main(int argc, char *argv[])
{
unsigned int    wdCount, wdTemp;
         char   sbBuffer[64];
/*
 ***********************************************************************
 *check commandline parameters
 ***********************************************************************
 */
memset(&strPeekStm32, 0, sizeof(strPeekStm32));
switch(argc)
        {
        case    2:
        case    3:
                {
                strPeekStm32.wdAddress = \
                (unsigned int)strtol(argv[1], (char **)NULL, 16);
                if(argc == 3)
                        {
                        strPeekStm32.wdValue = \
                        (unsigned int)strtol(argv[2], (char **)NULL, 16);
                        }

                break;
                }
        default:
        case    0:
        case    1:
                {
                printf("[peekstm32]\toptions\n\t\tadddress value[optional]\n");
                return 0;
                }
        }



/*
 ***********************************************************************
 *initialize variables and atexit routine
 ***********************************************************************
 */
if(atexit(func_atexit) != 0)
        {
        printf("[peekstm32]\tatexit() failed\n");
        return 0;
        }       



/*
 ***********************************************************************
 *initialize library
 ***********************************************************************
 */
if((wdTemp = libusb_init(NULL)) != 0)
        {
        printf("[peekstm32]\tlibusb_init() failed with %d\n",\
               wdTemp);
        return 0;
        }

if((strPeekStm32.ptrHandle=libusb_open_device_with_vid_pid(NULL,\
                                   STMUSB_VENDOR_ID,\
                                   STMUSB_PRODUCT_ID)) == NULL)
        {
        printf("[peekstm32]\tlibusb_open_device_vid_pid() failed\n");
        return 0;
        }

if((strPeekStm32.ptrDevice = libusb_get_device(strPeekStm32.ptrHandle)) == NULL)
        {
        printf("[peekstm32]\tlibusb_get_device() failed\n");
        return 0;
        }

if((wdTemp = libusb_kernel_driver_active(strPeekStm32.ptrHandle, 0)) !=0)
        {
        if((wdTemp = libusb_detach_kernel_driver(strPeekStm32.ptrHandle, 0)) !=0)
                {
                printf("[peekstm32]\tlibusb_detach_kernel_driver() failed with %d\n",\
                       wdTemp);
                return 0;
                }
        }
else
        {
        if((wdTemp = libusb_claim_interface(strPeekStm32.ptrHandle, 0)) != 0)
                {
                printf("[peekstm32]\tlibusb_claim_interface() failed with %d\n",\
                       wdTemp);
                return 0;
                }
        }



/*
 ***********************************************************************
 *get usb resources limits
 ***********************************************************************
 */
strPeekStm32.wdMaxPktSize = 0;
for(wdCount=0; wdCount < 16; wdCount++)
        {
        wdTemp = libusb_get_max_packet_size(strPeekStm32.ptrDevice, wdCount);
        if(wdTemp != LIBUSB_ERROR_NOT_FOUND && wdTemp != LIBUSB_ERROR_OTHER)
                strPeekStm32.wdMaxPktSize = wdTemp;
        }


if(strPeekStm32.wdMaxPktSize <8)
        {
        printf("[peekstm32]\tlibusb_get_max_packet_size() failed to return adequate value\n");
        return;
        }



/*
 ***********************************************************************
 *execute OUT transaction:COMMAND format is as follows:
 *      byte    0       = command
 *      byte    1       = length of data in bytes
 *      byte    2       = 0xed
 *      byte    3       = 0xfe
 *      byte    4       = 32bit address
 *      byte    5       = 
 *      byte    6       = 
 *      byte    7       = 
 ***********************************************************************
 */
if(argc == 2)                                   /*IN*/
        {
        sbBuffer[0] = STMUSB_CMD_PEEK;
        sbBuffer[1] = 8;                        /*8*/ 
        }
else
        {
        sbBuffer[0] = STMUSB_CMD_POKE;
        sbBuffer[1] = 12;                       /*8 + 4 byte (dword)value*/
        }
sbBuffer[2] = 0xed;
sbBuffer[3] = 0xfe;
memcpy(sbBuffer+4, &strPeekStm32.wdAddress, sizeof(int));

wdTemp = libusb_bulk_transfer(strPeekStm32.ptrHandle,\
                              STMUSB_BULK_ENDP_OUT,\
                              sbBuffer,\
                              8,\
                              &wdCount,\
                              STMUSB_TIMEOUT);
if(wdTemp != 0)
        {
        printf("[peekstm32]\tlibusb_bulk_transfer() command failed with %d\n",\
               wdTemp);
        return 0;
        }



/*
 ***********************************************************************
 *execute IN or OUT transaction depending on whether PEEK or POKE sought
 ***********************************************************************
 */
if(argc == 2)                                   /*IN*/
        {
        if((wdTemp =libusb_bulk_transfer(strPeekStm32.ptrHandle,\
                                STMUSB_BULK_ENDP_IN,\
                                (char *)&(strPeekStm32.wdValue),\
                                4,\
                                &wdCount,\
                                STMUSB_TIMEOUT)) != 0)
                {
                if(wdCount == 0)
                        {
                        printf("[peekstm32]\tlibusb_bulk_transfer() data failed with %d\n",\
                               wdTemp);
                        return 0;
                        }
                }

        printf("[%x] = %x\n", strPeekStm32.wdAddress,\
                              strPeekStm32.wdValue);
        return 0;
        }
else                                            /*OUT*/
        {
        memcpy(sbBuffer, &strPeekStm32.wdValue, sizeof(int));
        if((wdTemp = libusb_bulk_transfer(strPeekStm32.ptrHandle,\
                                STMUSB_BULK_ENDP_OUT,\
                                (char *)&(strPeekStm32.wdValue),\
                                4,\
                                &wdCount,\
                                STMUSB_TIMEOUT)) != 0)
                {
                printf("[peekstm32]\tlibusb_bulk_transfer() data failed with %d\n",\
                       wdTemp);
                return 0;
                }
        }



/*
 ***********************************************************************
 *atexit
 ***********************************************************************
 */
return 0;
}





/*
 ***********************************************************************
 *description:  at exit routine
 ***********************************************************************
 */
void    func_atexit(void)
{
if(strPeekStm32.ptrHandle != NULL)
        {
        libusb_release_interface(strPeekStm32.ptrHandle, 0);
        libusb_close(strPeekStm32.ptrHandle);
        }

return;
}






No comments:

Post a Comment