VAPI API Reference Documentation
2.18.x

vapi_diag_tool.c shows how to use the Diagtool firmware APIs to test the SDRAM.

/*
        This application shows how to use the Diagtool firmware API to test the SDRAM.

        command line to compile the application under Linux
        gcc -Wall vapi_diag_tool.c -I /usr/local/include -L /usr/local/lib -lvapi -lpthread -lgtlcommon -lgtlcsme -o vapi_diag_tool


        Some notes about using this application under the Linux:
        It requires VAPI to be built with this options :
                - make GTL=CSME install

        the example usage is:
        ./vapi_diag_tool -f diagtool-1.30.axf
*/


#include <argp.h>
#include <vapi/vapi.h>
#include <vapi/msp.h>
#include <vapi/gtl.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define DEVICE_CONTROL_MAC              {0x00,0x11,0x22,0x33,0xa5,0x52}
#define HOST_CONTROL_INTERFACE          "eth0"
#define HOST_CONTROL_MAC                {0x00,0x11,0xD8,0xe7,0xa5,0x52}

#define check_status(title, error_label)                                        \
        PDEBUG(DEBUG_ERROR, title ": %s", result == SUCCESS?"ok":"failed");     \
        if (result != SUCCESS)                                                  \
                goto error_label

#define info(fmt, args...)              fprintf(stderr, __FILE__ ": " fmt "\n", ## args)
#define PDEBUG(type, fmt, args...)      do { if (type) info("%d: " fmt, __LINE__ , ## args); } while(0)

#define DEBUG_INIT              1
#define DEBUG_FUNCTION          0
#define DEBUG_ERROR             1

/* Some Memory Test DDI Commands */
#define FC_DDI_GET_VERSION      0x0101
#define FC_DDI_MEM_ADDRBUS      0x0201
#define FC_DDI_MEM_DATABUS      0x0202
#define FC_DDI_MEM_ZERO         0x0203
#define FC_DDI_MEM_ONES         0x0204
#define FC_DDI_MEM_WONE8        0x0205
#define FC_DDI_MEM_WONEP8       0x0206
#define FC_DDI_MEM_WONE32       0x0207
#define FC_DDI_MEM_WONEP32      0x0208
#define FC_DDI_MEM_OWNA         0x0209
#define FC_DDI_MEM_FADE         0x020A
#define FC_DDI_MEM_PATTERN      0x020B
#define FC_DDI_MEM_SCOPE        0x020C
#define FC_DDI_TEST_TERMINATE   0x01FF

/* State definition used in the ddi_state_machine */
#define WAIT_DDI_MEM_ADDRBUS    0x0201
#define WAIT_DDI_MEM_DATABUS    0x0202
#define WAIT_DDI_MEM_ZERO       0x0203
#define WAIT_DDI_MEM_ONES       0x0204
#define WAIT_DDI_MEM_WONE8      0x0205
#define WAIT_DDI_MEM_WONEP8     0x0206
#define WAIT_DDI_MEM_WONE32     0x0207
#define WAIT_DDI_MEM_WONEP32    0x0208
#define WAIT_DDI_MEM_OWNA       0x0209
#define WAIT_DDI_MEM_FADE       0x020A
#define WAIT_DDI_MEM_PATTERN    0x020B
#define WAIT_DDI_MEM_SCOPE      0x020C

/* Memory Test payloads */
/* SDRAM Address Bus Test */
U16 addr_bus_param [4] = {0x8000,0x0000,0x1000,0x0010};
/* SDRAM Data Bus Test */
U16 data_bus_param [2] = {0x8000,0x0000};
/* SDRAM All Zeroes Test */
U16 all_zero_param [4] = {0x8000,0x0000,0x1000,0x0010};
/* SDRAM All Ones Test */
U16 all_ones_param [4] = {0x8000,0x0000,0x1000,0x0010};
/* SDRAM Walking Ones 8bit Test */
U16 ones_8bit_param [6] = {0x8000,0x0000,0x1000,0x0000,0x0001,0x0000};
/* SDRAM Walking Ones Pairs 8bit Test */
U16 ones_pair_8bit_param [5] = {0x8000,0x0000,0x1000,0x0000,0x0001};
/* SDRAM Walking Ones 32bit Test */
U16 ones_32bit_param [5] = {0x8000,0x0000,0x1000,0x0000,0x0000};
/* SDRAM Walking Ones Pairs 32bit Test */
U16 ones_pair_32bit_param [5] = {0x8000,0x0000,0x1000,0x0000,0x0000};
/* SDRAM Own Address Test */
U16 own_addr_param [4] = {0x8000,0x0000,0x1000,0x0000};
/* SDRAM Bit Fade Test */
U16 bit_fade_param [5] = {0x8000,0x0000,0x1000,0x0000,0x0001};
/* SDRAM Data Patern Test */
U16 data_pattern_param [6] = {0x8000,0x0000,0x1000,0x0000,0x1234,0xABCD};
/* SDRAM Scope Loop Test (2s timeout) */
U16 scope_param [6] = {0x8000,0x0000,0x1234,0xABCD,0x0002,0x0000};

static U16 device_id;
static char firmware[256];
static U16 ddi_state = 0;
static U16 ddi_event = 0;

const char *argp_program_version = "vapi_diag_tool 0.1";
const char *argp_program_bug_address = "philippe.vivarelli@mindspeed.com";
const char doc[] = "vapi_diag_tool - program to run Diagtool memory test using the VAPI library.";

/*GTL configuration */
SCSMEUsrData default_device_configuration = {
        NULL,                           /* pointer to next device */
        eCSM_ITF,                       /* control interface to use */
        0,                              /* device ID */
        0,                              /* Version infor (not used) */
        eSLAVE,                         /* Slave / Master mode */
        DEV_TYPE_M827XX,                /* Device type */
        True,                           /* Default or custom max channels */
        0,                              /* Max Channels if above flag is custom */
        DEVICE_CONTROL_MAC,             /* MAC address for control over csmencaps */
        {0x00,0x00,0x00,0x00,0x00,0x00}, /* Control Mac address interface. It is filled by the UT_GetInterfaceMac()
                                        In master mode this MAC is the eth1 MAC*/
        (char *)HOST_CONTROL_INTERFACE, /* host interface used to control the device */
        1                               /* csme ack required */
};

const struct argp_option options[] = {
        {"firmware", 'f', "FIRMWARE_FILE", 0, "firmware code filename (this option assumes slave mode)"},
        {0}
};

/*=================================================================================
 * This function reads the firmware (.axf or .elf) and store it to a buffer.
 =================================================================================*/
static int comcerto_read_firmware_file(char *filename, unsigned char **buf, int *size)
{
        FILE *fp;

        PDEBUG(DEBUG_FUNCTION, "trying to load '%s'", filename);
        fp = fopen(filename, "r");

        if (fp == NULL)
        {
                perror(filename);
                goto err0;
        }

        /* Figure out how big the size of the file and allocate that much space in memory */
        fseek(fp, 0, SEEK_END);
        *size = ftell(fp);

        *buf = (unsigned char *)malloc(*size);
        if (*buf == NULL)
        {
                PDEBUG(DEBUG_ERROR, "can't allocate memory");
                goto err1;
        }

        fseek(fp, 0, SEEK_SET);

        if (fread(*buf, sizeof(unsigned char), *size, fp) != *size)
        {
                PDEBUG(DEBUG_ERROR, "error reading '%s'", filename);
                goto err2;
        }

        fclose(fp);

        return 0;

      err2:
        free(*buf);

      err1:
        fclose(fp);

      err0:
        return -1;
}

/*=================================================================================
 *      This function boots the device by calling:
 *              - comcerto_read_firmware_file to read the firmware file
 *              - VAPI_AssignBootMAC
 *              - VAPI_BootDevice
 =================================================================================*/
int boot_device(U16 device_id, const char *firmware)
{
        int result;
        unsigned char *firmware_buf = NULL;
        int firmware_size;

        /* firmware filename comes from the -f option */
        result = comcerto_read_firmware_file((char *)firmware, &firmware_buf, &firmware_size);
        if (result)
                goto err0;

        info("firmware: '%s', size: %d", firmware, firmware_size);

        if (firmware_size > 0 && firmware_buf != NULL)
        {
                /* the device_id comes from the -d option */
                result = VAPI_AssignBootMAC(device_id, NULL);
                if (result != SUCCESS)
                {
                        PDEBUG(DEBUG_ERROR, "VAPI_AssignBootMAC failed, status: %d", result);
                        goto err1;
                }
                
#if VAPI_RELEASE >= (VAPI_VERSION(2, 6, 0))
                result = VAPI_BootDevice(device_id, firmware_buf, firmware_size, NULL, NULL);
#else
                result = VAPI_BootDevice(device_id, firmware_buf, firmware_size, NULL);
#endif
                if (result != SUCCESS)
                {
                        PDEBUG(DEBUG_ERROR, "VAPI_BootDevice failed, status: %d", result);
                        goto err1;
                }
        }

        if (firmware_buf)
                free(firmware_buf);

        return 0;

      err1:
        if (firmware_buf)
                free(firmware_buf);
      err0:
        return -1;
}

/*=================================================================================
 *      This function handles indications from the Comcerto device.\n
 *      This function is registered as call back for event.\n
 *      
 *      This function is called by VAPI every time a event occurs on the Comcerto device.\n
 =================================================================================*/
void comcerto_indication_handler(EEventCode eEventCode, void *pvData)
{
        SUndefinedEventParams *this_event;
        U32 test_result;

        /* FIXME: The parser below need to be improved */

        switch (eEventCode)
        {
        case eVAPI_TONE_DETECT_EVENT:
        case eVAPI_SSRC_CHANGE_EVENT:
        case eVAPI_SPI_EVENT:
        case eVAPI_TONE_GEN_CMPLT_EVENT:
        case eVAPI_PT_CHANGE_EVENT:
        case eVAPI_SSRC_VIOLATION_EVENT:
        case eVAPI_NTE_TRANSMIT_COMPLETE_EVENT:
        case eVAPI_NTE_RECVD_EVENT:
        case eVAPI_CALLER_ID_CMPLT_EVENT:
        case eVAPI_G711_CONCURRENT_DECODER_EVENT:
        case eVAPI_PASSTHRU_CONCURRENT_DECODER_EVENT:
        case eVAPI_CALLER_ID_DETECTED_EVENT:
        case eVAPI_REMOTE_DETECT_EVENT:
        case eVAPI_FAX_SWITCH_CMPLT_EVENT:
        case eVAPI_ALERT_IND:
                break;

        case eVAPI_UNDEFINED_EVENT:
                PDEBUG(DEBUG_INIT, "event %d received", eEventCode);
                this_event = (SUndefinedEventParams *) pvData;

                if (this_event->ucCmdType == CMD_TYPE_INDICATION)
                {
                        PDEBUG(DEBUG_INIT, "indication 0x%04x received", this_event->usFnCode);
                        ddi_event = this_event->usFnCode;

                        test_result = *((U32*)(&this_event->ausParams[1]));

                        /* The DDI_MEM_SCOPE is stopped by DDI_TEST_TERMINATE
                        the low 16bits are set to 0xffff, mask them*/
                        if(this_event->usFnCode == FC_DDI_MEM_SCOPE)
                                test_result &= 0xFFFF0000;

                        if(test_result == 0)
                                PDEBUG(DEBUG_INIT, "Test 0x%04x successfuly passed", this_event->usFnCode);
                        else
                                PDEBUG(DEBUG_INIT, "Test 0x%04x failed", this_event->usFnCode);

                }

                break;
        default:
                break;
        }

        return;
}



/*=================================================================================
        command line option parser
=================================================================================*/
static error_t parser(int key, char *arg, struct argp_state *state)
{
        switch (key)
        {

        case 'f':
                strncpy(firmware, arg, sizeof(firmware) - 1);
                break;

        default:
                return ARGP_ERR_UNKNOWN;
        }

        return 0;
}
static struct argp argp = { options, parser, 0, doc, };


/*=================================================================================
        This function builds and send a DDI command using the function code 
        and the parameters passed
=================================================================================*/
VSTATUS send_ddi_msg(U16 fucntion_code, U16 num_param, U16 *params)
{
        void *message;
        U32 response_len = DEFAULT_FIFO_MAX_SIZE;
        U8 device_response [DEFAULT_FIFO_MAX_SIZE];
        VSTATUS result;

        /* allocate a message to build commands */
        message = VAPI_AllocateMessage(DEFAULT_FIFO_MAX_SIZE);
        if (message == NULL)
                return VAPI_ERR_NOMEM;

        if (num_param == 0)
                result = VAPI_SetMessage(message, CMD_CLASS_DIAG_TOOL, CMD_TYPE_CONF_CHANGE, fucntion_code, 0);
        else
                result = VAPI_SetMessageFromBuffer(message, CMD_CLASS_DIAG_TOOL, CMD_TYPE_CONF_CHANGE, fucntion_code, num_param, params);

        if(result != SUCCESS)
                goto out_free;

        /* send the new VCEOPT to the connection */
        result = VAPI_SendDeviceMessage(device_id, (SMsg *)message, NULL, device_response, &response_len);

out_free:
        VAPI_FreeMessage(message);

        return result;
}

/*=================================================================================
        This function gets and prints the version of the diagtool firmware.
=================================================================================*/
VSTATUS ddi_get_versiom(void)
{
        void *message;
        U32 response_len = DEFAULT_FIFO_MAX_SIZE;
        U8 device_response [DEFAULT_FIFO_MAX_SIZE];
        VSTATUS result;

        /* allocate a message to build commands */
        message = VAPI_AllocateMessage(DEFAULT_FIFO_MAX_SIZE);
        if (message == NULL)
                return VAPI_ERR_NOMEM;

        result = VAPI_SetMessage(message, CMD_CLASS_DIAG_TOOL, CMD_TYPE_QUERY, FC_DDI_GET_VERSION, 0);

        if(result != SUCCESS)
                goto out_free;

        /* send the new VCEOPT to the connection */
        result = VAPI_SendDeviceMessage(device_id, (SMsg *)message, NULL, device_response, &response_len);

        if (result == SUCCESS)
                printf("Diagtool version = %d.%d\n", device_response[9], device_response[8]);
out_free:
        VAPI_FreeMessage(message);

        return result;
}

/*=================================================================================
        This function is a state machine.
        It sends a DDI command once a previous one has been finsished 
        and sent the result through an indication.
=================================================================================*/
void *ddi_machine_handler(void)
{
        int on_going = 1;
        /* We should have here a signal handler to interrupt the while loop
         * For now loop forever, CTRL-C to be used to stop.
         */
        PDEBUG(DEBUG_INIT, "ddi machine started");

        while (on_going)
        {
                        /* If the state is IDLE we should receive only OFFHOOK or RING events */
                switch (ddi_state)
                {
                case WAIT_DDI_MEM_ADDRBUS:
                        /* if indication DDI_MEM_ADDRESS received send WAIT_DDI_MEM_DATABUS */
                        if(ddi_event == WAIT_DDI_MEM_ADDRBUS)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_DATABUS");
                                ddi_state = WAIT_DDI_MEM_DATABUS;
                                send_ddi_msg(FC_DDI_MEM_DATABUS, 2, data_bus_param);
                        }
                        break;

                case WAIT_DDI_MEM_DATABUS:
                        /* if indication DDI_MEM_DATA received send DDI_MEM_ZERO */
                        if(ddi_event == WAIT_DDI_MEM_DATABUS)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_ZERO");
                                ddi_state = WAIT_DDI_MEM_ZERO;
                                send_ddi_msg(FC_DDI_MEM_ZERO, 4, all_zero_param);
                        }
                        break;

                case WAIT_DDI_MEM_ZERO:
                        /* if indication DDI_MEM_ZERO received send DDI_MEM_ONES */
                        if(ddi_event == WAIT_DDI_MEM_ZERO)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_ONES");
                                ddi_state = WAIT_DDI_MEM_ONES;
                                send_ddi_msg(FC_DDI_MEM_ONES, 4, all_ones_param);
                        }
                        break;

                case WAIT_DDI_MEM_ONES:
                        /* if indication DDI_MEM_ONES received send DDI_MEM_WONE */
                        if(ddi_event == WAIT_DDI_MEM_ONES)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_WONE8");
                                ddi_state = WAIT_DDI_MEM_WONE8;
                                send_ddi_msg(FC_DDI_MEM_WONE8, 6, ones_8bit_param);
                        }
                        break;

                case WAIT_DDI_MEM_WONE8:
                        /* if indication DDI_MEM_WONE8 received send DDI_MEM_WONEP8 */
                        if(ddi_event == WAIT_DDI_MEM_WONE8)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_WONEP8");
                                ddi_state = WAIT_DDI_MEM_WONEP8;
                                send_ddi_msg(FC_DDI_MEM_WONEP8, 5, ones_pair_8bit_param);
                        }
                        break;

                case WAIT_DDI_MEM_WONEP8:
                        /* if indication DDI_MEM_WONEP8 received send DDI_MEM_WONE32 */
                        if(ddi_event == WAIT_DDI_MEM_WONEP8)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_WONE32");
                                ddi_state = WAIT_DDI_MEM_WONE32;
                                send_ddi_msg(FC_DDI_MEM_WONE32, 5, ones_32bit_param);
                        }
                        break;

                case WAIT_DDI_MEM_WONE32:
                        /* if indication DDI_MEM_WONE32 received send DDI_MEM_WONEP32 */
                        if(ddi_event == WAIT_DDI_MEM_WONE32)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_WONEP32");
                                ddi_state = WAIT_DDI_MEM_WONEP32;
                                send_ddi_msg(FC_DDI_MEM_WONEP32, 5, ones_pair_32bit_param);
                        }
                        break;

                case WAIT_DDI_MEM_WONEP32:
                        /* if indication DDI_MEM_WONEP32 received send DDI_MEM_OWNA */
                        if(ddi_event == WAIT_DDI_MEM_WONEP32)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_OWNA");
                                ddi_state = WAIT_DDI_MEM_OWNA;
                                send_ddi_msg(FC_DDI_MEM_OWNA, 4, own_addr_param);
                        }
                        break;

                case WAIT_DDI_MEM_OWNA:
                        /* if indication DDI_MEM_OWNA received send DDI_MEM_FADE */
                        if(ddi_event == WAIT_DDI_MEM_OWNA)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_FADE");
                                ddi_state = WAIT_DDI_MEM_FADE;
                                send_ddi_msg(FC_DDI_MEM_FADE, 5, bit_fade_param);
                        }
                        break;

                case WAIT_DDI_MEM_FADE:
                        /* if indication DDI_MEM_FADE received send DDI_MEM_PATTERN */
                        if(ddi_event == WAIT_DDI_MEM_FADE)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_PATTERN");
                                ddi_state = WAIT_DDI_MEM_PATTERN;
                                send_ddi_msg(FC_DDI_MEM_PATTERN, 6, data_pattern_param);
                        }
                        break;

                case WAIT_DDI_MEM_PATTERN:
                        /* if indication DDI_MEM_PATTERN received send DDI_MEM_SCOPE */
                        if(ddi_event == WAIT_DDI_MEM_PATTERN)
                        {
                                PDEBUG(DEBUG_INIT, "Running DDI_MEM_SCOPE in infinite loop");
                                send_ddi_msg(FC_DDI_MEM_SCOPE, 6, scope_param);
                                /* exit from the state machine */
                                on_going = 0;
                        }
                        break;
                }
        }

        usleep(100);

        return NULL;
}


/*===============================================================================
        This is the main function of the application.\n
        It does:\n
                - Print the VAPI verson (VAPI_GetVersion)
                - Initialise VAPI (VAPI_Init)
                - Open the Device (VAPI_OpenDevice) 
                - Boot the Device (VAPI_AssignBootMAC, VAPI_BootDevice) if in Slave mode (if no firmware file name is provided it assumes master mode).
                - Get the Diagtool firmware
                - Launch the state machine to run the various DDI tests.
                - Stop the DDI_SCOPE test
*/

int main(int argc, char *argv[])
{
        int result;

        /* this function is defined in ut.c file; it retrieves the mac address from the net interface name*/
        UT_GetInterfaceMac(default_device_configuration.pucEthDevName, (char *)default_device_configuration.aucHostMac);

        /* keeping this call early, since we using VAPI logging facility */
        result = VAPI_Init(&default_device_configuration);
        if (result != SUCCESS)
        {
                /* VAPI init failed - we can't use VAPI logging */
                fprintf(stderr, "VAPI_Init: failed, result = %d\n", result);
                goto err0;
        }

        /* set global variables default values */
        device_id = 0;

        /* parse the arguments entered */
        argp_parse(&argp, argc, argv, 0, 0, NULL);

        info("%s", VAPI_GetVersion());

        result = VAPI_OpenDevice(device_id, NULL);
        check_status("VAPI_OpenDevice", err1);

        if (*firmware)
        {
                PDEBUG(DEBUG_INIT, "Booting device...");
                result = boot_device(device_id, firmware);
                check_status("VAPI_BootDevice", err2);
        }

        /* register the indication handler for the device */
        VAPI_RegisterEventCallback(device_id, EVENT_LEVEL_GENERIC, comcerto_indication_handler);

        /*get diagtool firmware version version */
        ddi_get_versiom();

        /*Send the first command */
        PDEBUG(DEBUG_INIT, "Running DDI_MEM_ADDRBUS");
        send_ddi_msg(FC_DDI_MEM_ADDRBUS, 4, addr_bus_param);

        /*Set the state to receive the in test result indication */
        ddi_state = WAIT_DDI_MEM_ADDRBUS;

        /* then start the state machine to wait for indications and send other commands */
        ddi_machine_handler();

        /* All the state machine tests have been performed, wait 10s for mem scope proccess */
        PDEBUG(DEBUG_INIT, "Test DDI_MEM_SCOPE will be stopped in 10 seconds");
        sleep(10);

        /* terminate the running test */
        PDEBUG(DEBUG_INIT, "Terminate DDI_MEM_SCOPE test");
        send_ddi_msg(FC_DDI_TEST_TERMINATE, 0, NULL);

        /* gives 1 sec to receive the indication */
        sleep(1);

        /*exit */
        result = VAPI_CloseDevice(device_id, ePURGE);
        check_status("VAPI_CloseDevice", err1);

        result = VAPI_Close();
        fprintf(stderr, "VAPI_Close: %s\n", result == SUCCESS ? "ok" : "failed");

        return 0;

err2:
        VAPI_CloseDevice(device_id, ePURGE);

err1:
        VAPI_Close();

err0:
        return FAILURE;
}





Mindspeed Technologies ®
Mindspeed Proprietary and Confidential