Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
scpi-def.cpp
- Committer:
- wuliqunyy
- Date:
- 2022-01-17
- Revision:
- 0:be95bfb06686
File content as of revision 0:be95bfb06686:
/*- * BSD 2-Clause License * * Copyright (c) 2012-2018, Jan Breuer * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @file scpi-def.c * @date Thu Nov 15 10:58:45 UTC 2012 * * @brief SCPI parser test * * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "types.h" #include "uart_mbed.h" #include "main_init.h" #include "i2c_mbed_fpga.h" #include "scpi/scpi.h" #include "scpi/parser.h" #include "scpi-def.h" #include "i2c_ram_defines.h" #include "nv_bitfield_map.h" //#include "test_vector.h" #include "test_fg.h" #include "test_ehp_reg.h" #include "mbed.h" extern i2c_mbed_fpga i2c; LocalFileSystem local("local"); static void reprogram_for_server() { i2c.i2c_word_write_simple((0x1018-0x1000)/2, 0x2080 ); i2c.i2c_word_write_simple((0x101A-0x1000)/2, 0xfc13); i2c.i2c_word_write_simple((0x101C-0x1000)/2, 0x7eb ); i2c.i2c_word_write_simple((0x1022-0x1000)/2, 0x2073); i2c.i2c_word_write_simple((0x1024-0x1000)/2, 0x1ff); i2c.i2c_word_write_simple((0x1026-0x1000)/2, 0xc); i2c.i2c_word_write_simple((0x1028-0x1000)/2, 0x800); i2c.i2c_word_write_simple((0x103A-0x1000)/2, 0xfff); i2c.i2c_word_write_simple((0x103C-0x1000)/2, 0x1); i2c.i2c_word_write_simple((0x003E)/2, 0x1); i2c.i2c_word_write_simple((0x1040-0x1000)/2, 0x0); i2c.i2c_word_write_simple((0x1042-0x1000)/2, 0x0); i2c.i2c_word_write_simple((0x1044-0x1000)/2, 0x7f); i2c.i2c_word_write_simple((0x1046-0x1000)/2, 0x7f7f); i2c.i2c_word_write_simple((0x1050-0x1000)/2, 0x700); } static uint16_t word_read_helper(uint16_t address) { uint16_t value; if((address >= 0x1000) && (address < 0x1200)) { address = (address - 0x1000) / 2; i2c.i2c_word_read_simple(address, &value); } else { i2c.i2c_word_read_interpreter(address, &value); } return value; } static scpi_result_t set_duty(scpi_t * context) { float input = 0; int32_t duty_cycle_scaled = 0; /* read first parameter if present */ if (!SCPI_ParamFloat(context, &input, TRUE)) { return SCPI_RES_ERR; } duty_cycle_scaled = ((int)(input * 65535.0)) / 100u; i2c.i2c_set_open_loop_duty(duty_cycle_scaled); return SCPI_RES_OK; } scpi_result_t get_duty(scpi_t* context) { float duty_percentage; uint16_t duty_cycle; i2c.i2c_word_read_simple(I2C_SPEED_DUTY, &duty_cycle); duty_percentage = ((float)duty_cycle)/655.35; SCPI_ResultFloat(context, duty_percentage); return SCPI_RES_OK; } const scpi_choice_def_t led_selects[] = { { "OFF", 0 }, { "ON", 1 }, SCPI_CHOICE_LIST_END }; static scpi_result_t set_led1(scpi_t * context) { int32_t input = 0; if (!SCPI_ParamChoice(context, led_selects, &input, TRUE)) return SCPI_RES_ERR; led1 = input; return SCPI_RES_OK; } scpi_result_t get_led1(scpi_t* context) { int led_value = led1; SCPI_ResultText(context, led_selects[led_value].name); return SCPI_RES_OK; } scpi_result_t read_word(scpi_t* context) { uint32_t address = 0; uint16_t value; /* read first parameter if present */ if (!SCPI_ParamUInt32(context, &address, TRUE)) { return SCPI_RES_ERR; } value = word_read_helper((uint16_t)address); SCPI_ResultUInt16Base(context, value, 16); return SCPI_RES_OK; } scpi_result_t write_word(scpi_t* context) { int32_t address = 0; int32_t value = 0; /* read first parameter: address */ if (!SCPI_ParamInt(context, &address, TRUE)) { return SCPI_RES_ERR; } /* read first parameter: address */ if (!SCPI_ParamInt(context, &value, TRUE)) { return SCPI_RES_ERR; } if((address >= 0x1000) && (address < 0x1200)) { address = (address - 0x1000) / 2; if(address == 15){ /* Special if-case for the windmilling debugging, writing the default registers */ i2c.i2c_word_write_simple(address, value); reprogram_for_server(); } else { /* Normal write operation */ i2c.i2c_word_write_simple(address, value); } } else { i2c.i2c_word_write_interpreter(address, value); } return SCPI_RES_OK; } scpi_result_t read_array(scpi_t* context) { uint32_t start_address = 0; uint32_t size = 0; /* read first parameter: start address */ if (!SCPI_ParamUInt32(context, &start_address, TRUE)) { return SCPI_RES_ERR; } /* read second parameter: size */ if (!SCPI_ParamUInt32(context, &size, TRUE)) { return SCPI_RES_ERR; } if(((size % 2) != 0u) || (size == 0)) { SCPI_ErrorPush(context,SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); return SCPI_RES_ERR; } uint16_t array[(size/2)]; // uint16_t* array = (uint16_t*)malloc(size); uint16_t index = 0; for(index = 0u; index < (size/2); index++) { array[index] = word_read_helper(start_address + (index * 2)); } SCPI_ResultArrayUInt16(context, array, (sizeof(array) / sizeof(*array)), SCPI_FORMAT_ASCII); return SCPI_RES_OK; } scpi_result_t repeat_read(scpi_t* context) { uint32_t interval_us; uint32_t first_address; uint32_t second_address; uint32_t samples; /* read first parameter: size */ if (!SCPI_ParamUInt32(context, &samples, TRUE)) { return SCPI_RES_ERR; } if (!SCPI_ParamUInt32( context, &interval_us, TRUE)) { return SCPI_RES_ERR; } /* The first address. This is mandatory */ if (!SCPI_ParamUInt32(context, &first_address, TRUE)) { return SCPI_RES_ERR; } /* A potential second address. Optional */ if (!SCPI_ParamUInt32(context, &second_address, FALSE)) { second_address = 0; } if(second_address != 0) { uint16_t array[samples*2]; // uint16_t* array = (uint16_t*)malloc(size); for(uint32_t index = 0u; index < samples*2; index=index+2) { array[index] = word_read_helper(first_address); array[index+1] = word_read_helper(second_address); wait_us(interval_us); } SCPI_ResultArrayUInt16(context, array, (sizeof(array) / sizeof(*array)), SCPI_FORMAT_ASCII); } else { uint16_t array[samples]; // uint16_t* array = (uint16_t*)malloc(size); for(uint32_t index = 0u; index < samples; index++) { array[index] = word_read_helper(first_address); wait_us(interval_us); } SCPI_ResultArrayUInt16(context, array, (sizeof(array) / sizeof(*array)), SCPI_FORMAT_ASCII); } return SCPI_RES_OK; } scpi_result_t dump_ram(scpi_t* context) { uint16_t start_address = 0x1000; uint16_t end_address = 0x1096; uint16_t data; FILE *RAMdump = fopen("/local/RAMdump.csv", "w"); // Open "RAMdump.csv" on the local file system (on the mbed) for writing led4 = !led4; wait_us(500000); for (uint16_t address=start_address ; address<=end_address-2; address=address+2) { data = word_read_helper((uint16_t)address); fprintf(RAMdump, "0x%.4X,0x%.4X\r\n", address, data); // Write each address and read data of the complete RAM to the external file } fclose(RAMdump); led4 = !led4; return SCPI_RES_OK; } scpi_result_t reset_config_mode(scpi_t* context) { main_init(); //wait_us(2000000); /* keep FPGA in reset for 2s, to let motor stop */ wait_us(100); /* reset the IO-pin for minimum few us */ enable_fpga(); /* enable FPGA */ i2c.wait_for_idle_state(); /* wait for FPGA responsive */ //wait_us(1000); wait_us(100); i2c.i2c_config_mode_entry();/* enter configuration mode */ return SCPI_RES_OK; } scpi_result_t reset_htol_mode(scpi_t* context) { i2c.i2c_soft_reset(); i2c.wait_for_idle_state(); /* wait for FPGA responsive */ //wait_us(1000); wait_us(100); i2c.i2c_mlx_mode_entry(); /* Enter melexis mode */ wait_us(100); i2c.i2c_htol_mode_entry(); /* Enter HTOL mode */ return SCPI_RES_OK; } const scpi_choice_def_t mlxmode_selects[] = { { "OFF", 0 }, { "ON", 1 }, SCPI_CHOICE_LIST_END }; scpi_result_t reset_application_mode(scpi_t* context) { int32_t mlxmode = 0; if (!SCPI_ParamChoice(context, mlxmode_selects, &mlxmode, FALSE)) mlxmode = 0; main_init(); wait_us(2000000); /* keep FPGA in reset for 5s, to let motor stop*/ enable_fpga(); /* enable FPGA */ if(mlxmode == 1) { i2c.wait_for_idle_state(); wait_us(1000); i2c.i2c_mlx_mode_entry(); } i2c.wait_for_application_state(); wait_us(1000); return SCPI_RES_OK; } scpi_result_t soft_reset_application_mode(scpi_t* context) { int32_t mlxmode = 0; if (!SCPI_ParamChoice(context, mlxmode_selects, &mlxmode, FALSE)) mlxmode = 0; i2c.i2c_soft_reset(); if(mlxmode == 1) { i2c.wait_for_idle_state(); wait_us(100); i2c.i2c_mlx_mode_entry(); i2c.wait_for_application_state(); } wait_us(100); return SCPI_RES_OK; } /* * self-test routines */ scpi_result_t test_capture_position_timing(scpi_t* context) { /*to be added*/ reset_fpga(); /*finish*/ return SCPI_RES_OK; } scpi_result_t test_ehp_reg_vector(scpi_t* context) { /*vector start, use template later: TBD*/ led3=1; test_ehp_reg test(p15,p16); test.configure(); test.run(); test.stop(); SCPI_ResultArrayUInt32(context, test.getResult(), test.getBufferSize(), SCPI_FORMAT_ASCII); SCPI_ResultText(context, test.getResultStatus() ); test.release(); /* test_vector* t; test_ehp_reg test(p15,p16); //p15 to capture timer -> non_flat. p16 to trigger ADC sample t = &test; t->configure(); t->run(); t->stop(); SCPI_ResultArrayUInt32(context, t->getResult(), t->getBufferSize(), SCPI_FORMAT_ASCII); SCPI_ResultText(context, t->getResultStatus() ); t->release(); */ led3=0; return SCPI_RES_OK; } scpi_result_t test_fg_vector(scpi_t* context) { /*vector start, use template later: TBD*/ led3=1; test_fg test(p15); test.configure(); test.run(); test.stop(); SCPI_ResultArrayUInt32(context, test.getResult(), test.getBufferSize(), SCPI_FORMAT_ASCII); SCPI_ResultText(context, test.getResultStatus() ); test.release(); /* test_vector* t; test_fg test(p15); //only two option to capture: p15 is CAP3.0 or p16 is CAP3.1 t = &test; t->configure(); t->run(); t->stop(); SCPI_ResultArrayUInt32(context, t->getResult(), t->getBufferSize(), SCPI_FORMAT_ASCII); SCPI_ResultText(context, t->getResultStatus() ); t->release(); */ led3=0; return SCPI_RES_OK; } /** * Reimplement IEEE488.2 *TST? * * Result should be 0 if everything is ok * Result should be 1 if something goes wrong * * Return SCPI_RES_OK */ static scpi_result_t My_CoreTstQ(scpi_t * context) { SCPI_ResultInt(context, 0); return SCPI_RES_OK; } void configure_scpi(void) { /* user_context will be pointer to socket */ SCPI_Init(&scpi_context, scpi_commands, &scpi_interface, scpi_units_def, "Melexis", "MLX90418", NULL, "0", scpi_input_buffer, SCPI_INPUT_BUFFER_LENGTH, scpi_error_queue_data, SCPI_ERROR_QUEUE_SIZE); } const scpi_command_t scpi_commands[] = { /* IEEE Mandated Commands (SCPI std V1999.0 4.1.1) */ {"*CLS", SCPI_CoreCls, 0}, {"*ESE", SCPI_CoreEse, 0}, {"*ESE?", SCPI_CoreEseQ, 0}, {"*ESR?", SCPI_CoreEsrQ, 0}, {"*IDN?", SCPI_CoreIdnQ, 0}, {"*OPC", SCPI_CoreOpc, 0}, {"*OPC?", SCPI_CoreOpcQ, 0}, {"*RST", SCPI_CoreRst, 0}, {"*SRE", SCPI_CoreSre, 0}, {"*SRE?", SCPI_CoreSreQ, 0}, {"*STB?", SCPI_CoreStbQ, 0}, {"*TST?", My_CoreTstQ, 0}, {"*WAI", SCPI_CoreWai, 0}, /* Required SCPI commands (SCPI std V1999.0 4.2.1) */ {"SYSTem:ERRor[:NEXT]?", SCPI_SystemErrorNextQ, 0}, {"SYSTem:ERRor:COUNt?", SCPI_SystemErrorCountQ, 0}, {"SYSTem:VERSion?", SCPI_SystemVersionQ, 0}, //{"STATus:OPERation?", scpi_stub_callback, 0}, //{"STATus:OPERation:EVENt?", scpi_stub_callback, 0}, //{"STATus:OPERation:CONDition?", scpi_stub_callback, 0}, //{"STATus:OPERation:ENABle", scpi_stub_callback, 0}, //{"STATus:OPERation:ENABle?", scpi_stub_callback, 0}, {"STATus:QUEStionable[:EVENt]?", SCPI_StatusQuestionableEventQ, 0}, //{"STATus:QUEStionable:CONDition?", scpi_stub_callback, 0}, {"STATus:QUEStionable:ENABle", SCPI_StatusQuestionableEnable, 0}, {"STATus:QUEStionable:ENABle?", SCPI_StatusQuestionableEnableQ, 0}, {"STATus:PRESet", SCPI_StatusPreset, 0}, /* DMM */ {"TARGet:DUTYcycle", set_duty, 0}, {"TARGet:DUTYcycle?", get_duty, 0}, {"TARGet:SPEED", set_duty, 0}, {"TARGet:SPEED?", get_duty, 0}, {"LED1", set_led1, 0}, {"LED1?", get_led1, 0}, {"MEMory:WORD?", read_word, 0}, {"MEMory:WORD", write_word, 0}, {"MEMory:ARRAY?", read_array, 0}, {"MEMory:REPEAT?", repeat_read, 0}, {"MEMory:DUMPRAM", dump_ram, 0}, {"SYSTem:RESET[:APPLImode]", reset_application_mode, 0}, {"SYSTem:SOFTRESET[:APPLImode]", soft_reset_application_mode, 0}, {"SYSTem:RESET:CONFIGmode", reset_config_mode, 0}, {"SYSTem:RESET:HTOLmode", reset_htol_mode, 0}, {"TEST:POSItion", test_capture_position_timing, 0}, {"TEST:TESTfg", test_fg_vector, 0}, {"TEST:TESTehpreg", test_ehp_reg_vector, 0}, SCPI_CMD_LIST_END }; scpi_interface_t scpi_interface = { /*.error = */ SCPI_Error, /*.write = */ SCPI_Write, /*.control = */ SCPI_Control, /*.flush = */ SCPI_Flush, /*.reset = */ SCPI_Reset, }; char scpi_input_buffer[SCPI_INPUT_BUFFER_LENGTH]; scpi_error_t scpi_error_queue_data[SCPI_ERROR_QUEUE_SIZE]; scpi_t scpi_context;