![]() |
|
| VAPI API Reference Documentation 2.18.x |
|
/* 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; }