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.
Revision 0:be95bfb06686, committed 2022-01-17
- Comitter:
- wuliqunyy
- Date:
- Mon Jan 17 13:20:09 2022 +0000
- Commit message:
- a working non_flat + adc_didt for ehp regulation version
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i2c_mbed_fpga.cpp Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,503 @@ +#include "mbed.h" +#include "i2c_mbed_fpga.h" + +#define COMM_STATE_I2C_IDLE (1u) +#define COMM_STATE_I2C_APPLICATION (2u) +#define COMM_STATE_DIRECT_IDLE (4u) +#define COMM_STATE_DIRECT_APPLICATION (6u) + +void i2c_mbed_fpga::wait_for_idle_state(void) +{ + int comm_state = 0; + do { + uint16_t tmp; + this->i2c_word_read_simple(I2C_STATE, &tmp); + comm_state = (tmp & I2C_STATE_COMM_STATE_MASK) >> I2C_STATE_COMM_STATE_OFFSET; + wait_us(500); + } while((comm_state != COMM_STATE_I2C_IDLE)&&(comm_state != COMM_STATE_DIRECT_IDLE)); +} + +void i2c_mbed_fpga::wait_for_application_state(void) +{ + int comm_state = 0; + do { + uint16_t tmp; + this->i2c_word_read_simple(I2C_STATE, &tmp); + comm_state = (tmp & I2C_STATE_COMM_STATE_MASK) >> I2C_STATE_COMM_STATE_OFFSET; + wait_us(500); + } while((comm_state != COMM_STATE_I2C_APPLICATION)&&(comm_state != COMM_STATE_DIRECT_APPLICATION)); +} + + + +/** i2c read from slave DUT using the command interpreter feature +* retun 0 on success, otherwise fails +* +* @param[in] address 16-bit address to read from +* @param[out] return value Pointer to the value read at address +* @retval 0 Read failed +* @retval 1 Read successful +*/ +int i2c_mbed_fpga::i2c_word_read_interpreter(uint16_t address, uint16_t* return_value){ + uint16_t read_value; + int busy; + int ack = 0; + while(i2c_check_busy_flag()) { + /* Wait for the busy flag to clear */ + } + ack += this->i2c_word_write_simple(I2C_CMD_INTERPRETER_ADDRESS, (address | 0x1)); /* Write the address with the LSB set to 1 to indicate a read operation */ + wait_us(100); + /* Check if the command is finished by polling the LSB of CMD_INTERPRETER_ADDRESS */ + do { + ack += this->i2c_word_read_simple(I2C_CMD_INTERPRETER_ADDRESS, &read_value); + if((read_value & 0x1) == 1u) { + busy = true; + } else { + busy = false; + } + wait_us(100); + } + while(busy == true); + + /* We know the read command has finished. Read back the value */ + ack += this->i2c_word_read_simple(I2C_CMD_INTERPRETER_DATA, &read_value); + *return_value = read_value; + return (ack == 0) ? 0 : 1; +} + + +bool i2c_mbed_fpga::i2c_check_busy_flag(void){ + bool retval = true; + uint16_t tmp; + this->i2c_word_read_simple(I2C_STATUS, &tmp); + if((tmp & I2C_STATUS_COMMAND_BUSY_MASK) == 0u) { + retval = false; + } + return retval; +} + +/** i2c read from slave DUT +* retun 0 on success, otherwise fails +* +* @param i2c_master specifies the i2c interface +* @param word is 4byte, first 2bytes as addr, the rest 2bytes to store data +*/ +int i2c_mbed_fpga::i2c_word_read(char *word){ + int ack = 0; + ack = i2c_master.write(I2C_SLAVE_ADDR, word, 1, true); //restart + ack += i2c_master.read(I2C_SLAVE_ADDR, word+1, 2, false); //stop bit + wait_us(100); + return (ack == 0) ? 0 : 1; +} + +/** i2c read from slave DUT +* retun 0 on success, otherwise fails +* +* @param i2c_master specifies the i2c interface +* @param word is 4byte, first 2bytes as addr, the rest 2bytes to store data +*/ +int i2c_mbed_fpga::i2c_word_read_simple(char address, uint16_t* return_value){ + int ack = 0; + char value[2]; + ack = i2c_master.write(I2C_SLAVE_ADDR, &address, 1, true); //restart + ack += i2c_master.read(I2C_SLAVE_ADDR, value, 2, false); //stop bit + *return_value = (int)value[1] | ((int)value[0] << 8); + wait_us(100); + return (ack == 0) ? 0 : 1; +} + +/** i2c write to slave DUT +* ==> one time write, not read back check +* +* @param i2c_master specifies the i2c interface +* @param word is considered as 4byte char data +*/ +int i2c_mbed_fpga::i2c_word_write(char *word){ + int ack = 0; + ack = i2c_master.write(I2C_SLAVE_ADDR, word, 3, false); + return ack; +} + +/** i2c read from slave DUT +* retun 0 on success, otherwise fails +* +* @param i2c_master specifies the i2c interface +* @param word is 4byte, first 2bytes as addr, the rest 2bytes to store data +*/ +int i2c_mbed_fpga::i2c_word_write_simple(char address, uint16_t value){ + int ack = 0; + char i2cMessage[3]; + *(i2cMessage+0) = (char)(address)& 0xff; + *(i2cMessage+1) = (char)((value >> 8u) & 0xff); + *(i2cMessage+2) = (char)(value & 0xff); + ack = i2c_word_write(i2cMessage); + wait_us(100); + return ack; +} + +int i2c_mbed_fpga::i2c_word_write_interpreter(uint16_t address, uint16_t value){ + uint16_t read_value; + int busy; + int ack = 0; + while(i2c_check_busy_flag()) { + /* Wait for the busy flag to clear */ + } + ack += this->i2c_word_write_simple(I2C_CMD_INTERPRETER_DATA, value); + ack += this->i2c_word_write_simple(I2C_CMD_INTERPRETER_ADDRESS, (address & 0xFFFE)); /* Write the address with the LSB set to 0 to indicate a write operation */ + /* Check if the command is finished by polling the LSB of CMD_INTERPRETER_ADDRESS */ + do { + ack += this->i2c_word_read_simple(I2C_CMD_INTERPRETER_ADDRESS, &read_value); + if((read_value & 0x1) == 0u) { + busy = true; + } else { + busy = false; + } + wait_us(100); + } + while(busy == true); + return (ack == 0) ? 0 : 1; +} + + + +/** i2c enter key to open I2C window (for old releases) +*/ +//int i2c_mbed_fpga::i2c_window_open(){ +// char i2cMessage[3]; +// *(i2cMessage+0) = (char)(I2C_CUST_ID3)& 0xff; +// *(i2cMessage+1) = (char)(0xD0)& 0xff; +// *(i2cMessage+2) = (char)(0xD0)& 0xff; +// return i2c_word_write(i2cMessage); +//} + +/** i2c enter key to Start the motor (for old releases) +*/ +//int i2c_mbed_fpga::i2c_motor_start(){ +// char i2cMessage[3]; +// *(i2cMessage+0) = (char)(I2C_CUST_ID3)& 0xff; +// *(i2cMessage+1) = (char)(0xCA)& 0xff; +// *(i2cMessage+2) = (char)(0xFE)& 0xff; +// return i2c_word_write(i2cMessage); +//} + + +/** i2c enter key to open I2C configuration mode entry*/ +int i2c_mbed_fpga::i2c_config_mode_entry(){ + return i2c_word_write_simple(I2C_COMMAND_CONTROL, 0x1DEA); +} + +/** i2c enter MLX key to open I2C MLX configuration mode entry*/ +int i2c_mbed_fpga::i2c_mlx_mode_entry(){ + int ack = 0; + ack += i2c_word_write_simple(I2C_COMMAND_KEY, 0x65A9); + ack += i2c_word_write_simple(I2C_COMMAND_CONTROL, 0x354B); + return ack; +} + +/** i2c enter key to enter HTOL mode*/ +int i2c_mbed_fpga::i2c_htol_mode_entry(){ + int ack = 0; + ack += i2c_word_write_simple(I2C_COMMAND_KEY, 0x2BAD); + ack += i2c_word_write_simple(I2C_COMMAND_CONTROL, 0xD1E0); + return ack; +} + +/** i2c ram start up flag set to skip OTP copy */ +int i2c_mbed_fpga::i2c_skip_app_copy(){ + return i2c_word_write_simple(I2C_STARTUP_FLAGS_1, 0x0500); +} + +/** i2c soft reset */ +int i2c_mbed_fpga::i2c_soft_reset(){ + return i2c_word_write_simple(I2C_COMMAND_CONTROL, 0xC1A0); +} + +/** i2c to set the 50k PWM*/ +int i2c_mbed_fpga::i2c_set_50k_pwm(unsigned int pwm50k){ + nv_gen_ctrl_val &= ~NV_PWM_50K_MASK; + nv_gen_ctrl_val |= pwm50k << NV_PWM_50K_OFFSET; + return i2c_word_write_simple(I2C_GEN_CTRL, nv_gen_ctrl_val); +} + +/** i2c to set the Postion Pulse width*/ +int i2c_mbed_fpga::i2c_set_position_pulse_width(unsigned int mantisaa_2b, unsigned int exponent_3b){ + nv_positin_val &= ~NV_POSITION_PULSE_TIME_MASK; + nv_positin_val |= ((exponent_3b << 2) | mantisaa_2b) << NV_POSITION_PULSE_TIME_OFFSET; + return i2c_word_write_simple(I2C_POSITION, nv_positin_val); +} + +/** i2c to set the Postion Flat width */ +int i2c_mbed_fpga::i2c_set_position_flat(unsigned int mantisaa_2b, unsigned int exponent_3b){ + nv_positin2_val &= ~NV_POSITION_FLAT_TIME_MASK; + nv_positin2_val |= ((exponent_3b << 2) | mantisaa_2b) << NV_POSITION_FLAT_TIME_OFFSET; + return i2c_word_write_simple(I2C_POSITION2, nv_positin2_val); +} + +/** i2c to set the Postion Pulse duty cycle */ +int i2c_mbed_fpga::i2c_set_position_duty(unsigned int duty_2b){ + nv_positin_val &= ~NV_POSITION_DUTY_MASK; + nv_positin_val |= duty_2b << NV_POSITION_DUTY_OFFSET; + return i2c_word_write_simple(I2C_POSITION, nv_positin_val); +} + +/** i2c to enable the Postion Pulse majority volting */ +int i2c_mbed_fpga::i2c_set_position_maj_vote(unsigned int maj_1b){ + nv_positin_val &= ~NV_POSI_MAJO_VOTE_MASK; + nv_positin_val |= maj_1b << NV_POSI_MAJO_VOTE_OFFSET; + return i2c_word_write_simple(I2C_POSITION, nv_positin_val); +} + +/** i2c to set the anti-cogging rotation direction */ +int i2c_mbed_fpga::i2c_set_position_anti_cog(unsigned int cog_1b){ + nv_positin_val &= ~NV_ANTI_COG_MASK; + nv_positin_val |= cog_1b << NV_ANTI_COG_OFFSET; + return i2c_word_write_simple(I2C_POSITION, nv_positin_val); +} + + +/** i2c to set the Start Up Pulse width (pulse train) */ +int i2c_mbed_fpga::i2c_set_start_up_pulse_width(unsigned int mantisaa_3b, unsigned int exponent_3b){ + nv_start_up_val &= ~NV_START_UP_TIME_MASK; + nv_start_up_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_START_UP_TIME_OFFSET; + return i2c_word_write_simple(I2C_START_UP, nv_start_up_val); +} + +/** i2c to set the Start Up Flat width */ +int i2c_mbed_fpga::i2c_set_start_up_flat(unsigned int mantisaa_3b, unsigned int exponent_3b){ + nv_positin2_val &= ~NV_START_UP_FLAT_TIME_MASK; + nv_positin2_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_START_UP_FLAT_TIME_OFFSET; + return i2c_word_write_simple(I2C_POSITION2, nv_positin2_val); +} + +/** i2c to set the Start up Pulse duty cycle (pulse train) */ +int i2c_mbed_fpga::i2c_set_start_up_duty(unsigned int duty_2b){ + nv_start_up_val &= ~NV_START_DUTY_MASK; + nv_start_up_val |= duty_2b << NV_START_DUTY_OFFSET; + return i2c_word_write_simple(I2C_START_UP, nv_start_up_val); +} + +/** i2c to set the Start up commutation number of EHPs (pulse train) */ +int i2c_mbed_fpga::i2c_set_start_up_num_comm(unsigned int comm){ + nv_start_up_val &= ~NV_COMM_START_NUM_MASK; + nv_start_up_val |= comm << NV_COMM_START_NUM_OFFSET; + return i2c_word_write_simple(I2C_START_UP, nv_start_up_val); +} + +/** i2c to set the Soft Start Up (pulse train) */ +int i2c_mbed_fpga::i2c_set_soft_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b, unsigned int step_size, unsigned int num_steps){ + int ack = 0; + nv_start_up_val &= ~NV_SOFT_START_MASK; + nv_start_up_val |= enbale << NV_SOFT_START_OFFSET; + nv_positin_val &= ~NV_FIRST_NON_FLAT_TIME_MASK; + nv_positin_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_FIRST_NON_FLAT_TIME_OFFSET; + nv_start_up_val &= ~NV_SOFT_STEP_SIZE_MASK; + nv_start_up_val |= step_size << NV_SOFT_STEP_SIZE_OFFSET; + nv_wind_brake_val &= ~NV_SOFT_NUM_STEP_MASK; + nv_wind_brake_val |= num_steps << NV_SOFT_NUM_STEP_OFFSET; + ack += i2c_word_write_simple(I2C_POSITION, nv_positin_val); + ack += i2c_word_write_simple(I2C_START_UP, nv_start_up_val); + ack += i2c_word_write_simple(I2C_WIND_BRAKE, nv_wind_brake_val); + + return ack; +} + +/** i2c to set the High Torque Start Up (pulse train */ +int i2c_mbed_fpga::i2c_set_high_torque_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b){ + int ack = 0; + nv_start_up_val &= ~NV_LONG_START_MASK; + nv_start_up_val |= enbale << NV_LONG_START_OFFSET; + nv_positin_val &= ~NV_FIRST_NON_FLAT_TIME_MASK; + nv_positin_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_FIRST_NON_FLAT_TIME_OFFSET; + ack += i2c_word_write_simple(I2C_POSITION, nv_positin_val); + ack += i2c_word_write_simple(I2C_START_UP, nv_start_up_val); + + return ack; +} + +/** i2c to set the Single Pulse Start Up (pulse train) */ +int i2c_mbed_fpga::i2c_set_single_pulse_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b){ + int ack = 0; + nv_start_up_val &= ~NV_SINGLE_PULSE_START_MASK; + nv_start_up_val |= enbale << NV_SINGLE_PULSE_START_OFFSET; + nv_positin_val &= ~NV_FIRST_NON_FLAT_TIME_MASK; + nv_positin_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_FIRST_NON_FLAT_TIME_OFFSET; + ack += i2c_word_write_simple(I2C_POSITION, nv_positin_val); + ack += i2c_word_write_simple(I2C_START_UP, nv_start_up_val); + + return ack; +} + +/** i2c to set the rough regulation gain */ +int i2c_mbed_fpga::i2c_force_rough_reg(unsigned int reg){ + int ack = 0; + nv_gen_ctrl_val &= ~NV_ROUGH_REG_MASK; + nv_gen_ctrl_val |= reg << NV_ROUGH_REG_OFFSET; + ack += i2c_word_write_simple(I2C_GEN_CTRL, nv_gen_ctrl_val); + + return ack; +} + +/** i2c to set the rough regulation gain */ +int i2c_mbed_fpga::i2c_set_rough_gain(unsigned int rough_gain){ + int ack = 0; + nv_gen_ctrl_val &= ~NV_ROUGH_GAIN_MASK; + nv_gen_ctrl_val |= rough_gain << NV_ROUGH_GAIN_OFFSET; + ack += i2c_word_write_simple(I2C_GEN_CTRL, nv_gen_ctrl_val); + + return ack; +} + +/** i2c to set the ehp regulation gain */ +int i2c_mbed_fpga::i2c_set_ehp_reg_gain(unsigned int ehp_gain){ + int ack = 0; + nv_gen_ctrl_val &= ~NV_EHP_REG_GAIN_MASK; + nv_gen_ctrl_val |= ehp_gain << NV_EHP_REG_GAIN_OFFSET; + ack += i2c_word_write_simple(I2C_GEN_CTRL, nv_gen_ctrl_val); + + return ack; +} + +/** i2c to set the ehp regulation gain */ +int i2c_mbed_fpga::i2c_set_fall_time_blank(unsigned int blank_time){ + int ack = 0; + nv_dig_config_val &= ~NV_FLAT_BLANK_MASK; + nv_dig_config_val |= blank_time << NV_FLAT_BLANK_OFFSET; + ack += i2c_word_write_simple(I2C_DIGITAL_CFG, nv_dig_config_val); + + return ack; +} + +/** i2c to set the current threshold for I_didt */ +int i2c_mbed_fpga::i2c_set_comm_i_thres(unsigned int i_thr_low, unsigned int i_thr_high){ + int ack = 0; + nv_i_zc_th_low_val &= ~NV_I_ZC_TH_LOW_MASK; + nv_i_zc_th_low_val |= i_thr_low << NV_I_ZC_TH_LOW_OFFSET; + nv_i_zc_th_high_val &= ~NV_I_ZC_TH_HIGH_MASK; + nv_i_zc_th_high_val |= i_thr_high << NV_I_ZC_TH_HIGH_OFFSET; + ack += i2c_word_write_simple(I2C_I_ZC_TH_LOW_REG, nv_i_zc_th_low_val); + ack += i2c_word_write_simple(I2C_I_ZC_TH_HIGH_REG, nv_i_zc_th_high_val); + return ack; +} + +/** i2c to set the di current threshold for didt */ +int i2c_mbed_fpga::i2c_set_comm_di_thres(unsigned int di_1st, unsigned int di_2nd){ + int ack = 0; + nv_di_th_1st_val &= ~NV_DI_TH_1ST_MASK; + nv_di_th_1st_val |= di_1st << NV_DI_TH_1ST_OFFSET; + nv_di_th_2nd_val &= ~NV_DI_TH_2ND_MASK; + nv_di_th_2nd_val |= di_2nd << NV_DI_TH_2ND_OFFSET; + ack += i2c_word_write_simple(I2C_DI_TH_1ST_REG, nv_di_th_1st_val); + ack += i2c_word_write_simple(I2C_DI_TH_2ND_REG, nv_di_th_2nd_val); + return ack; +} + +/** i2c to clean the I2C controller settins */ +int i2c_mbed_fpga::i2c_clear_spd_ctrl(){ + int ack = 0; + nv_spd_control_1_val = 0; + nv_spd_control_2_val = 0; + ack += i2c_word_write_simple(I2C_SPD_CTRL_1, nv_spd_control_1_val); + ack += i2c_word_write_simple(I2C_SPD_CTRL_2, nv_spd_control_2_val); + + return ack; +} + +/** i2c to set the I2C speed input mode */ +int i2c_mbed_fpga::i2c_set_input_mode(unsigned int mode){ + int ack = 0; + nv_application_cfg_val &= ~NV_INPUT_MODE_CFG_MASK; + nv_application_cfg_val |= mode << NV_INPUT_MODE_CFG_OFFSET; + ack += i2c_word_write_simple(I2C_APPLICATION_CFG, nv_application_cfg_val); + return ack; +} + +/** i2c to set the open loop mode */ +int i2c_mbed_fpga::i2c_set_loop_mode(unsigned int openloop){ + int ack = 0; + nv_spd_control_1_val &= ~NV_SPD_LOOP_MODE_MASK; + nv_spd_control_1_val |= openloop << NV_SPD_LOOP_MODE_OFFSET; + ack += i2c_word_write_simple(I2C_SPD_CTRL_1, nv_spd_control_1_val); + + return ack; +} + +/** i2c to set the Single Pulse Start Up (pulse train) */ +int i2c_mbed_fpga::i2c_set_open_loop_duty(unsigned int duty){ + int ack = 0; + ram_open_duty_val = duty; + ack += i2c_word_write_simple(I2C_SPEED_DUTY, ram_open_duty_val); + + return ack; +} + +/** i2c to set the speed curve type */ +int i2c_mbed_fpga::i2c_set_curve_type(unsigned int curvetype){ + int ack = 0; + nv_spd_control_1_val &= ~NV_CURVE_MODE_MASK; + nv_spd_control_1_val |= curvetype << NV_CURVE_MODE_OFFSET; + ack += i2c_word_write_simple(I2C_SPD_CTRL_1, nv_spd_control_1_val); + + return ack; +} + +/** i2c to set the open dc ini */ +int i2c_mbed_fpga::i2c_set_dc_ini(unsigned int ini){ + int ack = 0; + nv_spd_control_2_val &= ~NV_DC_OPENLOOP_INI_MASK; + nv_spd_control_2_val |= ini << NV_DC_OPENLOOP_INI_OFFSET; + ack += i2c_word_write_simple(I2C_SPD_CTRL_2, nv_spd_control_2_val); + + return ack; +} + +/** i2c to set the open dc slew rate */ +int i2c_mbed_fpga::i2c_set_dc_sr(unsigned int sr){ + int ack = 0; + nv_spd_control_2_val &= ~NV_DC_OPENLOOP_SR_MASK; + nv_spd_control_2_val |= sr << NV_DC_OPENLOOP_SR_OFFSET; + ack += i2c_word_write_simple(I2C_SPD_CTRL_2, nv_spd_control_2_val); + + return ack; +} + +/** i2c to set the target CLIM during start up */ +int i2c_mbed_fpga::i2c_set_clim_start_up(unsigned int clim){ + int ack = 0; + nv_clim_user_1_val &= ~NV_TARGET_CLIM_USER_PULSES_MASK; + nv_clim_user_1_val |= clim << NV_TARGET_CLIM_USER_PULSES_OFFSET; + ack += i2c_word_write_simple(I2C_CLIM_USER_1, nv_clim_user_1_val); + + return ack; +} + +/** i2c to set the target CLIM during brake */ +int i2c_mbed_fpga::i2c_set_clim_brake(unsigned int clim){ + int ack = 0; + nv_clim_user_0_val &= ~NV_TARGET_CLIM_USER_BRAKE_MASK; + nv_clim_user_0_val |= clim << NV_TARGET_CLIM_USER_BRAKE_OFFSET; + ack += i2c_word_write_simple(I2C_CLIM_USER_0, nv_clim_user_0_val); + + return ack; +} + +/** i2c to set the target CLIM during run time */ +int i2c_mbed_fpga::i2c_set_clim_run_time(unsigned int clim){ + int ack = 0; + nv_clim_user_0_val &= ~NV_TARGET_CLIM_USER_MOTOR_MASK; + nv_clim_user_0_val |= clim << NV_TARGET_CLIM_USER_MOTOR_OFFSET; + ack += i2c_word_write_simple(I2C_CLIM_USER_0, nv_clim_user_0_val); + + return ack; +} + + +/** i2c to enbale test debug mode */ +int i2c_mbed_fpga::i2c_enable_pules_debug_mode(unsigned int enable){ + int ack = 0; + ram_debug_ctrl_val &= ~0x0001; + ram_debug_ctrl_val |= enable; + ack += i2c_word_write_simple(0xEA, 1); + + return ack; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i2c_mbed_fpga.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,125 @@ +#ifndef I2C_MBED_FPGA_H +#define I2C_MBED_FPGA_H + +#include "nv_bitfield_map.h" +#include "i2c_ram_defines.h" +#include "nv_defaults.h" +#include "mbed.h" + + +#define I2C_SLAVE_ADDR 0x6A<<1 + +//Class delclarations +class i2c_mbed_fpga { + +public: + /*constructor*/ + // {p28:sda, p27:scl} + // {p9: sda, p10:scl} + i2c_mbed_fpga(): i2c_master(p9, p10){ + i2c_master.frequency(100000); + nv_positin_val = NV_POSITION_DEFAULT; + nv_start_up_val = NV_START_UP_DEFAULT; + nv_wind_brake_val = NV_WIND_BRAKE_DEFAULT; + ram_open_duty_val = RAM_OPEN_DUTY_DEFAULT; + nv_spd_control_1_val = NV_SPD_CONTROL_1_DEFAULT; + nv_spd_control_2_val = NV_SPD_CONTROL_1_DEFAULT; + nv_gen_ctrl_val = NV_GEN_CTRL_DEFAULT; + nv_application_cfg_val = NV_APPLICATION_CFG_DEFAULT; + nv_i_zc_th_high_val = NV_I_ZC_TH_HIGH_DEFAULT; + nv_i_zc_th_low_val = NV_I_ZC_TH_LOW_DEFAULT; + nv_di_th_1st_val = NV_DI_TH_1ST_DEFAULT; + nv_di_th_2nd_val = NV_DI_TH_2ND_DEFAULT; + nv_dig_config_val = NV_DIG_CONFIG_DEFAULT; + nv_clim_user_0_val = NV_CLIM_USER_0_DEFAULT; + nv_clim_user_1_val = NV_CLIM_USER_1_DEFAULT; + nv_positin2_val = NV_CLIM_POSITIN2_DEFAULT; + ram_debug_ctrl_val = RAM_DEBUG_CTRL_DEFAULT; + }; + + int i2c_word_read(char *word); + int i2c_word_read_simple(char address, uint16_t* return_value); + int i2c_word_read_interpreter(uint16_t address, uint16_t* return_value); + int i2c_word_write(char *word); + int i2c_word_write_simple(char address, uint16_t value); + int i2c_word_write_interpreter(uint16_t address, uint16_t value); + + //int i2c_window_open(); + //int i2c_motor_start(); + + int i2c_config_mode_entry(); + int i2c_mlx_mode_entry(); + int i2c_htol_mode_entry(); + int i2c_skip_app_copy(); + int i2c_soft_reset(); + bool i2c_check_busy_flag(void); + void wait_for_idle_state(void); + void wait_for_application_state(void); + + + int i2c_set_50k_pwm(unsigned int pwm50k); + + int i2c_set_position_pulse_width(unsigned int manstisa_2b, unsigned int exponenet_3b); + int i2c_set_position_flat(unsigned int mantisaa_2b, unsigned int exponent_3b); + int i2c_set_position_duty(unsigned int duty_2b); + int i2c_set_position_maj_vote(unsigned int maj_1b); + int i2c_set_position_anti_cog(unsigned int cog_1b); + + int i2c_set_start_up_pulse_width(unsigned int mantisaa_3b, unsigned int exponent_3b); + + int i2c_set_start_up_duty(unsigned int duty_2b); + int i2c_set_start_up_flat(unsigned int mantisaa_3b, unsigned int exponent_3b); + int i2c_set_start_up_num_comm(unsigned int comm); + int i2c_set_soft_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b, unsigned int step_size, unsigned int num_steps); + int i2c_set_high_torque_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b); + int i2c_set_single_pulse_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b); + + int i2c_force_rough_reg(unsigned int reg); + int i2c_set_rough_gain(unsigned int rough_gain); + int i2c_set_ehp_reg_gain(unsigned int ehp_gain); + int i2c_set_fall_time_blank(unsigned int blank_time); + + int i2c_set_comm_i_thres(unsigned int i_thr_low, unsigned int i_thr_high); + int i2c_set_comm_di_thres(unsigned int di_1st, unsigned int di_2nd); + + + int i2c_clear_spd_ctrl(); + int i2c_set_input_mode(unsigned int mode); + int i2c_set_loop_mode(unsigned int openloop); + int i2c_set_curve_type(unsigned int curvetype); + int i2c_set_dc_ini(unsigned int ini); + int i2c_set_dc_sr(unsigned int sr); + int i2c_set_open_loop_duty(unsigned int duty); + + int i2c_set_clim_start_up(unsigned int clim); + int i2c_set_clim_brake(unsigned int clim); + int i2c_set_clim_run_time(unsigned int clim); + + int i2c_enable_pules_debug_mode(unsigned int enable); + +private: + I2C i2c_master; + unsigned int nv_positin_val; + unsigned int nv_start_up_val; + unsigned int nv_wind_brake_val; + unsigned int nv_spd_control_1_val; + unsigned int nv_spd_control_2_val; + unsigned int ram_open_duty_val; + unsigned int nv_gen_ctrl_val; + unsigned int nv_comm_ctrl_val; + unsigned int nv_application_cfg_val; + unsigned int nv_i_zc_th_high_val; + unsigned int nv_i_zc_th_low_val; + unsigned int nv_di_th_1st_val; + unsigned int nv_di_th_2nd_val; + unsigned int nv_dig_config_val; + unsigned int nv_clim_user_1_val; + unsigned int nv_clim_user_0_val; + unsigned int nv_positin2_val; + unsigned int ram_debug_ctrl_val; + //Position Detection Task/Functions +}; + + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i2c_ram_defines.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,98 @@ +// Generated by 90418_MEMmap.xlsm on 2021-06-03 10:02 +// RAM zone defines +#define DMA_START_RAM_ZONE_RAM_STACK 0x1220 +#define DMA_START_RAM_ZONE_RAM_GLOBAL_VARIABLES 0x1200 +#define DMA_START_RAM_ZONE_RAM_PATCH_TRIM 0x11E0 +#define DMA_START_RAM_ZONE_RAM_PATCH_EXTENSION 0x1094 +#define DMA_START_RAM_ZONE_RAM_MLX_CALIBRATION 0x1064 +#define DMA_START_RAM_ZONE_RAM_MLX_I2C_REGISTER_MAPPING 0x105C +#define DMA_START_RAM_ZONE_RAM_APPLICATION_TRIMMING 0x1010 +#define DMA_START_RAM_ZONE_RAM_I2C_REGISTER_MAPPING 0x1000 + + +// I2C RAM command defines +#define I2C_RAM_PATCH_TRIM_0 0x00F0 +#define I2C_CRC_PATCH_23 0x004B +#define I2C_CRC_PATCH_01 0x004A +#define I2C_MLX_CALIB_23 0x0049 +#define I2C_MLX_CALIB_22 0x0048 +#define I2C_MLX_CALIB_21 0x0047 +#define I2C_MLX_CALIB_20 0x0046 +#define I2C_MLX_CALIB_19 0x0045 +#define I2C_MLX_CALIB_18 0x0044 +#define I2C_MLX_CALIB_17 0x0043 +#define I2C_MLX_CALIB_16 0x0042 +#define I2C_MLX_CALIB_15 0x0041 +#define I2C_MLX_CALIB_14 0x0040 +#define I2C_MLX_CALIB_13 0x003F +#define I2C_MLX_CALIB_12 0x003E +#define I2C_MLX_CALIB_11 0x003D +#define I2C_MLX_CALIB_10 0x003C +#define I2C_MLX_CALIB_9 0x003B +#define I2C_MLX_CALIB_8 0x003A +#define I2C_MLX_CALIB_7 0x0039 +#define I2C_MLX_CALIB_6 0x0038 +#define I2C_MLX_CALIB_5 0x0037 +#define I2C_MLX_CALIB_4 0x0036 +#define I2C_MLX_CALIB_3 0x0035 +#define I2C_MLX_CALIB_2 0x0034 +#define I2C_CLIM_SET 0x0033 +#define I2C_CLIM_CALIB 0x0032 +#define I2C_CMD_INTERPRETER_DATA 0x0031 +#define I2C_CMD_INTERPRETER_ADDRESS 0x0030 +#define I2C_STARTUP_FLAGS_2 0x002F +#define I2C_STARTUP_FLAGS_1 0x002E +#define I2C_MTP_CFGZONE_0 0x002D +#define I2C_CUST_ID0 0x002C +#define I2C_CUST_ID1 0x002B +#define I2C_CUST_ID2 0x002A +#define I2C_CUST_ID3 0x0029 +#define I2C_DIGITAL_CFG 0x0028 +#define I2C_ZONE0_RES1 0x0027 +#define I2C_ZONE0_RES2 0x0026 +#define I2C_ZONE0_RES3 0x0025 +#define I2C_ZONE0_RES4 0x0024 +#define I2C_CLIM_USER_1 0x0023 +#define I2C_CLIM_USER_0 0x0022 +#define I2C_OC_CL_CTRL 0x0021 +#define I2C_DI_TH_1ST_REG 0x0020 +#define I2C_DI_TH_2ND_REG 0x001F +#define I2C_I_ZC_TH_HIGH_REG 0x001E +#define I2C_I_ZC_TH_LOW_REG 0x001D +#define I2C_CURVE_PAR_F 0x001C +#define I2C_CURVE_PAR_E 0x001B +#define I2C_CURVE_PAR_D 0x001A +#define I2C_CURVE_PAR_C 0x0019 +#define I2C_CURVE_PAR_B 0x0018 +#define I2C_CURVE_PAR_A 0x0017 +#define I2C_CURVE_PNT_MAX 0x0016 +#define I2C_CURVE_PNT_MIN 0x0015 +#define I2C_SPD_CTRL_2 0x0014 +#define I2C_SPD_CTRL_1 0x0013 +#define I2C_MIN_EHP 0x0012 +#define I2C_POSITION2 0x0011 +#define I2C_WIND_BRAKE2 0x0010 +#define I2C_WIND_BRAKE 0x000F +#define I2C_START_UP 0x000E +#define I2C_POSITION 0x000D +#define I2C_GEN_CTRL 0x000C +#define I2C_APPLICATION_CFG4 0x000B +#define I2C_APPLICATION_CFG3 0x000A +#define I2C_APPLICATION_CFG2 0x0009 +#define I2C_APPLICATION_CFG 0x0008 +#define I2C_STATE 0x0007 +#define I2C_I2C_RESERVED_2 0x0006 +#define I2C_TEMPERATURE 0x0005 +#define I2C_STATUS 0x0004 +#define I2C_FEEDBACK 0x0003 +#define I2C_COMMAND_KEY 0x0002 +#define I2C_COMMAND_CONTROL 0x0001 +#define I2C_SPEED_DUTY 0x0000 + +// Useful masks +#define I2C_STATUS_COMMAND_BUSY_MASK (1u << 4u) +#define I2C_STATE_COMM_STATE_MASK (0xFF) +#define I2C_STATE_COMM_STATE_OFFSET (0u) + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/cc.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,206 @@ +/*- + * 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 cc.h + * + * @brief compiler detection + * + * + */ + +#ifndef __SCPI_CC_H_ +#define __SCPI_CC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__STDC__) +# define C89 1 +# if defined(__STDC_VERSION__) +# define C90 1 +# if (__STDC_VERSION__ >= 199409L) +# define C94 1 +# endif +# if (__STDC_VERSION__ >= 199901L) +# define C99 1 +# endif +# endif +#endif + +#if (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200809L) || \ + (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 700) + #define HAVE_STRNDUP 1 + #define HAVE_STRNLEN 1 +#endif + +#if (defined _BSD_SOURCE && _BSD_SOURCE) || \ + (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 500) || \ + (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ + (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \ + C99 + #define HAVE_SNPRINTF 1 +#endif + +#if (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) + #define HAVE_STRNCASECMP 1 +#endif + +#if (defined _BSD_SOURCE && _BSD_SOURCE) || \ + (defined _SVID_SOURCE && _SVID_SOURCE) || \ + (defined _XOPEN_SOURCE && _XOPEN_SOURCE) || \ + (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ + (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) ||\ + C99 + #define HAVE_ISNAN 1 +#endif + +#if (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 600)|| \ + (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ + (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \ + C99 + #define HAVE_ISFINITE 1 + #define HAVE_SIGNBIT 1 +#endif + +#if (defined _XOPEN_SOURCE && XOPEN_SOURCE >= 600) || \ + (defined _BSD_SOURCE && _BSD_SOURCE) || \ + (defined _SVID_SOURCE && _SVID_SOURCE) || \ + (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ + (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) + #define HAVE_STRTOLL 1 +#endif + +#if (defined _XOPEN_SOURCE && _XOPEN_SOURCE >= 600) || \ + (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || \ + (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 200112L) || \ + C99 + #define HAVE_STRTOF 1 +#endif + +#if (defined _ISOC99_SOURCE && _ISOC99_SOURCE) || C99 + #define HAVE_STDBOOL 1 +#endif + +/* Compiler specific */ +/* RealView/Keil ARM Compiler, e.g. Cortex-M CPUs */ +#if defined(__CC_ARM) +#define HAVE_STRNCASECMP 1 +#endif + +/* National Instruments (R) CVI x86/x64 PC platform */ +#if defined(_CVI_) +#define HAVE_STRNICMP 1 +#endif + +/* 8bit PIC - PIC16, etc */ +#if defined(_MPC_) +#define HAVE_STRNICMP 1 +#endif + +/* PIC24 */ +#if defined(__C30__) +#endif + +/* PIC32mx */ +#if defined(__C32__) +#define HAVE_FINITE 1 +#endif + +/* AVR libc */ +#if defined(__AVR__) +#include <stdlib.h> +#define HAVE_DTOSTRE 1 +#undef HAVE_STRTOF +#define HAVE_STRTOF 0 +#endif + +/* default values */ +#ifndef HAVE_STRNLEN +#define HAVE_STRNLEN 0 +#endif + +#ifndef HAVE_STRDUP +#define HAVE_STRDUP 0 +#endif + +#ifndef HAVE_STRNDUP +#define HAVE_STRNDUP 0 +#endif + +#ifndef HAVE_STRNICMP +#define HAVE_STRNICMP 0 +#endif + +#ifndef HAVE_STDBOOL +#define HAVE_STDBOOL 0 +#endif + +#ifndef HAVE_SNPRINTF +#define HAVE_SNPRINTF 0 +#endif + +#ifndef HAVE_STRNCASECMP +#define HAVE_STRNCASECMP 0 +#endif + +#ifndef HAVE_ISNAN +#define HAVE_ISNAN 0 +#endif + +#ifndef HAVE_ISFINITE +#define HAVE_ISFINITE 0 +#endif + +#ifndef HAVE_FINITE +#define HAVE_FINITE 0 +#endif + +#ifndef HAVE_SIGNBIT +#define HAVE_SIGNBIT 0 +#endif + +#ifndef HAVE_STRTOLL +#define HAVE_STRTOLL 0 +#endif + +#ifndef HAVE_STRTOF +#define HAVE_STRTOF 0 +#endif + +#ifndef HAVE_DTOSTRE +#define HAVE_DTOSTRE 0 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __SCPI_CC_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/config.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,288 @@ +/*- + * 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 config.h + * @date Wed Mar 20 12:21:26 UTC 2013 + * + * @brief SCPI Configuration + * + * + */ + +#ifndef __SCPI_CONFIG_H_ +#define __SCPI_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cc.h" + +#ifdef SCPI_USER_CONFIG +#include "scpi_user_config.h" +#endif + +/* set the termination character(s) */ +#define LINE_ENDING_CR "\r" /* use a <CR> carriage return as termination charcter */ +#define LINE_ENDING_LF "\n" /* use a <LF> line feed as termination charcter */ +#define LINE_ENDING_CRLF "\r\n" /* use <CR><LF> carriage return + line feed as termination charcters */ + +#ifndef SCPI_LINE_ENDING +#define SCPI_LINE_ENDING LINE_ENDING_CRLF +#endif + +/** + * Detect, if it has limited resources or it is running on a full blown operating system. + * All values can be overiden by scpi_user_config.h + */ +#define SYSTEM_BARE_METAL 0 +#define SYSTEM_FULL_BLOWN 1 + +/* This should cover all windows compilers (msvc, mingw, cvi) and all Linux/OSX/BSD and other UNIX compatible systems (gcc, clang) */ +#if defined(_WIN32) || defined(_WIN64) || defined(__unix) || defined(__unix__) || defined(__APPLE__) +#define SYSTEM_TYPE SYSTEM_FULL_BLOWN +#else +#define SYSTEM_TYPE SYSTEM_BARE_METAL +#endif + +/** + * Enable full error list + * 0 = Minimal set of errors + * 1 = Full set of errors + * + * For small systems, full set of errors will occupy large ammount of data + * It is enabled by default on full blown systems and disabled on limited bare metal systems + */ +#ifndef USE_FULL_ERROR_LIST +#define USE_FULL_ERROR_LIST SYSTEM_TYPE +#endif + +/** + * Enable also LIST_OF_USER_ERRORS to be included + * 0 = Use only library defined errors + * 1 = Use also LIST_OF_USER_ERRORS + */ +#ifndef USE_USER_ERROR_LIST +#define USE_USER_ERROR_LIST 0 +#endif + +#ifndef USE_DEVICE_DEPENDENT_ERROR_INFORMATION +#define USE_DEVICE_DEPENDENT_ERROR_INFORMATION SYSTEM_TYPE +#endif + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION +#ifndef USE_MEMORY_ALLOCATION_FREE +#define USE_MEMORY_ALLOCATION_FREE 1 +#endif +#else +#ifndef USE_MEMORY_ALLOCATION_FREE +#define USE_MEMORY_ALLOCATION_FREE 0 +#endif +#endif + +#ifndef USE_COMMAND_TAGS +#define USE_COMMAND_TAGS 1 +#endif + +#ifndef USE_DEPRECATED_FUNCTIONS +#define USE_DEPRECATED_FUNCTIONS 1 +#endif + +#ifndef USE_CUSTOM_DTOSTRE +#define USE_CUSTOM_DTOSTRE 0 +#endif + +#ifndef USE_UNITS_IMPERIAL +#define USE_UNITS_IMPERIAL 0 +#endif + +#ifndef USE_UNITS_ANGLE +#define USE_UNITS_ANGLE SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_PARTICLES +#define USE_UNITS_PARTICLES SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_DISTANCE +#define USE_UNITS_DISTANCE SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_MAGNETIC +#define USE_UNITS_MAGNETIC SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_LIGHT +#define USE_UNITS_LIGHT SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_ENERGY_FORCE_MASS +#define USE_UNITS_ENERGY_FORCE_MASS SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_TIME +#define USE_UNITS_TIME SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_TEMPERATURE +#define USE_UNITS_TEMPERATURE SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_RATIO +#define USE_UNITS_RATIO SYSTEM_TYPE +#endif + +#ifndef USE_UNITS_POWER +#define USE_UNITS_POWER 1 +#endif + +#ifndef USE_UNITS_FREQUENCY +#define USE_UNITS_FREQUENCY 1 +#endif + +#ifndef USE_UNITS_ELECTRIC +#define USE_UNITS_ELECTRIC 1 +#endif + +#ifndef USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE +#define USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE SYSTEM_TYPE +#endif + +/* define local macros depending on existance of strnlen */ +#if HAVE_STRNLEN +#define SCPIDEFINE_strnlen(s, l) strnlen((s), (l)) +#else +#define SCPIDEFINE_strnlen(s, l) BSD_strnlen((s), (l)) +#endif + +/* define local macros depending on existance of strncasecmp and strnicmp */ +#if HAVE_STRNCASECMP +#define SCPIDEFINE_strncasecmp(s1, s2, l) strncasecmp((s1), (s2), (l)) +#elif HAVE_STRNICMP +#define SCPIDEFINE_strncasecmp(s1, s2, l) strnicmp((s1), (s2), (l)) +#else +#define SCPIDEFINE_strncasecmp(s1, s2, l) OUR_strncasecmp((s1), (s2), (l)) +#endif + +#if HAVE_DTOSTRE +#define SCPIDEFINE_floatToStr(v, s, l) dtostre((double)(v), (s), 6, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE) +#elif USE_CUSTOM_DTOSTRE +#define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0) +#elif HAVE_SNPRINTF +#define SCPIDEFINE_floatToStr(v, s, l) snprintf((s), (l), "%g", (v)) +#else +#define SCPIDEFINE_floatToStr(v, s, l) SCPI_dtostre((v), (s), (l), 6, 0) +#endif + +#if HAVE_DTOSTRE +#define SCPIDEFINE_doubleToStr(v, s, l) dtostre((v), (s), 15, DTOSTR_PLUS_SIGN | DTOSTR_ALWAYS_SIGN | DTOSTR_UPPERCASE) +#elif USE_CUSTOM_DTOSTRE +#define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0) +#elif HAVE_SNPRINTF +#define SCPIDEFINE_doubleToStr(v, s, l) snprintf((s), (l), "%.15lg", (v)) +#else +#define SCPIDEFINE_doubleToStr(v, s, l) SCPI_dtostre((v), (s), (l), 15, 0) +#endif + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + + #if USE_MEMORY_ALLOCATION_FREE + #include <stdlib.h> + #include <string.h> + #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 2 + #if HAVE_STRNDUP + #define SCPIDEFINE_strndup(h, s, l) strndup((s), (l)) + #else + #define SCPIDEFINE_strndup(h, s, l) OUR_strndup((s), (l)) + #endif + #define SCPIDEFINE_free(h, s, r) free((s)) + #else + #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 3 + #define SCPIDEFINE_strndup(h, s, l) scpiheap_strndup((h), (s), (l)) + #define SCPIDEFINE_free(h, s, r) scpiheap_free((h), (s), (r)) + #define SCPIDEFINE_get_parts(h, s, l1, s2, l2) scpiheap_get_parts((h), (s), (l1), (s2), (l2)) + #endif +#else + #define SCPIDEFINE_DESCRIPTION_MAX_PARTS 1 + #define SCPIDEFINE_strndup(h, s, l) NULL + #define SCPIDEFINE_free(h, s, r) +#endif + +#if HAVE_SIGNBIT + #define SCPIDEFINE_signbit(n) signbit(n) +#else + #define SCPIDEFINE_signbit(n) ((n)<0) +#endif + +#if HAVE_FINITE + #define SCPIDEFINE_isfinite(n) finite(n) +#elif HAVE_ISFINITE + #define SCPIDEFINE_isfinite(n) isfinite(n) +#else + #define SCPIDEFINE_isfinite(n) (!SCPIDEFINE_isnan((n)) && ((n) < INFINITY) && ((n) > -INFINITY)) +#endif + +#if HAVE_STRTOF + #define SCPIDEFINE_strtof(n, p) strtof((n), (p)) +#else + #define SCPIDEFINE_strtof(n, p) strtod((n), (p)) +#endif + +#if HAVE_STRTOLL + #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b)) + #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b)) +#else + #define SCPIDEFINE_strtoll(n, p, b) strtoll((n), (p), (b)) + #define SCPIDEFINE_strtoull(n, p, b) strtoull((n), (p), (b)) + extern long long int strtoll(const char *nptr, char **endptr, int base); + extern unsigned long long int strtoull(const char *nptr, char **endptr, int base); + /* TODO: implement OUR_strtoll and OUR_strtoull */ + /* #warning "64bit string to int conversion not implemented" */ +#endif + +#if HAVE_ISNAN + #define SCPIDEFINE_isnan(n) isnan((n)) +#else + #define SCPIDEFINE_isnan(n) ((n) != (n)) +#endif + +#ifndef NAN + #define NAN (0.0 / 0.0) +#endif + +#ifndef INFINITY + #define INFINITY (1.0 / 0.0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/constants.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,63 @@ +/*- + * 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_constants.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI Device constants + * + * + */ + +#ifndef SCPI_CONSTANTS_H +#define SCPI_CONSTANTS_H + +#ifdef __cplusplus +extern "C" { +#endif + + /* 21.21 :VERSion? + * YYYY.V + * YYYY = SCPI year + * V = SCPI revision + */ +#define SCPI_STD_VERSION_REVISION "1999.0" + +/* 21.8 :ERRor Subsystem + * The maximum string length of <Error/event_description> plus <Device-dependent_info> is 255 characters. + */ +#define SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH 255 + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_CONSTANTS_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/error.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,209 @@ +/*- + * 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_error.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief Error handling and storing routines + * + * + */ + +#ifndef SCPI_ERROR_H +#define SCPI_ERROR_H + +#include "scpi/config.h" +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size); + void SCPI_ErrorClear(scpi_t * context); + scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error); + void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info, size_t info_len); + void SCPI_ErrorPush(scpi_t * context, int16_t err); + int32_t SCPI_ErrorCount(scpi_t * context); + const char * SCPI_ErrorTranslate(int16_t err); + + + /* Using X-Macro technique to define everything once + * http://en.wikipedia.org/wiki/X_Macro + * + * X macro is for minimal set of errors for library itself + * XE macro is for full set of SCPI errors available to user application + */ +#define LIST_OF_ERRORS \ + X(SCPI_ERROR_NO_ERROR, 0, "No error") \ + XE(SCPI_ERROR_COMMAND, -100, "Command error") \ + X(SCPI_ERROR_INVALID_CHARACTER, -101, "Invalid character") \ + XE(SCPI_ERROR_SYNTAX, -102, "Syntax error") \ + X(SCPI_ERROR_INVALID_SEPARATOR, -103, "Invalid separator") \ + X(SCPI_ERROR_DATA_TYPE_ERROR, -104, "Data type error") \ + XE(SCPI_ERROR_GET_NOT_ALLOWED, -105, "GET not allowed") \ + X(SCPI_ERROR_PARAMETER_NOT_ALLOWED, -108, "Parameter not allowed") \ + X(SCPI_ERROR_MISSING_PARAMETER, -109, "Missing parameter") \ + XE(SCPI_ERROR_COMMAND_HEADER, -110, "Command header error") \ + XE(SCPI_ERROR_HEADER_SEPARATOR, -111, "Header separator error") \ + XE(SCPI_ERROR_PRG_MNEMONIC_TOO_LONG, -112, "Program mnemonic too long") \ + X(SCPI_ERROR_UNDEFINED_HEADER, -113, "Undefined header") \ + XE(SCPI_ERROR_HEADER_SUFFIX_OUTOFRANGE, -114, "Header suffix out of range") \ + XE(SCPI_ERROR_UNEXP_NUM_OF_PARAMETER, -115, "Unexpected number of parameters") \ + XE(SCPI_ERROR_NUMERIC_DATA_ERROR, -120, "Numeric data error") \ + XE(SCPI_ERROR_INVAL_CHAR_IN_NUMBER, -121, "Invalid character in number") \ + XE(SCPI_ERROR_EXPONENT_TOO_LONG, -123, "Exponent too large") \ + XE(SCPI_ERROR_TOO_MANY_DIGITS, -124, "Too many digits") \ + XE(SCPI_ERROR_NUMERIC_DATA_NOT_ALLOWED, -128, "Numeric data not allowed") \ + XE(SCPI_ERROR_SUFFIX_ERROR, -130, "Suffix error") \ + X(SCPI_ERROR_INVALID_SUFFIX, -131, "Invalid suffix") \ + XE(SCPI_ERROR_SUFFIX_TOO_LONG, -134, "Suffix too long") \ + X(SCPI_ERROR_SUFFIX_NOT_ALLOWED, -138, "Suffix not allowed") \ + XE(SCPI_ERROR_CHARACTER_DATA_ERROR, -140, "Character data error") \ + XE(SCPI_ERROR_INVAL_CHARACTER_DATA, -141, "Invalid character data") \ + XE(SCPI_ERROR_CHARACTER_DATA_TOO_LONG, -144, "Character data too long") \ + XE(SCPI_ERROR_CHARACTER_DATA_NOT_ALLOWED, -148, "Character data not allowed") \ + XE(SCPI_ERROR_STRING_DATA_ERROR, -150, "String data error") \ + X(SCPI_ERROR_INVALID_STRING_DATA, -151, "Invalid string data") \ + XE(SCPI_ERROR_STRING_DATA_NOT_ALLOWED, -158, "String data not allowed") \ + XE(SCPI_ERROR_BLOCK_DATA_ERROR, -160, "Block data error") \ + XE(SCPI_ERROR_INVALID_BLOCK_DATA, -161, "Invalid block data") \ + XE(SCPI_ERROR_BLOCK_DATA_NOT_ALLOWED, -168, "Block data not allowed") \ + X(SCPI_ERROR_EXPRESSION_PARSING_ERROR, -170, "Expression error") \ + XE(SCPI_ERROR_INVAL_EXPRESSION, -171, "Invalid expression") \ + XE(SCPI_ERROR_EXPRESSION_DATA_NOT_ALLOWED, -178, "Expression data not allowed") \ + XE(SCPI_ERROR_MACRO_DEFINITION_ERROR, -180, "Macro error") \ + XE(SCPI_ERROR_INVAL_OUTSIDE_MACRO_DEF, -181, "Invalid outside macro definition") \ + XE(SCPI_ERROR_INVAL_INSIDE_MACRO_DEF, -183, "Invalid inside macro definition") \ + XE(SCPI_ERROR_MACRO_PARAMETER_ERROR, -184, "Macro parameter error") \ + X(SCPI_ERROR_EXECUTION_ERROR, -200, "Execution error") \ + XE(SCPI_ERROR_INVAL_WHILE_IN_LOCAL, -201, "Invalid while in local") \ + XE(SCPI_ERROR_SETTINGS_LOST_DUE_TO_RTL, -202, "Settings lost due to rtl") \ + XE(SCPI_ERROR_COMMAND_PROTECTED, -203, "Command protected") \ + XE(SCPI_ERROR_TRIGGER_ERROR, -210, "Trigger error") \ + XE(SCPI_ERROR_TRIGGER_IGNORED, -211, "Trigger ignored") \ + XE(SCPI_ERROR_ARM_IGNORED, -212, "Arm ignored") \ + XE(SCPI_ERROR_INIT_IGNORED, -213, "Init ignored") \ + XE(SCPI_ERROR_TRIGGER_DEADLOCK, -214, "Trigger deadlock") \ + XE(SCPI_ERROR_ARM_DEADLOCK, -215, "Arm deadlock") \ + XE(SCPI_ERROR_PARAMETER_ERROR, -220, "Parameter error") \ + XE(SCPI_ERROR_SETTINGS_CONFLICT, -221, "Settings conflict") \ + XE(SCPI_ERROR_DATA_OUT_OF_RANGE, -222, "Data out of range") \ + XE(SCPI_ERROR_TOO_MUCH_DATA, -223, "Too much data") \ + X(SCPI_ERROR_ILLEGAL_PARAMETER_VALUE, -224, "Illegal parameter value") \ + XE(SCPI_ERROR_OUT_OF_MEMORY_FOR_REQ_OP, -225, "Out of memory") \ + XE(SCPI_ERROR_LISTS_NOT_SAME_LENGTH, -226, "Lists not same length") \ + XE(SCPI_ERROR_DATA_CORRUPT, -230, "Data corrupt or stale") \ + XE(SCPI_ERROR_DATA_QUESTIONABLE, -231, "Data questionable") \ + XE(SCPI_ERROR_INVAL_VERSION, -233, "Invalid version") \ + XE(SCPI_ERROR_HARDWARE_ERROR, -240, "Hardware error") \ + XE(SCPI_ERROR_HARDWARE_MISSING, -241, "Hardware missing") \ + XE(SCPI_ERROR_MASS_STORAGE_ERROR, -250, "Mass storage error") \ + XE(SCPI_ERROR_MISSING_MASS_STORAGE, -251, "Missing mass storage") \ + XE(SCPI_ERROR_MISSING_MASS_MEDIA, -252, "Missing media") \ + XE(SCPI_ERROR_CORRUPT_MEDIA, -253, "Corrupt media") \ + XE(SCPI_ERROR_MEDIA_FULL, -254, "Media full") \ + XE(SCPI_ERROR_DIRECTORY_FULL, -255, "Directory full") \ + XE(SCPI_ERROR_FILE_NAME_NOT_FOUND, -256, "File name not found") \ + XE(SCPI_ERROR_FILE_NAME_ERROR, -257, "File name error") \ + XE(SCPI_ERROR_MEDIA_PROTECTED, -258, "Media protected") \ + XE(SCPI_ERROR_EXPRESSION_EXECUTING_ERROR, -260, "Expression error") \ + XE(SCPI_ERROR_MATH_ERROR_IN_EXPRESSION, -261, "Math error in expression") \ + XE(SCPI_ERROR_MACRO_UNDEF_EXEC_ERROR, -270, "Macro error") \ + XE(SCPI_ERROR_MACRO_SYNTAX_ERROR, -271, "Macro syntax error") \ + XE(SCPI_ERROR_MACRO_EXECUTION_ERROR, -272, "Macro execution error") \ + XE(SCPI_ERROR_ILLEGAL_MACRO_LABEL, -273, "Illegal macro label") \ + XE(SCPI_ERROR_IMPROPER_USED_MACRO_PARAM, -274, "Macro parameter error") \ + XE(SCPI_ERROR_MACRO_DEFINITION_TOO_LONG, -275, "Macro definition too long") \ + XE(SCPI_ERROR_MACRO_RECURSION_ERROR, -276, "Macro recursion error") \ + XE(SCPI_ERROR_MACRO_REDEF_NOT_ALLOWED, -277, "Macro redefinition not allowed") \ + XE(SCPI_ERROR_MACRO_HEADER_NOT_FOUND, -278, "Macro header not found") \ + XE(SCPI_ERROR_PROGRAM_ERROR, -280, "Program error") \ + XE(SCPI_ERROR_CANNOT_CREATE_PROGRAM, -281, "Cannot create program") \ + XE(SCPI_ERROR_ILLEGAL_PROGRAM_NAME, -282, "Illegal program name") \ + XE(SCPI_ERROR_ILLEGAL_VARIABLE_NAME, -283, "Illegal variable name") \ + XE(SCPI_ERROR_PROGRAM_CURRENTLY_RUNNING, -284, "Program currently running") \ + XE(SCPI_ERROR_PROGRAM_SYNTAX_ERROR, -285, "Program syntax error") \ + XE(SCPI_ERROR_PROGRAM_RUNTIME_ERROR, -286, "Program runtime error") \ + XE(SCPI_ERROR_MEMORY_USE_ERROR, -290, "Memory use error") \ + XE(SCPI_ERROR_OUT_OF_MEMORY, -291, "Out of memory") \ + XE(SCPI_ERROR_REF_NAME_DOES_NOT_EXIST, -292, "Referenced name does not exist") \ + XE(SCPI_ERROR_REF_NAME_ALREADY_EXISTS, -293, "Referenced name already exists") \ + XE(SCPI_ERROR_INCOMPATIBLE_TYPE, -294, "Incompatible type") \ + XE(SCPI_ERROR_DEVICE_ERROR, -300, "Device specific error") \ + X(SCPI_ERROR_SYSTEM_ERROR, -310, "System error") \ + XE(SCPI_ERROR_MEMORY_ERROR, -311, "Memory error") \ + XE(SCPI_ERROR_PUD_MEMORY_LOST, -312, "PUD memory lost") \ + XE(SCPI_ERROR_CALIBRATION_MEMORY_LOST, -313, "Calibration memory lost") \ + XE(SCPI_ERROR_SAVE_RECALL_MEMORY_LOST, -314, "Save/recall memory lost") \ + XE(SCPI_ERROR_CONFIGURATION_MEMORY_LOST, -315, "Configuration memory lost") \ + XE(SCPI_ERROR_STORAGE_FAULT, -320, "Storage fault") \ + XE(SCPI_ERROR_OUT_OF_DEVICE_MEMORY, -321, "Out of memory") \ + XE(SCPI_ERROR_SELF_TEST_FAILED, -330, "Self-test failed") \ + XE(SCPI_ERROR_CALIBRATION_FAILED, -340, "Calibration failed") \ + X(SCPI_ERROR_QUEUE_OVERFLOW, -350, "Queue overflow") \ + XE(SCPI_ERROR_COMMUNICATION_ERROR, -360, "Communication error") \ + XE(SCPI_ERROR_PARITY_ERROR_IN_CMD_MSG, -361, "Parity error in program message") \ + XE(SCPI_ERROR_FRAMING_ERROR_IN_CMD_MSG, -362, "Framing error in program message") \ + X(SCPI_ERROR_INPUT_BUFFER_OVERRUN, -363, "Input buffer overrun") \ + XE(SCPI_ERROR_TIME_OUT, -365, "Time out error") \ + XE(SCPI_ERROR_QUERY_ERROR, -400, "Query error") \ + XE(SCPI_ERROR_QUERY_INTERRUPTED, -410, "Query INTERRUPTED") \ + XE(SCPI_ERROR_QUERY_UNTERMINATED, -420, "Query UNTERMINATED") \ + XE(SCPI_ERROR_QUERY_DEADLOCKED, -430, "Query DEADLOCKED") \ + XE(SCPI_ERROR_QUERY_UNTERM_INDEF_RESP, -440, "Query UNTERMINATED after indefinite response") \ + XE(SCPI_ERROR_POWER_ON, -500, "Power on") \ + XE(SCPI_ERROR_USER_REQUEST, -600, "User request") \ + XE(SCPI_ERROR_REQUEST_CONTROL, -700, "Request control") \ + XE(SCPI_ERROR_OPERATION_COMPLETE, -800, "Operation complete") \ + + + enum { +#define X(def, val, str) def = val, +#if USE_FULL_ERROR_LIST +#define XE X +#else +#define XE(def, val, str) +#endif + LIST_OF_ERRORS + +#if USE_USER_ERROR_LIST + LIST_OF_USER_ERRORS +#endif +#undef X +#undef XE + }; + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_ERROR_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/expression.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,63 @@ +/*- + * 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 expression.h + * + * @brief Expressions handling + * + * + */ +#ifndef SCPI_EXPRESSION_H +#define SCPI_EXPRESSION_H + +#include "scpi/config.h" +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + enum _scpi_expr_result_t { + SCPI_EXPR_OK = 0, + SCPI_EXPR_ERROR, + SCPI_EXPR_NO_MORE, + }; + typedef enum _scpi_expr_result_t scpi_expr_result_t; + + scpi_expr_result_t SCPI_ExprNumericListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, scpi_parameter_t * valueFrom, scpi_parameter_t * valueTo); + scpi_expr_result_t SCPI_ExprNumericListEntryInt(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valueFrom, int32_t * valueTo); + scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo); + scpi_expr_result_t SCPI_ExprChannelListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valuesFrom, int32_t * valuesTo, size_t length, size_t * dimensions); + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_EXPRESSION_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/ieee488.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,95 @@ +/*- + * 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_ieee488.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief Implementation of IEEE488.2 commands and state model + * + * + */ + +#ifndef SCPI_IEEE488_H +#define SCPI_IEEE488_H + +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + scpi_result_t SCPI_CoreCls(scpi_t * context); + scpi_result_t SCPI_CoreEse(scpi_t * context); + scpi_result_t SCPI_CoreEseQ(scpi_t * context); + scpi_result_t SCPI_CoreEsrQ(scpi_t * context); + scpi_result_t SCPI_CoreIdnQ(scpi_t * context); + scpi_result_t SCPI_CoreOpc(scpi_t * context); + scpi_result_t SCPI_CoreOpcQ(scpi_t * context); + scpi_result_t SCPI_CoreRst(scpi_t * context); + scpi_result_t SCPI_CoreSre(scpi_t * context); + scpi_result_t SCPI_CoreSreQ(scpi_t * context); + scpi_result_t SCPI_CoreStbQ(scpi_t * context); + scpi_result_t SCPI_CoreTstQ(scpi_t * context); + scpi_result_t SCPI_CoreWai(scpi_t * context); + + +#define STB_R01 0x01 /* Not used */ +#define STB_PRO 0x02 /* Protection Event Flag */ +#define STB_QMA 0x04 /* Error/Event queue message available */ +#define STB_QES 0x08 /* Questionable status */ +#define STB_MAV 0x10 /* Message Available */ +#define STB_ESR 0x20 /* Standard Event Status Register */ +#define STB_SRQ 0x40 /* Service Request */ +#define STB_OPS 0x80 /* Operation Status Flag */ + + +#define ESR_OPC 0x01 /* Operation complete */ +#define ESR_REQ 0x02 /* Request Control */ +#define ESR_QER 0x04 /* Query Error */ +#define ESR_DER 0x08 /* Device Dependent Error */ +#define ESR_EER 0x10 /* Execution Error (e.g. range error) */ +#define ESR_CER 0x20 /* Command error (e.g. syntax error) */ +#define ESR_URQ 0x40 /* User Request */ +#define ESR_PON 0x80 /* Power On */ + + + scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name); + void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val); + void SCPI_RegSetBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits); + void SCPI_RegClearBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits); + + void SCPI_EventClear(scpi_t * context); + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_IEEE488_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/minimal.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,70 @@ +/*- + * 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_minimal.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI minimal implementation + * + * + */ + +#ifndef SCPI_MINIMAL_H +#define SCPI_MINIMAL_H + +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + scpi_result_t SCPI_Stub(scpi_t * context); + scpi_result_t SCPI_StubQ(scpi_t * context); + + scpi_result_t SCPI_SystemVersionQ(scpi_t * context); + scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context); + scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context); + scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context); + scpi_result_t SCPI_StatusQuestionableConditionQ(scpi_t * context); + scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context); + scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context); + scpi_result_t SCPI_StatusOperationConditionQ(scpi_t * context); + scpi_result_t SCPI_StatusOperationEventQ(scpi_t * context); + scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context); + scpi_result_t SCPI_StatusOperationEnable(scpi_t * context); + scpi_result_t SCPI_StatusPreset(scpi_t * context); + + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_MINIMAL_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/parser.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,152 @@ +/*- + * 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_parser.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI parser implementation + * + * + */ + +#ifndef SCPI_PARSER_H +#define SCPI_PARSER_H + +#include <string.h> +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + void SCPI_Init(scpi_t * context, + const scpi_command_t * commands, + scpi_interface_t * interface, + const scpi_unit_def_t * units, + const char * idn1, const char * idn2, const char * idn3, const char * idn4, + char * input_buffer, size_t input_buffer_length, + scpi_error_t * error_queue_data, int16_t error_queue_size); +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE + void SCPI_InitHeap(scpi_t * context, char * error_info_heap, size_t error_info_heap_length); +#endif + + scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len); + scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len); + + size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len); +#define SCPI_ResultMnemonic(context, data) SCPI_ResultCharacters((context), (data), strlen(data)) +#define SCPI_ResultUInt8Base(c, v, b) SCPI_ResultUInt32Base((c), (v), (uint8_t)(b)) +#define SCPI_ResultUInt8(c, v) SCPI_ResultUInt32Base((c), (uint8_t)(v), 10) +#define SCPI_ResultInt8(c, v) SCPI_ResultInt32((c), (int8_t)(v)) +#define SCPI_ResultUInt16Base(c, v, b) SCPI_ResultUInt32Base((c), (uint16_t)(v), (b)) +#define SCPI_ResultUInt16(c, v) SCPI_ResultUInt32Base((c), (uint16_t)(v), 10) +#define SCPI_ResultInt16(c, v) SCPI_ResultInt32((c), (int16_t)(v)) + size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base); +#define SCPI_ResultUInt32(c, v) SCPI_ResultUInt32Base((c), (v), 10) + size_t SCPI_ResultInt32(scpi_t * context, int32_t val); + size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base); +#define SCPI_ResultUInt64(c, v) SCPI_ResultUInt64Base((c), (v), 10) + size_t SCPI_ResultInt64(scpi_t * context, int64_t val); + size_t SCPI_ResultFloat(scpi_t * context, float val); + size_t SCPI_ResultDouble(scpi_t * context, double val); + size_t SCPI_ResultText(scpi_t * context, const char * data); + size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error); + size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len); + size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len); + size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len); + size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val); + + size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format); + size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format); + + scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamIsValid(scpi_parameter_t * parameter); + scpi_bool_t SCPI_ParamErrorOccurred(scpi_t * context); + scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed); + scpi_bool_t SCPI_ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value); + scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value); + scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value); + scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value); + scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value); + scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value); + scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value); + scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text); + + scpi_bool_t SCPI_ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamCopyText(scpi_t * context, char * buffer, size_t buffer_len, size_t * copy_len, scpi_bool_t mandatory); + + extern const scpi_choice_def_t scpi_bool_def[]; + scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory); + + scpi_bool_t SCPI_ParamArrayInt32(scpi_t * context, int32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamArrayUInt32(scpi_t * context, uint32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamArrayInt64(scpi_t * context, int64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamArrayUInt64(scpi_t * context, uint64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamArrayFloat(scpi_t * context, float *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); + scpi_bool_t SCPI_ParamArrayDouble(scpi_t * context, double *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory); + + scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd); +#if USE_COMMAND_TAGS + int32_t SCPI_CmdTag(scpi_t * context); +#endif /* USE_COMMAND_TAGS */ + scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len); + scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value); + +#if USE_DEPRECATED_FUNCTIONS + /* deprecated finction, should be removed later */ +#define SCPI_ResultIntBase(context, val, base) SCPI_ResultInt32Base ((context), (val), (base), TRUE) +#define SCPI_ResultInt(context, val) SCPI_ResultInt32 ((context), (val)) +#define SCPI_ParamToInt(context, parameter, value) SCPI_ParamToInt32((context), (parameter), (value)) +#define SCPI_ParamToUnsignedInt(context, parameter, value) SCPI_ParamToUInt32((context), (parameter), (value)) +#define SCPI_ParamInt(context, value, mandatory) SCPI_ParamInt32((context), (value), (mandatory)) +#define SCPI_ParamUnsignedInt(context, value, mandatory) SCPI_ParamUInt32((context), (value), (mandatory)) +#endif /* USE_DEPRECATED_FUNCTIONS */ + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_PARSER_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/scpi.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,52 @@ +/*- + * 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.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI library include file + * + * + */ + +#ifndef SCPI_H +#define SCPI_H + +#include "scpi/parser.h" +#include "scpi/ieee488.h" +#include "scpi/error.h" +#include "scpi/constants.h" +#include "scpi/minimal.h" +#include "scpi/units.h" +#include "scpi/utils.h" +#include "scpi/expression.h" + +#endif /* SCPI_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/types.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,402 @@ +/*- + * BSD 2-Clause License + * + * Copyright (c) 2012-2018, Jan Breuer, Richard.hmm + * 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_types.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI data types + * + * + */ + +#ifndef SCPI_TYPES_H +#define SCPI_TYPES_H + +#include <stddef.h> +#include <stdint.h> +#include "scpi/config.h" + +#if HAVE_STDBOOL +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +//#if !HAVE_STDBOOL +// typedef unsigned char bool; +//#endif + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + + /* basic data types */ + typedef bool scpi_bool_t; + /* typedef enum { FALSE = 0, TRUE } scpi_bool_t; */ + + /* IEEE 488.2 registers */ + enum _scpi_reg_name_t { + SCPI_REG_STB = 0, /* Status Byte */ + SCPI_REG_SRE, /* Service Request Enable Register */ + SCPI_REG_ESR, /* Standard Event Status Register (ESR, SESR) */ + SCPI_REG_ESE, /* Event Status Enable Register */ + SCPI_REG_OPER, /* OPERation Status Register */ + SCPI_REG_OPERE, /* OPERation Status Enable Register */ + SCPI_REG_OPERC, /* OPERation Status Condition Register */ + SCPI_REG_QUES, /* QUEStionable status register */ + SCPI_REG_QUESE, /* QUEStionable status Enable Register */ + SCPI_REG_QUESC, /* QUEStionable status Condition Register */ + + /* last definition - number of registers */ + SCPI_REG_COUNT + }; + typedef enum _scpi_reg_name_t scpi_reg_name_t; + + enum _scpi_ctrl_name_t { + SCPI_CTRL_SRQ = 1, /* service request */ + SCPI_CTRL_GTL, /* Go to local */ + SCPI_CTRL_SDC, /* Selected device clear */ + SCPI_CTRL_PPC, /* Parallel poll configure */ + SCPI_CTRL_GET, /* Group execute trigger */ + SCPI_CTRL_TCT, /* Take control */ + SCPI_CTRL_LLO, /* Device clear */ + SCPI_CTRL_DCL, /* Local lockout */ + SCPI_CTRL_PPU, /* Parallel poll unconfigure */ + SCPI_CTRL_SPE, /* Serial poll enable */ + SCPI_CTRL_SPD, /* Serial poll disable */ + SCPI_CTRL_MLA, /* My local address */ + SCPI_CTRL_UNL, /* Unlisten */ + SCPI_CTRL_MTA, /* My talk address */ + SCPI_CTRL_UNT, /* Untalk */ + SCPI_CTRL_MSA /* My secondary address */ + }; + typedef enum _scpi_ctrl_name_t scpi_ctrl_name_t; + + typedef uint16_t scpi_reg_val_t; + + /* scpi commands */ + enum _scpi_result_t { + SCPI_RES_OK = 1, + SCPI_RES_ERR = -1 + }; + typedef enum _scpi_result_t scpi_result_t; + + typedef struct _scpi_command_t scpi_command_t; + +#if USE_COMMAND_TAGS + #define SCPI_CMD_LIST_END {NULL, NULL, 0} +#else + #define SCPI_CMD_LIST_END {NULL, NULL} +#endif + + + /* scpi interface */ + typedef struct _scpi_t scpi_t; + typedef struct _scpi_interface_t scpi_interface_t; + + struct _scpi_buffer_t { + size_t length; + size_t position; + char * data; + }; + typedef struct _scpi_buffer_t scpi_buffer_t; + + struct _scpi_const_buffer_t { + size_t length; + size_t position; + const char * data; + }; + typedef struct _scpi_const_buffer_t scpi_const_buffer_t; + + typedef size_t(*scpi_write_t)(scpi_t * context, const char * data, size_t len); + typedef scpi_result_t(*scpi_write_control_t)(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val); + typedef int (*scpi_error_callback_t)(scpi_t * context, int_fast16_t error); + + /* scpi lexer */ + enum _scpi_token_type_t { + SCPI_TOKEN_COMMA, + SCPI_TOKEN_SEMICOLON, + SCPI_TOKEN_COLON, + SCPI_TOKEN_SPECIFIC_CHARACTER, + SCPI_TOKEN_QUESTION, + SCPI_TOKEN_NL, + SCPI_TOKEN_HEXNUM, + SCPI_TOKEN_OCTNUM, + SCPI_TOKEN_BINNUM, + SCPI_TOKEN_PROGRAM_MNEMONIC, + SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA, + SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX, + SCPI_TOKEN_SUFFIX_PROGRAM_DATA, + SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA, + SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA, + SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA, + SCPI_TOKEN_PROGRAM_EXPRESSION, + SCPI_TOKEN_COMPOUND_PROGRAM_HEADER, + SCPI_TOKEN_INCOMPLETE_COMPOUND_PROGRAM_HEADER, + SCPI_TOKEN_COMMON_PROGRAM_HEADER, + SCPI_TOKEN_INCOMPLETE_COMMON_PROGRAM_HEADER, + SCPI_TOKEN_COMPOUND_QUERY_PROGRAM_HEADER, + SCPI_TOKEN_COMMON_QUERY_PROGRAM_HEADER, + SCPI_TOKEN_WS, + SCPI_TOKEN_ALL_PROGRAM_DATA, + SCPI_TOKEN_INVALID, + SCPI_TOKEN_UNKNOWN, + }; + typedef enum _scpi_token_type_t scpi_token_type_t; + + struct _scpi_token_t { + scpi_token_type_t type; + char * ptr; + int len; + }; + typedef struct _scpi_token_t scpi_token_t; + + struct _lex_state_t { + char * buffer; + char * pos; + int len; + }; + typedef struct _lex_state_t lex_state_t; + + /* scpi parser */ + enum _message_termination_t { + SCPI_MESSAGE_TERMINATION_NONE, + SCPI_MESSAGE_TERMINATION_NL, + SCPI_MESSAGE_TERMINATION_SEMICOLON, + }; + typedef enum _message_termination_t message_termination_t; + + struct _scpi_parser_state_t { + scpi_token_t programHeader; + scpi_token_t programData; + int numberOfParameters; + message_termination_t termination; + }; + typedef struct _scpi_parser_state_t scpi_parser_state_t; + + typedef scpi_result_t(*scpi_command_callback_t)(scpi_t *); + + struct _scpi_error_info_heap_t { + size_t wr; + /* size_t rd; */ + size_t count; + size_t size; + char * data; + }; + typedef struct _scpi_error_info_heap_t scpi_error_info_heap_t; + + struct _scpi_error_t { + int16_t error_code; +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + char * device_dependent_info; +#endif + }; + typedef struct _scpi_error_t scpi_error_t; + + struct _scpi_fifo_t { + int16_t wr; + int16_t rd; + int16_t count; + int16_t size; + scpi_error_t * data; + }; + typedef struct _scpi_fifo_t scpi_fifo_t; + + /* scpi units */ + enum _scpi_unit_t { + SCPI_UNIT_NONE, + SCPI_UNIT_VOLT, + SCPI_UNIT_AMPER, + SCPI_UNIT_OHM, + SCPI_UNIT_HERTZ, + SCPI_UNIT_CELSIUS, + SCPI_UNIT_SECOND, + SCPI_UNIT_METER, + SCPI_UNIT_GRAY, + SCPI_UNIT_BECQUEREL, + SCPI_UNIT_MOLE, + SCPI_UNIT_DEGREE, + SCPI_UNIT_GRADE, + SCPI_UNIT_RADIAN, + SCPI_UNIT_REVOLUTION, + SCPI_UNIT_STERADIAN, + SCPI_UNIT_SIEVERT, + SCPI_UNIT_FARAD, + SCPI_UNIT_COULOMB, + SCPI_UNIT_SIEMENS, + SCPI_UNIT_ELECTRONVOLT, + SCPI_UNIT_JOULE, + SCPI_UNIT_NEWTON, + SCPI_UNIT_LUX, + SCPI_UNIT_HENRY, + SCPI_UNIT_ASTRONOMIC_UNIT, + SCPI_UNIT_INCH, + SCPI_UNIT_FOOT, + SCPI_UNIT_PARSEC, + SCPI_UNIT_MILE, + SCPI_UNIT_NAUTICAL_MILE, + SCPI_UNIT_LUMEN, + SCPI_UNIT_CANDELA, + SCPI_UNIT_WEBER, + SCPI_UNIT_TESLA, + SCPI_UNIT_ATOMIC_MASS, + SCPI_UNIT_KILOGRAM, + SCPI_UNIT_WATT, + SCPI_UNIT_DBM, + SCPI_UNIT_ATMOSPHERE, + SCPI_UNIT_INCH_OF_MERCURY, + SCPI_UNIT_MM_OF_MERCURY, + SCPI_UNIT_PASCAL, + SCPI_UNIT_TORT, + SCPI_UNIT_BAR, + SCPI_UNIT_DECIBEL, + SCPI_UNIT_UNITLESS, + SCPI_UNIT_FAHRENHEIT, + SCPI_UNIT_KELVIN, + SCPI_UNIT_DAY, + SCPI_UNIT_YEAR, + SCPI_UNIT_STROKES, + SCPI_UNIT_POISE, + SCPI_UNIT_LITER + }; + typedef enum _scpi_unit_t scpi_unit_t; + + struct _scpi_unit_def_t { + const char * name; + scpi_unit_t unit; + double mult; + }; +#define SCPI_UNITS_LIST_END {NULL, SCPI_UNIT_NONE, 0} + typedef struct _scpi_unit_def_t scpi_unit_def_t; + + enum _scpi_special_number_t { + SCPI_NUM_NUMBER, + SCPI_NUM_MIN, + SCPI_NUM_MAX, + SCPI_NUM_DEF, + SCPI_NUM_UP, + SCPI_NUM_DOWN, + SCPI_NUM_NAN, + SCPI_NUM_INF, + SCPI_NUM_NINF, + SCPI_NUM_AUTO + }; + typedef enum _scpi_special_number_t scpi_special_number_t; + + struct _scpi_choice_def_t { + const char * name; + int32_t tag; + }; +#define SCPI_CHOICE_LIST_END {NULL, -1} + typedef struct _scpi_choice_def_t scpi_choice_def_t; + + struct _scpi_param_list_t { + const scpi_command_t * cmd; + lex_state_t lex_state; + scpi_const_buffer_t cmd_raw; + }; + typedef struct _scpi_param_list_t scpi_param_list_t; + + struct _scpi_number_parameter_t { + scpi_bool_t special; + + union { + double value; + int32_t tag; + } content; + scpi_unit_t unit; + int8_t base; + }; + typedef struct _scpi_number_parameter_t scpi_number_t; + + struct _scpi_data_parameter_t { + const char * ptr; + int32_t len; + }; + typedef struct _scpi_data_parameter_t scpi_data_parameter_t; + + typedef scpi_token_t scpi_parameter_t; + + struct _scpi_command_t { + const char * pattern; + scpi_command_callback_t callback; +#if USE_COMMAND_TAGS + int32_t tag; +#endif /* USE_COMMAND_TAGS */ + }; + + struct _scpi_interface_t { + scpi_error_callback_t error; + scpi_write_t write; + scpi_write_control_t control; + scpi_command_callback_t flush; + scpi_command_callback_t reset; + }; + + struct _scpi_t { + const scpi_command_t * cmdlist; + scpi_buffer_t buffer; + scpi_param_list_t param_list; + scpi_interface_t * interface; + int_fast16_t output_count; + int_fast16_t input_count; + scpi_bool_t cmd_error; + scpi_fifo_t error_queue; +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE + scpi_error_info_heap_t error_info_heap; +#endif + scpi_reg_val_t registers[SCPI_REG_COUNT]; + const scpi_unit_def_t * units; + void * user_context; + scpi_parser_state_t parser_state; + const char * idn[4]; + size_t arbitrary_reminding; + }; + + enum _scpi_array_format_t { + SCPI_FORMAT_ASCII = 0, + SCPI_FORMAT_NORMAL = 1, + SCPI_FORMAT_SWAPPED = 2, + SCPI_FORMAT_BIGENDIAN = SCPI_FORMAT_NORMAL, + SCPI_FORMAT_LITTLEENDIAN = SCPI_FORMAT_SWAPPED, + }; + typedef enum _scpi_array_format_t scpi_array_format_t; + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_TYPES_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/units.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,61 @@ +/*- + * 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_units.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI Units + * + * + */ + +#ifndef SCPI_UNITS_H +#define SCPI_UNITS_H + +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + extern const scpi_unit_def_t scpi_units_def[]; + extern const scpi_choice_def_t scpi_special_numbers_def[]; + + scpi_bool_t SCPI_ParamNumber(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, scpi_bool_t mandatory); + + scpi_bool_t SCPI_ParamTranslateNumberVal(scpi_t * context, scpi_parameter_t * parameter); + size_t SCPI_NumberToStr(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, char * str, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_UNITS_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/inc/scpi/utils.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,63 @@ +/*- + * 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 utils.h + * + * @brief Conversion routines and string manipulation routines + * + * + */ + +#ifndef SCPI_UTILS_H +#define SCPI_UTILS_H + +#include <stdint.h> +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + size_t SCPI_UInt32ToStrBase(uint32_t val, char * str, size_t len, int8_t base); + size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len); + size_t SCPI_UInt64ToStrBase(uint64_t val, char * str, size_t len, int8_t base); + size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len); + size_t SCPI_FloatToStr(float val, char * str, size_t len); + size_t SCPI_DoubleToStr(double val, char * str, size_t len); + + /* deprecated finction, should be removed later */ +#define SCPI_LongToStr(val, str, len, base) SCPI_Int32ToStr((val), (str), (len), (base), TRUE) + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_UTILS_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/error.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,235 @@ +/*- + * 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_error.c + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief Error handling and storing routines + * + * + */ + +#include <stdint.h> + +#include "scpi/parser.h" +#include "scpi/ieee488.h" +#include "scpi/error.h" +#include "fifo_private.h" +#include "scpi/constants.h" + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION +#define SCPI_ERROR_SETVAL(e, c, i) do { (e)->error_code = (c); (e)->device_dependent_info = (i); } while(0) +#else +#define SCPI_ERROR_SETVAL(e, c, i) do { (e)->error_code = (c); (void)(i);} while(0) +#endif + +/** + * Initialize error queue + * @param context - scpi context + */ +void SCPI_ErrorInit(scpi_t * context, scpi_error_t * data, int16_t size) { + fifo_init(&context->error_queue, data, size); +} + +/** + * Emit no error + * @param context scpi context + */ +static void SCPI_ErrorEmitEmpty(scpi_t * context) { + if ((SCPI_ErrorCount(context) == 0) && (SCPI_RegGet(context, SCPI_REG_STB) & STB_QMA)) { + SCPI_RegClearBits(context, SCPI_REG_STB, STB_QMA); + + if (context->interface && context->interface->error) { + context->interface->error(context, 0); + } + } +} + +/** + * Emit error + * @param context scpi context + * @param err Error to emit + */ +static void SCPI_ErrorEmit(scpi_t * context, int16_t err) { + SCPI_RegSetBits(context, SCPI_REG_STB, STB_QMA); + + if (context->interface && context->interface->error) { + context->interface->error(context, err); + } +} + +/** + * Clear error queue + * @param context - scpi context + */ +void SCPI_ErrorClear(scpi_t * context) { +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + scpi_error_t error; + while (fifo_remove(&context->error_queue, &error)) { + SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); + } +#endif + fifo_clear(&context->error_queue); + + SCPI_ErrorEmitEmpty(context); +} + +/** + * Pop error from queue + * @param context - scpi context + * @param error + * @return + */ +scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error) { + if (!error || !context) return FALSE; + SCPI_ERROR_SETVAL(error, 0, NULL); + fifo_remove(&context->error_queue, error); + + SCPI_ErrorEmitEmpty(context); + + return TRUE; +} + +/** + * Return number of errors/events in the queue + * @param context + * @return + */ +int32_t SCPI_ErrorCount(scpi_t * context) { + int16_t result = 0; + + fifo_count(&context->error_queue, &result); + + return result; +} + +static scpi_bool_t SCPI_ErrorAddInternal(scpi_t * context, int16_t err, char * info, size_t info_len) { + scpi_error_t error_value; + /* SCPIDEFINE_strndup is sometimes a dumy that does not reference it's arguments. + Since info_len is not referenced elsewhere caoing to void prevents unusd argument warnings */ + (void) info_len; + char * info_ptr = info ? SCPIDEFINE_strndup(&context->error_info_heap, info, info_len) : NULL; + SCPI_ERROR_SETVAL(&error_value, err, info_ptr); + if (!fifo_add(&context->error_queue, &error_value)) { + SCPIDEFINE_free(&context->error_info_heap, error_value.device_dependent_info, true); + fifo_remove_last(&context->error_queue, &error_value); + SCPIDEFINE_free(&context->error_info_heap, error_value.device_dependent_info, true); + SCPI_ERROR_SETVAL(&error_value, SCPI_ERROR_QUEUE_OVERFLOW, NULL); + fifo_add(&context->error_queue, &error_value); + return FALSE; + } + return TRUE; +} + +struct error_reg { + int16_t from; + int16_t to; + scpi_reg_val_t esrBit; +}; + +#define ERROR_DEFS_N 9 + +static const struct error_reg errs[ERROR_DEFS_N] = { + {-100, -199, ESR_CER}, /* Command error (e.g. syntax error) ch 21.8.9 */ + {-200, -299, ESR_EER}, /* Execution Error (e.g. range error) ch 21.8.10 */ + {-300, -399, ESR_DER}, /* Device specific error -300, -399 ch 21.8.11 */ + { 1, 32767, ESR_DER}, /* Device designer provided specific error 1, 32767 ch 21.8.11 */ + {-400, -499, ESR_QER}, /* Query error -400, -499 ch 21.8.12 */ + {-500, -599, ESR_PON}, /* Power on event -500, -599 ch 21.8.13 */ + {-600, -699, ESR_URQ}, /* User Request Event -600, -699 ch 21.8.14 */ + {-700, -799, ESR_REQ}, /* Request Control Event -700, -799 ch 21.8.15 */ + {-800, -899, ESR_OPC}, /* Operation Complete Event -800, -899 ch 21.8.16 */ +}; + +/** + * Push error to queue + * @param context + * @param err - error number + * @param info - additional text information or NULL for no text + * @param info_len - length of text or 0 for automatic length + */ +void SCPI_ErrorPushEx(scpi_t * context, int16_t err, char * info, size_t info_len) { + int i; + /* automatic calculation of length */ + if (info && info_len == 0) { + info_len = SCPIDEFINE_strnlen(info, SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH); + } + scpi_bool_t queue_overflow = !SCPI_ErrorAddInternal(context, err, info, info_len); + + for (i = 0; i < ERROR_DEFS_N; i++) { + if ((err <= errs[i].from) && (err >= errs[i].to)) { + SCPI_RegSetBits(context, SCPI_REG_ESR, errs[i].esrBit); + } + } + + SCPI_ErrorEmit(context, err); + if (queue_overflow) { + SCPI_ErrorEmit(context, SCPI_ERROR_QUEUE_OVERFLOW); + } + + if (context) { + context->cmd_error = TRUE; + } +} + +/** + * Push error to queue + * @param context - scpi context + * @param err - error number + */ +void SCPI_ErrorPush(scpi_t * context, int16_t err) { + SCPI_ErrorPushEx(context, err, NULL, 0); + return; +} + +/** + * Translate error number to string + * @param err - error number + * @return Error string representation + */ +const char * SCPI_ErrorTranslate(int16_t err) { + switch (err) { +#define X(def, val, str) case def: return str; +#if USE_FULL_ERROR_LIST +#define XE X +#else +#define XE(def, val, str) +#endif + LIST_OF_ERRORS + +#if USE_USER_ERROR_LIST + LIST_OF_USER_ERRORS +#endif +#undef X +#undef XE + default: return "Unknown error"; + } +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/expression.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,317 @@ +/*- + * 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 expression.c + * + * @brief Expressions handling + * + * + */ + +#include "scpi/expression.h" +#include "scpi/error.h" +#include "scpi/parser.h" + +#include "lexer_private.h" + +/** + * Parse one range or single value + * @param state lexer state + * @param isRange return true if parsed expression is range + * @param valueFrom return parsed value from + * @param valueTo return parsed value to + * @return SCPI_EXPR_OK - parsing was succesful + * SCPI_EXPR_ERROR - parser error + * SCPI_EXPR_NO_MORE - no more data + */ +static scpi_expr_result_t numericRange(lex_state_t * state, scpi_bool_t * isRange, scpi_token_t * valueFrom, scpi_token_t * valueTo) { + if (scpiLex_DecimalNumericProgramData(state, valueFrom)) { + if (scpiLex_Colon(state, valueTo)) { + *isRange = TRUE; + if (scpiLex_DecimalNumericProgramData(state, valueTo)) { + return SCPI_EXPR_OK; + } else { + return SCPI_EXPR_ERROR; + } + } else { + *isRange = FALSE; + return SCPI_EXPR_OK; + } + } + + return SCPI_EXPR_NO_MORE; +} + +/** + * Parse entry on specified position + * @param context scpi context + * @param param input parameter + * @param index index of position (start from 0) + * @param isRange return true if expression at index was range + * @param valueFrom return value from + * @param valueTo return value to + * @return SCPI_EXPR_OK - parsing was succesful + * SCPI_EXPR_ERROR - parser error + * SCPI_EXPR_NO_MORE - no more data + * @see SCPI_ExprNumericListEntryInt, SCPI_ExprNumericListEntryDouble + */ +scpi_expr_result_t SCPI_ExprNumericListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, scpi_parameter_t * valueFrom, scpi_parameter_t * valueTo) { + lex_state_t lex; + int i; + scpi_expr_result_t res = SCPI_EXPR_OK; + + if (!isRange || !valueFrom || !valueTo || !param) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return SCPI_EXPR_ERROR; + } + + if (param->type != SCPI_TOKEN_PROGRAM_EXPRESSION) { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + return SCPI_EXPR_ERROR; + } + + lex.buffer = param->ptr + 1; + lex.pos = lex.buffer; + lex.len = param->len - 2; + + for (i = 0; i <= index; i++) { + res = numericRange(&lex, isRange, valueFrom, valueTo); + if (res != SCPI_EXPR_OK) { + break; + } + if (i != index) { + if (!scpiLex_Comma(&lex, valueFrom)) { + res = scpiLex_IsEos(&lex) ? SCPI_EXPR_NO_MORE : SCPI_EXPR_ERROR; + break; + } + } + } + + if (res == SCPI_EXPR_ERROR) { + SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); + } + return res; +} + +/** + * Parse entry on specified position and convert result to int32_t + * @param context scpi context + * @param param input parameter + * @param index index of position (start from 0) + * @param isRange return true if expression at index was range + * @param valueFrom return value from + * @param valueTo return value to + * @return SCPI_EXPR_OK - parsing was succesful + * SCPI_EXPR_ERROR - parser error + * SCPI_EXPR_NO_MORE - no more data + * @see SCPI_ExprNumericListEntry, SCPI_ExprNumericListEntryDouble + */ +scpi_expr_result_t SCPI_ExprNumericListEntryInt(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valueFrom, int32_t * valueTo) { + scpi_expr_result_t res; + scpi_bool_t range = FALSE; + scpi_parameter_t paramFrom; + scpi_parameter_t paramTo; + + res = SCPI_ExprNumericListEntry(context, param, index, &range, ¶mFrom, ¶mTo); + if (res == SCPI_EXPR_OK) { + *isRange = range; + SCPI_ParamToInt32(context, ¶mFrom, valueFrom); + if (range) { + SCPI_ParamToInt32(context, ¶mTo, valueTo); + } + } + + return res; +} + +/** + * Parse entry on specified position and convert result to double + * @param context scpi context + * @param param input parameter + * @param index index of position (start from 0) + * @param isRange return true if expression at index was range + * @param valueFrom return value from + * @param valueTo return value to + * @return SCPI_EXPR_OK - parsing was succesful + * SCPI_EXPR_ERROR - parser error + * SCPI_EXPR_NO_MORE - no more data + * @see SCPI_ExprNumericListEntry, SCPI_ExprNumericListEntryInt + */ +scpi_expr_result_t SCPI_ExprNumericListEntryDouble(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, double * valueFrom, double * valueTo) { + scpi_expr_result_t res; + scpi_bool_t range = FALSE; + scpi_parameter_t paramFrom; + scpi_parameter_t paramTo; + + res = SCPI_ExprNumericListEntry(context, param, index, &range, ¶mFrom, ¶mTo); + if (res == SCPI_EXPR_OK) { + *isRange = range; + SCPI_ParamToDouble(context, ¶mFrom, valueFrom); + if (range) { + SCPI_ParamToDouble(context, ¶mTo, valueTo); + } + } + + return res; +} + +/** + * Parse one channel_spec e.g. "1!5!8" + * @param context + * @param state lexer state + * @param values range values + * @param length length of values array + * @param dimensions real number of dimensions + */ +static scpi_expr_result_t channelSpec(scpi_t * context, lex_state_t * state, int32_t * values, size_t length, size_t * dimensions) { + scpi_parameter_t param; + size_t i = 0; + while (scpiLex_DecimalNumericProgramData(state, ¶m)) { + if (i < length) { + SCPI_ParamToInt32(context, ¶m, &values[i]); + } + + if (scpiLex_SpecificCharacter(state, ¶m, '!')) { + i++; + } else { + *dimensions = i + 1; + return SCPI_EXPR_OK; + } + } + + if (i == 0) { + return SCPI_EXPR_NO_MORE; + } else { + /* there was at least one number followed by !, but after ! was not another number */ + return SCPI_EXPR_ERROR; + } +} + +/** + * Parse channel_range e.g. "1!2:5!6" + * @param context + * @param state lexer state + * @param isRange return true if it is range + * @param valuesFrom return array of values from + * @param valuesTo return array of values to + * @param length length of values arrays + * @param dimensions real number of dimensions + */ +static scpi_expr_result_t channelRange(scpi_t * context, lex_state_t * state, scpi_bool_t * isRange, int32_t * valuesFrom, int32_t * valuesTo, size_t length, size_t * dimensions) { + scpi_token_t token; + scpi_expr_result_t err; + size_t fromDimensions; + size_t toDimensions; + + err = channelSpec(context, state, valuesFrom, length, &fromDimensions); + if (err == SCPI_EXPR_OK) { + if (scpiLex_Colon(state, &token)) { + *isRange = TRUE; + err = channelSpec(context, state, valuesTo, length, &toDimensions); + if (err != SCPI_EXPR_OK) { + return SCPI_EXPR_ERROR; + } + if (fromDimensions != toDimensions) { + return SCPI_EXPR_ERROR; + } + *dimensions = fromDimensions; + } else { + *isRange = FALSE; + *dimensions = fromDimensions; + return SCPI_EXPR_OK; + } + } else if (err == SCPI_EXPR_NO_MORE) { + err = SCPI_EXPR_ERROR; + } + + return err; +} + +/** + * Parse one list entry at specific position e.g. "1!2:5!6" + * @param context + * @param param + * @param index + * @param isRange return true if it is range + * @param valuesFrom return array of values from + * @param valuesTo return array of values to + * @param length length of values arrays + * @param dimensions real number of dimensions + */ +scpi_expr_result_t SCPI_ExprChannelListEntry(scpi_t * context, scpi_parameter_t * param, int index, scpi_bool_t * isRange, int32_t * valuesFrom, int32_t * valuesTo, size_t length, size_t * dimensions) { + lex_state_t lex; + int i; + scpi_expr_result_t res = SCPI_EXPR_OK; + scpi_token_t token; + + if (!isRange || !param || !dimensions || (length && (!valuesFrom || !valuesTo))) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return SCPI_EXPR_ERROR; + } + + if (param->type != SCPI_TOKEN_PROGRAM_EXPRESSION) { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + return SCPI_EXPR_ERROR; + } + + lex.buffer = param->ptr + 1; + lex.pos = lex.buffer; + lex.len = param->len - 2; + + /* detect channel list expression */ + if (!scpiLex_SpecificCharacter(&lex, &token, '@')) { + SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); + return SCPI_EXPR_ERROR; + } + + for (i = 0; i <= index; i++) { + res = channelRange(context, &lex, isRange, valuesFrom, valuesTo, (i == index) ? length : 0, dimensions); + if (res != SCPI_EXPR_OK) { + break; + } + if (i != index) { + if (!scpiLex_Comma(&lex, &token)) { + res = scpiLex_IsEos(&lex) ? SCPI_EXPR_NO_MORE : SCPI_EXPR_ERROR; + break; + } + } + } + + if (res == SCPI_EXPR_ERROR) { + SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); + } + if (res == SCPI_EXPR_NO_MORE) { + if (!scpiLex_IsEos(&lex)) { + res = SCPI_EXPR_ERROR; + SCPI_ErrorPush(context, SCPI_ERROR_EXPRESSION_PARSING_ERROR); + } + } + return res; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/fifo.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,147 @@ +/*- + * 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. + */ + +#include "fifo_private.h" + +/** + * Initialize fifo + * @param fifo + */ +void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) { + fifo->wr = 0; + fifo->rd = 0; + fifo->count = 0; + fifo->data = data; + fifo->size = size; +} + +/** + * Empty fifo + * @param fifo + */ +void fifo_clear(scpi_fifo_t * fifo) { + fifo->wr = 0; + fifo->rd = 0; + fifo->count = 0; +} + +/** + * Test if fifo is empty + * @param fifo + * @return + */ +scpi_bool_t fifo_is_empty(scpi_fifo_t * fifo) { + return fifo->count == 0; +} + +/** + * Test if fifo is full + * @param fifo + * @return + */ +scpi_bool_t fifo_is_full(scpi_fifo_t * fifo) { + return fifo->count == fifo->size; +} + +/** + * Add element to fifo. If fifo is full, return FALSE. + * @param fifo + * @param err + * @param info + * @return + */ +scpi_bool_t fifo_add(scpi_fifo_t * fifo, const scpi_error_t * value) { + /* FIFO full? */ + if (fifo_is_full(fifo)) { + return FALSE; + } + if (!value) { + return FALSE; + } + + fifo->data[fifo->wr] = *value; + fifo->wr = (fifo->wr + 1) % (fifo->size); + fifo->count += 1; + return TRUE; +} + +/** + * Remove element form fifo + * @param fifo + * @param value + * @return FALSE - fifo is empty + */ +scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) { + /* FIFO empty? */ + if (fifo_is_empty(fifo)) { + return FALSE; + } + + if (value) { + *value = fifo->data[fifo->rd]; + } + + fifo->rd = (fifo->rd + 1) % (fifo->size); + fifo->count -= 1; + + return TRUE; +} + +/** + * Remove last element from fifo + * @param fifo + * @param value + * @return FALSE - fifo is empty + */ +scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) { + /* FIFO empty? */ + if (fifo_is_empty(fifo)) { + return FALSE; + } + + fifo->wr = (fifo->wr + fifo->size - 1) % (fifo->size); + + if (value) { + *value = fifo->data[fifo->wr]; + } + fifo->count -= 1; + + return TRUE; +} + +/** + * Retrive number of elements in fifo + * @param fifo + * @param value + * @return + */ +scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) { + *value = fifo->count; + return TRUE; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/fifo_private.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,62 @@ +/*- + * 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_fifo.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief basic FIFO implementation + * + * + */ + +#ifndef SCPI_FIFO_H +#define SCPI_FIFO_H + +#include "scpi/types.h" +#include "utils_private.h" + +#ifdef __cplusplus +extern "C" { +#endif + + void fifo_init(scpi_fifo_t * fifo, scpi_error_t * data, int16_t size) LOCAL; + void fifo_clear(scpi_fifo_t * fifo) LOCAL; + scpi_bool_t fifo_is_empty(scpi_fifo_t * fifo) LOCAL; + scpi_bool_t fifo_is_full(scpi_fifo_t * fifo) LOCAL; + scpi_bool_t fifo_add(scpi_fifo_t * fifo, const scpi_error_t * value) LOCAL; + scpi_bool_t fifo_remove(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL; + scpi_bool_t fifo_remove_last(scpi_fifo_t * fifo, scpi_error_t * value) LOCAL; + scpi_bool_t fifo_count(scpi_fifo_t * fifo, int16_t * value) LOCAL; + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_FIFO_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/ieee488.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,372 @@ +/*- + * 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_ieee488.c + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief Implementation of IEEE488.2 commands and state model + * + * + */ + +#include "scpi/parser.h" +#include "scpi/ieee488.h" +#include "scpi/error.h" +#include "scpi/constants.h" + +#include <stdio.h> + +/** + * Update register value + * @param context + * @param name - register name + */ +static void regUpdate(scpi_t * context, scpi_reg_name_t name) { + SCPI_RegSet(context, name, SCPI_RegGet(context, name)); +} + +/** + * Update latching event register value based on bit transitions from 0 -> 1 + * in the condition register + * @param context + * @param condReg - condition register name + * @param eventReg - event register name + */ +static void regUpdateEvent(scpi_t * context, scpi_reg_val_t oldCondVal, scpi_reg_val_t newCondVal, scpi_reg_name_t eventReg) { + SCPI_RegSet(context, eventReg, ((oldCondVal ^ newCondVal) & newCondVal) | SCPI_RegGet(context, eventReg)); +} + +/** + * Update STB register according to value and its mask register + * @param context + * @param val value of register + * @param mask name of mask register (enable register) + * @param stbBits bits to clear or set in STB + */ +static void regUpdateSTB(scpi_t * context, scpi_reg_val_t val, scpi_reg_name_t mask, scpi_reg_val_t stbBits) { + if (val & SCPI_RegGet(context, mask)) { + SCPI_RegSetBits(context, SCPI_REG_STB, stbBits); + } else { + SCPI_RegClearBits(context, SCPI_REG_STB, stbBits); + } +} + +/** + * Get register value + * @param name - register name + * @return register value + */ +scpi_reg_val_t SCPI_RegGet(scpi_t * context, scpi_reg_name_t name) { + if ((name < SCPI_REG_COUNT) && context) { + return context->registers[name]; + } else { + return 0; + } +} + +/** + * Wrapper function to control interface from context + * @param context + * @param ctrl number of controll message + * @param value value of related register + */ +static size_t writeControl(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { + if (context && context->interface && context->interface->control) { + return context->interface->control(context, ctrl, val); + } else { + return 0; + } +} + +/** + * Set register value + * @param name - register name + * @param val - new value + */ +void SCPI_RegSet(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t val) { + scpi_bool_t srq = FALSE; + scpi_reg_val_t mask; + scpi_reg_val_t old_val; + + if ((name >= SCPI_REG_COUNT) || (context == NULL)) { + return; + } + + /* store old register value */ + old_val = context->registers[name]; + + /* set register value */ + context->registers[name] = val; + + /** @TODO: remove recutsion */ + switch (name) { + case SCPI_REG_STB: + mask = SCPI_RegGet(context, SCPI_REG_SRE); + mask &= ~STB_SRQ; + if (val & mask) { + val |= STB_SRQ; + /* avoid sending SRQ if nothing has changed */ + if (old_val != val) { + srq = TRUE; + } + } else { + val &= ~STB_SRQ; + } + break; + case SCPI_REG_SRE: + regUpdate(context, SCPI_REG_STB); + break; + case SCPI_REG_ESR: + regUpdateSTB(context, val, SCPI_REG_ESE, STB_ESR); + break; + case SCPI_REG_ESE: + regUpdate(context, SCPI_REG_ESR); + break; + case SCPI_REG_QUES: + regUpdateSTB(context, val, SCPI_REG_QUESE, STB_QES); + break; + case SCPI_REG_QUESE: + regUpdate(context, SCPI_REG_QUES); + break; + case SCPI_REG_QUESC: + regUpdateEvent(context, old_val, val, SCPI_REG_QUES); + break; + case SCPI_REG_OPER: + regUpdateSTB(context, val, SCPI_REG_OPERE, STB_OPS); + break; + case SCPI_REG_OPERE: + regUpdate(context, SCPI_REG_OPER); + break; + case SCPI_REG_OPERC: + regUpdateEvent(context, old_val, val, SCPI_REG_OPER); + break; + + + case SCPI_REG_COUNT: + /* nothing to do */ + break; + } + + /* set updated register value */ + context->registers[name] = val; + + if (srq) { + writeControl(context, SCPI_CTRL_SRQ, SCPI_RegGet(context, SCPI_REG_STB)); + } +} + +/** + * Set register bits + * @param name - register name + * @param bits bit mask + */ +void SCPI_RegSetBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits) { + SCPI_RegSet(context, name, SCPI_RegGet(context, name) | bits); +} + +/** + * Clear register bits + * @param name - register name + * @param bits bit mask + */ +void SCPI_RegClearBits(scpi_t * context, scpi_reg_name_t name, scpi_reg_val_t bits) { + SCPI_RegSet(context, name, SCPI_RegGet(context, name) & ~bits); +} + +/** + * Clear event register + * @param context + */ +void SCPI_EventClear(scpi_t * context) { + /* TODO */ + SCPI_RegSet(context, SCPI_REG_ESR, 0); +} + +/** + * *CLS - This command clears all status data structures in a device. + * For a device which minimally complies with SCPI. (SCPI std 4.1.3.2) + * @param context + * @return + */ +scpi_result_t SCPI_CoreCls(scpi_t * context) { + SCPI_EventClear(context); + SCPI_ErrorClear(context); + SCPI_RegSet(context, SCPI_REG_OPER, 0); + SCPI_RegSet(context, SCPI_REG_QUES, 0); + return SCPI_RES_OK; +} + +/** + * *ESE + * @param context + * @return + */ +scpi_result_t SCPI_CoreEse(scpi_t * context) { + int32_t new_ESE; + if (SCPI_ParamInt32(context, &new_ESE, TRUE)) { + SCPI_RegSet(context, SCPI_REG_ESE, (scpi_reg_val_t) new_ESE); + return SCPI_RES_OK; + } + return SCPI_RES_ERR; +} + +/** + * *ESE? + * @param context + * @return + */ +scpi_result_t SCPI_CoreEseQ(scpi_t * context) { + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_ESE)); + return SCPI_RES_OK; +} + +/** + * *ESR? + * @param context + * @return + */ +scpi_result_t SCPI_CoreEsrQ(scpi_t * context) { + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_ESR)); + SCPI_RegSet(context, SCPI_REG_ESR, 0); + return SCPI_RES_OK; +} + +/** + * *IDN? + * + * field1: MANUFACTURE + * field2: MODEL + * field4: SUBSYSTEMS REVISIONS + * + * example: MANUFACTURE,MODEL,0,01-02-01 + * @param context + * @return + */ +scpi_result_t SCPI_CoreIdnQ(scpi_t * context) { + int i; + for (i = 0; i < 4; i++) { + if (context->idn[i]) { + SCPI_ResultMnemonic(context, context->idn[i]); + } else { + SCPI_ResultMnemonic(context, "0"); + } + } + return SCPI_RES_OK; +} + +/** + * *OPC + * @param context + * @return + */ +scpi_result_t SCPI_CoreOpc(scpi_t * context) { + SCPI_RegSetBits(context, SCPI_REG_ESR, ESR_OPC); + return SCPI_RES_OK; +} + +/** + * *OPC? + * @param context + * @return + */ +scpi_result_t SCPI_CoreOpcQ(scpi_t * context) { + /* Operation is always completed */ + SCPI_ResultInt32(context, 1); + return SCPI_RES_OK; +} + +/** + * *RST + * @param context + * @return + */ +scpi_result_t SCPI_CoreRst(scpi_t * context) { + if (context && context->interface && context->interface->reset) { + return context->interface->reset(context); + } + return SCPI_RES_OK; +} + +/** + * *SRE + * @param context + * @return + */ +scpi_result_t SCPI_CoreSre(scpi_t * context) { + int32_t new_SRE; + if (SCPI_ParamInt32(context, &new_SRE, TRUE)) { + SCPI_RegSet(context, SCPI_REG_SRE, (scpi_reg_val_t) new_SRE); + return SCPI_RES_OK; + } + return SCPI_RES_ERR; +} + +/** + * *SRE? + * @param context + * @return + */ +scpi_result_t SCPI_CoreSreQ(scpi_t * context) { + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_SRE)); + return SCPI_RES_OK; +} + +/** + * *STB? + * @param context + * @return + */ +scpi_result_t SCPI_CoreStbQ(scpi_t * context) { + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_STB)); + return SCPI_RES_OK; +} + +/** + * *TST? + * @param context + * @return + */ +scpi_result_t SCPI_CoreTstQ(scpi_t * context) { + (void) context; + SCPI_ResultInt32(context, 0); + return SCPI_RES_OK; +} + +/** + * *WAI + * @param context + * @return + */ +scpi_result_t SCPI_CoreWai(scpi_t * context) { + (void) context; + /* NOP */ + return SCPI_RES_OK; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/lexer.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,936 @@ +/*- + * 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 lexer.c + * @date Wed Mar 20 19:35:19 UTC 2013 + * + * @brief SCPI Lexer + * + * + */ + +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#include "lexer_private.h" +#include "scpi/error.h" + +/** + * Is white space + * @param c + * @return + */ +static int isws(int c) { + if ((c == ' ') || (c == '\t')) { + return 1; + } + return 0; +} + +/** + * Is binary digit + * @param c + * @return + */ +static int isbdigit(int c) { + if ((c == '0') || (c == '1')) { + return 1; + } + return 0; +} + +/** + * Is hexadecimal digit + * @param c + * @return + */ +static int isqdigit(int c) { + if ((c == '0') || (c == '1') || (c == '2') || (c == '3') || (c == '4') || (c == '5') || (c == '6') || (c == '7')) { + return 1; + } + return 0; +} + +/** + * Is end of string + * @param state + * @return + */ +static int iseos(lex_state_t * state) { + if ((state->buffer + state->len) <= (state->pos)) { + return 1; + } else { + return 0; + } +} + +/** + * Private export of iseos + * @param state + * @return + */ +int scpiLex_IsEos(lex_state_t * state) { + return iseos(state); +} + +/** + * Test current character + * @param state + * @param chr + * @return + */ +static int ischr(lex_state_t * state, char chr) { + return (state->pos[0] == chr); +} + +/** + * Is plus or minus + * @param c + * @return + */ +static int isplusmn(int c) { + return c == '+' || c == '-'; +} + +/** + * Is letter H + * @param c + * @return + */ +static int isH(int c) { + return c == 'h' || c == 'H'; +} + +/** + * Is letter B + * @param c + * @return + */ +static int isB(int c) { + return c == 'b' || c == 'B'; +} + +/** + * Is letter Q + * @param c + * @return + */ +static int isQ(int c) { + return c == 'q' || c == 'Q'; +} + +/** + * Is letter E + * @param c + * @return + */ +static int isE(int c) { + return c == 'e' || c == 'E'; +} + +#define SKIP_NONE 0 +#define SKIP_OK 1 +#define SKIP_INCOMPLETE -1 + +/* skip characters */ +/* 7.4.1 <PROGRAM MESSAGE UNIT SEPARATOR>*/ +/* TODO: static int skipProgramMessageUnitSeparator(lex_state_t * state) */ + +/** + * Skip all whitespaces + * @param state + * @return + */ +static int skipWs(lex_state_t * state) { + int someSpace = 0; + while (!iseos(state) && isws(state->pos[0])) { + state->pos++; + someSpace++; + } + + return someSpace; +} + +/* 7.4.2 <PROGRAM DATA SEPARATOR> */ +/* static int skipProgramDataSeparator(lex_state_t * state) */ + +/* 7.5.2 <PROGRAM MESSAGE TERMINATOR> */ +/* static int skipProgramMessageTerminator(lex_state_t * state) */ + +/** + * Skip decimal digit + * @param state + * @return + */ +static int skipDigit(lex_state_t * state) { + if (!iseos(state) && isdigit((uint8_t)(state->pos[0]))) { + state->pos++; + return SKIP_OK; + } else { + return SKIP_NONE; + } +} + +/** + * Skip multiple decimal digits + * @param state + * @return + */ +static int skipNumbers(lex_state_t * state) { + int someNumbers = 0; + while (!iseos(state) && isdigit((uint8_t)(state->pos[0]))) { + state->pos++; + someNumbers++; + } + return someNumbers; +} + +/** + * Skip plus or minus + * @param state + * @return + */ +static int skipPlusmn(lex_state_t * state) { + if (!iseos(state) && isplusmn(state->pos[0])) { + state->pos++; + return SKIP_OK; + } else { + return SKIP_NONE; + } +} + +/** + * Skip any character from 'a'-'Z' + * @param state + * @return + */ +static int skipAlpha(lex_state_t * state) { + int someLetters = 0; + while (!iseos(state) && isalpha((uint8_t)(state->pos[0]))) { + state->pos++; + someLetters++; + } + return someLetters; +} + +/** + * Skip exact character chr or nothing + * @param state + * @param chr + * @return + */ +static int skipChr(lex_state_t * state, char chr) { + if (!iseos(state) && ischr(state, chr)) { + state->pos++; + return SKIP_OK; + } else { + return SKIP_NONE; + } +} + +/** + * Skip slash or dot + * @param state + * @return + */ +static int skipSlashDot(lex_state_t * state) { + if (!iseos(state) && (ischr(state, '/') | ischr(state, '.'))) { + state->pos++; + return SKIP_OK; + } else { + return SKIP_NONE; + } +} + +/** + * Skip star + * @param state + * @return + */ +static int skipStar(lex_state_t * state) { + if (!iseos(state) && ischr(state, '*')) { + state->pos++; + return SKIP_OK; + } else { + return SKIP_NONE; + } +} + +/** + * Skip colon + * @param state + * @return + */ +static int skipColon(lex_state_t * state) { + if (!iseos(state) && ischr(state, ':')) { + state->pos++; + return SKIP_OK; + } else { + return SKIP_NONE; + } +} + +/* 7.6.1.2 <COMMAND PROGRAM HEADER> */ + +/** + * Skip program mnemonic [a-z][a-z0-9_]* + * @param state + * @return + */ +static int skipProgramMnemonic(lex_state_t * state) { + const char * startPos = state->pos; + if (!iseos(state) && isalpha((uint8_t)(state->pos[0]))) { + state->pos++; + while (!iseos(state) && (isalnum((uint8_t)(state->pos[0])) || ischr(state, '_'))) { + state->pos++; + } + } + + if (iseos(state)) { + return (state->pos - startPos) * SKIP_INCOMPLETE; + } else { + return (state->pos - startPos) * SKIP_OK; + } +} + +/* tokens */ + +/** + * Detect token white space + * @param state + * @param token + * @return + */ +int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + skipWs(state); + + token->len = state->pos - token->ptr; + + if (token->len > 0) { + token->type = SCPI_TOKEN_WS; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + } + + return token->len; +} + +/* 7.6.1 <COMMAND PROGRAM HEADER> */ + +/** + * Skip command program header \*<PROGRAM MNEMONIC> + * @param state + * @return + */ +static int skipCommonProgramHeader(lex_state_t * state) { + int res; + if (skipStar(state)) { + res = skipProgramMnemonic(state); + if (res == SKIP_NONE && iseos(state)) { + return SKIP_INCOMPLETE; + } else if (res <= SKIP_INCOMPLETE) { + return SKIP_OK; + } else if (res >= SKIP_OK) { + return SKIP_OK; + } else { + return SKIP_INCOMPLETE; + } + } + return SKIP_NONE; +} + +/** + * Skip compound program header :<PROGRAM MNEMONIC>:<PROGRAM MNEMONIC>... + * @param state + * @return + */ +static int skipCompoundProgramHeader(lex_state_t * state) { + int res; + int firstColon = skipColon(state); + + res = skipProgramMnemonic(state); + if (res >= SKIP_OK) { + while (skipColon(state)) { + res = skipProgramMnemonic(state); + if (res <= SKIP_INCOMPLETE) { + return SKIP_OK; + } else if (res == SKIP_NONE) { + return SKIP_INCOMPLETE; + } + } + return SKIP_OK; + } else if (res <= SKIP_INCOMPLETE) { + return SKIP_OK; + } else if (firstColon) { + return SKIP_INCOMPLETE; + } else { + return SKIP_NONE; + } +} + +/** + * Detect token command or compound program header + * @param state + * @param token + * @return + */ +int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) { + int res; + token->ptr = state->pos; + token->type = SCPI_TOKEN_UNKNOWN; + + res = skipCommonProgramHeader(state); + if (res >= SKIP_OK) { + if (skipChr(state, '?') >= SKIP_OK) { + token->type = SCPI_TOKEN_COMMON_QUERY_PROGRAM_HEADER; + } else { + token->type = SCPI_TOKEN_COMMON_PROGRAM_HEADER; + } + } else if (res <= SKIP_INCOMPLETE) { + token->type = SCPI_TOKEN_INCOMPLETE_COMMON_PROGRAM_HEADER; + } else if (res == SKIP_NONE) { + res = skipCompoundProgramHeader(state); + + if (res >= SKIP_OK) { + if (skipChr(state, '?') >= SKIP_OK) { + token->type = SCPI_TOKEN_COMPOUND_QUERY_PROGRAM_HEADER; + } else { + token->type = SCPI_TOKEN_COMPOUND_PROGRAM_HEADER; + } + } else if (res <= SKIP_INCOMPLETE) { + token->type = SCPI_TOKEN_INCOMPLETE_COMPOUND_PROGRAM_HEADER; + } + } + + if (token->type != SCPI_TOKEN_UNKNOWN) { + token->len = state->pos - token->ptr; + } else { + token->len = 0; + state->pos = token->ptr; + } + + return token->len; +} + +/* 7.7.1 <CHARACTER PROGRAM DATA> */ + +/** + * Detect token "Character program data" + * @param state + * @param token + * @return + */ +int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + if (!iseos(state) && isalpha((uint8_t)(state->pos[0]))) { + state->pos++; + while (!iseos(state) && (isalnum((uint8_t)(state->pos[0])) || ischr(state, '_'))) { + state->pos++; + } + } + + token->len = state->pos - token->ptr; + if (token->len > 0) { + token->type = SCPI_TOKEN_PROGRAM_MNEMONIC; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + } + + return token->len; +} + +/* 7.7.2 <DECIMAL NUMERIC PROGRAM DATA> */ +static int skipMantisa(lex_state_t * state) { + int someNumbers = 0; + + skipPlusmn(state); + + someNumbers += skipNumbers(state); + + if (skipChr(state, '.')) { + someNumbers += skipNumbers(state); + } + + return someNumbers; +} + +static int skipExponent(lex_state_t * state) { + int someNumbers = 0; + + if (!iseos(state) && isE(state->pos[0])) { + state->pos++; + + skipWs(state); + + skipPlusmn(state); + + someNumbers = skipNumbers(state); + } + + return someNumbers; +} + +/** + * Detect token Decimal number + * @param state + * @param token + * @return + */ +int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) { + char * rollback; + token->ptr = state->pos; + + if (skipMantisa(state)) { + rollback = state->pos; + skipWs(state); + if (!skipExponent(state)) { + state->pos = rollback; + } + } else { + state->pos = token->ptr; + } + + token->len = state->pos - token->ptr; + if (token->len > 0) { + token->type = SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + } + + return token->len; +} + +/* 7.7.3 <SUFFIX PROGRAM DATA> */ +int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + skipChr(state, '/'); + + /* TODO: strict parsing : SLASH? (ALPHA+ (MINUS? DIGIT)?) ((SLASH | DOT) (ALPHA+ (MINUS? DIGIT)?))* */ + if (skipAlpha(state)) { + skipChr(state, '-'); + skipDigit(state); + + while (skipSlashDot(state)) { + skipAlpha(state); + skipChr(state, '-'); + skipDigit(state); + } + } + + token->len = state->pos - token->ptr; + if ((token->len > 0)) { + token->type = SCPI_TOKEN_SUFFIX_PROGRAM_DATA; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + state->pos = token->ptr; + token->len = 0; + } + + return token->len; +} + +/* 7.7.4 <NONDECIMAL NUMERIC PROGRAM DATA> */ +static int skipHexNum(lex_state_t * state) { + int someNumbers = 0; + while (!iseos(state) && isxdigit((uint8_t)(state->pos[0]))) { + state->pos++; + someNumbers++; + } + return someNumbers; +} + +static int skipOctNum(lex_state_t * state) { + int someNumbers = 0; + while (!iseos(state) && isqdigit(state->pos[0])) { + state->pos++; + someNumbers++; + } + return someNumbers; +} + +static int skipBinNum(lex_state_t * state) { + int someNumbers = 0; + while (!iseos(state) && isbdigit(state->pos[0])) { + state->pos++; + someNumbers++; + } + return someNumbers; +} + +/** + * Detect token nondecimal number + * @param state + * @param token + * @return + */ +int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) { + int someNumbers = 0; + token->ptr = state->pos; + if (skipChr(state, '#')) { + if (!iseos(state)) { + if (isH(state->pos[0])) { + state->pos++; + someNumbers = skipHexNum(state); + token->type = SCPI_TOKEN_HEXNUM; + } else if (isQ(state->pos[0])) { + state->pos++; + someNumbers = skipOctNum(state); + token->type = SCPI_TOKEN_OCTNUM; + } else if (isB(state->pos[0])) { + state->pos++; + someNumbers = skipBinNum(state); + token->type = SCPI_TOKEN_BINNUM; + } + } + } + + if (someNumbers) { + token->ptr += 2; /* ignore number prefix */ + token->len = state->pos - token->ptr; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + state->pos = token->ptr; + token->len = 0; + } + return token->len > 0 ? token->len + 2 : 0; +} + +/* 7.7.5 <STRING PROGRAM DATA> */ +static int isascii7bit(int c) { + return (c >= 0) && (c <= 0x7f); +} + +static void skipQuoteProgramData(lex_state_t * state, char quote) { + while (!iseos(state)) { + if (isascii7bit(state->pos[0]) && !ischr(state, quote)) { + state->pos++; + } else if (ischr(state, quote)) { + state->pos++; + if (!iseos(state) && ischr(state, quote)) { + state->pos++; + } else { + state->pos--; + break; + } + } else { + break; + } + } +} + +static void skipDoubleQuoteProgramData(lex_state_t * state) { + skipQuoteProgramData(state, '"'); +} + +static void skipSingleQuoteProgramData(lex_state_t * state) { + skipQuoteProgramData(state, '\''); +} + +/** + * Detect token String data + * @param state + * @param token + * @return + */ +int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + if (!iseos(state)) { + if (ischr(state, '"')) { + state->pos++; + token->type = SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA; + skipDoubleQuoteProgramData(state); + if (!iseos(state) && ischr(state, '"')) { + state->pos++; + token->len = state->pos - token->ptr; + } else { + state->pos = token->ptr; + } + } else if (ischr(state, '\'')) { + state->pos++; + token->type = SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA; + skipSingleQuoteProgramData(state); + if (!iseos(state) && ischr(state, '\'')) { + state->pos++; + token->len = state->pos - token->ptr; + } else { + state->pos = token->ptr; + } + } + } + + token->len = state->pos - token->ptr; + + if ((token->len > 0)) { + /* token->ptr++; + * token->len -= 2; */ + } else { + token->type = SCPI_TOKEN_UNKNOWN; + state->pos = token->ptr; + token->len = 0; + } + + return token->len > 0 ? token->len : 0; +} + +/* 7.7.6 <ARBITRARY BLOCK PROGRAM DATA> */ +static int isNonzeroDigit(int c) { + return isdigit(c) && (c != '0'); +} + +/** + * Detect token Block Data + * @param state + * @param token + * @return + */ +int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) { + int i; + int arbitraryBlockLength = 0; + const char * ptr = state->pos; + int validData = -1; + token->ptr = state->pos; + + if (skipChr(state, '#')) { + if (!iseos(state) && isNonzeroDigit(state->pos[0])) { + /* Get number of digits */ + i = state->pos[0] - '0'; + state->pos++; + + for (; i > 0; i--) { + if (!iseos(state) && isdigit((uint8_t)(state->pos[0]))) { + arbitraryBlockLength *= 10; + arbitraryBlockLength += (state->pos[0] - '0'); + state->pos++; + } else { + break; + } + } + + if (i == 0) { + state->pos += arbitraryBlockLength; + if ((state->buffer + state->len) >= (state->pos)) { + token->ptr = state->pos - arbitraryBlockLength; + token->len = arbitraryBlockLength; + validData = 1; + } else { + validData = 0; + } + } else if (iseos(state)) { + validData = 0; + } + } else if (iseos(state)) { + validData = 0; + } + } + + if (validData == 1) { + /* valid */ + token->type = SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA; + } else if (validData == 0) { + /* incomplete */ + token->type = SCPI_TOKEN_UNKNOWN; + token->len = 0; + state->pos = state->buffer + state->len; + } else { + /* invalid */ + token->type = SCPI_TOKEN_UNKNOWN; + state->pos = token->ptr; + token->len = 0; + } + + return token->len + (token->ptr - ptr); +} + +/* 7.7.7 <EXPRESSION PROGRAM DATA> */ +static int isProgramExpression(int c) { + if ((c >= 0x20) && (c <= 0x7e)) { + if ((c != '"') + && (c != '#') + && (c != '\'') + && (c != '(') + && (c != ')') + && (c != ';')) { + return 1; + } + } + + return 0; +} + +static void skipProgramExpression(lex_state_t * state) { + while (!iseos(state) && isProgramExpression(state->pos[0])) { + state->pos++; + } +} + +/* TODO: 7.7.7.2-2 recursive - any program data */ + +/** + * Detect token Expression + * @param state + * @param token + * @return + */ +int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + if (!iseos(state) && ischr(state, '(')) { + state->pos++; + skipProgramExpression(state); + + if (!iseos(state) && ischr(state, ')')) { + state->pos++; + token->len = state->pos - token->ptr; + } else { + token->len = 0; + } + } + + if ((token->len > 0)) { + token->type = SCPI_TOKEN_PROGRAM_EXPRESSION; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + state->pos = token->ptr; + token->len = 0; + } + + return token->len; +} + +/** + * Detect token comma + * @param state + * @param token + * @return + */ +int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + if (skipChr(state, ',')) { + token->len = 1; + token->type = SCPI_TOKEN_COMMA; + } else { + token->len = 0; + token->type = SCPI_TOKEN_UNKNOWN; + } + + return token->len; +} + +/** + * Detect token semicolon + * @param state + * @param token + * @return + */ +int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + if (skipChr(state, ';')) { + token->len = 1; + token->type = SCPI_TOKEN_SEMICOLON; + } else { + token->len = 0; + token->type = SCPI_TOKEN_UNKNOWN; + } + + return token->len; +} + +/** + * Detect token colon + * @param state + * @param token + * @return + */ +int scpiLex_Colon(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + if (skipChr(state, ':')) { + token->len = 1; + token->type = SCPI_TOKEN_COLON; + } else { + token->len = 0; + token->type = SCPI_TOKEN_UNKNOWN; + } + + return token->len; +} + +/** + * Detect specified character + * @param state + * @param token + * @return + */ +int scpiLex_SpecificCharacter(lex_state_t * state, scpi_token_t * token, char chr) { + token->ptr = state->pos; + + if (skipChr(state, chr)) { + token->len = 1; + token->type = SCPI_TOKEN_SPECIFIC_CHARACTER; + } else { + token->len = 0; + token->type = SCPI_TOKEN_UNKNOWN; + } + + return token->len; +} + +/** + * Detect token New line + * @param state + * @param token + * @return + */ +int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) { + token->ptr = state->pos; + + skipChr(state, '\r'); + skipChr(state, '\n'); + + token->len = state->pos - token->ptr; + + if ((token->len > 0)) { + token->type = SCPI_TOKEN_NL; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + state->pos = token->ptr; + token->len = 0; + } + + return token->len; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/lexer_private.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,70 @@ +/*- + * 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 lexer.h + * @date Thu Mar 21 15:00:58 UTC 2013 + * + * @brief SCPI Lexer + * + * + */ + +#ifndef SCPI_LEXER_H +#define SCPI_LEXER_H + +#include "scpi/types.h" +#include "utils_private.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int scpiLex_IsEos(lex_state_t * state) LOCAL; + int scpiLex_WhiteSpace(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_ProgramHeader(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_CharacterProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_DecimalNumericProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_NondecimalNumericData(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_StringProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_ArbitraryBlockProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_ProgramExpression(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_Comma(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_Semicolon(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_Colon(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_NewLine(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiLex_SpecificCharacter(lex_state_t * state, scpi_token_t * token, char chr) LOCAL; + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_LEXER_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/minimal.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,216 @@ +/*- + * 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_minimal.c + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI minimal implementation + * + * + */ + + +#include "scpi/parser.h" +#include "scpi/minimal.h" +#include "scpi/constants.h" +#include "scpi/error.h" +#include "scpi/ieee488.h" +#include "utils_private.h" + +/** + * Command stub function + * @param context + * @return + */ +scpi_result_t SCPI_Stub(scpi_t * context) { + (void) context; + return SCPI_RES_OK; +} + +/** + * Query command stub function + * @param context + * @return + */ +scpi_result_t SCPI_StubQ(scpi_t * context) { + SCPI_ResultInt32(context, 0); + return SCPI_RES_OK; +} + +/** + * SYSTem:VERSion? + * @param context + * @return + */ +scpi_result_t SCPI_SystemVersionQ(scpi_t * context) { + SCPI_ResultMnemonic(context, SCPI_STD_VERSION_REVISION); + return SCPI_RES_OK; +} + +/** + * SYSTem:ERRor[:NEXT]? + * @param context + * @return + */ +scpi_result_t SCPI_SystemErrorNextQ(scpi_t * context) { + scpi_error_t error; + SCPI_ErrorPop(context, &error); + SCPI_ResultError(context, &error); +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); +#endif + return SCPI_RES_OK; +} + +/** + * SYSTem:ERRor:COUNt? + * @param context + * @return + */ +scpi_result_t SCPI_SystemErrorCountQ(scpi_t * context) { + SCPI_ResultInt32(context, SCPI_ErrorCount(context)); + + return SCPI_RES_OK; +} + +/** + * STATus:QUEStionable:CONDition? + * @param context + * @return + */ +scpi_result_t SCPI_StatusQuestionableConditionQ(scpi_t * context) { + /* return value */ + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUESC)); + + return SCPI_RES_OK; +} + +/** + * STATus:QUEStionable[:EVENt]? + * @param context + * @return + */ +scpi_result_t SCPI_StatusQuestionableEventQ(scpi_t * context) { + /* return value */ + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUES)); + + /* clear register */ + SCPI_RegSet(context, SCPI_REG_QUES, 0); + + return SCPI_RES_OK; +} + +/** + * STATus:QUEStionable:ENABle? + * @param context + * @return + */ +scpi_result_t SCPI_StatusQuestionableEnableQ(scpi_t * context) { + /* return value */ + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_QUESE)); + + return SCPI_RES_OK; +} + +/** + * STATus:QUEStionable:ENABle + * @param context + * @return + */ +scpi_result_t SCPI_StatusQuestionableEnable(scpi_t * context) { + int32_t new_QUESE; + if (SCPI_ParamInt32(context, &new_QUESE, TRUE)) { + SCPI_RegSet(context, SCPI_REG_QUESE, (scpi_reg_val_t) new_QUESE); + } + return SCPI_RES_OK; +} + +/** + * STATus:OPERation:CONDition? + * @param context + * @return + */ +scpi_result_t SCPI_StatusOperationConditionQ(scpi_t * context) { + /* return value */ + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPERC)); + + return SCPI_RES_OK; +} + +/** + * STATus:OPERation[:EVENt]? + * @param context + * @return + */ +scpi_result_t SCPI_StatusOperationEventQ(scpi_t * context) { + /* return value */ + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPER)); + + /* clear register */ + SCPI_RegSet(context, SCPI_REG_OPER, 0); + + return SCPI_RES_OK; +} + +/** + * STATus:OPERation:ENABle? + * @param context + * @return + */ + scpi_result_t SCPI_StatusOperationEnableQ(scpi_t * context) { + /* return value */ + SCPI_ResultInt32(context, SCPI_RegGet(context, SCPI_REG_OPERE)); + + return SCPI_RES_OK; +} + +/** + * STATus:OPERation:ENABle + * @param context + * @return + */ +scpi_result_t SCPI_StatusOperationEnable(scpi_t * context) { + int32_t new_OPERE; + if (SCPI_ParamInt32(context, &new_OPERE, TRUE)) { + SCPI_RegSet(context, SCPI_REG_OPERE, (scpi_reg_val_t) new_OPERE); + } + return SCPI_RES_OK; +} + +/** + * STATus:PRESet + * @param context + * @return + */ +scpi_result_t SCPI_StatusPreset(scpi_t * context) { + /* clear STATUS:... */ + SCPI_RegSet(context, SCPI_REG_QUES, 0); + return SCPI_RES_OK; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/parser.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,1824 @@ +/*- + * 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_parser.c + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI parser implementation + * + * + */ + +#include <ctype.h> +#include <string.h> + +#include "scpi/config.h" +#include "scpi/parser.h" +#include "parser_private.h" +#include "lexer_private.h" +#include "scpi/error.h" +#include "scpi/constants.h" +#include "scpi/utils.h" + +/** + * Write data to SCPI output + * @param context + * @param data + * @param len - lenght of data to be written + * @return number of bytes written + */ +static size_t writeData(scpi_t * context, const char * data, size_t len) { + if (len > 0) { + return context->interface->write(context, data, len); + } else { + return 0; + } +} + +/** + * Flush data to SCPI output + * @param context + * @return + */ +static int flushData(scpi_t * context) { + if (context && context->interface && context->interface->flush) { + return context->interface->flush(context); + } else { + return SCPI_RES_OK; + } +} + +/** + * Write result delimiter to output + * @param context + * @return number of bytes written + */ +static size_t writeDelimiter(scpi_t * context) { + if (context->output_count > 0) { + return writeData(context, ",", 1); + } else { + return 0; + } +} + +/** + * Conditionaly write "New Line" + * @param context + * @return number of characters written + */ +static size_t writeNewLine(scpi_t * context) { + if (context->output_count > 0) { + size_t len; +#ifndef SCPI_LINE_ENDING +#error no termination character defined +#endif + len = writeData(context, SCPI_LINE_ENDING, strlen(SCPI_LINE_ENDING)); + flushData(context); + return len; + } else { + return 0; + } +} + +/** + * Conditionaly write ";" + * @param context + * @return number of characters written + */ +static size_t writeSemicolon(scpi_t * context) { + if (context->output_count > 0) { + return writeData(context, ";", 1); + } else { + return 0; + } +} + +/** + * Process command + * @param context + */ +static scpi_bool_t processCommand(scpi_t * context) { + const scpi_command_t * cmd = context->param_list.cmd; + lex_state_t * state = &context->param_list.lex_state; + scpi_bool_t result = TRUE; + + /* conditionaly write ; */ + writeSemicolon(context); + + context->cmd_error = FALSE; + context->output_count = 0; + context->input_count = 0; + context->arbitrary_reminding = 0; + + /* if callback exists - call command callback */ + if (cmd->callback != NULL) { + if ((cmd->callback(context) != SCPI_RES_OK)) { + if (!context->cmd_error) { + SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR); + } + result = FALSE; + } else { + if (context->cmd_error) { + result = FALSE; + } + } + } + + /* set error if command callback did not read all parameters */ + if (state->pos < (state->buffer + state->len) && !context->cmd_error) { + SCPI_ErrorPush(context, SCPI_ERROR_PARAMETER_NOT_ALLOWED); + result = FALSE; + } + + return result; +} + +/** + * Cycle all patterns and search matching pattern. Execute command callback. + * @param context + * @result TRUE if context->paramlist is filled with correct values + */ +static scpi_bool_t findCommandHeader(scpi_t * context, const char * header, int len) { + int32_t i; + const scpi_command_t * cmd; + + for (i = 0; context->cmdlist[i].pattern != NULL; i++) { + cmd = &context->cmdlist[i]; + if (matchCommand(cmd->pattern, header, len, NULL, 0, 0)) { + context->param_list.cmd = cmd; + return TRUE; + } + } + return FALSE; +} + +/** + * Parse one command line + * @param context + * @param data - complete command line + * @param len - command line length + * @return FALSE if there was some error during evaluation of commands + */ +scpi_bool_t SCPI_Parse(scpi_t * context, char * data, int len) { + scpi_bool_t result = TRUE; + scpi_parser_state_t * state; + int r; + scpi_token_t cmd_prev = {SCPI_TOKEN_UNKNOWN, NULL, 0}; + + if (context == NULL) { + return FALSE; + } + + state = &context->parser_state; + context->output_count = 0; + + while (1) { + r = scpiParser_detectProgramMessageUnit(state, data, len); + + if (state->programHeader.type == SCPI_TOKEN_INVALID) { + SCPI_ErrorPush(context, SCPI_ERROR_INVALID_CHARACTER); + result = FALSE; + } else if (state->programHeader.len > 0) { + + composeCompoundCommand(&cmd_prev, &state->programHeader); + + if (findCommandHeader(context, state->programHeader.ptr, state->programHeader.len)) { + + context->param_list.lex_state.buffer = state->programData.ptr; + context->param_list.lex_state.pos = context->param_list.lex_state.buffer; + context->param_list.lex_state.len = state->programData.len; + context->param_list.cmd_raw.data = state->programHeader.ptr; + context->param_list.cmd_raw.position = 0; + context->param_list.cmd_raw.length = state->programHeader.len; + + result &= processCommand(context); + cmd_prev = state->programHeader; + } else { + /* place undefined header with error */ + /* calculate length of errornouse header and trim \r\n */ + size_t r2 = r; + while (r2 > 0 && (data[r2 - 1] == '\r' || data[r2 - 1] == '\n')) r2--; + SCPI_ErrorPushEx(context, SCPI_ERROR_UNDEFINED_HEADER, data, r2); + result = FALSE; + } + } + + if (r < len) { + data += r; + len -= r; + } else { + break; + } + + } + + /* conditionaly write new line */ + writeNewLine(context); + + return result; +} + +/** + * Initialize SCPI context structure + * @param context + * @param commands + * @param interface + * @param units + * @param idn1 + * @param idn2 + * @param idn3 + * @param idn4 + * @param input_buffer + * @param input_buffer_length + * @param error_queue_data + * @param error_queue_size + */ +void SCPI_Init(scpi_t * context, + const scpi_command_t * commands, + scpi_interface_t * interface, + const scpi_unit_def_t * units, + const char * idn1, const char * idn2, const char * idn3, const char * idn4, + char * input_buffer, size_t input_buffer_length, + scpi_error_t * error_queue_data, int16_t error_queue_size) { + memset(context, 0, sizeof (*context)); + context->cmdlist = commands; + context->interface = interface; + context->units = units; + context->idn[0] = idn1; + context->idn[1] = idn2; + context->idn[2] = idn3; + context->idn[3] = idn4; + context->buffer.data = input_buffer; + context->buffer.length = input_buffer_length; + context->buffer.position = 0; + SCPI_ErrorInit(context, error_queue_data, error_queue_size); +} + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE + +/** + * Initialize context's + * @param context + * @param data + * @param len + * @return + */ +void SCPI_InitHeap(scpi_t * context, + char * error_info_heap, size_t error_info_heap_length) { + scpiheap_init(&context->error_info_heap, error_info_heap, error_info_heap_length); +} +#endif + +/** + * Interface to the application. Adds data to system buffer and try to search + * command line termination. If the termination is found or if len=0, command + * parser is called. + * + * @param context + * @param data - data to process + * @param len - length of data + * @return + */ +scpi_bool_t SCPI_Input(scpi_t * context, const char * data, int len) { + scpi_bool_t result = TRUE; + size_t totcmdlen = 0; + int cmdlen = 0; + + if (len == 0) { + context->buffer.data[context->buffer.position] = 0; + result = SCPI_Parse(context, context->buffer.data, context->buffer.position); + context->buffer.position = 0; + } else { + int buffer_free; + + buffer_free = context->buffer.length - context->buffer.position; + if (len > (buffer_free - 1)) { + /* Input buffer overrun - invalidate buffer */ + context->buffer.position = 0; + context->buffer.data[context->buffer.position] = 0; + SCPI_ErrorPush(context, SCPI_ERROR_INPUT_BUFFER_OVERRUN); + return FALSE; + } + memcpy(&context->buffer.data[context->buffer.position], data, len); + context->buffer.position += len; + context->buffer.data[context->buffer.position] = 0; + + + while (1) { + cmdlen = scpiParser_detectProgramMessageUnit(&context->parser_state, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen); + totcmdlen += cmdlen; + + if (context->parser_state.termination == SCPI_MESSAGE_TERMINATION_NL) { + result = SCPI_Parse(context, context->buffer.data, totcmdlen); + memmove(context->buffer.data, context->buffer.data + totcmdlen, context->buffer.position - totcmdlen); + context->buffer.position -= totcmdlen; + totcmdlen = 0; + } else { + if (context->parser_state.programHeader.type == SCPI_TOKEN_UNKNOWN + && context->parser_state.termination == SCPI_MESSAGE_TERMINATION_NONE) break; + if (totcmdlen >= context->buffer.position) break; + } + } + } + + return result; +} + +/* writing results */ + +/** + * Write raw string result to the output + * @param context + * @param data + * @return + */ +size_t SCPI_ResultCharacters(scpi_t * context, const char * data, size_t len) { + size_t result = 0; + result += writeDelimiter(context); + result += writeData(context, data, len); + context->output_count++; + return result; +} + +/** + * Return prefix of nondecimal base + * @param base + * @return + */ +static const char * getBasePrefix(int8_t base) { + switch (base) { + case 2: return "#B"; + case 8: return "#Q"; + case 16: return "#H"; + default: return NULL; + } +} + +/** + * Write signed/unsigned 32 bit integer value in specific base to the result + * @param context + * @param val + * @param base + * @param sign + * @return + */ +static size_t resultUInt32BaseSign(scpi_t * context, uint32_t val, int8_t base, scpi_bool_t sign) { + char buffer[32 + 1]; + const char * basePrefix; + size_t result = 0; + size_t len; + + len = UInt32ToStrBaseSign(val, buffer, sizeof (buffer), base, sign); + basePrefix = getBasePrefix(base); + + result += writeDelimiter(context); + if (basePrefix != NULL) { + result += writeData(context, basePrefix, 2); + } + result += writeData(context, buffer, len); + context->output_count++; + return result; +} + +/** + * Write signed/unsigned 64 bit integer value in specific base to the result + * @param context + * @param val + * @param base + * @param sign + * @return + */ +static size_t resultUInt64BaseSign(scpi_t * context, uint64_t val, int8_t base, scpi_bool_t sign) { + char buffer[64 + 1]; + const char * basePrefix; + size_t result = 0; + size_t len; + + len = UInt64ToStrBaseSign(val, buffer, sizeof (buffer), base, sign); + basePrefix = getBasePrefix(base); + + result += writeDelimiter(context); + if (basePrefix != NULL) { + result += writeData(context, basePrefix, 2); + } + result += writeData(context, buffer, len); + context->output_count++; + return result; +} + +/** + * Write signed 32 bit integer value to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultInt32(scpi_t * context, int32_t val) { + return resultUInt32BaseSign(context, val, 10, TRUE); +} + +/** + * Write unsigned 32 bit integer value in specific base to the result + * Write signed/unsigned 32 bit integer value in specific base to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultUInt32Base(scpi_t * context, uint32_t val, int8_t base) { + return resultUInt32BaseSign(context, val, base, FALSE); +} + +/** + * Write signed 64 bit integer value to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultInt64(scpi_t * context, int64_t val) { + return resultUInt64BaseSign(context, val, 10, TRUE); +} + +/** + * Write unsigned 64 bit integer value in specific base to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultUInt64Base(scpi_t * context, uint64_t val, int8_t base) { + return resultUInt64BaseSign(context, val, base, FALSE); +} + +/** + * Write float (32 bit) value to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultFloat(scpi_t * context, float val) { + char buffer[32]; + size_t result = 0; + size_t len = SCPI_FloatToStr(val, buffer, sizeof (buffer)); + result += writeDelimiter(context); + result += writeData(context, buffer, len); + context->output_count++; + return result; +} + +/** + * Write double (64bit) value to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultDouble(scpi_t * context, double val) { + char buffer[32]; + size_t result = 0; + size_t len = SCPI_DoubleToStr(val, buffer, sizeof (buffer)); + result += writeDelimiter(context); + result += writeData(context, buffer, len); + context->output_count++; + return result; +} + +/** + * Write string withn " to the result + * @param context + * @param data + * @return + */ +size_t SCPI_ResultText(scpi_t * context, const char * data) { + size_t result = 0; + size_t len = strlen(data); + const char * quote; + result += writeDelimiter(context); + result += writeData(context, "\"", 1); + while ((quote = strnpbrk(data, len, "\""))) { + result += writeData(context, data, quote - data + 1); + result += writeData(context, "\"", 1); + len -= quote - data + 1; + data = quote + 1; + } + result += writeData(context, data, len); + result += writeData(context, "\"", 1); + context->output_count++; + return result; +} + +/** + * SCPI-99:21.8 Device-dependent error information. + * Write error information with the following syntax: + * <Error/event_number>,"<Error/event_description>[;<Device-dependent_info>]" + * The maximum string length of <Error/event_description> plus <Device-dependent_info> + * is SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH (255) characters. + * + * @param context + * @param error + * @return + */ +size_t SCPI_ResultError(scpi_t * context, scpi_error_t * error) { + size_t result = 0; + size_t outputlimit = SCPI_STD_ERROR_DESC_MAX_STRING_LENGTH; + size_t step = 0; + const char * quote; + + const char * data[SCPIDEFINE_DESCRIPTION_MAX_PARTS]; + size_t len[SCPIDEFINE_DESCRIPTION_MAX_PARTS]; + size_t i; + + data[0] = SCPI_ErrorTranslate(error->error_code); + len[0] = strlen(data[0]); + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION + data[1] = error->device_dependent_info; +#if USE_MEMORY_ALLOCATION_FREE + len[1] = error->device_dependent_info ? strlen(data[1]) : 0; +#else + SCPIDEFINE_get_parts(&context->error_info_heap, data[1], &len[1], &data[2], &len[2]); +#endif +#endif + + result += SCPI_ResultInt32(context, error->error_code); + result += writeDelimiter(context); + result += writeData(context, "\"", 1); + + for (i = 0; (i < SCPIDEFINE_DESCRIPTION_MAX_PARTS) && data[i] && outputlimit; i++) { + if (i == 1) { + result += writeSemicolon(context); + outputlimit -= 1; + } + if (len[i] > outputlimit) { + len[i] = outputlimit; + } + + while ((quote = strnpbrk(data[i], len[i], "\""))) { + if ((step = quote - data[i] + 1) >= outputlimit) { + len[i] -= 1; + outputlimit -= 1; + break; + } + result += writeData(context, data[i], step); + result += writeData(context, "\"", 1); + len[i] -= step; + outputlimit -= step + 1; + data[i] = quote + 1; + if (len[i] > outputlimit) { + len[i] = outputlimit; + } + } + + result += writeData(context, data[i], len[i]); + outputlimit -= len[i]; + } + result += writeData(context, "\"", 1); + + return result; +} + +/** + * Write arbitrary block header with length + * @param context + * @param len + * @return + */ +size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len) { + char block_header[12]; + size_t header_len; + block_header[0] = '#'; + SCPI_UInt32ToStrBase((uint32_t) len, block_header + 2, 10, 10); + + header_len = strlen(block_header + 2); + block_header[1] = (char) (header_len + '0'); + + context->arbitrary_reminding = len; + return writeData(context, block_header, header_len + 2); +} + +/** + * Add data to arbitrary block + * @param context + * @param data + * @param len + * @return + */ +size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len) { + + if (context->arbitrary_reminding < len) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return 0; + } + + context->arbitrary_reminding -= len; + + if (context->arbitrary_reminding == 0) { + context->output_count++; + } + + return writeData(context, (const char *) data, len); +} + +/** + * Write arbitrary block program data to the result + * @param context + * @param data + * @param len + * @return + */ +size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len) { + size_t result = 0; + result += SCPI_ResultArbitraryBlockHeader(context, len); + result += SCPI_ResultArbitraryBlockData(context, data, len); + return result; +} + +/** + * Write boolean value to the result + * @param context + * @param val + * @return + */ +size_t SCPI_ResultBool(scpi_t * context, scpi_bool_t val) { + return resultUInt32BaseSign(context, val ? 1 : 0, 10, FALSE); +} + +/* parsing parameters */ + +/** + * Invalidate token + * @param token + * @param ptr + */ +static void invalidateToken(scpi_token_t * token, char * ptr) { + token->len = 0; + token->ptr = ptr; + token->type = SCPI_TOKEN_UNKNOWN; +} + +/** + * Get one parameter from command line + * @param context + * @param parameter + * @param mandatory + * @return + */ +scpi_bool_t SCPI_Parameter(scpi_t * context, scpi_parameter_t * parameter, scpi_bool_t mandatory) { + lex_state_t * state; + + if (!parameter) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + invalidateToken(parameter, NULL); + + state = &context->param_list.lex_state; + + if (state->pos >= (state->buffer + state->len)) { + if (mandatory) { + SCPI_ErrorPush(context, SCPI_ERROR_MISSING_PARAMETER); + } else { + parameter->type = SCPI_TOKEN_PROGRAM_MNEMONIC; /* TODO: select something different */ + } + return FALSE; + } + if (context->input_count != 0) { + scpiLex_Comma(state, parameter); + if (parameter->type != SCPI_TOKEN_COMMA) { + invalidateToken(parameter, NULL); + SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SEPARATOR); + return FALSE; + } + } + + context->input_count++; + + scpiParser_parseProgramData(&context->param_list.lex_state, parameter); + + switch (parameter->type) { + case SCPI_TOKEN_HEXNUM: + case SCPI_TOKEN_OCTNUM: + case SCPI_TOKEN_BINNUM: + case SCPI_TOKEN_PROGRAM_MNEMONIC: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + case SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA: + case SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA: + case SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA: + case SCPI_TOKEN_PROGRAM_EXPRESSION: + return TRUE; + default: + invalidateToken(parameter, NULL); + SCPI_ErrorPush(context, SCPI_ERROR_INVALID_STRING_DATA); + return FALSE; + } +} + +/** + * Detect if parameter is number + * @param parameter + * @param suffixAllowed + * @return + */ +scpi_bool_t SCPI_ParamIsNumber(scpi_parameter_t * parameter, scpi_bool_t suffixAllowed) { + switch (parameter->type) { + case SCPI_TOKEN_HEXNUM: + case SCPI_TOKEN_OCTNUM: + case SCPI_TOKEN_BINNUM: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + return TRUE; + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + return suffixAllowed; + default: + return FALSE; + } +} + +/** + * Convert parameter to signed/unsigned 32 bit integer + * @param context + * @param parameter + * @param value result + * @param sign + * @return TRUE if succesful + */ +static scpi_bool_t ParamSignToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value, scpi_bool_t sign) { + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + switch (parameter->type) { + case SCPI_TOKEN_HEXNUM: + return strBaseToUInt32(parameter->ptr, value, 16) > 0 ? TRUE : FALSE; + case SCPI_TOKEN_OCTNUM: + return strBaseToUInt32(parameter->ptr, value, 8) > 0 ? TRUE : FALSE; + case SCPI_TOKEN_BINNUM: + return strBaseToUInt32(parameter->ptr, value, 2) > 0 ? TRUE : FALSE; + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + if (sign) { + return strBaseToInt32(parameter->ptr, (int32_t *) value, 10) > 0 ? TRUE : FALSE; + } else { + return strBaseToUInt32(parameter->ptr, value, 10) > 0 ? TRUE : FALSE; + } + default: + return FALSE; + } +} + +/** + * Convert parameter to signed/unsigned 64 bit integer + * @param context + * @param parameter + * @param value result + * @param sign + * @return TRUE if succesful + */ +static scpi_bool_t ParamSignToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value, scpi_bool_t sign) { + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + switch (parameter->type) { + case SCPI_TOKEN_HEXNUM: + return strBaseToUInt64(parameter->ptr, value, 16) > 0 ? TRUE : FALSE; + case SCPI_TOKEN_OCTNUM: + return strBaseToUInt64(parameter->ptr, value, 8) > 0 ? TRUE : FALSE; + case SCPI_TOKEN_BINNUM: + return strBaseToUInt64(parameter->ptr, value, 2) > 0 ? TRUE : FALSE; + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + if (sign) { + return strBaseToInt64(parameter->ptr, (int64_t *) value, 10) > 0 ? TRUE : FALSE; + } else { + return strBaseToUInt64(parameter->ptr, value, 10) > 0 ? TRUE : FALSE; + } + default: + return FALSE; + } +} + +/** + * Convert parameter to signed 32 bit integer + * @param context + * @param parameter + * @param value result + * @return TRUE if succesful + */ +scpi_bool_t SCPI_ParamToInt32(scpi_t * context, scpi_parameter_t * parameter, int32_t * value) { + return ParamSignToUInt32(context, parameter, (uint32_t *) value, TRUE); +} + +/** + * Convert parameter to unsigned 32 bit integer + * @param context + * @param parameter + * @param value result + * @return TRUE if succesful + */ +scpi_bool_t SCPI_ParamToUInt32(scpi_t * context, scpi_parameter_t * parameter, uint32_t * value) { + return ParamSignToUInt32(context, parameter, value, FALSE); +} + +/** + * Convert parameter to signed 64 bit integer + * @param context + * @param parameter + * @param value result + * @return TRUE if succesful + */ +scpi_bool_t SCPI_ParamToInt64(scpi_t * context, scpi_parameter_t * parameter, int64_t * value) { + return ParamSignToUInt64(context, parameter, (uint64_t *) value, TRUE); +} + +/** + * Convert parameter to unsigned 32 bit integer + * @param context + * @param parameter + * @param value result + * @return TRUE if succesful + */ +scpi_bool_t SCPI_ParamToUInt64(scpi_t * context, scpi_parameter_t * parameter, uint64_t * value) { + return ParamSignToUInt64(context, parameter, value, FALSE); +} + +/** + * Convert parameter to float (32 bit) + * @param context + * @param parameter + * @param value result + * @return TRUE if succesful + */ +scpi_bool_t SCPI_ParamToFloat(scpi_t * context, scpi_parameter_t * parameter, float * value) { + scpi_bool_t result; + uint32_t valint; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + switch (parameter->type) { + case SCPI_TOKEN_HEXNUM: + case SCPI_TOKEN_OCTNUM: + case SCPI_TOKEN_BINNUM: + result = SCPI_ParamToUInt32(context, parameter, &valint); + *value = valint; + break; + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + result = strToFloat(parameter->ptr, value) > 0 ? TRUE : FALSE; + break; + default: + result = FALSE; + } + return result; +} + +/** + * Convert parameter to double (64 bit) + * @param context + * @param parameter + * @param value result + * @return TRUE if succesful + */ +scpi_bool_t SCPI_ParamToDouble(scpi_t * context, scpi_parameter_t * parameter, double * value) { + scpi_bool_t result; + uint64_t valint; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + switch (parameter->type) { + case SCPI_TOKEN_HEXNUM: + case SCPI_TOKEN_OCTNUM: + case SCPI_TOKEN_BINNUM: + result = SCPI_ParamToUInt64(context, parameter, &valint); + *value = valint; + break; + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + result = strToDouble(parameter->ptr, value) > 0 ? TRUE : FALSE; + break; + default: + result = FALSE; + } + return result; +} + +/** + * Read floating point float (32 bit) parameter + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamFloat(scpi_t * context, float * value, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + if (SCPI_ParamIsNumber(¶m, FALSE)) { + SCPI_ParamToFloat(context, ¶m, value); + } else if (SCPI_ParamIsNumber(¶m, TRUE)) { + SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED); + result = FALSE; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + result = FALSE; + } + } + return result; +} + +/** + * Read floating point double (64 bit) parameter + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamDouble(scpi_t * context, double * value, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + if (SCPI_ParamIsNumber(¶m, FALSE)) { + SCPI_ParamToDouble(context, ¶m, value); + } else if (SCPI_ParamIsNumber(¶m, TRUE)) { + SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED); + result = FALSE; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + result = FALSE; + } + } + return result; +} + +/** + * Read signed/unsigned 32 bit integer parameter + * @param context + * @param value + * @param mandatory + * @param sign + * @return + */ +static scpi_bool_t ParamSignUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory, scpi_bool_t sign) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + if (SCPI_ParamIsNumber(¶m, FALSE)) { + result = ParamSignToUInt32(context, ¶m, value, sign); + } else if (SCPI_ParamIsNumber(¶m, TRUE)) { + SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED); + result = FALSE; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + result = FALSE; + } + } + return result; +} + +/** + * Read signed/unsigned 64 bit integer parameter + * @param context + * @param value + * @param mandatory + * @param sign + * @return + */ +static scpi_bool_t ParamSignUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory, scpi_bool_t sign) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + if (SCPI_ParamIsNumber(¶m, FALSE)) { + result = ParamSignToUInt64(context, ¶m, value, sign); + } else if (SCPI_ParamIsNumber(¶m, TRUE)) { + SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED); + result = FALSE; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + result = FALSE; + } + } + return result; +} + +/** + * Read signed 32 bit integer parameter + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamInt32(scpi_t * context, int32_t * value, scpi_bool_t mandatory) { + return ParamSignUInt32(context, (uint32_t *) value, mandatory, TRUE); +} + +/** + * Read unsigned 32 bit integer parameter + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamUInt32(scpi_t * context, uint32_t * value, scpi_bool_t mandatory) { + return ParamSignUInt32(context, value, mandatory, FALSE); +} + +/** + * Read signed 64 bit integer parameter + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamInt64(scpi_t * context, int64_t * value, scpi_bool_t mandatory) { + return ParamSignUInt64(context, (uint64_t *) value, mandatory, TRUE); +} + +/** + * Read unsigned 64 bit integer parameter + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamUInt64(scpi_t * context, uint64_t * value, scpi_bool_t mandatory) { + return ParamSignUInt64(context, value, mandatory, FALSE); +} + +/** + * Read character parameter + * @param context + * @param value + * @param len + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamCharacters(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!value || !len) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + switch (param.type) { + case SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA: + case SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA: + *value = param.ptr + 1; + *len = param.len - 2; + break; + default: + *value = param.ptr; + *len = param.len; + break; + } + + /* TODO: return also parameter type (ProgramMnemonic, ArbitraryBlockProgramData, SingleQuoteProgramData, DoubleQuoteProgramData */ + } + + return result; +} + +/** + * Get arbitrary block program data and returns pointer to data + * @param context + * @param value result pointer to data + * @param len result length of data + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamArbitraryBlock(scpi_t * context, const char ** value, size_t * len, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!value || !len) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + if (param.type == SCPI_TOKEN_ARBITRARY_BLOCK_PROGRAM_DATA) { + *value = param.ptr; + *len = param.len; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + result = FALSE; + } + } + + return result; +} + +scpi_bool_t SCPI_ParamCopyText(scpi_t * context, char * buffer, size_t buffer_len, size_t * copy_len, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + size_t i_from; + size_t i_to; + char quote; + + if (!buffer || !copy_len) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + + switch (param.type) { + case SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA: + case SCPI_TOKEN_DOUBLE_QUOTE_PROGRAM_DATA: + quote = param.type == SCPI_TOKEN_SINGLE_QUOTE_PROGRAM_DATA ? '\'' : '"'; + for (i_from = 1, i_to = 0; i_from < (size_t) (param.len - 1); i_from++) { + if (i_from >= buffer_len) { + break; + } + buffer[i_to] = param.ptr[i_from]; + i_to++; + if (param.ptr[i_from] == quote) { + i_from++; + } + } + *copy_len = i_to; + if (i_to < buffer_len) { + buffer[i_to] = 0; + } + break; + default: + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + result = FALSE; + } + } + + return result; +} + +/** + * Convert parameter to choice + * @param context + * @param parameter - should be PROGRAM_MNEMONIC + * @param options - NULL terminated list of choices + * @param value - index to options + * @return + */ +scpi_bool_t SCPI_ParamToChoice(scpi_t * context, scpi_parameter_t * parameter, const scpi_choice_def_t * options, int32_t * value) { + size_t res; + scpi_bool_t result = FALSE; + + if (!options || !value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + if (parameter->type == SCPI_TOKEN_PROGRAM_MNEMONIC) { + for (res = 0; options[res].name; ++res) { + if (matchPattern(options[res].name, strlen(options[res].name), parameter->ptr, parameter->len, NULL)) { + *value = options[res].tag; + result = TRUE; + break; + } + } + + if (!result) { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + } + } else { + SCPI_ErrorPush(context, SCPI_ERROR_DATA_TYPE_ERROR); + } + + return result; +} + +/** + * Find tag in choices and returns its first textual representation + * @param options specifications of choices numbers (patterns) + * @param tag numerical representatio of choice + * @param text result text + * @return TRUE if succesfule, else FALSE + */ +scpi_bool_t SCPI_ChoiceToName(const scpi_choice_def_t * options, int32_t tag, const char ** text) { + int i; + + for (i = 0; options[i].name != NULL; i++) { + if (options[i].tag == tag) { + *text = options[i].name; + return TRUE; + } + } + + return FALSE; +} + +/* + * Definition of BOOL choice list + */ +const scpi_choice_def_t scpi_bool_def[] = { + {"OFF", 0}, + {"ON", 1}, + SCPI_CHOICE_LIST_END /* termination of option list */ +}; + +/** + * Read BOOL parameter (0,1,ON,OFF) + * @param context + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + int32_t intval; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + + if (result) { + if (param.type == SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA) { + SCPI_ParamToInt32(context, ¶m, &intval); + *value = intval ? TRUE : FALSE; + } else { + result = SCPI_ParamToChoice(context, ¶m, scpi_bool_def, &intval); + if (result) { + *value = intval ? TRUE : FALSE; + } + } + } + + return result; +} + +/** + * Read value from list of options + * @param context + * @param options + * @param value + * @param mandatory + * @return + */ +scpi_bool_t SCPI_ParamChoice(scpi_t * context, const scpi_choice_def_t * options, int32_t * value, scpi_bool_t mandatory) { + scpi_bool_t result; + scpi_parameter_t param; + + if (!options || !value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + if (result) { + result = SCPI_ParamToChoice(context, ¶m, options, value); + } + + return result; +} + +/** + * Parse one parameter and detect type + * @param state + * @param token + * @return + */ +int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) { + scpi_token_t tmp; + int result = 0; + int wsLen; + int suffixLen; + int realLen = 0; + realLen += scpiLex_WhiteSpace(state, &tmp); + + if (result == 0) result = scpiLex_NondecimalNumericData(state, token); + if (result == 0) result = scpiLex_CharacterProgramData(state, token); + if (result == 0) { + result = scpiLex_DecimalNumericProgramData(state, token); + if (result != 0) { + wsLen = scpiLex_WhiteSpace(state, &tmp); + suffixLen = scpiLex_SuffixProgramData(state, &tmp); + if (suffixLen > 0) { + token->len += wsLen + suffixLen; + token->type = SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX; + result = token->len; + } + } + } + + if (result == 0) result = scpiLex_StringProgramData(state, token); + if (result == 0) result = scpiLex_ArbitraryBlockProgramData(state, token); + if (result == 0) result = scpiLex_ProgramExpression(state, token); + + realLen += scpiLex_WhiteSpace(state, &tmp); + + return result + realLen; +} + +/** + * Skip all parameters to correctly detect end of command line. + * @param state + * @param token + * @param numberOfParameters + * @return + */ +int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) { + + int result; + scpi_token_t tmp; + int paramCount = 0; + + token->len = -1; + token->type = SCPI_TOKEN_ALL_PROGRAM_DATA; + token->ptr = state->pos; + + + for (result = 1; result != 0; result = scpiLex_Comma(state, &tmp)) { + token->len += result; + + result = scpiParser_parseProgramData(state, &tmp); + if (tmp.type != SCPI_TOKEN_UNKNOWN) { + token->len += result; + } else { + token->type = SCPI_TOKEN_UNKNOWN; + token->len = 0; + paramCount = -1; + break; + } + paramCount++; + } + + if (numberOfParameters != NULL) { + *numberOfParameters = paramCount; + } + return token->len; +} + +/** + * Skip complete command line - program header and parameters + * @param state + * @param buffer + * @param len + * @return + */ +int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, char * buffer, int len) { + lex_state_t lex_state; + scpi_token_t tmp; + int result = 0; + + lex_state.buffer = lex_state.pos = buffer; + lex_state.len = len; + state->numberOfParameters = 0; + + /* ignore whitespace at the begginig */ + scpiLex_WhiteSpace(&lex_state, &tmp); + + if (scpiLex_ProgramHeader(&lex_state, &state->programHeader) >= 0) { + if (scpiLex_WhiteSpace(&lex_state, &tmp) > 0) { + scpiParser_parseAllProgramData(&lex_state, &state->programData, &state->numberOfParameters); + } else { + invalidateToken(&state->programData, lex_state.pos); + } + } else { + invalidateToken(&state->programHeader, lex_state.buffer); + invalidateToken(&state->programData, lex_state.buffer); + } + + if (result == 0) result = scpiLex_NewLine(&lex_state, &tmp); + if (result == 0) result = scpiLex_Semicolon(&lex_state, &tmp); + + if (!scpiLex_IsEos(&lex_state) && (result == 0)) { + lex_state.pos++; + + state->programHeader.len = 1; + state->programHeader.type = SCPI_TOKEN_INVALID; + + invalidateToken(&state->programData, lex_state.buffer); + } + + if (SCPI_TOKEN_SEMICOLON == tmp.type) { + state->termination = SCPI_MESSAGE_TERMINATION_SEMICOLON; + } else if (SCPI_TOKEN_NL == tmp.type) { + state->termination = SCPI_MESSAGE_TERMINATION_NL; + } else { + state->termination = SCPI_MESSAGE_TERMINATION_NONE; + } + + return lex_state.pos - lex_state.buffer; +} + +/** + * Check current command + * - suitable for one handle to multiple commands + * @param context + * @param cmd + * @return + */ +scpi_bool_t SCPI_IsCmd(scpi_t * context, const char * cmd) { + const char * pattern; + + if (!context->param_list.cmd) { + return FALSE; + } + + pattern = context->param_list.cmd->pattern; + return matchCommand(pattern, cmd, strlen(cmd), NULL, 0, 0); +} + +#if USE_COMMAND_TAGS + +/** + * Return the .tag field of the matching scpi_command_t + * @param context + * @return + */ +int32_t SCPI_CmdTag(scpi_t * context) { + if (context->param_list.cmd) { + return context->param_list.cmd->tag; + } else { + return 0; + } +} +#endif /* USE_COMMAND_TAGS */ + +scpi_bool_t SCPI_Match(const char * pattern, const char * value, size_t len) { + return matchCommand(pattern, value, len, NULL, 0, 0); +} + +scpi_bool_t SCPI_CommandNumbers(scpi_t * context, int32_t * numbers, size_t len, int32_t default_value) { + return matchCommand(context->param_list.cmd->pattern, context->param_list.cmd_raw.data, context->param_list.cmd_raw.length, numbers, len, default_value); +} + +/** + * If SCPI_Parameter() returns FALSE, this function can detect, if the parameter + * is just missing (TRUE) or if there was an error during processing of the command (FALSE) + * @param parameter + * @return + */ +scpi_bool_t SCPI_ParamIsValid(scpi_parameter_t * parameter) { + return parameter->type == SCPI_TOKEN_UNKNOWN ? FALSE : TRUE; +} + +/** + * Returns TRUE if there was an error during parameter handling + * @param context + * @return + */ +scpi_bool_t SCPI_ParamErrorOccurred(scpi_t * context) { + return context->cmd_error; +} + +/** + * Result binary array and swap bytes if needed (native endiannes != required endiannes) + * @param context + * @param array + * @param count + * @param item_size + * @param format + * @return + */ +static size_t produceResultArrayBinary(scpi_t * context, const void * array, size_t count, size_t item_size, scpi_array_format_t format) { + + if (SCPI_GetNativeFormat() == format) { + switch (item_size) { + case 1: + case 2: + case 4: + case 8: + return SCPI_ResultArbitraryBlock(context, array, count * item_size); + default: + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return 0; + } + } else { + size_t result = 0; + size_t i; + switch (item_size) { + case 1: + case 2: + case 4: + case 8: + result += SCPI_ResultArbitraryBlockHeader(context, count * item_size); + break; + default: + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return 0; + } + + switch (item_size) { + case 1: + result += SCPI_ResultArbitraryBlockData(context, array, count); + break; + case 2: + for (i = 0; i < count; i++) { + uint16_t val = SCPI_Swap16(((uint16_t*) array)[i]); + result += SCPI_ResultArbitraryBlockData(context, &val, item_size); + } + break; + case 4: + for (i = 0; i < count; i++) { + uint32_t val = SCPI_Swap32(((uint32_t*) array)[i]); + result += SCPI_ResultArbitraryBlockData(context, &val, item_size); + } + break; + case 8: + for (i = 0; i < count; i++) { + uint64_t val = SCPI_Swap64(((uint64_t*) array)[i]); + result += SCPI_ResultArbitraryBlockData(context, &val, item_size); + } + break; + } + + return result; + } +} + + +#define RESULT_ARRAY(func) do {\ + size_t result = 0;\ + if (format == SCPI_FORMAT_ASCII) {\ + size_t i;\ + for (i = 0; i < count; i++) {\ + result += func(context, array[i]);\ + }\ + } else {\ + result = produceResultArrayBinary(context, array, count, sizeof(*array), format);\ + }\ + return result;\ +} while(0) + +/** + * Result array of signed 8bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt8); +} + +/** + * Result array of unsigned 8bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt8); +} + +/** + * Result array of signed 16bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt16); +} + +/** + * Result array of unsigned 16bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt16); +} + +/** + * Result array of signed 32bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt32); +} + +/** + * Result array of unsigned 32bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt32); +} + +/** + * Result array of signed 64bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt64); +} + +/** + * Result array of unsigned 64bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt64); +} + +/** + * Result array of floats + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultFloat); +} + +/** + * Result array of doubles + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultDouble); +} + +/* + * Template macro to generate all SCPI_ParamArrayXYZ function + */ +#define PARAM_ARRAY_TEMPLATE(func) do{\ + if (format != SCPI_FORMAT_ASCII) return FALSE;\ + for (*o_count = 0; *o_count < i_count; (*o_count)++) {\ + if (!func(context, &data[*o_count], mandatory)) {\ + break;\ + }\ + mandatory = FALSE;\ + }\ + return mandatory ? FALSE : TRUE;\ +}while(0) + +/** + * Read list of values up to i_count + * @param context + * @param data - array to fill + * @param i_count - number of elements of data + * @param o_count - real number of filled elements + * @param mandatory + * @return TRUE on success + */ +scpi_bool_t SCPI_ParamArrayInt32(scpi_t * context, int32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory) { + PARAM_ARRAY_TEMPLATE(SCPI_ParamInt32); +} + +/** + * Read list of values up to i_count + * @param context + * @param data - array to fill + * @param i_count - number of elements of data + * @param o_count - real number of filled elements + * @param mandatory + * @return TRUE on success + */ +scpi_bool_t SCPI_ParamArrayUInt32(scpi_t * context, uint32_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory) { + PARAM_ARRAY_TEMPLATE(SCPI_ParamUInt32); +} + +/** + * Read list of values up to i_count + * @param context + * @param data - array to fill + * @param i_count - number of elements of data + * @param o_count - real number of filled elements + * @param mandatory + * @return TRUE on success + */ +scpi_bool_t SCPI_ParamArrayInt64(scpi_t * context, int64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory) { + PARAM_ARRAY_TEMPLATE(SCPI_ParamInt64); +} + +/** + * Read list of values up to i_count + * @param context + * @param data - array to fill + * @param i_count - number of elements of data + * @param o_count - real number of filled elements + * @param mandatory + * @return TRUE on success + */ +scpi_bool_t SCPI_ParamArrayUInt64(scpi_t * context, uint64_t *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory) { + PARAM_ARRAY_TEMPLATE(SCPI_ParamUInt64); +} + +/** + * Read list of values up to i_count + * @param context + * @param data - array to fill + * @param i_count - number of elements of data + * @param o_count - real number of filled elements + * @param mandatory + * @return TRUE on success + */ +scpi_bool_t SCPI_ParamArrayFloat(scpi_t * context, float *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory) { + PARAM_ARRAY_TEMPLATE(SCPI_ParamFloat); +} + +/** + * Read list of values up to i_count + * @param context + * @param data - array to fill + * @param i_count - number of elements of data + * @param o_count - real number of filled elements + * @param mandatory + * @return TRUE on success + */ +scpi_bool_t SCPI_ParamArrayDouble(scpi_t * context, double *data, size_t i_count, size_t *o_count, scpi_array_format_t format, scpi_bool_t mandatory) { + PARAM_ARRAY_TEMPLATE(SCPI_ParamDouble); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/parser_private.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,57 @@ +/*- + * 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 parser_private.h + * + * @brief SCPI Parser private definitions + * + * + */ + +#ifndef SCPI_PARSER_PRIVATE_H +#define SCPI_PARSER_PRIVATE_H + +#include "scpi/types.h" +#include "utils_private.h" + +#ifdef __cplusplus +extern "C" { +#endif + + int scpiParser_parseProgramData(lex_state_t * state, scpi_token_t * token) LOCAL; + int scpiParser_parseAllProgramData(lex_state_t * state, scpi_token_t * token, int * numberOfParameters) LOCAL; + int scpiParser_detectProgramMessageUnit(scpi_parser_state_t * state, char * buffer, int len) LOCAL; + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_PARSER_PRIVATE_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/scpi.g Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,142 @@ +grammar scpi; + +terminatedProgramMessage + : programMessage NL? EOF + ; + +programMessage + : programMessageUnit (SEMICOLON programMessageUnit)* + ; + + +programMessageUnit + : WS* programHeader (WS programData (COMMA programData)*)? + ; + +programHeader + : compoundProgramHeader + | commonProgramHeader + ; + +compoundProgramHeader + : COLON? PROGRAM_MNEMONIC (COLON PROGRAM_MNEMONIC)* QUESTION? + ; + +commonProgramHeader + : STAR PROGRAM_MNEMONIC QUESTION? + ; + +programDataSeparator + : WS* + ; + +programData + : WS* programDataType WS* + ; + +programDataType + : nondecimalNumericProgramData + | characterProgramData + | decimalNumericProgramData + | stringProgramData + | arbitraryBlockProgramData + | expressionProgramData +// | suffixProgramData + ; + +nondecimalNumericProgramData + : HEXNUM + | OCTNUM + | BINNUM + ; + +characterProgramData + : PROGRAM_MNEMONIC + ; + +decimalNumericProgramData + : DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX + ; + +//suffixProgramData +// : PROGRAM_MNEMONIC//SUFFIX_PROGRAM_DATA +// ; + +stringProgramData + : SINGLE_QUOTE_PROGRAM_DATA + | DOUBLE_QUOTE_PROGRAM_DATA + ; + +expressionProgramData + : PROGRAM_EXPRESSION + ; + +// support only nonzero prefix +arbitraryBlockProgramData + : SHARP NONZERO_DIGIT NUMBER .* + ; + +PROGRAM_MNEMONIC : ALPHA (ALPHA | DIGIT | UNDERSCORE)*; +HEXNUM : SHARP H HEXDIGIT*; +BINNUM : SHARP Q OCTDIGIT*; +OCTNUM : SHARP B BINDIGIT*; +UNDERSCORE : '_'; +SEMICOLON : ';'; +QUESTION : '?'; +COLON : ':'; +COMMA : ','; +STAR : '*'; +NL : '\r'? '\n' ; +WS : (SPACE | TAB); + +DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX : DECIMAL_NUMERIC_PROGRAM_DATA WS* (SUFFIX_PROGRAM_DATA)?; +fragment DECIMAL_NUMERIC_PROGRAM_DATA : MANTISA WS* (EXPONENT)?; +SINGLE_QUOTE_PROGRAM_DATA : SINGLE_QUOTE ( (NON_SINGLE_QUOTE) | (SINGLE_QUOTE SINGLE_QUOTE))* SINGLE_QUOTE; +DOUBLE_QUOTE_PROGRAM_DATA : DOUBLE_QUOTE ( (NON_DOUBLE_QUOTE) | (DOUBLE_QUOTE DOUBLE_QUOTE))* DOUBLE_QUOTE; +//SUFFIX_PROGRAM_DATA : SLASH? (ALPHA+ (MINUS? DIGIT)?) ((SLASH | DOT) (ALPHA+ (MINUS? DIGIT)?))*; +fragment SUFFIX_PROGRAM_DATA : SLASH? ALPHA+ ((SLASH | DOT) ALPHA+)*; +//fragment SUFFIX_PROGRAM_DATA : ALPHA+; + +fragment PROGRAM_EXPRESSION_CHARACTER : (SPACE | '!' | '$'..'&' | '*'..':' | '<' ..'~'); +PROGRAM_EXPRESSION : LBRACKET PROGRAM_EXPRESSION_CHARACTER RBRACKET; + +fragment PLUSMN : (PLUS | MINUS); +fragment MANTISA : PLUSMN? ( (NUMBER) | (NUMBER DOT NUMBER?) | (DOT NUMBER)); + +//fragment EXPONENT : WS* E WS* PLUSMN? NUMBER; +fragment EXPONENT : E WS* PLUSMN? NUMBER; + +fragment NUMBER : DIGIT+; + +fragment LBRACKET : '('; +fragment RBRACKET : ')'; + +fragment ALPHA : ('a'..'z'|'A'..'Z'); +fragment DIGIT : ('0'..'9'); +fragment NONZERO_DIGIT : ('1'..'9'); + +fragment HEXDIGIT : (DIGIT | 'a'..'f' | 'A'..'F'); +fragment OCTDIGIT : ('0'..'7'); +fragment BINDIGIT : ('0' | '1'); + +fragment SHARP : '#'; + +fragment E : ('E'|'e'); +fragment H : ('H'|'h'); +fragment Q : ('Q'|'q'); +fragment B : ('B'|'b'); + +fragment SPACE : ' '; +fragment TAB : '\t'; + +fragment PLUS : '+'; +fragment MINUS : '-'; +fragment DOT : '.'; +fragment SLASH : '/'; +fragment SINGLE_QUOTE : '\''; +fragment DOUBLE_QUOTE : '"'; +fragment NON_SINGLE_QUOTE : ~SINGLE_QUOTE; +fragment NON_DOUBLE_QUOTE : ~DOUBLE_QUOTE; + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/units.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,513 @@ +/*- + * 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_units.c + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief SCPI units + * + * + */ + +#include <string.h> +#include "scpi/parser.h" +#include "scpi/units.h" +#include "utils_private.h" +#include "scpi/utils.h" +#include "scpi/error.h" +#include "lexer_private.h" + + +/* + * multipliers IEEE 488.2-1992 tab 7-2 + * 1E18 EX + * 1E15 PE + * 1E12 T + * 1E9 G + * 1E6 MA (use M for OHM and HZ) + * 1E3 K + * 1E-3 M (disaalowed for OHM and HZ) + * 1E-6 U + * 1E-9 N + * 1E-12 P + * 1E-15 F + * 1E-18 A + */ + +/* + * units definition IEEE 488.2-1992 tab 7-1 + */ +const scpi_unit_def_t scpi_units_def[] = { +#if USE_UNITS_PARTICLES + /* Absorbet dose */ + {/* name */ "GY", /* unit */ SCPI_UNIT_GRAY, /* mult */ 1}, + + /* Activity of radionuclide */ + {/* name */ "BQ", /* unit */ SCPI_UNIT_BECQUEREL, /* mult */ 1}, + + /* Amount of substance */ + {/* name */ "MOL", /* unit */ SCPI_UNIT_MOLE, /* mult */ 1}, + + /* Dose equivalent */ + {/* name */ "NSV", /* unit */ SCPI_UNIT_SIEVERT, /* mult */ 1e-9}, + {/* name */ "USV", /* unit */ SCPI_UNIT_SIEVERT, /* mult */ 1e-6}, + {/* name */ "MSV", /* unit */ SCPI_UNIT_SIEVERT, /* mult */ 1e-3}, + {/* name */ "SV", /* unit */ SCPI_UNIT_SIEVERT, /* mult */ 1}, + {/* name */ "KSV", /* unit */ SCPI_UNIT_SIEVERT, /* mult */ 1e3}, + {/* name */ "MASV", /* unit */ SCPI_UNIT_SIEVERT, /* mult */ 1e6}, + + /* Energy */ + {/* name */ "EV", /* unit */ SCPI_UNIT_ELECTRONVOLT, /* mult */ 1}, + {/* name */ "KEV", /* unit */ SCPI_UNIT_ELECTRONVOLT, /* mult */ 1e3}, + {/* name */ "MAEV", /* unit */ SCPI_UNIT_ELECTRONVOLT, /* mult */ 1e6}, + {/* name */ "GEV", /* unit */ SCPI_UNIT_ELECTRONVOLT, /* mult */ 1e9}, + {/* name */ "TEV", /* unit */ SCPI_UNIT_ELECTRONVOLT, /* mult */ 1e12}, + + /* Mass */ + {/* name */ "U", /* unit */ SCPI_UNIT_ATOMIC_MASS, /* mult */ 1}, +#endif /* USE_UNITS_PARTICLES */ + +#if USE_UNITS_ANGLE + /* Angle */ + {/* name */ "DEG", /* unit */ SCPI_UNIT_DEGREE, /* mult */ 1}, + {/* name */ "GON", /* unit */ SCPI_UNIT_GRADE, /* mult */ 1}, + {/* name */ "MNT", /* unit */ SCPI_UNIT_DEGREE, /* mult */ 1. / 60.}, + {/* name */ "RAD", /* unit */ SCPI_UNIT_RADIAN, /* mult */ 1}, + {/* name */ "SEC", /* unit */ SCPI_UNIT_DEGREE, /* mult */ 1. / 3600.}, + {/* name */ "REV", /* unit */ SCPI_UNIT_REVOLUTION, /* mult */ 1}, + {/* name */ "RS", /* unit */ SCPI_UNIT_STERADIAN, /* mult */ 1}, +#endif /* USE_UNITS_ANGLE */ + +#if USE_UNITS_ELECTRIC + /* Electric - capacitance */ + {/* name */ "PF", /* unit */ SCPI_UNIT_FARAD, /* mult */ 1e-12}, + {/* name */ "NF", /* unit */ SCPI_UNIT_FARAD, /* mult */ 1e-9}, + {/* name */ "UF", /* unit */ SCPI_UNIT_FARAD, /* mult */ 1e-6}, + {/* name */ "MF", /* unit */ SCPI_UNIT_FARAD, /* mult */ 1e-3}, + {/* name */ "F", /* unit */ SCPI_UNIT_FARAD, /* mult */ 1}, + + /* Electric - current */ + {/* name */ "UA", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1e-6}, + {/* name */ "MA", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1e-3}, + {/* name */ "A", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1}, + {/* name */ "KA", /* unit */ SCPI_UNIT_AMPER, /* mult */ 1e3}, + + /* Electric - potential */ + {/* name */ "UV", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1e-6}, + {/* name */ "MV", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1e-3}, + {/* name */ "V", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1}, + {/* name */ "KV", /* unit */ SCPI_UNIT_VOLT, /* mult */ 1e3}, + + /* Electric - resistance */ + {/* name */ "OHM", /* unit */ SCPI_UNIT_OHM, /* mult */ 1}, + {/* name */ "KOHM", /* unit */ SCPI_UNIT_OHM, /* mult */ 1e3}, + {/* name */ "MOHM", /* unit */ SCPI_UNIT_OHM, /* mult */ 1e6}, + + /* Inductance */ + {/* name */ "UH", /* unit */ SCPI_UNIT_HENRY, /* mult */ 1e-6}, + {/* name */ "MH", /* unit */ SCPI_UNIT_HENRY, /* mult */ 1e-3}, + {/* name */ "H", /* unit */ SCPI_UNIT_HENRY, /* mult */ 1}, +#endif /* USE_UNITS_ELECTRIC */ + +#if USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE + /* Electric - charge */ + {/* name */ "C", /* unit */ SCPI_UNIT_COULOMB, /* mult */ 1}, + + /* Electric - conductance */ + {/* name */ "USIE", /* unit */ SCPI_UNIT_SIEMENS, /* mult */ 1e-6}, + {/* name */ "MSIE", /* unit */ SCPI_UNIT_SIEMENS, /* mult */ 1e-3}, + {/* name */ "SIE", /* unit */ SCPI_UNIT_SIEMENS, /* mult */ 1}, +#endif /* USE_UNITS_ELECTRIC_CHARGE_CONDUCTANCE */ + +#if USE_UNITS_ENERGY_FORCE_MASS + /* Energy */ + {/* name */ "J", /* unit */ SCPI_UNIT_JOULE, /* mult */ 1}, + {/* name */ "KJ", /* unit */ SCPI_UNIT_JOULE, /* mult */ 1e3}, + {/* name */ "MAJ", /* unit */ SCPI_UNIT_JOULE, /* mult */ 1e6}, + + /* Force */ + {/* name */ "N", /* unit */ SCPI_UNIT_NEWTON, /* mult */ 1}, + {/* name */ "KN", /* unit */ SCPI_UNIT_NEWTON, /* mult */ 1e3}, + + /* Pressure */ + {/* name */ "ATM", /* unit */ SCPI_UNIT_ATMOSPHERE, /* mult */ 1}, + {/* name */ "INHG", /* unit */ SCPI_UNIT_INCH_OF_MERCURY, /* mult */ 1}, + {/* name */ "MMHG", /* unit */ SCPI_UNIT_MM_OF_MERCURY, /* mult */ 1}, + + {/* name */ "TORR", /* unit */ SCPI_UNIT_TORT, /* mult */ 1}, + {/* name */ "BAR", /* unit */ SCPI_UNIT_BAR, /* mult */ 1}, + + {/* name */ "PAL", /* unit */ SCPI_UNIT_PASCAL, /* mult */ 1}, + {/* name */ "KPAL", /* unit */ SCPI_UNIT_PASCAL, /* mult */ 1e3}, + {/* name */ "MAPAL", /* unit */ SCPI_UNIT_PASCAL, /* mult */ 1e6}, + + /* Viscosity kinematic */ + {/* name */ "ST", /* unit */ SCPI_UNIT_STROKES, /* mult */ 1}, + + /* Viscosity dynamic */ + {/* name */ "P", /* unit */ SCPI_UNIT_POISE, /* mult */ 1}, + + /* Viscosity dynamic */ + {/* name */ "L", /* unit */ SCPI_UNIT_LITER, /* mult */ 1}, + + /* Mass */ + {/* name */ "MG", /* unit */ SCPI_UNIT_KILOGRAM, /* mult */ 1e-6}, + {/* name */ "G", /* unit */ SCPI_UNIT_KILOGRAM, /* mult */ 1e-3}, + {/* name */ "KG", /* unit */ SCPI_UNIT_KILOGRAM, /* mult */ 1}, + {/* name */ "TNE", /* unit */ SCPI_UNIT_KILOGRAM, /* mult */ 1000}, +#endif /* USE_UNITS_ENERGY_FORCE_MASS */ + +#if USE_UNITS_FREQUENCY + /* Frequency */ + {/* name */ "HZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1}, + {/* name */ "KHZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1e3}, + {/* name */ "MHZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1e6}, + {/* name */ "GHZ", /* unit */ SCPI_UNIT_HERTZ, /* mult */ 1e9}, +#endif /* USE_UNITS_FREQUENCY */ + +#if USE_UNITS_DISTANCE + /* Length */ + {/* name */ "ASU", /* unit */ SCPI_UNIT_ASTRONOMIC_UNIT, /* mult */ 1}, + {/* name */ "PRS", /* unit */ SCPI_UNIT_PARSEC, /* mult */ 1}, +#if USE_UNITS_IMPERIAL + {/* name */ "IN", /* unit */ SCPI_UNIT_INCH, /* mult */ 1}, + {/* name */ "FT", /* unit */ SCPI_UNIT_FOOT, /* mult */ 1}, + {/* name */ "MI", /* unit */ SCPI_UNIT_MILE, /* mult */ 1}, + {/* name */ "NAMI", /* unit */ SCPI_UNIT_NAUTICAL_MILE, /* mult */ 1}, +#endif /* USE_UNITS_IMPERIAL */ + + {/* name */ "NM", /* unit */ SCPI_UNIT_METER, /* mult */ 1e-9}, + {/* name */ "UM", /* unit */ SCPI_UNIT_METER, /* mult */ 1e-6}, + {/* name */ "MM", /* unit */ SCPI_UNIT_METER, /* mult */ 1e-3}, + {/* name */ "M", /* unit */ SCPI_UNIT_METER, /* mult */ 1}, + {/* name */ "KM", /* unit */ SCPI_UNIT_METER, /* mult */ 1e3}, +#endif /* USE_UNITS_DISTANCE */ + +#if USE_UNITS_LIGHT + /* Illuminance */ + {/* name */ "LX", /* unit */ SCPI_UNIT_LUX, /* mult */ 1}, + + /* Luminous flux */ + {/* name */ "LM", /* unit */ SCPI_UNIT_LUMEN, /* mult */ 1}, + + /* Luminous intensity */ + {/* name */ "CD", /* unit */ SCPI_UNIT_CANDELA, /* mult */ 1}, +#endif /* USE_UNITS_LIGHT */ + +#if USE_UNITS_MAGNETIC + /* Magnetic flux */ + {/* name */ "WB", /* unit */ SCPI_UNIT_WEBER, /* mult */ 1}, + + /* Magnetic induction */ + {/* name */ "NT", /* unit */ SCPI_UNIT_TESLA, /* mult */ 1e-9}, + {/* name */ "UT", /* unit */ SCPI_UNIT_TESLA, /* mult */ 1e-6}, + {/* name */ "MT", /* unit */ SCPI_UNIT_TESLA, /* mult */ 1e-3}, + {/* name */ "T", /* unit */ SCPI_UNIT_TESLA, /* mult */ 1}, +#endif /* USE_UNITS_MAGNETIC */ + +#if USE_UNITS_POWER + /* Power */ + {/* name */ "W", /* unit */ SCPI_UNIT_WATT, /* mult */ 1}, + {/* name */ "DBM", /* unit */ SCPI_UNIT_DBM, /* mult */ 1}, + {/* name */ "DBMW", /* unit */ SCPI_UNIT_DBM, /* mult */ 1}, +#endif /* USE_UNITS_POWER */ + +#if USE_UNITS_RATIO + /* Ratio */ + {/* name */ "DB", /* unit */ SCPI_UNIT_DECIBEL, /* mult */ 1}, + {/* name */ "PCT", /* unit */ SCPI_UNIT_UNITLESS, /* mult */ 1e-2}, + {/* name */ "PPM", /* unit */ SCPI_UNIT_UNITLESS, /* mult */ 1e-6}, +#endif /* USE_UNITS_RATIO */ + +#if USE_UNITS_TEMPERATURE + /* Temperature */ + {/* name */ "CEL", /* unit */ SCPI_UNIT_CELSIUS, /* mult */ 1}, +#if USE_UNITS_IMPERIAL + {/* name */ "FAR", /* unit */ SCPI_UNIT_FAHRENHEIT, /* mult */ 1}, +#endif /* USE_UNITS_IMPERIAL */ + {/* name */ "K", /* unit */ SCPI_UNIT_KELVIN, /* mult */ 1}, +#endif /* USE_UNITS_TEMPERATURE */ + +#if USE_UNITS_TIME + /* Time */ + {/* name */ "PS", /* unit */ SCPI_UNIT_SECOND, /* mult */ 1e-12}, + {/* name */ "NS", /* unit */ SCPI_UNIT_SECOND, /* mult */ 1e-9}, + {/* name */ "US", /* unit */ SCPI_UNIT_SECOND, /* mult */ 1e-6}, + {/* name */ "MS", /* unit */ SCPI_UNIT_SECOND, /* mult */ 1e-3}, + {/* name */ "S", /* unit */ SCPI_UNIT_SECOND, /* mult */ 1}, + {/* name */ "MIN", /* unit */ SCPI_UNIT_SECOND, /* mult */ 60}, + {/* name */ "HR", /* unit */ SCPI_UNIT_SECOND, /* mult */ 3600}, + {/* name */ "D", /* unit */ SCPI_UNIT_DAY, /* mult */ 1}, + {/* name */ "ANN", /* unit */ SCPI_UNIT_YEAR, /* mult */ 1}, +#endif /* USE_UNITS_TIME */ + + SCPI_UNITS_LIST_END, +}; + +/* + * Special number values definition + */ +const scpi_choice_def_t scpi_special_numbers_def[] = { + {/* name */ "MINimum", /* type */ SCPI_NUM_MIN}, + {/* name */ "MAXimum", /* type */ SCPI_NUM_MAX}, + {/* name */ "DEFault", /* type */ SCPI_NUM_DEF}, + {/* name */ "UP", /* type */ SCPI_NUM_UP}, + {/* name */ "DOWN", /* type */ SCPI_NUM_DOWN}, + {/* name */ "NAN", /* type */ SCPI_NUM_NAN}, + {/* name */ "INFinity", /* type */ SCPI_NUM_INF}, + {/* name */ "NINF", /* type */ SCPI_NUM_NINF}, + {/* name */ "AUTO", /* type */ SCPI_NUM_AUTO}, + SCPI_CHOICE_LIST_END, +}; + +/** + * Convert string describing unit to its representation + * @param units units patterns + * @param unit text representation of unknown unit + * @param len length of text representation + * @return pointer of related unit definition or NULL + */ +static const scpi_unit_def_t * translateUnit(const scpi_unit_def_t * units, const char * unit, size_t len) { + int i; + + if (units == NULL) { + return NULL; + } + + for (i = 0; units[i].name != NULL; i++) { + if (compareStr(unit, len, units[i].name, strlen(units[i].name))) { + return &units[i]; + } + } + + return NULL; +} + +/** + * Convert unit definition to string + * @param units units definitions (patterns) + * @param unit type of unit + * @return string representation of unit + */ +static const char * translateUnitInverse(const scpi_unit_def_t * units, const scpi_unit_t unit) { + int i; + + if (units == NULL) { + return NULL; + } + + for (i = 0; units[i].name != NULL; i++) { + if ((units[i].unit == unit) && (units[i].mult == 1)) { + return units[i].name; + } + } + + return NULL; +} + +/** + * Transform number to base units + * @param context + * @param unit text representation of unit + * @param len length of text representation + * @param value preparsed numeric value + * @return TRUE if value parameter was converted to base units + */ +static scpi_bool_t transformNumber(scpi_t * context, const char * unit, size_t len, scpi_number_t * value) { + size_t s; + const scpi_unit_def_t * unitDef; + s = skipWhitespace(unit, len); + + if (s == len) { + value->unit = SCPI_UNIT_NONE; + return TRUE; + } + + unitDef = translateUnit(context->units, unit + s, len - s); + + if (unitDef == NULL) { + SCPI_ErrorPush(context, SCPI_ERROR_INVALID_SUFFIX); + return FALSE; + } + + value->content.value *= unitDef->mult; + value->unit = unitDef->unit; + + return TRUE; +} + +/** + * Parse parameter as number, number with unit or special value (min, max, default, ...) + * @param context + * @param value return value + * @param mandatory if the parameter is mandatory + * @return + */ +scpi_bool_t SCPI_ParamNumber(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, scpi_bool_t mandatory) { + scpi_token_t token; + lex_state_t state; + scpi_parameter_t param; + scpi_bool_t result; + int32_t tag; + + if (!value) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return FALSE; + } + + result = SCPI_Parameter(context, ¶m, mandatory); + + if (!result) { + return result; + } + + state.buffer = param.ptr; + state.pos = state.buffer; + state.len = param.len; + + switch (param.type) { + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_HEXNUM: + case SCPI_TOKEN_OCTNUM: + case SCPI_TOKEN_BINNUM: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + case SCPI_TOKEN_PROGRAM_MNEMONIC: + value->unit = SCPI_UNIT_NONE; + value->special = FALSE; + result = TRUE; + break; + default: + break; + } + + switch (param.type) { + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + case SCPI_TOKEN_PROGRAM_MNEMONIC: + value->base = 10; + break; + case SCPI_TOKEN_BINNUM: + value->base = 2; + break; + case SCPI_TOKEN_HEXNUM: + value->base = 16; + break; + case SCPI_TOKEN_OCTNUM: + value->base = 8; + break; + default: + break; + } + + switch (param.type) { + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: + SCPI_ParamToDouble(context, ¶m, &(value->content.value)); + break; + case SCPI_TOKEN_HEXNUM: + SCPI_ParamToDouble(context, ¶m, &(value->content.value)); + break; + case SCPI_TOKEN_OCTNUM: + SCPI_ParamToDouble(context, ¶m, &(value->content.value)); + break; + case SCPI_TOKEN_BINNUM: + SCPI_ParamToDouble(context, ¶m, &(value->content.value)); + break; + case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: + scpiLex_DecimalNumericProgramData(&state, &token); + scpiLex_WhiteSpace(&state, &token); + scpiLex_SuffixProgramData(&state, &token); + + SCPI_ParamToDouble(context, ¶m, &(value->content.value)); + + result = transformNumber(context, token.ptr, token.len, value); + break; + case SCPI_TOKEN_PROGRAM_MNEMONIC: + scpiLex_WhiteSpace(&state, &token); + scpiLex_CharacterProgramData(&state, &token); + + /* convert string to special number type */ + result = SCPI_ParamToChoice(context, &token, special, &tag); + + value->special = TRUE; + value->content.tag = tag; + + break; + default: + result = FALSE; + } + + return result; +} + +/** + * Convert scpi_number_t to string + * @param context + * @param value number value + * @param str target string + * @param len max length of string including null-character termination + * @return number of chars written to string + */ +size_t SCPI_NumberToStr(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, char * str, size_t len) { + const char * type; + const char * unit; + size_t result; + + if (!value || !str || len==0) { + return 0; + } + + if (value->special) { + if (SCPI_ChoiceToName(special, value->content.tag, &type)) { + strncpy(str, type, len); + result = SCPIDEFINE_strnlen(str, len - 1); + str[result] = '\0'; + return result; + } else { + str[0] = '\0'; + return 0; + } + } + + result = SCPI_DoubleToStr(value->content.value, str, len); + + if (result + 1 < len) { + unit = translateUnitInverse(context->units, value->unit); + + if (unit) { + strncat(str, " ", len - result); + if (result + 2 < len) { + strncat(str, unit, len - result - 1); + } + result = strlen(str); + } + } + + return result; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/utils.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,1143 @@ +/*- + * BSD 2-Clause License + * + * Copyright (c) 2012-2018, Jan Breuer, Richard.hmm + * 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_utils.c + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief Conversion routines and string manipulation routines + * + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <math.h> + +#include "utils_private.h" +#include "scpi/utils.h" + +static size_t patternSeparatorShortPos(const char * pattern, size_t len); +static size_t patternSeparatorPos(const char * pattern, size_t len); +static size_t cmdSeparatorPos(const char * cmd, size_t len); + +/** + * Find the first occurrence in str of a character in set. + * @param str + * @param size + * @param set + * @return + */ +char * strnpbrk(const char *str, size_t size, const char *set) { + const char *scanp; + long c, sc; + const char * strend = str + size; + + while ((strend != str) && ((c = *str++) != 0)) { + for (scanp = set; (sc = *scanp++) != '\0';) + if (sc == c) + return ((char *) (str - 1)); + } + return (NULL); +} + +/** + * Converts signed/unsigned 32 bit integer value to string in specific base + * @param val integer value + * @param str converted textual representation + * @param len string buffer length + * @param base output base + * @param sign + * @return number of bytes written to str (without '\0') + */ +size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) { + const char digits[] = "0123456789ABCDEF"; + +#define ADD_CHAR(c) if (pos < len) str[pos++] = (c) + uint32_t x = 0; + int_fast8_t digit; + size_t pos = 0; + uint32_t uval = val; + + if (uval == 0) { + ADD_CHAR('0'); + } else { + + switch (base) { + case 2: + x = 0x80000000L; + break; + case 8: + x = 0x40000000L; + break; + default: + case 10: + base = 10; + x = 1000000000L; + break; + case 16: + x = 0x10000000L; + break; + } + + /* add sign for numbers in base 10 */ + if (sign && ((int32_t) val < 0) && (base == 10)) { + uval = -val; + ADD_CHAR('-'); + } + + /* remove leading zeros */ + while ((uval / x) == 0) { + x /= base; + } + + do { + digit = (uint8_t) (uval / x); + ADD_CHAR(digits[digit]); + uval -= digit * x; + x /= base; + } while (x && (pos < len)); + } + + if (pos < len) str[pos] = 0; + return pos; +#undef ADD_CHAR +} + +/** + * Converts signed 32 bit integer value to string + * @param val integer value + * @param str converted textual representation + * @param len string buffer length + * @return number of bytes written to str (without '\0') + */ +size_t SCPI_Int32ToStr(int32_t val, char * str, size_t len) { + return UInt32ToStrBaseSign((uint32_t) val, str, len, 10, TRUE); +} + +/** + * Converts unsigned 32 bit integer value to string in specific base + * @param val integer value + * @param str converted textual representation + * @param len string buffer length + * @param base output base + * @return number of bytes written to str (without '\0') + */ +size_t SCPI_UInt32ToStrBase(uint32_t val, char * str, size_t len, int8_t base) { + return UInt32ToStrBaseSign(val, str, len, base, FALSE); +} + +/** + * Converts signed/unsigned 64 bit integer value to string in specific base + * @param val integer value + * @param str converted textual representation + * @param len string buffer length + * @param base output base + * @param sign + * @return number of bytes written to str (without '\0') + */ +size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) { + const char digits[] = "0123456789ABCDEF"; + +#define ADD_CHAR(c) if (pos < len) str[pos++] = (c) + uint64_t x = 0; + int_fast8_t digit; + size_t pos = 0; + uint64_t uval = val; + + if (uval == 0) { + ADD_CHAR('0'); + } else { + + switch (base) { + case 2: + x = 0x8000000000000000ULL; + break; + case 8: + x = 0x8000000000000000ULL; + break; + default: + case 10: + x = 10000000000000000000ULL; + base = 10; + break; + case 16: + x = 0x1000000000000000ULL; + break; + } + + /* add sign for numbers in base 10 */ + if (sign && ((int64_t) val < 0) && (base == 10)) { + uval = -val; + ADD_CHAR('-'); + } + + /* remove leading zeros */ + while ((uval / x) == 0) { + x /= base; + } + + do { + digit = (uint8_t) (uval / x); + ADD_CHAR(digits[digit]); + uval -= digit * x; + x /= base; + } while (x && (pos < len)); + } + + if (pos < len) str[pos] = 0; + return pos; +#undef ADD_CHAR +} + +/** + * Converts signed 64 bit integer value to string + * @param val integer value + * @param str converted textual representation + * @param len string buffer length + * @return number of bytes written to str (without '\0') + */ +size_t SCPI_Int64ToStr(int64_t val, char * str, size_t len) { + return UInt64ToStrBaseSign((uint64_t) val, str, len, 10, TRUE); +} + +/** + * Converts signed/unsigned 64 bit integer value to string in specific base + * @param val integer value + * @param str converted textual representation + * @param len string buffer length + * @param base output base + * @return number of bytes written to str (without '\0') + */ +size_t SCPI_UInt64ToStrBase(uint64_t val, char * str, size_t len, int8_t base) { + return UInt64ToStrBaseSign(val, str, len, base, FALSE); +} + +/** + * Converts float (32 bit) value to string + * @param val long value + * @param str converted textual representation + * @param len string buffer length + * @return number of bytes written to str (without '\0') + */ +size_t SCPI_FloatToStr(float val, char * str, size_t len) { + SCPIDEFINE_floatToStr(val, str, len); + return strlen(str); +} + +/** + * Converts double (64 bit) value to string + * @param val double value + * @param str converted textual representation + * @param len string buffer length + * @return number of bytes written to str (without '\0') + */ +size_t SCPI_DoubleToStr(double val, char * str, size_t len) { + SCPIDEFINE_doubleToStr(val, str, len); + return strlen(str); +} + +/** + * Converts string to signed 32bit integer representation + * @param str string value + * @param val 32bit integer result + * @return number of bytes used in string + */ +size_t strBaseToInt32(const char * str, int32_t * val, int8_t base) { + char * endptr; + *val = strtol(str, &endptr, base); + return endptr - str; +} + +/** + * Converts string to unsigned 32bit integer representation + * @param str string value + * @param val 32bit integer result + * @return number of bytes used in string + */ +size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) { + char * endptr; + *val = strtoul(str, &endptr, base); + return endptr - str; +} + +/** + * Converts string to signed 64bit integer representation + * @param str string value + * @param val 64bit integer result + * @return number of bytes used in string + */ +size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) { + char * endptr; + *val = SCPIDEFINE_strtoll(str, &endptr, base); + return endptr - str; +} + +/** + * Converts string to unsigned 64bit integer representation + * @param str string value + * @param val 64bit integer result + * @return number of bytes used in string + */ +size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) { + char * endptr; + *val = SCPIDEFINE_strtoull(str, &endptr, base); + return endptr - str; +} + +/** + * Converts string to float (32 bit) representation + * @param str string value + * @param val float result + * @return number of bytes used in string + */ +size_t strToFloat(const char * str, float * val) { + char * endptr; + *val = SCPIDEFINE_strtof(str, &endptr); + return endptr - str; +} + +/** + * Converts string to double (64 bit) representation + * @param str string value + * @param val double result + * @return number of bytes used in string + */ +size_t strToDouble(const char * str, double * val) { + char * endptr; + *val = strtod(str, &endptr); + return endptr - str; +} + +/** + * Compare two strings with exact length + * @param str1 + * @param len1 + * @param str2 + * @param len2 + * @return TRUE if len1==len2 and "len" characters of both strings are equal + */ +scpi_bool_t compareStr(const char * str1, size_t len1, const char * str2, size_t len2) { + if (len1 != len2) { + return FALSE; + } + + if (SCPIDEFINE_strncasecmp(str1, str2, len2) == 0) { + return TRUE; + } + + return FALSE; +} + +/** + * Compare two strings, one be longer but may contains only numbers in that section + * @param str1 + * @param len1 + * @param str2 + * @param len2 + * @return TRUE if strings match + */ +scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) { + scpi_bool_t result = FALSE; + size_t i; + + if (len2 < len1) { + return FALSE; + } + + if (SCPIDEFINE_strncasecmp(str1, str2, len1) == 0) { + result = TRUE; + + if (num) { + if (len1 == len2) { + /* *num = 1; */ + } else { + int32_t tmpNum; + i = len1 + strBaseToInt32(str2 + len1, &tmpNum, 10); + if (i != len2) { + result = FALSE; + } else { + *num = tmpNum; + } + } + } else { + for (i = len1; i < len2; i++) { + if (!isdigit((int) str2[i])) { + result = FALSE; + break; + } + } + } + } + + return result; +} + +/** + * Count white spaces from the beggining + * @param cmd - command + * @param len - max search length + * @return number of white spaces + */ +size_t skipWhitespace(const char * cmd, size_t len) { + size_t i; + for (i = 0; i < len; i++) { + if (!isspace((unsigned char) cmd[i])) { + return i; + } + } + return len; +} + +/** + * Pattern is composed from upper case an lower case letters. This function + * search the first lowercase letter + * @param pattern + * @param len - max search length + * @return position of separator or len + */ +static size_t patternSeparatorShortPos(const char * pattern, size_t len) { + size_t i; + for (i = 0; (i < len) && pattern[i]; i++) { + if (islower((unsigned char) pattern[i])) { + return i; + } + } + return i; +} + +/** + * Find pattern separator position + * @param pattern + * @param len - max search length + * @return position of separator or len + */ +static size_t patternSeparatorPos(const char * pattern, size_t len) { + + char * separator = strnpbrk(pattern, len, "?:[]"); + if (separator == NULL) { + return len; + } else { + return separator - pattern; + } +} + +/** + * Find command separator position + * @param cmd - input command + * @param len - max search length + * @return position of separator or len + */ +static size_t cmdSeparatorPos(const char * cmd, size_t len) { + char * separator = strnpbrk(cmd, len, ":?"); + size_t result; + if (separator == NULL) { + result = len; + } else { + result = separator - cmd; + } + + return result; +} + +/** + * Match pattern and str. Pattern is in format UPPERCASElowercase + * @param pattern + * @param pattern_len + * @param str + * @param str_len + * @return + */ +scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len, int32_t * num) { + int pattern_sep_pos_short; + + if ((pattern_len > 0) && pattern[pattern_len - 1] == '#') { + size_t new_pattern_len = pattern_len - 1; + + pattern_sep_pos_short = patternSeparatorShortPos(pattern, new_pattern_len); + + return compareStrAndNum(pattern, new_pattern_len, str, str_len, num) || + compareStrAndNum(pattern, pattern_sep_pos_short, str, str_len, num); + } else { + + pattern_sep_pos_short = patternSeparatorShortPos(pattern, pattern_len); + + return compareStr(pattern, pattern_len, str, str_len) || + compareStr(pattern, pattern_sep_pos_short, str, str_len); + } +} + +/** + * Compare pattern and command + * @param pattern eg. [:MEASure]:VOLTage:DC? + * @param cmd - command + * @param len - max search length + * @return TRUE if pattern matches, FALSE otherwise + */ +scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value) { +#define SKIP_PATTERN(n) do {pattern_ptr += (n); pattern_len -= (n);} while(0) +#define SKIP_CMD(n) do {cmd_ptr += (n); cmd_len -= (n);} while(0) + + scpi_bool_t result = FALSE; + int brackets = 0; + int cmd_sep_pos = 0; + + size_t numbers_idx = 0; + int32_t *number_ptr = NULL; + + const char * pattern_ptr = pattern; + int pattern_len = strlen(pattern); + + const char * cmd_ptr = cmd; + size_t cmd_len = SCPIDEFINE_strnlen(cmd, len); + + /* both commands are query commands? */ + if (pattern_ptr[pattern_len - 1] == '?') { + if (cmd_ptr[cmd_len - 1] == '?') { + cmd_len -= 1; + pattern_len -= 1; + } else { + return FALSE; + } + } + + /* now support optional keywords in pattern style, e.g. [:MEASure]:VOLTage:DC? */ + if (pattern_ptr[0] == '[') { /* skip first '[' */ + SKIP_PATTERN(1); + brackets++; + } + if (pattern_ptr[0] == ':') { /* skip first ':' */ + SKIP_PATTERN(1); + } + + if (cmd_ptr[0] == ':') { + /* handle errornouse ":*IDN?" */ + if (cmd_len >= 2) { + if (cmd_ptr[1] != '*') { + SKIP_CMD(1); + } else { + return FALSE; + } + } + } + + while (1) { + int pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_len); + + cmd_sep_pos = cmdSeparatorPos(cmd_ptr, cmd_len); + + if ((pattern_sep_pos > 0) && pattern_ptr[pattern_sep_pos - 1] == '#') { + if (numbers && (numbers_idx < numbers_len)) { + number_ptr = numbers + numbers_idx; + *number_ptr = default_value; /* default value */ + } else { + number_ptr = NULL; + } + numbers_idx++; + } else { + number_ptr = NULL; + } + + if (matchPattern(pattern_ptr, pattern_sep_pos, cmd_ptr, cmd_sep_pos, number_ptr)) { + SKIP_PATTERN(pattern_sep_pos); + SKIP_CMD(cmd_sep_pos); + result = TRUE; + + /* command is complete */ + if ((pattern_len == 0) && (cmd_len == 0)) { + break; + } + + /* pattern complete, but command not */ + if ((pattern_len == 0) && (cmd_len > 0)) { + result = FALSE; + break; + } + + /* command complete, but pattern not */ + if (cmd_len == 0) { + /* verify all subsequent pattern parts are also optional */ + while (pattern_len) { + pattern_sep_pos = patternSeparatorPos(pattern_ptr, pattern_len); + switch (pattern_ptr[pattern_sep_pos]) { + case '[': + brackets++; + break; + case ']': + brackets--; + break; + default: + break; + } + SKIP_PATTERN(pattern_sep_pos + 1); + if (brackets == 0) { + if ((pattern_len > 0) && (pattern_ptr[0] == '[')) { + continue; + } else { + break; + } + } + } + if (pattern_len != 0) { + result = FALSE; + } + break; /* exist optional keyword, command is complete */ + } + + /* both command and patter contains command separator at this position */ + if ((pattern_len > 0) + && ((pattern_ptr[0] == cmd_ptr[0]) + && (pattern_ptr[0] == ':'))) { + SKIP_PATTERN(1); + SKIP_CMD(1); + } else if ((pattern_len > 1) + && (pattern_ptr[1] == cmd_ptr[0]) + && (pattern_ptr[0] == '[') + && (pattern_ptr[1] == ':')) { + SKIP_PATTERN(2); /* for skip '[' in "[:" */ + SKIP_CMD(1); + brackets++; + } else if ((pattern_len > 1) + && (pattern_ptr[1] == cmd_ptr[0]) + && (pattern_ptr[0] == ']') + && (pattern_ptr[1] == ':')) { + SKIP_PATTERN(2); /* for skip ']' in "]:" */ + SKIP_CMD(1); + brackets--; + } else if ((pattern_len > 2) + && (pattern_ptr[2] == cmd_ptr[0]) + && (pattern_ptr[0] == ']') + && (pattern_ptr[1] == '[') + && (pattern_ptr[2] == ':')) { + SKIP_PATTERN(3); /* for skip '][' in "][:" */ + SKIP_CMD(1); + /* brackets++; */ + /* brackets--; */ + } else { + result = FALSE; + break; + } + } else { + SKIP_PATTERN(pattern_sep_pos); + if ((pattern_ptr[0] == ']') && (pattern_ptr[1] == ':')) { + SKIP_PATTERN(2); /* for skip ']' in "]:" , pattern_ptr continue, while cmd_ptr remain unchanged */ + brackets--; + } else if ((pattern_len > 2) && (pattern_ptr[0] == ']') + && (pattern_ptr[1] == '[') + && (pattern_ptr[2] == ':')) { + SKIP_PATTERN(3); /* for skip ']' in "][:" , pattern_ptr continue, while cmd_ptr remain unchanged */ + /* brackets++; */ + /* brackets--; */ + } else { + result = FALSE; + break; + } + } + } + + return result; +#undef SKIP_PATTERN +#undef SKIP_CMD +} + +/** + * Compose command from previous command anc current command + * + * @param prev pointer to previous command + * @param current pointer of current command + * + * prev and current should be in the same memory buffer + */ +scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) { + size_t i; + + /* Invalid input */ + if (current == NULL || current->ptr == NULL || current->len == 0) + return FALSE; + + /* no previous command - nothing to do*/ + if (prev->ptr == NULL || prev->len == 0) + return TRUE; + + /* Common command or command root - nothing to do */ + if (current->ptr[0] == '*' || current->ptr[0] == ':') + return TRUE; + + /* Previsou command was common command - nothing to do */ + if (prev->ptr[0] == '*') + return TRUE; + + /* Find last occurence of ':' */ + for (i = prev->len; i > 0; i--) { + if (prev->ptr[i - 1] == ':') { + break; + } + } + + /* Previous command was simple command - nothing to do*/ + if (i == 0) + return TRUE; + + current->ptr -= i; + current->len += i; + memmove(current->ptr, prev->ptr, i); + return TRUE; +} + + + +#if !HAVE_STRNLEN +/* use FreeBSD strnlen */ + +/*- + * Copyright (c) 2009 David Schultz <das@FreeBSD.org> + * All rights reserved. + */ +size_t +BSD_strnlen(const char *s, size_t maxlen) { + size_t len; + + for (len = 0; len < maxlen; len++, s++) { + if (!*s) + break; + } + return (len); +} +#endif + +#if !HAVE_STRNCASECMP && !HAVE_STRNICMP + +int OUR_strncasecmp(const char *s1, const char *s2, size_t n) { + unsigned char c1, c2; + + for (; n != 0; n--) { + c1 = tolower((unsigned char) *s1++); + c2 = tolower((unsigned char) *s2++); + if (c1 != c2) { + return c1 - c2; + } + if (c1 == '\0') { + return 0; + } + } + return 0; +} +#endif + +#if USE_MEMORY_ALLOCATION_FREE && !HAVE_STRNDUP +char *OUR_strndup(const char *s, size_t n) { + size_t len = SCPIDEFINE_strnlen(s, n); + char * result = malloc(len + 1); + if (!result) { + return NULL; + } + memcpy(result, s, len); + result[len] = '\0'; + return result; +} +#endif + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE + +/** + * Initialize heap structure + * @param heap - pointer to manual allocated heap buffer + * @param error_info_heap - buffer for the heap + * @param error_info_heap_length - length of the heap + */ +void scpiheap_init(scpi_error_info_heap_t * heap, char * error_info_heap, size_t error_info_heap_length) +{ + heap->data = error_info_heap; + heap->wr = 0; + heap->size = error_info_heap_length; + heap->count = heap->size; + memset(heap->data, 0, heap->size); +} + +/** + * Duplicate string if "strdup" ("malloc/free") not supported on system. + * Allocate space in heap if it possible + * + * @param heap - pointer to manual allocated heap buffer + * @param s - current pointer of duplication string + * @return - pointer of duplicated string or NULL, if duplicate is not possible. + */ +char * scpiheap_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) { + if (!s || !heap || !heap->size) { + return NULL; + } + + if (heap->data[heap->wr] != '\0') { + return NULL; + } + + if (*s == '\0') { + return NULL; + } + + size_t len = SCPIDEFINE_strnlen(s, n) + 1; /* additional '\0' at end */ + if (len > heap->count) { + return NULL; + } + const char * ptrs = s; + char * head = &heap->data[heap->wr]; + size_t rem = heap->size - (&heap->data[heap->wr] - heap->data); + + if (len >= rem) { + memcpy(&heap->data[heap->wr], s, rem); + len = len - rem; + ptrs += rem; + heap->wr = 0; + heap->count -= rem; + } + + memcpy(&heap->data[heap->wr], ptrs, len); + heap->wr += len; + heap->count -= len; + + /* ensure '\0' a the end */ + if (heap->wr > 0) { + heap->data[heap->wr - 1] = '\0'; + } else { + heap->data[heap->size - 1] = '\0'; + } + return head; +} + +/** + * Return pointers and lengths two parts of string in the circular buffer from heap + * + * @param heap - pointer to manual allocated heap buffer + * @param s - pointer of duplicate string. + * @return len1 - lenght of first part of string. + * @return s2 - pointer of second part of string, if string splited . + * @return len2 - lenght of second part of string. + */ +scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap, const char * s, size_t * len1, const char ** s2, size_t * len2) { + if (!heap || !s || !len1 || !s2 || !len2) { + return FALSE; + } + + if (*s == '\0') { + return FALSE; + } + + *len1 = 0; + size_t rem = heap->size - (s - heap->data); + *len1 = strnlen(s, rem); + + if (&s[*len1 - 1] == &heap->data[heap->size - 1]) { + *s2 = heap->data; + *len2 = strnlen(*s2, heap->size); + } else { + *s2 = NULL; + *len2 = 0; + } + return TRUE; +} + +/** + * Frees space in heap, if "malloc/free" not supported on system, or nothing. + * + * @param heap - pointer to manual allocated heap buffer + * @param s - pointer of duplicate string + * @param rollback - backward write pointer in heap + */ +void scpiheap_free(scpi_error_info_heap_t * heap, char * s, scpi_bool_t rollback) { + + if (!s) return; + + char * data_add; + size_t len[2]; + + if (!scpiheap_get_parts(heap, s, &len[0], (const char **)&data_add, &len[1])) return; + + if (data_add) { + len[1]++; + memset(data_add, 0, len[1]); + heap->count += len[1]; + } else { + len[0]++; + } + memset(s, 0, len[0]); + heap->count += len[0]; + if (heap->count == heap->size) { + heap->wr = 0; + return; + } + if (rollback) { + size_t rb = len[0] + len[1]; + if (rb > heap->wr) { + heap->wr += heap->size; + } + heap->wr -= rb; + } +} + +#endif + +/* + * Floating point to string conversion routines + * + * Copyright (C) 2002 Michael Ringgaard. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 OWNER 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. + */ + +static char *scpi_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf, size_t bufsize) { + int r1, r2; + double fi, fj; + int w1, w2; + + if (ndigits < 0) ndigits = 0; + if (ndigits >= (int) (bufsize - 1)) ndigits = bufsize - 2; + + r2 = 0; + *sign = 0; + w1 = 0; + if (arg < 0) { + *sign = 1; + arg = -arg; + } + frexp(arg, &r1); + arg = modf(arg, &fi); + + if (fi != 0) { + r1 = r1 * 308 / 1024 - ndigits; + w2 = bufsize; + while (r1 > 0) { + fj = modf(fi / 10, &fi); + r2++; + r1--; + } + while (fi != 0) { + fj = modf(fi / 10, &fi); + buf[--w2] = (int) ((fj + .03) * 10) + '0'; + r2++; + } + while (w2 < (int) bufsize) buf[w1++] = buf[w2++]; + } else if (arg > 0) { + while ((fj = arg * 10) < 1) { + arg = fj; + r2--; + } + } + w2 = ndigits; + *decpt = r2; + if (w2 < 0) { + buf[0] = '\0'; + return buf; + } + while (w1 <= w2 && w1 < (int) bufsize) { + arg *= 10; + arg = modf(arg, &fj); + buf[w1++] = (int) fj + '0'; + } + if (w2 >= (int) bufsize) { + buf[bufsize - 1] = '\0'; + return buf; + } + w1 = w2; + buf[w2] += 5; + while (buf[w2] > '9') { + buf[w2] = '0'; + if (w2 > 0) { + ++buf[--w2]; + } else { + buf[w2] = '1'; + (*decpt)++; + } + } + buf[w1] = '\0'; + return buf; +} + +#define SCPI_DTOSTRE_BUFFER_SIZE 32 + +char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags) { + char buffer[SCPI_DTOSTRE_BUFFER_SIZE]; + + int sign = SCPIDEFINE_signbit(__val); + char * s = buffer; + int decpt; + if (sign) { + __val = -__val; + s[0] = '-'; + s++; + } else if (!SCPIDEFINE_isnan(__val)) { + if (SCPI_DTOSTRE_PLUS_SIGN & __flags) { + s[0] = '+'; + s++; + } else if (SCPI_DTOSTRE_ALWAYS_SIGN & __flags) { + s[0] = ' '; + s++; + } + } + + if (!SCPIDEFINE_isfinite(__val)) { + if (SCPIDEFINE_isnan(__val)) { + strcpy(s, (__flags & SCPI_DTOSTRE_UPPERCASE) ? "NAN" : "nan"); + } else { + strcpy(s, (__flags & SCPI_DTOSTRE_UPPERCASE) ? "INF" : "inf"); + } + strncpy(__s, buffer, __ssize); + __s[__ssize - 1] = '\0'; + return __s; + } + + scpi_ecvt(__val, __prec, &decpt, &sign, s, SCPI_DTOSTRE_BUFFER_SIZE - 1); + if (decpt > 1 && decpt <= __prec) { + memmove(s + decpt + 1, s + decpt, __prec + 1 - decpt); + s[decpt] = '.'; + decpt = 0; + } else if (decpt > -4 && decpt <= 0) { + decpt = -decpt + 1; + memmove(s + decpt + 1, s, __prec + 1); + memset(s, '0', decpt + 1); + s[1] = '.'; + decpt = 0; + } else { + memmove(s + 2, s + 1, __prec + 1); + s[1] = '.'; + decpt--; + } + + s = &s[__prec]; + while (s[0] == '0') { + s[0] = 0; + s--; + } + if (s[0] == '.') { + s[0] = 0; + s--; + } + + if (decpt != 0) { + s++; + s[0] = 'e'; + s++; + if (decpt != 0) { + if (decpt > 0) { + s[0] = '+'; + } + if (decpt < 0) { + s[0] = '-'; + decpt = -decpt; + } + s++; + } + UInt32ToStrBaseSign(decpt, s, 5, 10, 0); + if (s[1] == 0) { + s[2] = s[1]; + s[1] = s[0]; + s[0] = '0'; + } + } + + strncpy(__s, buffer, __ssize); + __s[__ssize - 1] = '\0'; + return __s; +} + +/** + * Get native CPU endiannes + * @return + */ +scpi_array_format_t SCPI_GetNativeFormat(void) { + + union { + uint32_t i; + char c[4]; + } bint = {0x01020304}; + + return bint.c[0] == 1 ? SCPI_FORMAT_BIGENDIAN : SCPI_FORMAT_LITTLEENDIAN; +} + +/** + * Swap 16bit number + * @param val + * @return + */ +uint16_t SCPI_Swap16(uint16_t val) { + return ((val & 0x00FF) << 8) | + ((val & 0xFF00) >> 8); +} + +/** + * Swap 32bit number + * @param val + * @return + */ +uint32_t SCPI_Swap32(uint32_t val) { + return ((val & 0x000000FFul) << 24) | + ((val & 0x0000FF00ul) << 8) | + ((val & 0x00FF0000ul) >> 8) | + ((val & 0xFF000000ul) >> 24); +} + +/** + * Swap 64bit number + * @param val + * @return + */ +uint64_t SCPI_Swap64(uint64_t val) { + return ((val & 0x00000000000000FFull) << 56) | + ((val & 0x000000000000FF00ull) << 40) | + ((val & 0x0000000000FF0000ull) << 24) | + ((val & 0x00000000FF000000ull) << 8) | + ((val & 0x000000FF00000000ull) >> 8) | + ((val & 0x0000FF0000000000ull) >> 24) | + ((val & 0x00FF000000000000ull) >> 40) | + ((val & 0xFF00000000000000ull) >> 56); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libscpi/src/utils_private.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,129 @@ +/*- + * 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_utils.h + * @date Thu Nov 15 10:58:45 UTC 2012 + * + * @brief Conversion routines and string manipulation routines + * + * + */ + +#ifndef SCPI_UTILS_PRIVATE_H +#define SCPI_UTILS_PRIVATE_H + +#include <stdint.h> +#include "scpi/config.h" +#include "scpi/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) && (__GNUC__ >= 4) +#define LOCAL __attribute__((visibility ("hidden"))) +#else +#define LOCAL +#endif + + char * strnpbrk(const char *str, size_t size, const char *set) LOCAL; + scpi_bool_t compareStr(const char * str1, size_t len1, const char * str2, size_t len2) LOCAL; + scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) LOCAL; + size_t UInt32ToStrBaseSign(uint32_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; + size_t UInt64ToStrBaseSign(uint64_t val, char * str, size_t len, int8_t base, scpi_bool_t sign) LOCAL; + size_t strBaseToInt32(const char * str, int32_t * val, int8_t base) LOCAL; + size_t strBaseToUInt32(const char * str, uint32_t * val, int8_t base) LOCAL; + size_t strBaseToInt64(const char * str, int64_t * val, int8_t base) LOCAL; + size_t strBaseToUInt64(const char * str, uint64_t * val, int8_t base) LOCAL; + size_t strToFloat(const char * str, float * val) LOCAL; + size_t strToDouble(const char * str, double * val) LOCAL; + scpi_bool_t locateText(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; + scpi_bool_t locateStr(const char * str1, size_t len1, const char ** str2, size_t * len2) LOCAL; + size_t skipWhitespace(const char * cmd, size_t len) LOCAL; + scpi_bool_t matchPattern(const char * pattern, size_t pattern_len, const char * str, size_t str_len, int32_t * num) LOCAL; + scpi_bool_t matchCommand(const char * pattern, const char * cmd, size_t len, int32_t *numbers, size_t numbers_len, int32_t default_value) LOCAL; + scpi_bool_t composeCompoundCommand(const scpi_token_t * prev, scpi_token_t * current) LOCAL; + +#define SCPI_DTOSTRE_UPPERCASE 1 +#define SCPI_DTOSTRE_ALWAYS_SIGN 2 +#define SCPI_DTOSTRE_PLUS_SIGN 4 + char * SCPI_dtostre(double __val, char * __s, size_t __ssize, unsigned char __prec, unsigned char __flags); + + scpi_array_format_t SCPI_GetNativeFormat(void); + uint16_t SCPI_Swap16(uint16_t val); + uint32_t SCPI_Swap32(uint32_t val); + uint64_t SCPI_Swap64(uint64_t val); + +#if !HAVE_STRNLEN + size_t BSD_strnlen(const char *s, size_t maxlen) LOCAL; +#endif + +#if !HAVE_STRNCASECMP && !HAVE_STRNICMP + int OUR_strncasecmp(const char *s1, const char *s2, size_t n) LOCAL; +#endif + +#if USE_DEVICE_DEPENDENT_ERROR_INFORMATION && !USE_MEMORY_ALLOCATION_FREE + void scpiheap_init(scpi_error_info_heap_t * heap, char * error_info_heap, size_t error_info_heap_length); + char * scpiheap_strndup(scpi_error_info_heap_t * heap, const char *s, size_t n) LOCAL; + void scpiheap_free(scpi_error_info_heap_t * heap, char *s, scpi_bool_t rollback) LOCAL; + scpi_bool_t scpiheap_get_parts(scpi_error_info_heap_t * heap, const char *s1, size_t * len1, const char ** s2, size_t * len2) LOCAL; +#endif + +#if !HAVE_STRNDUP + char *OUR_strndup(const char *s, size_t n); +#endif + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef max +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#if 0 +#define max(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a > _b ? _a : _b; }) + +#define min(a,b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SCPI_UTILS_PRIVATE_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,74 @@ +#include "mbed.h" +#include "main_init.h" +#include "i2c_mbed_fpga.h" +#include "uart_mbed.h" +#include "scpi-def.h" + +#define RAM_END_ADDR 0x4B +//#define HAVE_STDBOOL + +i2c_mbed_fpga i2c; + +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); +DigitalOut fpga_rstb(p27); //On FPGA PCB with red marked version ID it should be p20, (p27 of MBED is connected to p22 of the FPGA CMOD for 90415FPGA_EVB2) +//DigitalIn TimerIn(p29); //p29 shall be input pin + +/* Main function */ +int main() { + char i2cBuffer[3]; + char i2cTestPassFlag = 0; +// char i2cRamDumpFlag = 0; + char i2cTestPulseDebugFlag = 0; + + fpga_rstb = 1; + configure_scpi(); + + if(i2cTestPulseDebugFlag == 1) { + i2c.i2c_mlx_mode_entry(); + wait_us(1000); + *(i2cBuffer+0) = (char)(I2C_STATUS)& 0xff; + i2c.i2c_word_read(i2cBuffer); + uart_print(i2cBuffer); + + if( i2cBuffer[2] == 0x0C ){ + uart_I2C_test_pass(); + i2cTestPassFlag = 1; + led4 = 0; + } + else { + uart_I2C_test_fail(); + i2cTestPassFlag = 0; + led4 = 1; + } + + if(i2cTestPassFlag == 1){ + i2c.i2c_enable_pules_debug_mode(1); + wait_us(1000); + } + } + + if(i2cTestPulseDebugFlag == 1) { + wait_us(100000); + char i; + for(i=0xEA;i<=0xEF;i++) { + *(i2cBuffer+0) = i; + i2c.i2c_word_read(i2cBuffer); + uart_print(i2cBuffer); + wait_us(300000); + } + uart_ram_dump_finish(); + } + /*enter infinite loop, motor should be running*/ + + while (1) { + char buffer[50]; + uart_read(buffer); + strcat(buffer, "\n"); + SCPI_Input(&scpi_context, buffer, strlen(buffer)); + + } + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_init.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,30 @@ +#ifndef MAIN_INIT_H +#define MAIN_INIT_H + +#include "mbed.h" + +/*Digital outputs*/ +extern DigitalOut led1; +extern DigitalOut led2; +extern DigitalOut led3; +extern DigitalOut led4; +extern DigitalOut fpga_rstb; //p27 of MBED is connectted to p22 of the FPGA CMOD for 90415FPGA_EVB2 +//extern DigitalIn TimerIn; + +inline void reset_fpga(){ + fpga_rstb = 0; +} + +inline void enable_fpga(){ + fpga_rstb = 1; +} + +inline void main_init(){ + led1 = 0; + led2 = 0; + led3 = 0; + led4 = 0; + reset_fpga(); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed_config.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,26 @@ +/* + * mbed SDK + * Copyright (c) 2017 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Automatically generated configuration file. +// DO NOT EDIT, content will be overwritten. + +#ifndef __MBED_CONFIG_DATA__ +#define __MBED_CONFIG_DATA__ + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nv_bitfield_map.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,2697 @@ +#define NV_D_CORDAT_ID_ADDRESS 0x09FE +#define NV_D_CORDAT_ID_OFFSET 10 +#define NV_D_CORDAT_ID_LENGTH 6 +#define NV_D_CORDAT_ID_MASK 0xFC00 + +#define NV_D_FAB_ID_ADDRESS 0x09FE +#define NV_D_FAB_ID_OFFSET 6 +#define NV_D_FAB_ID_LENGTH 4 +#define NV_D_FAB_ID_MASK 0x03C0 + +#define NV_D_LOT_ID_16_11_ADDRESS 0x09FE +#define NV_D_LOT_ID_16_11_OFFSET 0 +#define NV_D_LOT_ID_16_11_LENGTH 6 +#define NV_D_LOT_ID_16_11_MASK 0x003F + +#define NV_D_LOT_ID_10_0_ADDRESS 0x09FC +#define NV_D_LOT_ID_10_0_OFFSET 5 +#define NV_D_LOT_ID_10_0_LENGTH 11 +#define NV_D_LOT_ID_10_0_MASK 0xFFE0 + +#define NV_D_WFR_ID_ADDRESS 0x09FC +#define NV_D_WFR_ID_OFFSET 0 +#define NV_D_WFR_ID_LENGTH 5 +#define NV_D_WFR_ID_MASK 0x001F + +#define NV_D_YPOS_ID_ADDRESS 0x09FA +#define NV_D_YPOS_ID_OFFSET 8 +#define NV_D_YPOS_ID_LENGTH 8 +#define NV_D_YPOS_ID_MASK 0xFF00 + +#define NV_D_XPOS_ID_ADDRESS 0x09FA +#define NV_D_XPOS_ID_OFFSET 0 +#define NV_D_XPOS_ID_LENGTH 8 +#define NV_D_XPOS_ID_MASK 0x00FF + +#define NV_TRACEABILITY_0_ADDRESS 0x09F8 +#define NV_TRACEABILITY_0_OFFSET 0 +#define NV_TRACEABILITY_0_LENGTH 16 +#define NV_TRACEABILITY_0_MASK 0xFFFF + +#define NV_CRC_MLX_TRIMMING_ADDRESS 0x09F6 +#define NV_CRC_MLX_TRIMMING_OFFSET 8 +#define NV_CRC_MLX_TRIMMING_LENGTH 8 +#define NV_CRC_MLX_TRIMMING_MASK 0xFF00 + +#define NV_CLAMP_RES_HIGH_DELAY_DRV_ADDRESS 0x09F4 +#define NV_CLAMP_RES_HIGH_DELAY_DRV_OFFSET 15 +#define NV_CLAMP_RES_HIGH_DELAY_DRV_LENGTH 1 +#define NV_CLAMP_RES_HIGH_DELAY_DRV_MASK 0x8000 + +#define NV_VS_UVDET_HYST_SUP_ADDRESS 0x09F4 +#define NV_VS_UVDET_HYST_SUP_OFFSET 14 +#define NV_VS_UVDET_HYST_SUP_LENGTH 1 +#define NV_VS_UVDET_HYST_SUP_MASK 0x4000 + +#define NV_VS_UVDET_SEL_SUP_ADDRESS 0x09F4 +#define NV_VS_UVDET_SEL_SUP_OFFSET 11 +#define NV_VS_UVDET_SEL_SUP_LENGTH 3 +#define NV_VS_UVDET_SEL_SUP_MASK 0x3800 + +#define NV_OC_ADJ_DRV_ADDRESS 0x09F4 +#define NV_OC_ADJ_DRV_OFFSET 10 +#define NV_OC_ADJ_DRV_LENGTH 1 +#define NV_OC_ADJ_DRV_MASK 0x0400 + +#define NV_OC_ONDET_ENABLE_DRV_ADDRESS 0x09F4 +#define NV_OC_ONDET_ENABLE_DRV_OFFSET 9 +#define NV_OC_ONDET_ENABLE_DRV_LENGTH 1 +#define NV_OC_ONDET_ENABLE_DRV_MASK 0x0200 + +#define NV_CL_ONDET_ENABLE_DRV_ADDRESS 0x09F4 +#define NV_CL_ONDET_ENABLE_DRV_OFFSET 8 +#define NV_CL_ONDET_ENABLE_DRV_LENGTH 1 +#define NV_CL_ONDET_ENABLE_DRV_MASK 0x0100 + +#define NV_OV_BLANK_OPTION_ADDRESS 0x09F4 +#define NV_OV_BLANK_OPTION_OFFSET 6 +#define NV_OV_BLANK_OPTION_LENGTH 2 +#define NV_OV_BLANK_OPTION_MASK 0x00C0 + +#define NV_OV_BLANK_TIMER_DIS_ADDRESS 0x09F4 +#define NV_OV_BLANK_TIMER_DIS_OFFSET 5 +#define NV_OV_BLANK_TIMER_DIS_LENGTH 1 +#define NV_OV_BLANK_TIMER_DIS_MASK 0x0020 + +#define NV_OV_BLANK_DIS_ADDRESS 0x09F4 +#define NV_OV_BLANK_DIS_OFFSET 4 +#define NV_OV_BLANK_DIS_LENGTH 1 +#define NV_OV_BLANK_DIS_MASK 0x0010 + +#define NV_OV_TIMEBASE_SELECT_ADDRESS 0x09F4 +#define NV_OV_TIMEBASE_SELECT_OFFSET 2 +#define NV_OV_TIMEBASE_SELECT_LENGTH 2 +#define NV_OV_TIMEBASE_SELECT_MASK 0x000C + +#define NV_VS_OVDET_SEL_SUP_ADDRESS 0x09F4 +#define NV_VS_OVDET_SEL_SUP_OFFSET 0 +#define NV_VS_OVDET_SEL_SUP_LENGTH 2 +#define NV_VS_OVDET_SEL_SUP_MASK 0x0003 + +#define NV_DRV_MODE_SEL_DRV_ADDRESS 0x09F2 +#define NV_DRV_MODE_SEL_DRV_OFFSET 14 +#define NV_DRV_MODE_SEL_DRV_LENGTH 1 +#define NV_DRV_MODE_SEL_DRV_MASK 0x4000 + +#define NV_DRVMOD_OSC_DIV4_EN_DRV_ADDRESS 0x09F2 +#define NV_DRVMOD_OSC_DIV4_EN_DRV_OFFSET 13 +#define NV_DRVMOD_OSC_DIV4_EN_DRV_LENGTH 1 +#define NV_DRVMOD_OSC_DIV4_EN_DRV_MASK 0x2000 + +#define NV_DRVMOD_OSC_DIV4_SETTING_DRV_ADDRESS 0x09F2 +#define NV_DRVMOD_OSC_DIV4_SETTING_DRV_OFFSET 12 +#define NV_DRVMOD_OSC_DIV4_SETTING_DRV_LENGTH 1 +#define NV_DRVMOD_OSC_DIV4_SETTING_DRV_MASK 0x1000 + +#define NV_HS_BOOST_PD_MODE_DRV_ADDRESS 0x09F2 +#define NV_HS_BOOST_PD_MODE_DRV_OFFSET 10 +#define NV_HS_BOOST_PD_MODE_DRV_LENGTH 2 +#define NV_HS_BOOST_PD_MODE_DRV_MASK 0x0C00 + +#define NV_HS_BOOST_PU_MODE_DRV_ADDRESS 0x09F2 +#define NV_HS_BOOST_PU_MODE_DRV_OFFSET 8 +#define NV_HS_BOOST_PU_MODE_DRV_LENGTH 2 +#define NV_HS_BOOST_PU_MODE_DRV_MASK 0x0300 + +#define NV_HS_HIGH_I_MODE_DRV_ADDRESS 0x09F2 +#define NV_HS_HIGH_I_MODE_DRV_OFFSET 6 +#define NV_HS_HIGH_I_MODE_DRV_LENGTH 2 +#define NV_HS_HIGH_I_MODE_DRV_MASK 0x00C0 + +#define NV_HS_ONSW_DELAY_ENABLE_DRV_ADDRESS 0x09F2 +#define NV_HS_ONSW_DELAY_ENABLE_DRV_OFFSET 5 +#define NV_HS_ONSW_DELAY_ENABLE_DRV_LENGTH 1 +#define NV_HS_ONSW_DELAY_ENABLE_DRV_MASK 0x0020 + +#define NV_LS_BOOST_MODE_DRV_ADDRESS 0x09F2 +#define NV_LS_BOOST_MODE_DRV_OFFSET 3 +#define NV_LS_BOOST_MODE_DRV_LENGTH 2 +#define NV_LS_BOOST_MODE_DRV_MASK 0x0018 + +#define NV_LS_HIGH_I_MODE_DRV_ADDRESS 0x09F2 +#define NV_LS_HIGH_I_MODE_DRV_OFFSET 1 +#define NV_LS_HIGH_I_MODE_DRV_LENGTH 2 +#define NV_LS_HIGH_I_MODE_DRV_MASK 0x0006 + +#define NV_DISABLE_DRVSUP_STARTLOAD_DRV_ADDRESS 0x09F2 +#define NV_DISABLE_DRVSUP_STARTLOAD_DRV_OFFSET 0 +#define NV_DISABLE_DRVSUP_STARTLOAD_DRV_LENGTH 1 +#define NV_DISABLE_DRVSUP_STARTLOAD_DRV_MASK 0x0001 + +#define NV_THR_SEL_OTD_MISC_ADDRESS 0x09F0 +#define NV_THR_SEL_OTD_MISC_OFFSET 0 +#define NV_THR_SEL_OTD_MISC_LENGTH 3 +#define NV_THR_SEL_OTD_MISC_MASK 0x0007 + +#define NV_OTP_VPP_SETUP_TIME_ADDRESS 0x09EC +#define NV_OTP_VPP_SETUP_TIME_OFFSET 5 +#define NV_OTP_VPP_SETUP_TIME_LENGTH 5 +#define NV_OTP_VPP_SETUP_TIME_MASK 0x03E0 + +#define NV_OTP_PROGRAM_WIDTH_ADDRESS 0x09EC +#define NV_OTP_PROGRAM_WIDTH_OFFSET 0 +#define NV_OTP_PROGRAM_WIDTH_LENGTH 5 +#define NV_OTP_PROGRAM_WIDTH_MASK 0x001F + +#define NV_OTP_USETIMINGS_ADDRESS 0x09EA +#define NV_OTP_USETIMINGS_OFFSET 15 +#define NV_OTP_USETIMINGS_LENGTH 1 +#define NV_OTP_USETIMINGS_MASK 0x8000 + +#define NV_OTP_CEB_SETUP_WIDTH_ADDRESS 0x09EA +#define NV_OTP_CEB_SETUP_WIDTH_OFFSET 10 +#define NV_OTP_CEB_SETUP_WIDTH_LENGTH 5 +#define NV_OTP_CEB_SETUP_WIDTH_MASK 0x7C00 + +#define NV_OTP_WAIT_STATES_ADDRESS 0x09EA +#define NV_OTP_WAIT_STATES_OFFSET 5 +#define NV_OTP_WAIT_STATES_LENGTH 5 +#define NV_OTP_WAIT_STATES_MASK 0x03E0 + +#define NV_OTP_RESET_PULSE_WIDTH_ADDRESS 0x09EA +#define NV_OTP_RESET_PULSE_WIDTH_OFFSET 0 +#define NV_OTP_RESET_PULSE_WIDTH_LENGTH 5 +#define NV_OTP_RESET_PULSE_WIDTH_MASK 0x001F + +#define NV_OC_FB_DIS_DRV_ADDRESS 0x09E8 +#define NV_OC_FB_DIS_DRV_OFFSET 1 +#define NV_OC_FB_DIS_DRV_LENGTH 1 +#define NV_OC_FB_DIS_DRV_MASK 0x0002 + +#define NV_CL_FB_DIS_DRV_ADDRESS 0x09E8 +#define NV_CL_FB_DIS_DRV_OFFSET 0 +#define NV_CL_FB_DIS_DRV_LENGTH 1 +#define NV_CL_FB_DIS_DRV_MASK 0x0001 + +#define NV_MLX_TRIM_7_ADDRESS 0x09E6 +#define NV_MLX_TRIM_7_OFFSET 0 +#define NV_MLX_TRIM_7_LENGTH 16 +#define NV_MLX_TRIM_7_MASK 0xFFFF + +#define NV_MLX_TRIM_6_ADDRESS 0x09E4 +#define NV_MLX_TRIM_6_OFFSET 0 +#define NV_MLX_TRIM_6_LENGTH 16 +#define NV_MLX_TRIM_6_MASK 0xFFFF + +#define TR_RINT_TEMP_COM_MISC_ADDRESS 0x09E2 +#define TR_RINT_TEMP_COM_MISC_OFFSET 0 +#define TR_RINT_TEMP_COM_MISC_LENGTH 8 +#define TR_RINT_TEMP_COM_MISC_MASK 0x00FF + +#define TR_DRVSUP_DRV_ADDRESS 0x09E0 +#define TR_DRVSUP_DRV_OFFSET 12 +#define TR_DRVSUP_DRV_LENGTH 4 +#define TR_DRVSUP_DRV_MASK 0xF000 + +#define TR_CPCLK_DRV_ADDRESS 0x09E0 +#define TR_CPCLK_DRV_OFFSET 0 +#define TR_CPCLK_DRV_LENGTH 10 +#define TR_CPCLK_DRV_MASK 0x03FF + +#define TR_OC_DRV_ADDRESS 0x09DE +#define TR_OC_DRV_OFFSET 8 +#define TR_OC_DRV_LENGTH 5 +#define TR_OC_DRV_MASK 0x1F00 + +#define TR_SLWRT_DRV_ADDRESS 0x09DE +#define TR_SLWRT_DRV_OFFSET 4 +#define TR_SLWRT_DRV_LENGTH 4 +#define TR_SLWRT_DRV_MASK 0x00F0 + +#define TR_VSMCLAMP_DRV_ADDRESS 0x09DE +#define TR_VSMCLAMP_DRV_OFFSET 0 +#define TR_VSMCLAMP_DRV_LENGTH 4 +#define TR_VSMCLAMP_DRV_MASK 0x000F + +#define I2C_SDA_IN_FILT_ADDRESS 0x09DC +#define I2C_SDA_IN_FILT_OFFSET 10 +#define I2C_SDA_IN_FILT_LENGTH 2 +#define I2C_SDA_IN_FILT_MASK 0x0C00 + +#define I2C_SDA_OUT_FILT_ADDRESS 0x09DC +#define I2C_SDA_OUT_FILT_OFFSET 8 +#define I2C_SDA_OUT_FILT_LENGTH 2 +#define I2C_SDA_OUT_FILT_MASK 0x0300 + +#define TR_OTPVPP_SUP_ADDRESS 0x09DC +#define TR_OTPVPP_SUP_OFFSET 6 +#define TR_OTPVPP_SUP_LENGTH 2 +#define TR_OTPVPP_SUP_MASK 0x00C0 + +#define TR_FDA_GAIN_ISENSE_ADDRESS 0x09DC +#define TR_FDA_GAIN_ISENSE_OFFSET 0 +#define TR_FDA_GAIN_ISENSE_LENGTH 6 +#define TR_FDA_GAIN_ISENSE_MASK 0x003F + +#define TR_MSB_OSC_ADDRESS 0x09DA +#define TR_MSB_OSC_OFFSET 15 +#define TR_MSB_OSC_LENGTH 1 +#define TR_MSB_OSC_MASK 0x8000 + +#define TR_OSC_ADDRESS 0x09DA +#define TR_OSC_OFFSET 6 +#define TR_OSC_LENGTH 9 +#define TR_OSC_MASK 0x7FC0 + +#define TR_HIGHSPEED_OSC_ADDRESS 0x09DA +#define TR_HIGHSPEED_OSC_OFFSET 5 +#define TR_HIGHSPEED_OSC_LENGTH 1 +#define TR_HIGHSPEED_OSC_MASK 0x0020 + +#define TR_IREF_SUP_ADDRESS 0x09DA +#define TR_IREF_SUP_OFFSET 0 +#define TR_IREF_SUP_LENGTH 5 +#define TR_IREF_SUP_MASK 0x001F + +#define TR_BGTC_SUP_ADDRESS 0x09D8 +#define TR_BGTC_SUP_OFFSET 11 +#define TR_BGTC_SUP_LENGTH 5 +#define TR_BGTC_SUP_MASK 0xF800 + +#define TR_BGDC_SUP_ADDRESS 0x09D8 +#define TR_BGDC_SUP_OFFSET 8 +#define TR_BGDC_SUP_LENGTH 3 +#define TR_BGDC_SUP_MASK 0x0700 + +#define TR_VDDA_SUP_ADDRESS 0x09D8 +#define TR_VDDA_SUP_OFFSET 4 +#define TR_VDDA_SUP_LENGTH 3 +#define TR_VDDA_SUP_MASK 0x0070 + +#define TR_VDDD_SUP_ADDRESS 0x09D8 +#define TR_VDDD_SUP_OFFSET 0 +#define TR_VDDD_SUP_LENGTH 3 +#define TR_VDDD_SUP_MASK 0x0007 + +#define NV_CRC_MLX_CALIBRATION_ADDRESS 0x09D6 +#define NV_CRC_MLX_CALIBRATION_OFFSET 8 +#define NV_CRC_MLX_CALIBRATION_LENGTH 8 +#define NV_CRC_MLX_CALIBRATION_MASK 0xFF00 + +#define NV_MLX_CALIB_22_ADDRESS 0x09D4 +#define NV_MLX_CALIB_22_OFFSET 0 +#define NV_MLX_CALIB_22_LENGTH 16 +#define NV_MLX_CALIB_22_MASK 0xFFFF + +#define NV_MLX_CALIB_21_ADDRESS 0x09D2 +#define NV_MLX_CALIB_21_OFFSET 0 +#define NV_MLX_CALIB_21_LENGTH 16 +#define NV_MLX_CALIB_21_MASK 0xFFFF + +#define NV_MLX_CALIB_20_ADDRESS 0x09D0 +#define NV_MLX_CALIB_20_OFFSET 0 +#define NV_MLX_CALIB_20_LENGTH 16 +#define NV_MLX_CALIB_20_MASK 0xFFFF + +#define NV_MLX_CALIB_19_ADDRESS 0x09CE +#define NV_MLX_CALIB_19_OFFSET 0 +#define NV_MLX_CALIB_19_LENGTH 16 +#define NV_MLX_CALIB_19_MASK 0xFFFF + +#define NV_MLX_CALIB_18_ADDRESS 0x09CC +#define NV_MLX_CALIB_18_OFFSET 0 +#define NV_MLX_CALIB_18_LENGTH 16 +#define NV_MLX_CALIB_18_MASK 0xFFFF + +#define NV_MLX_CALIB_17_ADDRESS 0x09CA +#define NV_MLX_CALIB_17_OFFSET 0 +#define NV_MLX_CALIB_17_LENGTH 16 +#define NV_MLX_CALIB_17_MASK 0xFFFF + +#define NV_MLX_CALIB_16_ADDRESS 0x09C8 +#define NV_MLX_CALIB_16_OFFSET 0 +#define NV_MLX_CALIB_16_LENGTH 16 +#define NV_MLX_CALIB_16_MASK 0xFFFF + +#define NV_MLX_CALIB_15_ADDRESS 0x09C6 +#define NV_MLX_CALIB_15_OFFSET 0 +#define NV_MLX_CALIB_15_LENGTH 16 +#define NV_MLX_CALIB_15_MASK 0xFFFF + +#define NV_MLX_CALIB_14_ADDRESS 0x09C4 +#define NV_MLX_CALIB_14_OFFSET 0 +#define NV_MLX_CALIB_14_LENGTH 16 +#define NV_MLX_CALIB_14_MASK 0xFFFF + +#define NV_MLX_CALIB_13_ADDRESS 0x09C2 +#define NV_MLX_CALIB_13_OFFSET 0 +#define NV_MLX_CALIB_13_LENGTH 16 +#define NV_MLX_CALIB_13_MASK 0xFFFF + +#define NV_MLX_CALIB_12_ADDRESS 0x09C0 +#define NV_MLX_CALIB_12_OFFSET 0 +#define NV_MLX_CALIB_12_LENGTH 16 +#define NV_MLX_CALIB_12_MASK 0xFFFF + +#define NV_MLX_CALIB_11_ADDRESS 0x09BE +#define NV_MLX_CALIB_11_OFFSET 0 +#define NV_MLX_CALIB_11_LENGTH 16 +#define NV_MLX_CALIB_11_MASK 0xFFFF + +#define NV_MLX_CALIB_10_ADDRESS 0x09BC +#define NV_MLX_CALIB_10_OFFSET 0 +#define NV_MLX_CALIB_10_LENGTH 16 +#define NV_MLX_CALIB_10_MASK 0xFFFF + +#define NV_MLX_CALIB_9_ADDRESS 0x09BA +#define NV_MLX_CALIB_9_OFFSET 0 +#define NV_MLX_CALIB_9_LENGTH 16 +#define NV_MLX_CALIB_9_MASK 0xFFFF + +#define NV_MLX_CALIB_8_ADDRESS 0x09B8 +#define NV_MLX_CALIB_8_OFFSET 0 +#define NV_MLX_CALIB_8_LENGTH 16 +#define NV_MLX_CALIB_8_MASK 0xFFFF + +#define NV_MLX_CALIB_7_ADDRESS 0x09B6 +#define NV_MLX_CALIB_7_OFFSET 0 +#define NV_MLX_CALIB_7_LENGTH 16 +#define NV_MLX_CALIB_7_MASK 0xFFFF + +#define NV_MLX_CALIB_6_ADDRESS 0x09B4 +#define NV_MLX_CALIB_6_OFFSET 0 +#define NV_MLX_CALIB_6_LENGTH 16 +#define NV_MLX_CALIB_6_MASK 0xFFFF + +#define NV_MLX_CALIB_5_ADDRESS 0x09B2 +#define NV_MLX_CALIB_5_OFFSET 0 +#define NV_MLX_CALIB_5_LENGTH 16 +#define NV_MLX_CALIB_5_MASK 0xFFFF + +#define NV_MLX_CALIB_4_ADDRESS 0x09B0 +#define NV_MLX_CALIB_4_OFFSET 0 +#define NV_MLX_CALIB_4_LENGTH 16 +#define NV_MLX_CALIB_4_MASK 0xFFFF + +#define NV_MLX_CALIB_3_ADDRESS 0x09AE +#define NV_MLX_CALIB_3_OFFSET 0 +#define NV_MLX_CALIB_3_LENGTH 16 +#define NV_MLX_CALIB_3_MASK 0xFFFF + +#define NV_MLX_CALIB_2_ADDRESS 0x09AC +#define NV_MLX_CALIB_2_OFFSET 0 +#define NV_MLX_CALIB_2_LENGTH 16 +#define NV_MLX_CALIB_2_MASK 0xFFFF + +#define NV_MAX_CLIM_USER_ADDRESS 0x09AA +#define NV_MAX_CLIM_USER_OFFSET 0 +#define NV_MAX_CLIM_USER_LENGTH 8 +#define NV_MAX_CLIM_USER_MASK 0x00FF + +#define NV_CLIM_GAIN_ADDRESS 0x09A8 +#define NV_CLIM_GAIN_OFFSET 8 +#define NV_CLIM_GAIN_LENGTH 8 +#define NV_CLIM_GAIN_MASK 0xFF00 + +#define NV_CLIM_OFFSET_ADDRESS 0x09A8 +#define NV_CLIM_OFFSET_OFFSET 0 +#define NV_CLIM_OFFSET_LENGTH 8 +#define NV_CLIM_OFFSET_MASK 0x00FF + +#define NV_FREE_89_ADDRESS 0x09A6 +#define NV_FREE_89_OFFSET 0 +#define NV_FREE_89_LENGTH 16 +#define NV_FREE_89_MASK 0xFFFF + +#define NV_FREE_88_ADDRESS 0x09A4 +#define NV_FREE_88_OFFSET 0 +#define NV_FREE_88_LENGTH 16 +#define NV_FREE_88_MASK 0xFFFF + +#define NV_FREE_87_ADDRESS 0x09A2 +#define NV_FREE_87_OFFSET 0 +#define NV_FREE_87_LENGTH 16 +#define NV_FREE_87_MASK 0xFFFF + +#define NV_FREE_86_ADDRESS 0x09A0 +#define NV_FREE_86_OFFSET 0 +#define NV_FREE_86_LENGTH 16 +#define NV_FREE_86_MASK 0xFFFF + +#define NV_FREE_85_ADDRESS 0x099E +#define NV_FREE_85_OFFSET 0 +#define NV_FREE_85_LENGTH 16 +#define NV_FREE_85_MASK 0xFFFF + +#define NV_FREE_84_ADDRESS 0x099C +#define NV_FREE_84_OFFSET 0 +#define NV_FREE_84_LENGTH 16 +#define NV_FREE_84_MASK 0xFFFF + +#define NV_FREE_83_ADDRESS 0x099A +#define NV_FREE_83_OFFSET 0 +#define NV_FREE_83_LENGTH 16 +#define NV_FREE_83_MASK 0xFFFF + +#define NV_FREE_82_ADDRESS 0x0998 +#define NV_FREE_82_OFFSET 0 +#define NV_FREE_82_LENGTH 16 +#define NV_FREE_82_MASK 0xFFFF + +#define NV_FREE_81_ADDRESS 0x0996 +#define NV_FREE_81_OFFSET 0 +#define NV_FREE_81_LENGTH 16 +#define NV_FREE_81_MASK 0xFFFF + +#define NV_FREE_80_ADDRESS 0x0994 +#define NV_FREE_80_OFFSET 0 +#define NV_FREE_80_LENGTH 16 +#define NV_FREE_80_MASK 0xFFFF + +#define NV_FREE_79_ADDRESS 0x0992 +#define NV_FREE_79_OFFSET 0 +#define NV_FREE_79_LENGTH 16 +#define NV_FREE_79_MASK 0xFFFF + +#define NV_FREE_78_ADDRESS 0x0990 +#define NV_FREE_78_OFFSET 0 +#define NV_FREE_78_LENGTH 16 +#define NV_FREE_78_MASK 0xFFFF + +#define NV_FREE_77_ADDRESS 0x098E +#define NV_FREE_77_OFFSET 0 +#define NV_FREE_77_LENGTH 16 +#define NV_FREE_77_MASK 0xFFFF + +#define NV_FREE_76_ADDRESS 0x098C +#define NV_FREE_76_OFFSET 0 +#define NV_FREE_76_LENGTH 16 +#define NV_FREE_76_MASK 0xFFFF + +#define NV_FREE_75_ADDRESS 0x098A +#define NV_FREE_75_OFFSET 0 +#define NV_FREE_75_LENGTH 16 +#define NV_FREE_75_MASK 0xFFFF + +#define NV_FREE_74_ADDRESS 0x0988 +#define NV_FREE_74_OFFSET 0 +#define NV_FREE_74_LENGTH 16 +#define NV_FREE_74_MASK 0xFFFF + +#define NV_FREE_73_ADDRESS 0x0986 +#define NV_FREE_73_OFFSET 0 +#define NV_FREE_73_LENGTH 16 +#define NV_FREE_73_MASK 0xFFFF + +#define NV_FREE_72_ADDRESS 0x0984 +#define NV_FREE_72_OFFSET 0 +#define NV_FREE_72_LENGTH 16 +#define NV_FREE_72_MASK 0xFFFF + +#define NV_FREE_71_ADDRESS 0x0982 +#define NV_FREE_71_OFFSET 0 +#define NV_FREE_71_LENGTH 16 +#define NV_FREE_71_MASK 0xFFFF + +#define NV_FREE_70_ADDRESS 0x0980 +#define NV_FREE_70_OFFSET 0 +#define NV_FREE_70_LENGTH 16 +#define NV_FREE_70_MASK 0xFFFF + +#define NV_FREE_69_ADDRESS 0x097E +#define NV_FREE_69_OFFSET 0 +#define NV_FREE_69_LENGTH 16 +#define NV_FREE_69_MASK 0xFFFF + +#define NV_FREE_68_ADDRESS 0x097C +#define NV_FREE_68_OFFSET 0 +#define NV_FREE_68_LENGTH 16 +#define NV_FREE_68_MASK 0xFFFF + +#define NV_FREE_67_ADDRESS 0x097A +#define NV_FREE_67_OFFSET 0 +#define NV_FREE_67_LENGTH 16 +#define NV_FREE_67_MASK 0xFFFF + +#define NV_FREE_66_ADDRESS 0x0978 +#define NV_FREE_66_OFFSET 0 +#define NV_FREE_66_LENGTH 16 +#define NV_FREE_66_MASK 0xFFFF + +#define NV_FREE_65_ADDRESS 0x0976 +#define NV_FREE_65_OFFSET 0 +#define NV_FREE_65_LENGTH 16 +#define NV_FREE_65_MASK 0xFFFF + +#define NV_FREE_64_ADDRESS 0x0974 +#define NV_FREE_64_OFFSET 0 +#define NV_FREE_64_LENGTH 16 +#define NV_FREE_64_MASK 0xFFFF + +#define NV_FREE_63_ADDRESS 0x0972 +#define NV_FREE_63_OFFSET 0 +#define NV_FREE_63_LENGTH 16 +#define NV_FREE_63_MASK 0xFFFF + +#define NV_FREE_62_ADDRESS 0x0970 +#define NV_FREE_62_OFFSET 0 +#define NV_FREE_62_LENGTH 16 +#define NV_FREE_62_MASK 0xFFFF + +#define NV_FREE_61_ADDRESS 0x096E +#define NV_FREE_61_OFFSET 0 +#define NV_FREE_61_LENGTH 16 +#define NV_FREE_61_MASK 0xFFFF + +#define NV_FREE_60_ADDRESS 0x096C +#define NV_FREE_60_OFFSET 0 +#define NV_FREE_60_LENGTH 16 +#define NV_FREE_60_MASK 0xFFFF + +#define NV_FREE_59_ADDRESS 0x096A +#define NV_FREE_59_OFFSET 0 +#define NV_FREE_59_LENGTH 16 +#define NV_FREE_59_MASK 0xFFFF + +#define NV_FREE_58_ADDRESS 0x0968 +#define NV_FREE_58_OFFSET 0 +#define NV_FREE_58_LENGTH 16 +#define NV_FREE_58_MASK 0xFFFF + +#define NV_FREE_57_ADDRESS 0x0966 +#define NV_FREE_57_OFFSET 0 +#define NV_FREE_57_LENGTH 16 +#define NV_FREE_57_MASK 0xFFFF + +#define NV_FREE_56_ADDRESS 0x0964 +#define NV_FREE_56_OFFSET 0 +#define NV_FREE_56_LENGTH 16 +#define NV_FREE_56_MASK 0xFFFF + +#define NV_FREE_55_ADDRESS 0x0962 +#define NV_FREE_55_OFFSET 0 +#define NV_FREE_55_LENGTH 16 +#define NV_FREE_55_MASK 0xFFFF + +#define NV_FREE_54_ADDRESS 0x0960 +#define NV_FREE_54_OFFSET 0 +#define NV_FREE_54_LENGTH 16 +#define NV_FREE_54_MASK 0xFFFF + +#define NV_FREE_53_ADDRESS 0x095E +#define NV_FREE_53_OFFSET 0 +#define NV_FREE_53_LENGTH 16 +#define NV_FREE_53_MASK 0xFFFF + +#define NV_FREE_52_ADDRESS 0x095C +#define NV_FREE_52_OFFSET 0 +#define NV_FREE_52_LENGTH 16 +#define NV_FREE_52_MASK 0xFFFF + +#define NV_FREE_51_ADDRESS 0x095A +#define NV_FREE_51_OFFSET 0 +#define NV_FREE_51_LENGTH 16 +#define NV_FREE_51_MASK 0xFFFF + +#define NV_FREE_50_ADDRESS 0x0958 +#define NV_FREE_50_OFFSET 0 +#define NV_FREE_50_LENGTH 16 +#define NV_FREE_50_MASK 0xFFFF + +#define NV_FREE_49_ADDRESS 0x0956 +#define NV_FREE_49_OFFSET 0 +#define NV_FREE_49_LENGTH 16 +#define NV_FREE_49_MASK 0xFFFF + +#define NV_FREE_48_ADDRESS 0x0954 +#define NV_FREE_48_OFFSET 0 +#define NV_FREE_48_LENGTH 16 +#define NV_FREE_48_MASK 0xFFFF + +#define NV_FREE_47_ADDRESS 0x0952 +#define NV_FREE_47_OFFSET 0 +#define NV_FREE_47_LENGTH 16 +#define NV_FREE_47_MASK 0xFFFF + +#define NV_FREE_46_ADDRESS 0x0950 +#define NV_FREE_46_OFFSET 0 +#define NV_FREE_46_LENGTH 16 +#define NV_FREE_46_MASK 0xFFFF + +#define NV_FREE_45_ADDRESS 0x094E +#define NV_FREE_45_OFFSET 0 +#define NV_FREE_45_LENGTH 16 +#define NV_FREE_45_MASK 0xFFFF + +#define NV_FREE_44_ADDRESS 0x094C +#define NV_FREE_44_OFFSET 0 +#define NV_FREE_44_LENGTH 16 +#define NV_FREE_44_MASK 0xFFFF + +#define NV_FREE_43_ADDRESS 0x094A +#define NV_FREE_43_OFFSET 0 +#define NV_FREE_43_LENGTH 16 +#define NV_FREE_43_MASK 0xFFFF + +#define NV_FREE_42_ADDRESS 0x0948 +#define NV_FREE_42_OFFSET 0 +#define NV_FREE_42_LENGTH 16 +#define NV_FREE_42_MASK 0xFFFF + +#define NV_FREE_41_ADDRESS 0x0946 +#define NV_FREE_41_OFFSET 0 +#define NV_FREE_41_LENGTH 16 +#define NV_FREE_41_MASK 0xFFFF + +#define NV_FREE_40_ADDRESS 0x0944 +#define NV_FREE_40_OFFSET 0 +#define NV_FREE_40_LENGTH 16 +#define NV_FREE_40_MASK 0xFFFF + +#define NV_FREE_39_ADDRESS 0x0942 +#define NV_FREE_39_OFFSET 0 +#define NV_FREE_39_LENGTH 16 +#define NV_FREE_39_MASK 0xFFFF + +#define NV_FREE_38_ADDRESS 0x0940 +#define NV_FREE_38_OFFSET 0 +#define NV_FREE_38_LENGTH 16 +#define NV_FREE_38_MASK 0xFFFF + +#define NV_FREE_37_ADDRESS 0x093E +#define NV_FREE_37_OFFSET 0 +#define NV_FREE_37_LENGTH 16 +#define NV_FREE_37_MASK 0xFFFF + +#define NV_FREE_36_ADDRESS 0x093C +#define NV_FREE_36_OFFSET 0 +#define NV_FREE_36_LENGTH 16 +#define NV_FREE_36_MASK 0xFFFF + +#define NV_FREE_35_ADDRESS 0x093A +#define NV_FREE_35_OFFSET 0 +#define NV_FREE_35_LENGTH 16 +#define NV_FREE_35_MASK 0xFFFF + +#define NV_FREE_34_ADDRESS 0x0938 +#define NV_FREE_34_OFFSET 0 +#define NV_FREE_34_LENGTH 16 +#define NV_FREE_34_MASK 0xFFFF + +#define NV_FREE_33_ADDRESS 0x0936 +#define NV_FREE_33_OFFSET 0 +#define NV_FREE_33_LENGTH 16 +#define NV_FREE_33_MASK 0xFFFF + +#define NV_FREE_32_ADDRESS 0x0934 +#define NV_FREE_32_OFFSET 0 +#define NV_FREE_32_LENGTH 16 +#define NV_FREE_32_MASK 0xFFFF + +#define NV_FREE_31_ADDRESS 0x0932 +#define NV_FREE_31_OFFSET 0 +#define NV_FREE_31_LENGTH 16 +#define NV_FREE_31_MASK 0xFFFF + +#define NV_FREE_30_ADDRESS 0x0930 +#define NV_FREE_30_OFFSET 0 +#define NV_FREE_30_LENGTH 16 +#define NV_FREE_30_MASK 0xFFFF + +#define NV_FREE_29_ADDRESS 0x092E +#define NV_FREE_29_OFFSET 0 +#define NV_FREE_29_LENGTH 16 +#define NV_FREE_29_MASK 0xFFFF + +#define NV_FREE_28_ADDRESS 0x092C +#define NV_FREE_28_OFFSET 0 +#define NV_FREE_28_LENGTH 16 +#define NV_FREE_28_MASK 0xFFFF + +#define NV_FREE_27_ADDRESS 0x092A +#define NV_FREE_27_OFFSET 0 +#define NV_FREE_27_LENGTH 16 +#define NV_FREE_27_MASK 0xFFFF + +#define NV_FREE_26_ADDRESS 0x0928 +#define NV_FREE_26_OFFSET 0 +#define NV_FREE_26_LENGTH 16 +#define NV_FREE_26_MASK 0xFFFF + +#define NV_FREE_25_ADDRESS 0x0926 +#define NV_FREE_25_OFFSET 0 +#define NV_FREE_25_LENGTH 16 +#define NV_FREE_25_MASK 0xFFFF + +#define NV_FREE_24_ADDRESS 0x0924 +#define NV_FREE_24_OFFSET 0 +#define NV_FREE_24_LENGTH 16 +#define NV_FREE_24_MASK 0xFFFF + +#define NV_FREE_23_ADDRESS 0x0922 +#define NV_FREE_23_OFFSET 0 +#define NV_FREE_23_LENGTH 16 +#define NV_FREE_23_MASK 0xFFFF + +#define NV_FREE_22_ADDRESS 0x0920 +#define NV_FREE_22_OFFSET 0 +#define NV_FREE_22_LENGTH 16 +#define NV_FREE_22_MASK 0xFFFF + +#define NV_FREE_21_ADDRESS 0x091E +#define NV_FREE_21_OFFSET 0 +#define NV_FREE_21_LENGTH 16 +#define NV_FREE_21_MASK 0xFFFF + +#define NV_FREE_20_ADDRESS 0x091C +#define NV_FREE_20_OFFSET 0 +#define NV_FREE_20_LENGTH 16 +#define NV_FREE_20_MASK 0xFFFF + +#define NV_FREE_19_ADDRESS 0x091A +#define NV_FREE_19_OFFSET 0 +#define NV_FREE_19_LENGTH 16 +#define NV_FREE_19_MASK 0xFFFF + +#define NV_FREE_18_ADDRESS 0x0918 +#define NV_FREE_18_OFFSET 0 +#define NV_FREE_18_LENGTH 16 +#define NV_FREE_18_MASK 0xFFFF + +#define NV_FREE_17_ADDRESS 0x0916 +#define NV_FREE_17_OFFSET 0 +#define NV_FREE_17_LENGTH 16 +#define NV_FREE_17_MASK 0xFFFF + +#define NV_FREE_16_ADDRESS 0x0914 +#define NV_FREE_16_OFFSET 0 +#define NV_FREE_16_LENGTH 16 +#define NV_FREE_16_MASK 0xFFFF + +#define NV_FREE_15_ADDRESS 0x0912 +#define NV_FREE_15_OFFSET 0 +#define NV_FREE_15_LENGTH 16 +#define NV_FREE_15_MASK 0xFFFF + +#define NV_FREE_14_ADDRESS 0x0910 +#define NV_FREE_14_OFFSET 0 +#define NV_FREE_14_LENGTH 16 +#define NV_FREE_14_MASK 0xFFFF + +#define NV_FREE_13_ADDRESS 0x090E +#define NV_FREE_13_OFFSET 0 +#define NV_FREE_13_LENGTH 16 +#define NV_FREE_13_MASK 0xFFFF + +#define NV_FREE_12_ADDRESS 0x090C +#define NV_FREE_12_OFFSET 0 +#define NV_FREE_12_LENGTH 16 +#define NV_FREE_12_MASK 0xFFFF + +#define NV_FREE_11_ADDRESS 0x090A +#define NV_FREE_11_OFFSET 0 +#define NV_FREE_11_LENGTH 16 +#define NV_FREE_11_MASK 0xFFFF + +#define NV_FREE_10_ADDRESS 0x0908 +#define NV_FREE_10_OFFSET 0 +#define NV_FREE_10_LENGTH 16 +#define NV_FREE_10_MASK 0xFFFF + +#define NV_FREE_9_ADDRESS 0x0906 +#define NV_FREE_9_OFFSET 0 +#define NV_FREE_9_LENGTH 16 +#define NV_FREE_9_MASK 0xFFFF + +#define NV_FREE_8_ADDRESS 0x0904 +#define NV_FREE_8_OFFSET 0 +#define NV_FREE_8_LENGTH 16 +#define NV_FREE_8_MASK 0xFFFF + +#define NV_FREE_7_ADDRESS 0x0902 +#define NV_FREE_7_OFFSET 0 +#define NV_FREE_7_LENGTH 16 +#define NV_FREE_7_MASK 0xFFFF + +#define NV_FREE_6_ADDRESS 0x0900 +#define NV_FREE_6_OFFSET 0 +#define NV_FREE_6_LENGTH 16 +#define NV_FREE_6_MASK 0xFFFF + +#define NV_FREE_5_ADDRESS 0x08FE +#define NV_FREE_5_OFFSET 0 +#define NV_FREE_5_LENGTH 16 +#define NV_FREE_5_MASK 0xFFFF + +#define NV_FREE_4_ADDRESS 0x08FC +#define NV_FREE_4_OFFSET 0 +#define NV_FREE_4_LENGTH 16 +#define NV_FREE_4_MASK 0xFFFF + +#define NV_FREE_3_ADDRESS 0x08FA +#define NV_FREE_3_OFFSET 0 +#define NV_FREE_3_LENGTH 16 +#define NV_FREE_3_MASK 0xFFFF + +#define NV_FREE_2_ADDRESS 0x08F8 +#define NV_FREE_2_OFFSET 0 +#define NV_FREE_2_LENGTH 16 +#define NV_FREE_2_MASK 0xFFFF + +#define NV_CRC_PATCH_3_ADDRESS 0x08F6 +#define NV_CRC_PATCH_3_OFFSET 8 +#define NV_CRC_PATCH_3_LENGTH 8 +#define NV_CRC_PATCH_3_MASK 0xFF00 + +#define NV_CRC_PATCH_2_ADDRESS 0x08F6 +#define NV_CRC_PATCH_2_OFFSET 0 +#define NV_CRC_PATCH_2_LENGTH 8 +#define NV_CRC_PATCH_2_MASK 0x00FF + +#define NV_CRC_PATCH_1_ADDRESS 0x08F4 +#define NV_CRC_PATCH_1_OFFSET 8 +#define NV_CRC_PATCH_1_LENGTH 8 +#define NV_CRC_PATCH_1_MASK 0xFF00 + +#define NV_CRC_PATCH_0_ADDRESS 0x08F4 +#define NV_CRC_PATCH_0_OFFSET 0 +#define NV_CRC_PATCH_0_LENGTH 8 +#define NV_CRC_PATCH_0_MASK 0x00FF + +#define NV_PATCH_3_INSTRUCTION_ADDRESS 0x08F2 +#define NV_PATCH_3_INSTRUCTION_OFFSET 0 +#define NV_PATCH_3_INSTRUCTION_LENGTH 16 +#define NV_PATCH_3_INSTRUCTION_MASK 0xFFFF + +#define NV_PATCH_3_ADDRESS_ADDRESS 0x08F0 +#define NV_PATCH_3_ADDRESS_OFFSET 0 +#define NV_PATCH_3_ADDRESS_LENGTH 16 +#define NV_PATCH_3_ADDRESS_MASK 0xFFFF + +#define NV_PATCH_2_INSTRUCTION_ADDRESS 0x08EE +#define NV_PATCH_2_INSTRUCTION_OFFSET 0 +#define NV_PATCH_2_INSTRUCTION_LENGTH 16 +#define NV_PATCH_2_INSTRUCTION_MASK 0xFFFF + +#define NV_PATCH_2_ADDRESS_ADDRESS 0x08EC +#define NV_PATCH_2_ADDRESS_OFFSET 0 +#define NV_PATCH_2_ADDRESS_LENGTH 16 +#define NV_PATCH_2_ADDRESS_MASK 0xFFFF + +#define NV_PATCH_1_INSTRUCTION_ADDRESS 0x08EA +#define NV_PATCH_1_INSTRUCTION_OFFSET 0 +#define NV_PATCH_1_INSTRUCTION_LENGTH 16 +#define NV_PATCH_1_INSTRUCTION_MASK 0xFFFF + +#define MV_PATCH_1_ADDRESS_ADDRESS 0x08E8 +#define MV_PATCH_1_ADDRESS_OFFSET 0 +#define MV_PATCH_1_ADDRESS_LENGTH 16 +#define MV_PATCH_1_ADDRESS_MASK 0xFFFF + +#define NV_PATCH_0_INSTRUCTION_ADDRESS 0x08E6 +#define NV_PATCH_0_INSTRUCTION_OFFSET 0 +#define NV_PATCH_0_INSTRUCTION_LENGTH 16 +#define NV_PATCH_0_INSTRUCTION_MASK 0xFFFF + +#define NV_PATCH_0_ADDRESS_ADDRESS 0x08E4 +#define NV_PATCH_0_ADDRESS_OFFSET 0 +#define NV_PATCH_0_ADDRESS_LENGTH 16 +#define NV_PATCH_0_ADDRESS_MASK 0xFFFF + +#define NV_MTP_USE_ZONE_2_ADDRESS 0x08E2 +#define NV_MTP_USE_ZONE_2_OFFSET 8 +#define NV_MTP_USE_ZONE_2_LENGTH 8 +#define NV_MTP_USE_ZONE_2_MASK 0xFF00 + +#define NV_CRC_MTP_ZONE_2_ADDRESS 0x08E2 +#define NV_CRC_MTP_ZONE_2_OFFSET 0 +#define NV_CRC_MTP_ZONE_2_LENGTH 8 +#define NV_CRC_MTP_ZONE_2_MASK 0x00FF + +#define NV_copy_zone2_36_ADDRESS 0x08E0 +#define NV_copy_zone2_36_OFFSET 0 +#define NV_copy_zone2_36_LENGTH 16 +#define NV_copy_zone2_36_MASK 0xFFFF + +#define NV_copy_zone2_35_ADDRESS 0x08DE +#define NV_copy_zone2_35_OFFSET 0 +#define NV_copy_zone2_35_LENGTH 16 +#define NV_copy_zone2_35_MASK 0xFFFF + +#define NV_copy_zone2_34_ADDRESS 0x08DC +#define NV_copy_zone2_34_OFFSET 0 +#define NV_copy_zone2_34_LENGTH 16 +#define NV_copy_zone2_34_MASK 0xFFFF + +#define NV_copy_zone2_33_ADDRESS 0x08DA +#define NV_copy_zone2_33_OFFSET 0 +#define NV_copy_zone2_33_LENGTH 16 +#define NV_copy_zone2_33_MASK 0xFFFF + +#define NV_copy_zone2_32_ADDRESS 0x08D8 +#define NV_copy_zone2_32_OFFSET 0 +#define NV_copy_zone2_32_LENGTH 16 +#define NV_copy_zone2_32_MASK 0xFFFF + +#define NV_copy_zone2_31_ADDRESS 0x08D6 +#define NV_copy_zone2_31_OFFSET 0 +#define NV_copy_zone2_31_LENGTH 16 +#define NV_copy_zone2_31_MASK 0xFFFF + +#define NV_copy_zone2_30_ADDRESS 0x08D4 +#define NV_copy_zone2_30_OFFSET 0 +#define NV_copy_zone2_30_LENGTH 16 +#define NV_copy_zone2_30_MASK 0xFFFF + +#define NV_copy_zone2_29_ADDRESS 0x08D2 +#define NV_copy_zone2_29_OFFSET 0 +#define NV_copy_zone2_29_LENGTH 16 +#define NV_copy_zone2_29_MASK 0xFFFF + +#define NV_copy_zone2_28_ADDRESS 0x08D0 +#define NV_copy_zone2_28_OFFSET 0 +#define NV_copy_zone2_28_LENGTH 16 +#define NV_copy_zone2_28_MASK 0xFFFF + +#define NV_copy_zone2_27_ADDRESS 0x08CE +#define NV_copy_zone2_27_OFFSET 0 +#define NV_copy_zone2_27_LENGTH 16 +#define NV_copy_zone2_27_MASK 0xFFFF + +#define NV_copy_zone2_26_ADDRESS 0x08CC +#define NV_copy_zone2_26_OFFSET 0 +#define NV_copy_zone2_26_LENGTH 16 +#define NV_copy_zone2_26_MASK 0xFFFF + +#define NV_copy_zone2_25_ADDRESS 0x08CA +#define NV_copy_zone2_25_OFFSET 0 +#define NV_copy_zone2_25_LENGTH 16 +#define NV_copy_zone2_25_MASK 0xFFFF + +#define NV_copy_zone2_24_ADDRESS 0x08C8 +#define NV_copy_zone2_24_OFFSET 0 +#define NV_copy_zone2_24_LENGTH 16 +#define NV_copy_zone2_24_MASK 0xFFFF + +#define NV_copy_zone2_23_ADDRESS 0x08C6 +#define NV_copy_zone2_23_OFFSET 0 +#define NV_copy_zone2_23_LENGTH 16 +#define NV_copy_zone2_23_MASK 0xFFFF + +#define NV_copy_zone2_22_ADDRESS 0x08C4 +#define NV_copy_zone2_22_OFFSET 0 +#define NV_copy_zone2_22_LENGTH 16 +#define NV_copy_zone2_22_MASK 0xFFFF + +#define NV_copy_zone2_21_ADDRESS 0x08C2 +#define NV_copy_zone2_21_OFFSET 0 +#define NV_copy_zone2_21_LENGTH 16 +#define NV_copy_zone2_21_MASK 0xFFFF + +#define NV_copy_zone2_20_ADDRESS 0x08C0 +#define NV_copy_zone2_20_OFFSET 0 +#define NV_copy_zone2_20_LENGTH 16 +#define NV_copy_zone2_20_MASK 0xFFFF + +#define NV_copy_zone2_19_ADDRESS 0x08BE +#define NV_copy_zone2_19_OFFSET 0 +#define NV_copy_zone2_19_LENGTH 16 +#define NV_copy_zone2_19_MASK 0xFFFF + +#define NV_copy_zone2_18_ADDRESS 0x08BC +#define NV_copy_zone2_18_OFFSET 0 +#define NV_copy_zone2_18_LENGTH 16 +#define NV_copy_zone2_18_MASK 0xFFFF + +#define NV_copy_zone2_17_ADDRESS 0x08BA +#define NV_copy_zone2_17_OFFSET 0 +#define NV_copy_zone2_17_LENGTH 16 +#define NV_copy_zone2_17_MASK 0xFFFF + +#define NV_copy_zone2_16_ADDRESS 0x08B8 +#define NV_copy_zone2_16_OFFSET 0 +#define NV_copy_zone2_16_LENGTH 16 +#define NV_copy_zone2_16_MASK 0xFFFF + +#define NV_copy_zone2_15_ADDRESS 0x08B6 +#define NV_copy_zone2_15_OFFSET 0 +#define NV_copy_zone2_15_LENGTH 16 +#define NV_copy_zone2_15_MASK 0xFFFF + +#define NV_copy_zone2_14_ADDRESS 0x08B4 +#define NV_copy_zone2_14_OFFSET 0 +#define NV_copy_zone2_14_LENGTH 16 +#define NV_copy_zone2_14_MASK 0xFFFF + +#define NV_copy_zone2_13_ADDRESS 0x08B2 +#define NV_copy_zone2_13_OFFSET 0 +#define NV_copy_zone2_13_LENGTH 16 +#define NV_copy_zone2_13_MASK 0xFFFF + +#define NV_copy_zone2_12_ADDRESS 0x08B0 +#define NV_copy_zone2_12_OFFSET 0 +#define NV_copy_zone2_12_LENGTH 16 +#define NV_copy_zone2_12_MASK 0xFFFF + +#define NV_copy_zone2_11_ADDRESS 0x08AE +#define NV_copy_zone2_11_OFFSET 0 +#define NV_copy_zone2_11_LENGTH 16 +#define NV_copy_zone2_11_MASK 0xFFFF + +#define NV_copy_zone2_10_ADDRESS 0x08AC +#define NV_copy_zone2_10_OFFSET 0 +#define NV_copy_zone2_10_LENGTH 16 +#define NV_copy_zone2_10_MASK 0xFFFF + +#define NV_copy_zone2_9_ADDRESS 0x08AA +#define NV_copy_zone2_9_OFFSET 0 +#define NV_copy_zone2_9_LENGTH 16 +#define NV_copy_zone2_9_MASK 0xFFFF + +#define NV_copy_zone2_8_ADDRESS 0x08A8 +#define NV_copy_zone2_8_OFFSET 0 +#define NV_copy_zone2_8_LENGTH 16 +#define NV_copy_zone2_8_MASK 0xFFFF + +#define NV_copy_zone2_7_ADDRESS 0x08A6 +#define NV_copy_zone2_7_OFFSET 0 +#define NV_copy_zone2_7_LENGTH 16 +#define NV_copy_zone2_7_MASK 0xFFFF + +#define NV_copy_zone2_6_ADDRESS 0x08A4 +#define NV_copy_zone2_6_OFFSET 0 +#define NV_copy_zone2_6_LENGTH 16 +#define NV_copy_zone2_6_MASK 0xFFFF + +#define NV_copy_zone2_5_ADDRESS 0x08A2 +#define NV_copy_zone2_5_OFFSET 0 +#define NV_copy_zone2_5_LENGTH 16 +#define NV_copy_zone2_5_MASK 0xFFFF + +#define NV_copy_zone2_4_ADDRESS 0x08A0 +#define NV_copy_zone2_4_OFFSET 0 +#define NV_copy_zone2_4_LENGTH 16 +#define NV_copy_zone2_4_MASK 0xFFFF + +#define NV_copy_zone2_3_ADDRESS 0x089E +#define NV_copy_zone2_3_OFFSET 0 +#define NV_copy_zone2_3_LENGTH 16 +#define NV_copy_zone2_3_MASK 0xFFFF + +#define NV_copy_zone2_2_ADDRESS 0x089C +#define NV_copy_zone2_2_OFFSET 0 +#define NV_copy_zone2_2_LENGTH 16 +#define NV_copy_zone2_2_MASK 0xFFFF + +#define NV_copy_zone2_1_ADDRESS 0x089A +#define NV_copy_zone2_1_OFFSET 0 +#define NV_copy_zone2_1_LENGTH 16 +#define NV_copy_zone2_1_MASK 0xFFFF + +#define NV_copy_zone2_0_ADDRESS 0x0898 +#define NV_copy_zone2_0_OFFSET 0 +#define NV_copy_zone2_0_LENGTH 16 +#define NV_copy_zone2_0_MASK 0xFFFF + +#define NV_MTP_USE_ZONE_1_ADDRESS 0x0896 +#define NV_MTP_USE_ZONE_1_OFFSET 8 +#define NV_MTP_USE_ZONE_1_LENGTH 8 +#define NV_MTP_USE_ZONE_1_MASK 0xFF00 + +#define NV_CRC_MTP_ZONE_1_ADDRESS 0x0896 +#define NV_CRC_MTP_ZONE_1_OFFSET 0 +#define NV_CRC_MTP_ZONE_1_LENGTH 8 +#define NV_CRC_MTP_ZONE_1_MASK 0x00FF + +#define NV_copy_zone1_36_ADDRESS 0x0894 +#define NV_copy_zone1_36_OFFSET 0 +#define NV_copy_zone1_36_LENGTH 16 +#define NV_copy_zone1_36_MASK 0xFFFF + +#define NV_copy_zone1_35_ADDRESS 0x0892 +#define NV_copy_zone1_35_OFFSET 0 +#define NV_copy_zone1_35_LENGTH 16 +#define NV_copy_zone1_35_MASK 0xFFFF + +#define NV_copy_zone1_34_ADDRESS 0x0890 +#define NV_copy_zone1_34_OFFSET 0 +#define NV_copy_zone1_34_LENGTH 16 +#define NV_copy_zone1_34_MASK 0xFFFF + +#define NV_copy_zone1_33_ADDRESS 0x088E +#define NV_copy_zone1_33_OFFSET 0 +#define NV_copy_zone1_33_LENGTH 16 +#define NV_copy_zone1_33_MASK 0xFFFF + +#define NV_copy_zone1_32_ADDRESS 0x088C +#define NV_copy_zone1_32_OFFSET 0 +#define NV_copy_zone1_32_LENGTH 16 +#define NV_copy_zone1_32_MASK 0xFFFF + +#define NV_copy_zone1_31_ADDRESS 0x088A +#define NV_copy_zone1_31_OFFSET 0 +#define NV_copy_zone1_31_LENGTH 16 +#define NV_copy_zone1_31_MASK 0xFFFF + +#define NV_copy_zone1_30_ADDRESS 0x0888 +#define NV_copy_zone1_30_OFFSET 0 +#define NV_copy_zone1_30_LENGTH 16 +#define NV_copy_zone1_30_MASK 0xFFFF + +#define NV_copy_zone1_29_ADDRESS 0x0886 +#define NV_copy_zone1_29_OFFSET 0 +#define NV_copy_zone1_29_LENGTH 16 +#define NV_copy_zone1_29_MASK 0xFFFF + +#define NV_copy_zone1_28_ADDRESS 0x0884 +#define NV_copy_zone1_28_OFFSET 0 +#define NV_copy_zone1_28_LENGTH 16 +#define NV_copy_zone1_28_MASK 0xFFFF + +#define NV_copy_zone1_27_ADDRESS 0x0882 +#define NV_copy_zone1_27_OFFSET 0 +#define NV_copy_zone1_27_LENGTH 16 +#define NV_copy_zone1_27_MASK 0xFFFF + +#define NV_copy_zone1_26_ADDRESS 0x0880 +#define NV_copy_zone1_26_OFFSET 0 +#define NV_copy_zone1_26_LENGTH 16 +#define NV_copy_zone1_26_MASK 0xFFFF + +#define NV_copy_zone1_25_ADDRESS 0x087E +#define NV_copy_zone1_25_OFFSET 0 +#define NV_copy_zone1_25_LENGTH 16 +#define NV_copy_zone1_25_MASK 0xFFFF + +#define NV_copy_zone1_24_ADDRESS 0x087C +#define NV_copy_zone1_24_OFFSET 0 +#define NV_copy_zone1_24_LENGTH 16 +#define NV_copy_zone1_24_MASK 0xFFFF + +#define NV_copy_zone1_23_ADDRESS 0x087A +#define NV_copy_zone1_23_OFFSET 0 +#define NV_copy_zone1_23_LENGTH 16 +#define NV_copy_zone1_23_MASK 0xFFFF + +#define NV_copy_zone1_22_ADDRESS 0x0878 +#define NV_copy_zone1_22_OFFSET 0 +#define NV_copy_zone1_22_LENGTH 16 +#define NV_copy_zone1_22_MASK 0xFFFF + +#define NV_copy_zone1_21_ADDRESS 0x0876 +#define NV_copy_zone1_21_OFFSET 0 +#define NV_copy_zone1_21_LENGTH 16 +#define NV_copy_zone1_21_MASK 0xFFFF + +#define NV_copy_zone1_20_ADDRESS 0x0874 +#define NV_copy_zone1_20_OFFSET 0 +#define NV_copy_zone1_20_LENGTH 16 +#define NV_copy_zone1_20_MASK 0xFFFF + +#define NV_copy_zone1_19_ADDRESS 0x0872 +#define NV_copy_zone1_19_OFFSET 0 +#define NV_copy_zone1_19_LENGTH 16 +#define NV_copy_zone1_19_MASK 0xFFFF + +#define NV_copy_zone1_18_ADDRESS 0x0870 +#define NV_copy_zone1_18_OFFSET 0 +#define NV_copy_zone1_18_LENGTH 16 +#define NV_copy_zone1_18_MASK 0xFFFF + +#define NV_copy_zone1_17_ADDRESS 0x086E +#define NV_copy_zone1_17_OFFSET 0 +#define NV_copy_zone1_17_LENGTH 16 +#define NV_copy_zone1_17_MASK 0xFFFF + +#define NV_copy_zone1_16_ADDRESS 0x086C +#define NV_copy_zone1_16_OFFSET 0 +#define NV_copy_zone1_16_LENGTH 16 +#define NV_copy_zone1_16_MASK 0xFFFF + +#define NV_copy_zone1_15_ADDRESS 0x086A +#define NV_copy_zone1_15_OFFSET 0 +#define NV_copy_zone1_15_LENGTH 16 +#define NV_copy_zone1_15_MASK 0xFFFF + +#define NV_copy_zone1_14_ADDRESS 0x0868 +#define NV_copy_zone1_14_OFFSET 0 +#define NV_copy_zone1_14_LENGTH 16 +#define NV_copy_zone1_14_MASK 0xFFFF + +#define NV_copy_zone1_13_ADDRESS 0x0866 +#define NV_copy_zone1_13_OFFSET 0 +#define NV_copy_zone1_13_LENGTH 16 +#define NV_copy_zone1_13_MASK 0xFFFF + +#define NV_copy_zone1_12_ADDRESS 0x0864 +#define NV_copy_zone1_12_OFFSET 0 +#define NV_copy_zone1_12_LENGTH 16 +#define NV_copy_zone1_12_MASK 0xFFFF + +#define NV_copy_zone1_11_ADDRESS 0x0862 +#define NV_copy_zone1_11_OFFSET 0 +#define NV_copy_zone1_11_LENGTH 16 +#define NV_copy_zone1_11_MASK 0xFFFF + +#define NV_copy_zone1_10_ADDRESS 0x0860 +#define NV_copy_zone1_10_OFFSET 0 +#define NV_copy_zone1_10_LENGTH 16 +#define NV_copy_zone1_10_MASK 0xFFFF + +#define NV_copy_zone1_9_ADDRESS 0x085E +#define NV_copy_zone1_9_OFFSET 0 +#define NV_copy_zone1_9_LENGTH 16 +#define NV_copy_zone1_9_MASK 0xFFFF + +#define NV_copy_zone1_8_ADDRESS 0x085C +#define NV_copy_zone1_8_OFFSET 0 +#define NV_copy_zone1_8_LENGTH 16 +#define NV_copy_zone1_8_MASK 0xFFFF + +#define NV_copy_zone1_7_ADDRESS 0x085A +#define NV_copy_zone1_7_OFFSET 0 +#define NV_copy_zone1_7_LENGTH 16 +#define NV_copy_zone1_7_MASK 0xFFFF + +#define NV_copy_zone1_6_ADDRESS 0x0858 +#define NV_copy_zone1_6_OFFSET 0 +#define NV_copy_zone1_6_LENGTH 16 +#define NV_copy_zone1_6_MASK 0xFFFF + +#define NV_copy_zone1_5_ADDRESS 0x0856 +#define NV_copy_zone1_5_OFFSET 0 +#define NV_copy_zone1_5_LENGTH 16 +#define NV_copy_zone1_5_MASK 0xFFFF + +#define NV_copy_zone1_4_ADDRESS 0x0854 +#define NV_copy_zone1_4_OFFSET 0 +#define NV_copy_zone1_4_LENGTH 16 +#define NV_copy_zone1_4_MASK 0xFFFF + +#define NV_copy_zone1_3_ADDRESS 0x0852 +#define NV_copy_zone1_3_OFFSET 0 +#define NV_copy_zone1_3_LENGTH 16 +#define NV_copy_zone1_3_MASK 0xFFFF + +#define NV_copy_zone1_2_ADDRESS 0x0850 +#define NV_copy_zone1_2_OFFSET 0 +#define NV_copy_zone1_2_LENGTH 16 +#define NV_copy_zone1_2_MASK 0xFFFF + +#define NV_copy_zone1_1_ADDRESS 0x084E +#define NV_copy_zone1_1_OFFSET 0 +#define NV_copy_zone1_1_LENGTH 16 +#define NV_copy_zone1_1_MASK 0xFFFF + +#define NV_copy_zone1_0_ADDRESS 0x084C +#define NV_copy_zone1_0_OFFSET 0 +#define NV_copy_zone1_0_LENGTH 16 +#define NV_copy_zone1_0_MASK 0xFFFF + +#define NV_MTP_USE_ZONE_0_ADDRESS 0x084A +#define NV_MTP_USE_ZONE_0_OFFSET 8 +#define NV_MTP_USE_ZONE_0_LENGTH 8 +#define NV_MTP_USE_ZONE_0_MASK 0xFF00 + +#define NV_CRC_MTP_ZONE_0_ADDRESS 0x084A +#define NV_CRC_MTP_ZONE_0_OFFSET 0 +#define NV_CRC_MTP_ZONE_0_LENGTH 8 +#define NV_CRC_MTP_ZONE_0_MASK 0x00FF + +#define NV_CUST_ID0_ADDRESS 0x0848 +#define NV_CUST_ID0_OFFSET 0 +#define NV_CUST_ID0_LENGTH 16 +#define NV_CUST_ID0_MASK 0xFFFF + +#define NV_CUST_ID1_ADDRESS 0x0846 +#define NV_CUST_ID1_OFFSET 0 +#define NV_CUST_ID1_LENGTH 16 +#define NV_CUST_ID1_MASK 0xFFFF + +#define NV_CUST_ID2_ADDRESS 0x0844 +#define NV_CUST_ID2_OFFSET 0 +#define NV_CUST_ID2_LENGTH 16 +#define NV_CUST_ID2_MASK 0xFFFF + +#define NV_CUST_ID3_ADDRESS 0x0842 +#define NV_CUST_ID3_OFFSET 0 +#define NV_CUST_ID3_LENGTH 16 +#define NV_CUST_ID3_MASK 0xFFFF + +#define NV_FLAT_BLANK_ADDRESS 0x0840 +#define NV_FLAT_BLANK_OFFSET 8 +#define NV_FLAT_BLANK_LENGTH 8 +#define NV_FLAT_BLANK_MASK 0xFF00 + +#define NV_INTEGRATOR_PRE_DIV_ADDRESS 0x0840 +#define NV_INTEGRATOR_PRE_DIV_OFFSET 5 +#define NV_INTEGRATOR_PRE_DIV_LENGTH 2 +#define NV_INTEGRATOR_PRE_DIV_MASK 0x0060 + +#define NV_INTEGRATOR_TIME_ADDRESS 0x0840 +#define NV_INTEGRATOR_TIME_OFFSET 3 +#define NV_INTEGRATOR_TIME_LENGTH 2 +#define NV_INTEGRATOR_TIME_MASK 0x0018 + +#define NV_INTEGRATOR_START_OPTION_ADDRESS 0x0840 +#define NV_INTEGRATOR_START_OPTION_OFFSET 2 +#define NV_INTEGRATOR_START_OPTION_LENGTH 1 +#define NV_INTEGRATOR_START_OPTION_MASK 0x0004 + +#define NV_INTEGRATOR_RESYNC_OPTION_ADDRESS 0x0840 +#define NV_INTEGRATOR_RESYNC_OPTION_OFFSET 1 +#define NV_INTEGRATOR_RESYNC_OPTION_LENGTH 1 +#define NV_INTEGRATOR_RESYNC_OPTION_MASK 0x0002 + +#define NV_INTEGRATOR_EDGE_INV_ADDRESS 0x0840 +#define NV_INTEGRATOR_EDGE_INV_OFFSET 0 +#define NV_INTEGRATOR_EDGE_INV_LENGTH 1 +#define NV_INTEGRATOR_EDGE_INV_MASK 0x0001 + +#define NV_ZONE0_RES1_ADDRESS 0x083E +#define NV_ZONE0_RES1_OFFSET 0 +#define NV_ZONE0_RES1_LENGTH 16 +#define NV_ZONE0_RES1_MASK 0xFFFF + +#define NV_ZONE0_RES2_ADDRESS 0x083C +#define NV_ZONE0_RES2_OFFSET 0 +#define NV_ZONE0_RES2_LENGTH 16 +#define NV_ZONE0_RES2_MASK 0xFFFF + +#define NV_ZONE0_RES3_ADDRESS 0x083A +#define NV_ZONE0_RES3_OFFSET 0 +#define NV_ZONE0_RES3_LENGTH 16 +#define NV_ZONE0_RES3_MASK 0xFFFF + +#define NV_ZONE0_RES4_ADDRESS 0x0838 +#define NV_ZONE0_RES4_OFFSET 0 +#define NV_ZONE0_RES4_LENGTH 16 +#define NV_ZONE0_RES4_MASK 0xFFFF + +#define NV_TARGET_CLIM_USER_PULSES_ADDRESS 0x0836 +#define NV_TARGET_CLIM_USER_PULSES_OFFSET 0 +#define NV_TARGET_CLIM_USER_PULSES_LENGTH 8 +#define NV_TARGET_CLIM_USER_PULSES_MASK 0x00FF + +#define NV_TARGET_CLIM_USER_BRAKE_ADDRESS 0x0834 +#define NV_TARGET_CLIM_USER_BRAKE_OFFSET 8 +#define NV_TARGET_CLIM_USER_BRAKE_LENGTH 8 +#define NV_TARGET_CLIM_USER_BRAKE_MASK 0xFF00 + +#define NV_TARGET_CLIM_USER_MOTOR_ADDRESS 0x0834 +#define NV_TARGET_CLIM_USER_MOTOR_OFFSET 0 +#define NV_TARGET_CLIM_USER_MOTOR_LENGTH 8 +#define NV_TARGET_CLIM_USER_MOTOR_MASK 0x00FF + +#define NV_CL_BLANK_SELECT_ADDRESS 0x0832 +#define NV_CL_BLANK_SELECT_OFFSET 8 +#define NV_CL_BLANK_SELECT_LENGTH 6 +#define NV_CL_BLANK_SELECT_MASK 0x3F00 + +#define NV_OC_BLANK_SELECT_ADDRESS 0x0832 +#define NV_OC_BLANK_SELECT_OFFSET 0 +#define NV_OC_BLANK_SELECT_LENGTH 6 +#define NV_OC_BLANK_SELECT_MASK 0x003F + +#define NV_DI_TH_1ST_ADDRESS 0x0830 +#define NV_DI_TH_1ST_OFFSET 0 +#define NV_DI_TH_1ST_LENGTH 12 +#define NV_DI_TH_1ST_MASK 0x0FFF + +#define NV_DI_TH_2ND_ADDRESS 0x082E +#define NV_DI_TH_2ND_OFFSET 0 +#define NV_DI_TH_2ND_LENGTH 12 +#define NV_DI_TH_2ND_MASK 0x0FFF + +#define NV_I_ZC_TH_HIGH_ADDRESS 0x082C +#define NV_I_ZC_TH_HIGH_OFFSET 0 +#define NV_I_ZC_TH_HIGH_LENGTH 12 +#define NV_I_ZC_TH_HIGH_MASK 0x0FFF + +#define NV_I_ZC_TH_LOW_ADDRESS 0x082A +#define NV_I_ZC_TH_LOW_OFFSET 0 +#define NV_I_ZC_TH_LOW_LENGTH 12 +#define NV_I_ZC_TH_LOW_MASK 0x0FFF + +#define NV_RPM_F_ADDRESS 0x0828 +#define NV_RPM_F_OFFSET 7 +#define NV_RPM_F_LENGTH 9 +#define NV_RPM_F_MASK 0xFF80 + +#define NV_SPD_F_ADDRESS 0x0828 +#define NV_SPD_F_OFFSET 0 +#define NV_SPD_F_LENGTH 7 +#define NV_SPD_F_MASK 0x007F + +#define NV_RPM_E_ADDRESS 0x0826 +#define NV_RPM_E_OFFSET 7 +#define NV_RPM_E_LENGTH 9 +#define NV_RPM_E_MASK 0xFF80 + +#define NV_SPD_E_ADDRESS 0x0826 +#define NV_SPD_E_OFFSET 0 +#define NV_SPD_E_LENGTH 7 +#define NV_SPD_E_MASK 0x007F + +#define NV_RPM_D_ADDRESS 0x0824 +#define NV_RPM_D_OFFSET 7 +#define NV_RPM_D_LENGTH 9 +#define NV_RPM_D_MASK 0xFF80 + +#define NV_SPD_D_ADDRESS 0x0824 +#define NV_SPD_D_OFFSET 0 +#define NV_SPD_D_LENGTH 7 +#define NV_SPD_D_MASK 0x007F + +#define NV_RPM_C_ADDRESS 0x0822 +#define NV_RPM_C_OFFSET 7 +#define NV_RPM_C_LENGTH 9 +#define NV_RPM_C_MASK 0xFF80 + +#define NV_SPD_C_ADDRESS 0x0822 +#define NV_SPD_C_OFFSET 0 +#define NV_SPD_C_LENGTH 7 +#define NV_SPD_C_MASK 0x007F + +#define NV_RPM_B_ADDRESS 0x0820 +#define NV_RPM_B_OFFSET 7 +#define NV_RPM_B_LENGTH 9 +#define NV_RPM_B_MASK 0xFF80 + +#define NV_SPD_B_ADDRESS 0x0820 +#define NV_SPD_B_OFFSET 0 +#define NV_SPD_B_LENGTH 7 +#define NV_SPD_B_MASK 0x007F + +#define NV_RPM_A_ADDRESS 0x081E +#define NV_RPM_A_OFFSET 7 +#define NV_RPM_A_LENGTH 9 +#define NV_RPM_A_MASK 0xFF80 + +#define NV_SPD_A_ADDRESS 0x081E +#define NV_SPD_A_OFFSET 0 +#define NV_SPD_A_LENGTH 7 +#define NV_SPD_A_MASK 0x007F + +#define NV_RPM_MAX_ADDRESS 0x081C +#define NV_RPM_MAX_OFFSET 7 +#define NV_RPM_MAX_LENGTH 9 +#define NV_RPM_MAX_MASK 0xFF80 + +#define NV_SPD_MAX_ADDRESS 0x081C +#define NV_SPD_MAX_OFFSET 0 +#define NV_SPD_MAX_LENGTH 7 +#define NV_SPD_MAX_MASK 0x007F + +#define NV_RPM_MIN_ADDRESS 0x081A +#define NV_RPM_MIN_OFFSET 7 +#define NV_RPM_MIN_LENGTH 9 +#define NV_RPM_MIN_MASK 0xFF80 + +#define NV_SPD_MIN_ADDRESS 0x081A +#define NV_SPD_MIN_OFFSET 0 +#define NV_SPD_MIN_LENGTH 7 +#define NV_SPD_MIN_MASK 0x007F + +#define NV_DUTY_RAMPING_ADDRESS 0x0818 +#define NV_DUTY_RAMPING_OFFSET 15 +#define NV_DUTY_RAMPING_LENGTH 1 +#define NV_DUTY_RAMPING_MASK 0x8000 + +#define NV_ILIM_RAMPING_ADDRESS 0x0818 +#define NV_ILIM_RAMPING_OFFSET 14 +#define NV_ILIM_RAMPING_LENGTH 1 +#define NV_ILIM_RAMPING_MASK 0x4000 + +#define NV_DC_OPENLOOP_SR_ADDRESS 0x0818 +#define NV_DC_OPENLOOP_SR_OFFSET 12 +#define NV_DC_OPENLOOP_SR_LENGTH 2 +#define NV_DC_OPENLOOP_SR_MASK 0x3000 + +#define NV_DC_OPENLOOP_INI_ADDRESS 0x0818 +#define NV_DC_OPENLOOP_INI_OFFSET 10 +#define NV_DC_OPENLOOP_INI_LENGTH 2 +#define NV_DC_OPENLOOP_INI_MASK 0x0C00 + +#define NV_SPD_KI_ADDRESS 0x0818 +#define NV_SPD_KI_OFFSET 7 +#define NV_SPD_KI_LENGTH 3 +#define NV_SPD_KI_MASK 0x0380 + +#define NV_SPD_KP_ADDRESS 0x0818 +#define NV_SPD_KP_OFFSET 4 +#define NV_SPD_KP_LENGTH 3 +#define NV_SPD_KP_MASK 0x0070 + +#define NV_SPD_HC_HYST_ADDRESS 0x0818 +#define NV_SPD_HC_HYST_OFFSET 2 +#define NV_SPD_HC_HYST_LENGTH 2 +#define NV_SPD_HC_HYST_MASK 0x000C + +#define NV_SPD_LC_HYST_ADDRESS 0x0818 +#define NV_SPD_LC_HYST_OFFSET 0 +#define NV_SPD_LC_HYST_LENGTH 2 +#define NV_SPD_LC_HYST_MASK 0x0003 + +#define NV_SPD_BOOST_ADDRESS 0x0816 +#define NV_SPD_BOOST_OFFSET 13 +#define NV_SPD_BOOST_LENGTH 1 +#define NV_SPD_BOOST_MASK 0x2000 + +#define NV_SPD_BOOST_SS_ADDRESS 0x0816 +#define NV_SPD_BOOST_SS_OFFSET 12 +#define NV_SPD_BOOST_SS_LENGTH 1 +#define NV_SPD_BOOST_SS_MASK 0x1000 + +#define NV_SPD_CTRL_1_RESERVED_ADDRESS 0x0816 +#define NV_SPD_CTRL_1_RESERVED_OFFSET 11 +#define NV_SPD_CTRL_1_RESERVED_LENGTH 1 +#define NV_SPD_CTRL_1_RESERVED_MASK 0x0800 + +#define NV_SPD_LOOP_MODE_ADDRESS 0x0816 +#define NV_SPD_LOOP_MODE_OFFSET 10 +#define NV_SPD_LOOP_MODE_LENGTH 1 +#define NV_SPD_LOOP_MODE_MASK 0x0400 + +#define NV_RPM_LC_ADDRESS 0x0816 +#define NV_RPM_LC_OFFSET 9 +#define NV_RPM_LC_LENGTH 1 +#define NV_RPM_LC_MASK 0x0200 + +#define NV_RPM_HC_ADDRESS 0x0816 +#define NV_RPM_HC_OFFSET 8 +#define NV_RPM_HC_LENGTH 1 +#define NV_RPM_HC_MASK 0x0100 + +#define NV_SPD_LC_VAL_ADDRESS 0x0816 +#define NV_SPD_LC_VAL_OFFSET 6 +#define NV_SPD_LC_VAL_LENGTH 2 +#define NV_SPD_LC_VAL_MASK 0x00C0 + +#define NV_SPD_HC_VAL_ADDRESS 0x0816 +#define NV_SPD_HC_VAL_OFFSET 4 +#define NV_SPD_HC_VAL_LENGTH 2 +#define NV_SPD_HC_VAL_MASK 0x0030 + +#define NV_CURVE_MODE_ADDRESS 0x0816 +#define NV_CURVE_MODE_OFFSET 2 +#define NV_CURVE_MODE_LENGTH 2 +#define NV_CURVE_MODE_MASK 0x000C + +#define NV_SPD_TICK_ADDRESS 0x0816 +#define NV_SPD_TICK_OFFSET 0 +#define NV_SPD_TICK_LENGTH 2 +#define NV_SPD_TICK_MASK 0x0003 + +#define NV_MIN_EHP_RESERVED_ADDRESS 0x0814 +#define NV_MIN_EHP_RESERVED_OFFSET 15 +#define NV_MIN_EHP_RESERVED_LENGTH 1 +#define NV_MIN_EHP_RESERVED_MASK 0x8000 + +#define NV_EHP_TIMER_PRESCALER_ADDRESS 0x0814 +#define NV_EHP_TIMER_PRESCALER_OFFSET 13 +#define NV_EHP_TIMER_PRESCALER_LENGTH 2 +#define NV_EHP_TIMER_PRESCALER_MASK 0x6000 + +#define NV_EHP_FULL_RANGE_ADDRESS 0x0814 +#define NV_EHP_FULL_RANGE_OFFSET 0 +#define NV_EHP_FULL_RANGE_LENGTH 13 +#define NV_EHP_FULL_RANGE_MASK 0x1FFF + +#define NV_POSITION_FLAT_TIME_ADDRESS 0x0812 +#define NV_POSITION_FLAT_TIME_OFFSET 6 +#define NV_POSITION_FLAT_TIME_LENGTH 5 +#define NV_POSITION_FLAT_TIME_MASK 0x07C0 + +#define NV_START_UP_FLAT_TIME_ADDRESS 0x0812 +#define NV_START_UP_FLAT_TIME_OFFSET 0 +#define NV_START_UP_FLAT_TIME_LENGTH 6 +#define NV_START_UP_FLAT_TIME_MASK 0x003F + +#define NV_BEMF_SMALL_THRES_ADDRESS 0x0810 +#define NV_BEMF_SMALL_THRES_OFFSET 0 +#define NV_BEMF_SMALL_THRES_LENGTH 4 +#define NV_BEMF_SMALL_THRES_MASK 0x000F + +#define NV_QUICK_START_ADDRESS 0x080E +#define NV_QUICK_START_OFFSET 15 +#define NV_QUICK_START_LENGTH 1 +#define NV_QUICK_START_MASK 0x8000 + +#define NV_WIND_START_ADDRESS 0x080E +#define NV_WIND_START_OFFSET 14 +#define NV_WIND_START_LENGTH 1 +#define NV_WIND_START_MASK 0x4000 + +#define NV_SOFT_NUM_STEP_ADDRESS 0x080E +#define NV_SOFT_NUM_STEP_OFFSET 8 +#define NV_SOFT_NUM_STEP_LENGTH 3 +#define NV_SOFT_NUM_STEP_MASK 0x0700 + +#define NV_WIND_WINDOW_ADDRESS 0x080E +#define NV_WIND_WINDOW_OFFSET 4 +#define NV_WIND_WINDOW_LENGTH 4 +#define NV_WIND_WINDOW_MASK 0x00F0 + +#define NV_BRAKE_WINDOW_ADDRESS 0x080E +#define NV_BRAKE_WINDOW_OFFSET 0 +#define NV_BRAKE_WINDOW_LENGTH 4 +#define NV_BRAKE_WINDOW_MASK 0x000F + +#define NV_SINGLE_PULSE_START_ADDRESS 0x080C +#define NV_SINGLE_PULSE_START_OFFSET 15 +#define NV_SINGLE_PULSE_START_LENGTH 1 +#define NV_SINGLE_PULSE_START_MASK 0x8000 + +#define NV_LONG_START_ADDRESS 0x080C +#define NV_LONG_START_OFFSET 14 +#define NV_LONG_START_LENGTH 1 +#define NV_LONG_START_MASK 0x4000 + +#define NV_SOFT_START_ADDRESS 0x080C +#define NV_SOFT_START_OFFSET 13 +#define NV_SOFT_START_LENGTH 1 +#define NV_SOFT_START_MASK 0x2000 + +#define NV_COMM_START_NUM_ADDRESS 0x080C +#define NV_COMM_START_NUM_OFFSET 11 +#define NV_COMM_START_NUM_LENGTH 2 +#define NV_COMM_START_NUM_MASK 0x1800 + +#define NV_START_DUTY_ADDRESS 0x080C +#define NV_START_DUTY_OFFSET 9 +#define NV_START_DUTY_LENGTH 2 +#define NV_START_DUTY_MASK 0x0600 + +#define NV_SOFT_STEP_SIZE_ADDRESS 0x080C +#define NV_SOFT_STEP_SIZE_OFFSET 6 +#define NV_SOFT_STEP_SIZE_LENGTH 3 +#define NV_SOFT_STEP_SIZE_MASK 0x01C0 + +#define NV_START_UP_TIME_ADDRESS 0x080C +#define NV_START_UP_TIME_OFFSET 0 +#define NV_START_UP_TIME_LENGTH 6 +#define NV_START_UP_TIME_MASK 0x003F + +#define NV_POSITION_DUTY_ADDRESS 0x080A +#define NV_POSITION_DUTY_OFFSET 14 +#define NV_POSITION_DUTY_LENGTH 2 +#define NV_POSITION_DUTY_MASK 0xC000 + +#define NV_POSITION_PULSE_TIME_ADDRESS 0x080A +#define NV_POSITION_PULSE_TIME_OFFSET 9 +#define NV_POSITION_PULSE_TIME_LENGTH 5 +#define NV_POSITION_PULSE_TIME_MASK 0x3E00 + +#define NV_POSI_MAJO_VOTE_ADDRESS 0x080A +#define NV_POSI_MAJO_VOTE_OFFSET 8 +#define NV_POSI_MAJO_VOTE_LENGTH 1 +#define NV_POSI_MAJO_VOTE_MASK 0x0100 + +#define NV_ANTI_COG_ADDRESS 0x080A +#define NV_ANTI_COG_OFFSET 7 +#define NV_ANTI_COG_LENGTH 1 +#define NV_ANTI_COG_MASK 0x0080 + +#define NV_POSITION_RESERVED_ADDRESS 0x080A +#define NV_POSITION_RESERVED_OFFSET 6 +#define NV_POSITION_RESERVED_LENGTH 1 +#define NV_POSITION_RESERVED_MASK 0x0040 + +#define NV_FIRST_NON_FLAT_TIME_ADDRESS 0x080A +#define NV_FIRST_NON_FLAT_TIME_OFFSET 0 +#define NV_FIRST_NON_FLAT_TIME_LENGTH 6 +#define NV_FIRST_NON_FLAT_TIME_MASK 0x003F + +#define NV_ROUGH_REG_ADDRESS 0x0808 +#define NV_ROUGH_REG_OFFSET 14 +#define NV_ROUGH_REG_LENGTH 1 +#define NV_ROUGH_REG_MASK 0x4000 + +#define NV_ADC_FLAT_FILT_DEP_ADDRESS 0x0808 +#define NV_ADC_FLAT_FILT_DEP_OFFSET 12 +#define NV_ADC_FLAT_FILT_DEP_LENGTH 2 +#define NV_ADC_FLAT_FILT_DEP_MASK 0x3000 + +#define NV_EHP_REG_GAIN_ADDRESS 0x0808 +#define NV_EHP_REG_GAIN_OFFSET 10 +#define NV_EHP_REG_GAIN_LENGTH 2 +#define NV_EHP_REG_GAIN_MASK 0x0C00 + +#define NV_ROUGH_GAIN_ADDRESS 0x0808 +#define NV_ROUGH_GAIN_OFFSET 9 +#define NV_ROUGH_GAIN_LENGTH 1 +#define NV_ROUGH_GAIN_MASK 0x0200 + +#define NV_PWM_MOD_ADDRESS 0x0808 +#define NV_PWM_MOD_OFFSET 8 +#define NV_PWM_MOD_LENGTH 1 +#define NV_PWM_MOD_MASK 0x0100 + +#define NV_PWM_50K_ADDRESS 0x0808 +#define NV_PWM_50K_OFFSET 7 +#define NV_PWM_50K_LENGTH 1 +#define NV_PWM_50K_MASK 0x0080 + +#define NV_SS_RISE_MODE_ADDRESS 0x0808 +#define NV_SS_RISE_MODE_OFFSET 3 +#define NV_SS_RISE_MODE_LENGTH 3 +#define NV_SS_RISE_MODE_MASK 0x0038 + +#define NV_SS_FALL_MODE_ADDRESS 0x0808 +#define NV_SS_FALL_MODE_OFFSET 0 +#define NV_SS_FALL_MODE_LENGTH 3 +#define NV_SS_FALL_MODE_MASK 0x0007 + +#define NV_FG_SLOPECTRL_ADDRESS 0x0804 +#define NV_FG_SLOPECTRL_OFFSET 14 +#define NV_FG_SLOPECTRL_LENGTH 2 +#define NV_FG_SLOPECTRL_MASK 0xC000 + +#define NV_LVIO_SLOPECTRL_ADDRESS 0x0804 +#define NV_LVIO_SLOPECTRL_OFFSET 12 +#define NV_LVIO_SLOPECTRL_LENGTH 2 +#define NV_LVIO_SLOPECTRL_MASK 0x3000 + +#define NV_HVIO_SLOPECTRL_ADDRESS 0x0804 +#define NV_HVIO_SLOPECTRL_OFFSET 10 +#define NV_HVIO_SLOPECTRL_LENGTH 2 +#define NV_HVIO_SLOPECTRL_MASK 0x0C00 + +#define NV_I2C_SLAVE_ADDRESS_ADDRESS 0x0804 +#define NV_I2C_SLAVE_ADDRESS_OFFSET 0 +#define NV_I2C_SLAVE_ADDRESS_LENGTH 7 +#define NV_I2C_SLAVE_ADDRESS_MASK 0x007F + +#define NV_I2C_DEBUGGING_DISABLED_ADDRESS 0x0802 +#define NV_I2C_DEBUGGING_DISABLED_OFFSET 15 +#define NV_I2C_DEBUGGING_DISABLED_LENGTH 1 +#define NV_I2C_DEBUGGING_DISABLED_MASK 0x8000 + +#define NV_I2C_TOGGLE_ENTRY_ADDRESS 0x0802 +#define NV_I2C_TOGGLE_ENTRY_OFFSET 14 +#define NV_I2C_TOGGLE_ENTRY_LENGTH 1 +#define NV_I2C_TOGGLE_ENTRY_MASK 0x4000 + +#define NV_HVIO_PU_PD_CFG_ADDRESS 0x0802 +#define NV_HVIO_PU_PD_CFG_OFFSET 12 +#define NV_HVIO_PU_PD_CFG_LENGTH 2 +#define NV_HVIO_PU_PD_CFG_MASK 0x3000 + +#define NV_LVIO_PU_PD_CFG_ADDRESS 0x0802 +#define NV_LVIO_PU_PD_CFG_OFFSET 10 +#define NV_LVIO_PU_PD_CFG_LENGTH 2 +#define NV_LVIO_PU_PD_CFG_MASK 0x0C00 + +#define NV_PWM_PU_PD_CFG_ADDRESS 0x0802 +#define NV_PWM_PU_PD_CFG_OFFSET 8 +#define NV_PWM_PU_PD_CFG_LENGTH 2 +#define NV_PWM_PU_PD_CFG_MASK 0x0300 + +#define NV_SLEEP_MODE_ENABLED_ADDRESS 0x0802 +#define NV_SLEEP_MODE_ENABLED_OFFSET 7 +#define NV_SLEEP_MODE_ENABLED_LENGTH 1 +#define NV_SLEEP_MODE_ENABLED_MASK 0x0080 + +#define NV_SLEEP_MODE_POLARITY_ADDRESS 0x0802 +#define NV_SLEEP_MODE_POLARITY_OFFSET 6 +#define NV_SLEEP_MODE_POLARITY_LENGTH 1 +#define NV_SLEEP_MODE_POLARITY_MASK 0x0040 + +#define NV_DIAG_MODE_CFG_ADDRESS 0x0802 +#define NV_DIAG_MODE_CFG_OFFSET 4 +#define NV_DIAG_MODE_CFG_LENGTH 2 +#define NV_DIAG_MODE_CFG_MASK 0x0030 + +#define NV_FG_FILTERED_ADDRESS 0x0802 +#define NV_FG_FILTERED_OFFSET 3 +#define NV_FG_FILTERED_LENGTH 1 +#define NV_FG_FILTERED_MASK 0x0008 + +#define NV_FG_SPEED_ADDRESS 0x0802 +#define NV_FG_SPEED_OFFSET 0 +#define NV_FG_SPEED_LENGTH 3 +#define NV_FG_SPEED_MASK 0x0007 + +#define NV_FG_RD_ACTIVE_STATE_ADDRESS 0x0800 +#define NV_FG_RD_ACTIVE_STATE_OFFSET 13 +#define NV_FG_RD_ACTIVE_STATE_LENGTH 1 +#define NV_FG_RD_ACTIVE_STATE_MASK 0x2000 + +#define NV_FG_RD_INIT_LOW_ADDRESS 0x0800 +#define NV_FG_RD_INIT_LOW_OFFSET 12 +#define NV_FG_RD_INIT_LOW_LENGTH 1 +#define NV_FG_RD_INIT_LOW_MASK 0x1000 + +#define NV_SELECT_RD_FGB_ADDRESS 0x0800 +#define NV_SELECT_RD_FGB_OFFSET 11 +#define NV_SELECT_RD_FGB_LENGTH 1 +#define NV_SELECT_RD_FGB_MASK 0x0800 + +#define NV_HVIO_MODE_CFG_ADDRESS 0x0800 +#define NV_HVIO_MODE_CFG_OFFSET 8 +#define NV_HVIO_MODE_CFG_LENGTH 3 +#define NV_HVIO_MODE_CFG_MASK 0x0700 + +#define NV_LVIO_MODE_CFG_ADDRESS 0x0800 +#define NV_LVIO_MODE_CFG_OFFSET 5 +#define NV_LVIO_MODE_CFG_LENGTH 3 +#define NV_LVIO_MODE_CFG_MASK 0x00E0 + +#define NV_FG_MODE_CFG_ADDRESS 0x0800 +#define NV_FG_MODE_CFG_OFFSET 3 +#define NV_FG_MODE_CFG_LENGTH 2 +#define NV_FG_MODE_CFG_MASK 0x0018 + +#define NV_INPUT_MODE_CFG_ADDRESS 0x0800 +#define NV_INPUT_MODE_CFG_OFFSET 0 +#define NV_INPUT_MODE_CFG_LENGTH 3 +#define NV_INPUT_MODE_CFG_MASK 0x0007 + +#define RAM_PATCH_TRIM_0_ADDRESS 0x11E0 +#define RAM_PATCH_TRIM_0_OFFSET 0 +#define RAM_PATCH_TRIM_0_LENGTH 16 +#define RAM_PATCH_TRIM_0_MASK 0xFFFF + +#define CRC_PATCH_3_ADDRESS 0x1096 +#define CRC_PATCH_3_OFFSET 8 +#define CRC_PATCH_3_LENGTH 8 +#define CRC_PATCH_3_MASK 0xFF00 + +#define CRC_PATCH_2_ADDRESS 0x1096 +#define CRC_PATCH_2_OFFSET 0 +#define CRC_PATCH_2_LENGTH 8 +#define CRC_PATCH_2_MASK 0x00FF + +#define CRC_PATCH_1_ADDRESS 0x1094 +#define CRC_PATCH_1_OFFSET 8 +#define CRC_PATCH_1_LENGTH 8 +#define CRC_PATCH_1_MASK 0xFF00 + +#define CRC_PATCH_0_ADDRESS 0x1094 +#define CRC_PATCH_0_OFFSET 0 +#define CRC_PATCH_0_LENGTH 8 +#define CRC_PATCH_0_MASK 0x00FF + +#define CRC_MLX_CALIBRATION_ADDRESS 0x1092 +#define CRC_MLX_CALIBRATION_OFFSET 8 +#define CRC_MLX_CALIBRATION_LENGTH 8 +#define CRC_MLX_CALIBRATION_MASK 0xFF00 + +#define MLX_CALIB_22_ADDRESS 0x1090 +#define MLX_CALIB_22_OFFSET 0 +#define MLX_CALIB_22_LENGTH 16 +#define MLX_CALIB_22_MASK 0xFFFF + +#define MLX_CALIB_21_ADDRESS 0x108E +#define MLX_CALIB_21_OFFSET 0 +#define MLX_CALIB_21_LENGTH 16 +#define MLX_CALIB_21_MASK 0xFFFF + +#define MLX_CALIB_20_ADDRESS 0x108C +#define MLX_CALIB_20_OFFSET 0 +#define MLX_CALIB_20_LENGTH 16 +#define MLX_CALIB_20_MASK 0xFFFF + +#define MLX_CALIB_19_ADDRESS 0x108A +#define MLX_CALIB_19_OFFSET 0 +#define MLX_CALIB_19_LENGTH 16 +#define MLX_CALIB_19_MASK 0xFFFF + +#define MLX_CALIB_18_ADDRESS 0x1088 +#define MLX_CALIB_18_OFFSET 0 +#define MLX_CALIB_18_LENGTH 16 +#define MLX_CALIB_18_MASK 0xFFFF + +#define MLX_CALIB_17_ADDRESS 0x1086 +#define MLX_CALIB_17_OFFSET 0 +#define MLX_CALIB_17_LENGTH 16 +#define MLX_CALIB_17_MASK 0xFFFF + +#define MLX_CALIB_16_ADDRESS 0x1084 +#define MLX_CALIB_16_OFFSET 0 +#define MLX_CALIB_16_LENGTH 16 +#define MLX_CALIB_16_MASK 0xFFFF + +#define MLX_CALIB_15_ADDRESS 0x1082 +#define MLX_CALIB_15_OFFSET 0 +#define MLX_CALIB_15_LENGTH 16 +#define MLX_CALIB_15_MASK 0xFFFF + +#define MLX_CALIB_14_ADDRESS 0x1080 +#define MLX_CALIB_14_OFFSET 0 +#define MLX_CALIB_14_LENGTH 16 +#define MLX_CALIB_14_MASK 0xFFFF + +#define MLX_CALIB_13_ADDRESS 0x107E +#define MLX_CALIB_13_OFFSET 0 +#define MLX_CALIB_13_LENGTH 16 +#define MLX_CALIB_13_MASK 0xFFFF + +#define MLX_CALIB_12_ADDRESS 0x107C +#define MLX_CALIB_12_OFFSET 0 +#define MLX_CALIB_12_LENGTH 16 +#define MLX_CALIB_12_MASK 0xFFFF + +#define MLX_CALIB_11_ADDRESS 0x107A +#define MLX_CALIB_11_OFFSET 0 +#define MLX_CALIB_11_LENGTH 16 +#define MLX_CALIB_11_MASK 0xFFFF + +#define MLX_CALIB_10_ADDRESS 0x1078 +#define MLX_CALIB_10_OFFSET 0 +#define MLX_CALIB_10_LENGTH 16 +#define MLX_CALIB_10_MASK 0xFFFF + +#define MLX_CALIB_9_ADDRESS 0x1076 +#define MLX_CALIB_9_OFFSET 0 +#define MLX_CALIB_9_LENGTH 16 +#define MLX_CALIB_9_MASK 0xFFFF + +#define MLX_CALIB_8_ADDRESS 0x1074 +#define MLX_CALIB_8_OFFSET 0 +#define MLX_CALIB_8_LENGTH 16 +#define MLX_CALIB_8_MASK 0xFFFF + +#define MLX_CALIB_7_ADDRESS 0x1072 +#define MLX_CALIB_7_OFFSET 0 +#define MLX_CALIB_7_LENGTH 16 +#define MLX_CALIB_7_MASK 0xFFFF + +#define MLX_CALIB_7_BEMF_GAIN_ADDRESS 0x1072 +#define MLX_CALIB_7_BEMF_GAIN_OFFSET 7 +#define MLX_CALIB_7_BEMF_GAIN_LENGTH 9 +#define MLX_CALIB_7_BEMF_GAIN_MASK 0xFF80 + +#define MLX_CALIB_7_BEMF_OFFSET_ADDRESS 0x1072 +#define MLX_CALIB_7_BEMF_OFFSET_OFFSET 0 +#define MLX_CALIB_7_BEMF_OFFSET_LENGTH 7 +#define MLX_CALIB_7_BEMF_OFFSET_MASK 0x007F + +#define MLX_CALIB_6_ADDRESS 0x1070 +#define MLX_CALIB_6_OFFSET 0 +#define MLX_CALIB_6_LENGTH 16 +#define MLX_CALIB_6_MASK 0xFFFF + +#define MLX_CALIB_5_ADDRESS 0x106E +#define MLX_CALIB_5_OFFSET 0 +#define MLX_CALIB_5_LENGTH 16 +#define MLX_CALIB_5_MASK 0xFFFF + +#define MLX_CALIB_4_ADDRESS 0x106C +#define MLX_CALIB_4_OFFSET 0 +#define MLX_CALIB_4_LENGTH 16 +#define MLX_CALIB_4_MASK 0xFFFF + +#define MLX_CALIB_3_ADDRESS 0x106A +#define MLX_CALIB_3_OFFSET 0 +#define MLX_CALIB_3_LENGTH 16 +#define MLX_CALIB_3_MASK 0xFFFF + +#define MLX_CALIB_2_ADDRESS 0x1068 +#define MLX_CALIB_2_OFFSET 0 +#define MLX_CALIB_2_LENGTH 16 +#define MLX_CALIB_2_MASK 0xFFFF + +#define MAX_CLIM_USER_ADDRESS 0x1066 +#define MAX_CLIM_USER_OFFSET 0 +#define MAX_CLIM_USER_LENGTH 8 +#define MAX_CLIM_USER_MASK 0x00FF + +#define CLIM_GAIN_ADDRESS 0x1064 +#define CLIM_GAIN_OFFSET 8 +#define CLIM_GAIN_LENGTH 8 +#define CLIM_GAIN_MASK 0xFF00 + +#define CLIM_OFFSET_ADDRESS 0x1064 +#define CLIM_OFFSET_OFFSET 0 +#define CLIM_OFFSET_LENGTH 8 +#define CLIM_OFFSET_MASK 0x00FF + +#define CMD_INTERPRETER_DATA_ADDRESS 0x1062 +#define CMD_INTERPRETER_DATA_OFFSET 0 +#define CMD_INTERPRETER_DATA_LENGTH 16 +#define CMD_INTERPRETER_DATA_MASK 0xFFFF + +#define CMD_INTERPRETER_ADDRESS_ADDRESS 0x1060 +#define CMD_INTERPRETER_ADDRESS_OFFSET 0 +#define CMD_INTERPRETER_ADDRESS_LENGTH 16 +#define CMD_INTERPRETER_ADDRESS_MASK 0xFFFF + +#define MLX_CALIB_RECALL_ADDRESS 0x105E +#define MLX_CALIB_RECALL_OFFSET 0 +#define MLX_CALIB_RECALL_LENGTH 4 +#define MLX_CALIB_RECALL_MASK 0x000F + +#define PATCH_EXT_RECALL_ADDRESS 0x105C +#define PATCH_EXT_RECALL_OFFSET 12 +#define PATCH_EXT_RECALL_LENGTH 4 +#define PATCH_EXT_RECALL_MASK 0xF000 + +#define APP_TRIM_RECALL_ADDRESS 0x105C +#define APP_TRIM_RECALL_OFFSET 8 +#define APP_TRIM_RECALL_LENGTH 4 +#define APP_TRIM_RECALL_MASK 0x0F00 + +#define TRIM_SOURCE_ADDRESS 0x105C +#define TRIM_SOURCE_OFFSET 4 +#define TRIM_SOURCE_LENGTH 4 +#define TRIM_SOURCE_MASK 0x00F0 + +#define PATCH_SOURCE_ADDRESS 0x105C +#define PATCH_SOURCE_OFFSET 0 +#define PATCH_SOURCE_LENGTH 4 +#define PATCH_SOURCE_MASK 0x000F + +#define MTP_USE_ZONE_0_ADDRESS 0x105A +#define MTP_USE_ZONE_0_OFFSET 8 +#define MTP_USE_ZONE_0_LENGTH 8 +#define MTP_USE_ZONE_0_MASK 0xFF00 + +#define CRC_MTP_ZONE_0_ADDRESS 0x105A +#define CRC_MTP_ZONE_0_OFFSET 0 +#define CRC_MTP_ZONE_0_LENGTH 8 +#define CRC_MTP_ZONE_0_MASK 0x00FF + +#define CUST_ID0_ADDRESS 0x1058 +#define CUST_ID0_OFFSET 0 +#define CUST_ID0_LENGTH 16 +#define CUST_ID0_MASK 0xFFFF + +#define CUST_ID1_ADDRESS 0x1056 +#define CUST_ID1_OFFSET 0 +#define CUST_ID1_LENGTH 16 +#define CUST_ID1_MASK 0xFFFF + +#define CUST_ID2_ADDRESS 0x1054 +#define CUST_ID2_OFFSET 0 +#define CUST_ID2_LENGTH 16 +#define CUST_ID2_MASK 0xFFFF + +#define CUST_ID3_ADDRESS 0x1052 +#define CUST_ID3_OFFSET 0 +#define CUST_ID3_LENGTH 16 +#define CUST_ID3_MASK 0xFFFF + +#define FLAT_BLANK_ADDRESS 0x1050 +#define FLAT_BLANK_OFFSET 8 +#define FLAT_BLANK_LENGTH 8 +#define FLAT_BLANK_MASK 0xFF00 + +#define INTEGRATOR_PRE_DIV_ADDRESS 0x1050 +#define INTEGRATOR_PRE_DIV_OFFSET 5 +#define INTEGRATOR_PRE_DIV_LENGTH 2 +#define INTEGRATOR_PRE_DIV_MASK 0x0060 + +#define INTEGRATOR_TIME_ADDRESS 0x1050 +#define INTEGRATOR_TIME_OFFSET 3 +#define INTEGRATOR_TIME_LENGTH 2 +#define INTEGRATOR_TIME_MASK 0x0018 + +#define INTEGRATOR_START_OPTION_ADDRESS 0x1050 +#define INTEGRATOR_START_OPTION_OFFSET 2 +#define INTEGRATOR_START_OPTION_LENGTH 1 +#define INTEGRATOR_START_OPTION_MASK 0x0004 + +#define INTEGRATOR_RESYNC_OPTION_ADDRESS 0x1050 +#define INTEGRATOR_RESYNC_OPTION_OFFSET 1 +#define INTEGRATOR_RESYNC_OPTION_LENGTH 1 +#define INTEGRATOR_RESYNC_OPTION_MASK 0x0002 + +#define INTEGRATOR_EDGE_INV_ADDRESS 0x1050 +#define INTEGRATOR_EDGE_INV_OFFSET 0 +#define INTEGRATOR_EDGE_INV_LENGTH 1 +#define INTEGRATOR_EDGE_INV_MASK 0x0001 + +#define ZONE0_RES1_ADDRESS 0x104E +#define ZONE0_RES1_OFFSET 0 +#define ZONE0_RES1_LENGTH 16 +#define ZONE0_RES1_MASK 0xFFFF + +#define ZONE0_RES2_ADDRESS 0x104C +#define ZONE0_RES2_OFFSET 0 +#define ZONE0_RES2_LENGTH 16 +#define ZONE0_RES2_MASK 0xFFFF + +#define ZONE0_RES3_ADDRESS 0x104A +#define ZONE0_RES3_OFFSET 0 +#define ZONE0_RES3_LENGTH 16 +#define ZONE0_RES3_MASK 0xFFFF + +#define ZONE0_RES4_ADDRESS 0x1048 +#define ZONE0_RES4_OFFSET 0 +#define ZONE0_RES4_LENGTH 16 +#define ZONE0_RES4_MASK 0xFFFF + +#define TARGET_CLIM_USER_PULSES_ADDRESS 0x1046 +#define TARGET_CLIM_USER_PULSES_OFFSET 0 +#define TARGET_CLIM_USER_PULSES_LENGTH 8 +#define TARGET_CLIM_USER_PULSES_MASK 0x00FF + +#define TARGET_CLIM_USER_BRAKE_ADDRESS 0x1044 +#define TARGET_CLIM_USER_BRAKE_OFFSET 8 +#define TARGET_CLIM_USER_BRAKE_LENGTH 8 +#define TARGET_CLIM_USER_BRAKE_MASK 0xFF00 + +#define TARGET_CLIM_USER_MOTOR_ADDRESS 0x1044 +#define TARGET_CLIM_USER_MOTOR_OFFSET 0 +#define TARGET_CLIM_USER_MOTOR_LENGTH 8 +#define TARGET_CLIM_USER_MOTOR_MASK 0x00FF + +#define CL_BLANK_SELECT_ADDRESS 0x1042 +#define CL_BLANK_SELECT_OFFSET 8 +#define CL_BLANK_SELECT_LENGTH 6 +#define CL_BLANK_SELECT_MASK 0x3F00 + +#define OC_BLANK_SELECT_ADDRESS 0x1042 +#define OC_BLANK_SELECT_OFFSET 0 +#define OC_BLANK_SELECT_LENGTH 6 +#define OC_BLANK_SELECT_MASK 0x003F + +#define DI_TH_1ST_ADDRESS 0x1040 +#define DI_TH_1ST_OFFSET 0 +#define DI_TH_1ST_LENGTH 12 +#define DI_TH_1ST_MASK 0x0FFF + +#define DI_TH_2ND_ADDRESS 0x103E +#define DI_TH_2ND_OFFSET 0 +#define DI_TH_2ND_LENGTH 12 +#define DI_TH_2ND_MASK 0x0FFF + +#define I_ZC_TH_HIGH_ADDRESS 0x103C +#define I_ZC_TH_HIGH_OFFSET 0 +#define I_ZC_TH_HIGH_LENGTH 12 +#define I_ZC_TH_HIGH_MASK 0x0FFF + +#define I_ZC_TH_LOW_ADDRESS 0x103A +#define I_ZC_TH_LOW_OFFSET 0 +#define I_ZC_TH_LOW_LENGTH 12 +#define I_ZC_TH_LOW_MASK 0x0FFF + +#define RPM_F_ADDRESS 0x1038 +#define RPM_F_OFFSET 7 +#define RPM_F_LENGTH 9 +#define RPM_F_MASK 0xFF80 + +#define SPD_F_ADDRESS 0x1038 +#define SPD_F_OFFSET 0 +#define SPD_F_LENGTH 7 +#define SPD_F_MASK 0x007F + +#define RPM_E_ADDRESS 0x1036 +#define RPM_E_OFFSET 7 +#define RPM_E_LENGTH 9 +#define RPM_E_MASK 0xFF80 + +#define SPD_E_ADDRESS 0x1036 +#define SPD_E_OFFSET 0 +#define SPD_E_LENGTH 7 +#define SPD_E_MASK 0x007F + +#define RPM_D_ADDRESS 0x1034 +#define RPM_D_OFFSET 7 +#define RPM_D_LENGTH 9 +#define RPM_D_MASK 0xFF80 + +#define SPD_D_ADDRESS 0x1034 +#define SPD_D_OFFSET 0 +#define SPD_D_LENGTH 7 +#define SPD_D_MASK 0x007F + +#define RPM_C_ADDRESS 0x1032 +#define RPM_C_OFFSET 7 +#define RPM_C_LENGTH 9 +#define RPM_C_MASK 0xFF80 + +#define SPD_C_ADDRESS 0x1032 +#define SPD_C_OFFSET 0 +#define SPD_C_LENGTH 7 +#define SPD_C_MASK 0x007F + +#define RPM_B_ADDRESS 0x1030 +#define RPM_B_OFFSET 7 +#define RPM_B_LENGTH 9 +#define RPM_B_MASK 0xFF80 + +#define SPD_B_ADDRESS 0x1030 +#define SPD_B_OFFSET 0 +#define SPD_B_LENGTH 7 +#define SPD_B_MASK 0x007F + +#define RPM_A_ADDRESS 0x102E +#define RPM_A_OFFSET 7 +#define RPM_A_LENGTH 9 +#define RPM_A_MASK 0xFF80 + +#define SPD_A_ADDRESS 0x102E +#define SPD_A_OFFSET 0 +#define SPD_A_LENGTH 7 +#define SPD_A_MASK 0x007F + +#define RPM_MAX_ADDRESS 0x102C +#define RPM_MAX_OFFSET 7 +#define RPM_MAX_LENGTH 9 +#define RPM_MAX_MASK 0xFF80 + +#define SPD_MAX_ADDRESS 0x102C +#define SPD_MAX_OFFSET 0 +#define SPD_MAX_LENGTH 7 +#define SPD_MAX_MASK 0x007F + +#define RPM_MIN_ADDRESS 0x102A +#define RPM_MIN_OFFSET 7 +#define RPM_MIN_LENGTH 9 +#define RPM_MIN_MASK 0xFF80 + +#define SPD_MIN_ADDRESS 0x102A +#define SPD_MIN_OFFSET 0 +#define SPD_MIN_LENGTH 7 +#define SPD_MIN_MASK 0x007F + +#define DUTY_RAMPING_ADDRESS 0x1028 +#define DUTY_RAMPING_OFFSET 15 +#define DUTY_RAMPING_LENGTH 1 +#define DUTY_RAMPING_MASK 0x8000 + +#define ILIM_RAMPING_ADDRESS 0x1028 +#define ILIM_RAMPING_OFFSET 14 +#define ILIM_RAMPING_LENGTH 1 +#define ILIM_RAMPING_MASK 0x4000 + +#define DC_OPENLOOP_SR_ADDRESS 0x1028 +#define DC_OPENLOOP_SR_OFFSET 12 +#define DC_OPENLOOP_SR_LENGTH 2 +#define DC_OPENLOOP_SR_MASK 0x3000 + +#define DC_OPENLOOP_INI_ADDRESS 0x1028 +#define DC_OPENLOOP_INI_OFFSET 10 +#define DC_OPENLOOP_INI_LENGTH 2 +#define DC_OPENLOOP_INI_MASK 0x0C00 + +#define SPD_KI_ADDRESS 0x1028 +#define SPD_KI_OFFSET 7 +#define SPD_KI_LENGTH 3 +#define SPD_KI_MASK 0x0380 + +#define SPD_KP_ADDRESS 0x1028 +#define SPD_KP_OFFSET 4 +#define SPD_KP_LENGTH 3 +#define SPD_KP_MASK 0x0070 + +#define SPD_HC_HYST_ADDRESS 0x1028 +#define SPD_HC_HYST_OFFSET 2 +#define SPD_HC_HYST_LENGTH 2 +#define SPD_HC_HYST_MASK 0x000C + +#define SPD_LC_HYST_ADDRESS 0x1028 +#define SPD_LC_HYST_OFFSET 0 +#define SPD_LC_HYST_LENGTH 2 +#define SPD_LC_HYST_MASK 0x0003 + +#define SPD_BOOST_ADDRESS 0x1026 +#define SPD_BOOST_OFFSET 13 +#define SPD_BOOST_LENGTH 1 +#define SPD_BOOST_MASK 0x2000 + +#define SPD_BOOST_SS_ADDRESS 0x1026 +#define SPD_BOOST_SS_OFFSET 12 +#define SPD_BOOST_SS_LENGTH 1 +#define SPD_BOOST_SS_MASK 0x1000 + +#define SPD_CTRL_1_RESERVED_ADDRESS 0x1026 +#define SPD_CTRL_1_RESERVED_OFFSET 11 +#define SPD_CTRL_1_RESERVED_LENGTH 1 +#define SPD_CTRL_1_RESERVED_MASK 0x0800 + +#define SPD_LOOP_MODE_ADDRESS 0x1026 +#define SPD_LOOP_MODE_OFFSET 10 +#define SPD_LOOP_MODE_LENGTH 1 +#define SPD_LOOP_MODE_MASK 0x0400 + +#define RPM_LC_ADDRESS 0x1026 +#define RPM_LC_OFFSET 9 +#define RPM_LC_LENGTH 1 +#define RPM_LC_MASK 0x0200 + +#define RPM_HC_ADDRESS 0x1026 +#define RPM_HC_OFFSET 8 +#define RPM_HC_LENGTH 1 +#define RPM_HC_MASK 0x0100 + +#define SPD_LC_VAL_ADDRESS 0x1026 +#define SPD_LC_VAL_OFFSET 6 +#define SPD_LC_VAL_LENGTH 2 +#define SPD_LC_VAL_MASK 0x00C0 + +#define SPD_HC_VAL_ADDRESS 0x1026 +#define SPD_HC_VAL_OFFSET 4 +#define SPD_HC_VAL_LENGTH 2 +#define SPD_HC_VAL_MASK 0x0030 + +#define CURVE_MODE_ADDRESS 0x1026 +#define CURVE_MODE_OFFSET 2 +#define CURVE_MODE_LENGTH 2 +#define CURVE_MODE_MASK 0x000C + +#define SPD_TICK_ADDRESS 0x1026 +#define SPD_TICK_OFFSET 0 +#define SPD_TICK_LENGTH 2 +#define SPD_TICK_MASK 0x0003 + +#define MIN_EHP_RESERVED_ADDRESS 0x1024 +#define MIN_EHP_RESERVED_OFFSET 15 +#define MIN_EHP_RESERVED_LENGTH 1 +#define MIN_EHP_RESERVED_MASK 0x8000 + +#define EHP_TIMER_PRESCALER_ADDRESS 0x1024 +#define EHP_TIMER_PRESCALER_OFFSET 13 +#define EHP_TIMER_PRESCALER_LENGTH 2 +#define EHP_TIMER_PRESCALER_MASK 0x6000 + +#define EHP_FULL_RANGE_ADDRESS 0x1024 +#define EHP_FULL_RANGE_OFFSET 0 +#define EHP_FULL_RANGE_LENGTH 13 +#define EHP_FULL_RANGE_MASK 0x1FFF + +#define POSITION_FLAT_TIME_ADDRESS 0x1022 +#define POSITION_FLAT_TIME_OFFSET 6 +#define POSITION_FLAT_TIME_LENGTH 5 +#define POSITION_FLAT_TIME_MASK 0x07C0 + +#define START_UP_FLAT_TIME_ADDRESS 0x1022 +#define START_UP_FLAT_TIME_OFFSET 0 +#define START_UP_FLAT_TIME_LENGTH 6 +#define START_UP_FLAT_TIME_MASK 0x003F + +#define BEMF_SMALL_THRES_ADDRESS 0x1020 +#define BEMF_SMALL_THRES_OFFSET 0 +#define BEMF_SMALL_THRES_LENGTH 4 +#define BEMF_SMALL_THRES_MASK 0x000F + +#define QUICK_START_ADDRESS 0x101E +#define QUICK_START_OFFSET 15 +#define QUICK_START_LENGTH 1 +#define QUICK_START_MASK 0x8000 + +#define WIND_START_ADDRESS 0x101E +#define WIND_START_OFFSET 14 +#define WIND_START_LENGTH 1 +#define WIND_START_MASK 0x4000 + +#define SOFT_NUM_STEP_ADDRESS 0x101E +#define SOFT_NUM_STEP_OFFSET 8 +#define SOFT_NUM_STEP_LENGTH 3 +#define SOFT_NUM_STEP_MASK 0x0700 + +#define WIND_WINDOW_ADDRESS 0x101E +#define WIND_WINDOW_OFFSET 4 +#define WIND_WINDOW_LENGTH 4 +#define WIND_WINDOW_MASK 0x00F0 + +#define BRAKE_WINDOW_ADDRESS 0x101E +#define BRAKE_WINDOW_OFFSET 0 +#define BRAKE_WINDOW_LENGTH 4 +#define BRAKE_WINDOW_MASK 0x000F + +#define SINGLE_PULSE_START_ADDRESS 0x101C +#define SINGLE_PULSE_START_OFFSET 15 +#define SINGLE_PULSE_START_LENGTH 1 +#define SINGLE_PULSE_START_MASK 0x8000 + +#define LONG_START_ADDRESS 0x101C +#define LONG_START_OFFSET 14 +#define LONG_START_LENGTH 1 +#define LONG_START_MASK 0x4000 + +#define SOFT_START_ADDRESS 0x101C +#define SOFT_START_OFFSET 13 +#define SOFT_START_LENGTH 1 +#define SOFT_START_MASK 0x2000 + +#define COMM_START_NUM_ADDRESS 0x101C +#define COMM_START_NUM_OFFSET 11 +#define COMM_START_NUM_LENGTH 2 +#define COMM_START_NUM_MASK 0x1800 + +#define START_DUTY_ADDRESS 0x101C +#define START_DUTY_OFFSET 9 +#define START_DUTY_LENGTH 2 +#define START_DUTY_MASK 0x0600 + +#define SOFT_STEP_SIZE_ADDRESS 0x101C +#define SOFT_STEP_SIZE_OFFSET 6 +#define SOFT_STEP_SIZE_LENGTH 3 +#define SOFT_STEP_SIZE_MASK 0x01C0 + +#define START_UP_TIME_ADDRESS 0x101C +#define START_UP_TIME_OFFSET 0 +#define START_UP_TIME_LENGTH 6 +#define START_UP_TIME_MASK 0x003F + +#define POSITION_DUTY_ADDRESS 0x101A +#define POSITION_DUTY_OFFSET 14 +#define POSITION_DUTY_LENGTH 2 +#define POSITION_DUTY_MASK 0xC000 + +#define POSITION_PULSE_TIME_ADDRESS 0x101A +#define POSITION_PULSE_TIME_OFFSET 9 +#define POSITION_PULSE_TIME_LENGTH 5 +#define POSITION_PULSE_TIME_MASK 0x3E00 + +#define POSI_MAJO_VOTE_ADDRESS 0x101A +#define POSI_MAJO_VOTE_OFFSET 8 +#define POSI_MAJO_VOTE_LENGTH 1 +#define POSI_MAJO_VOTE_MASK 0x0100 + +#define ANTI_COG_ADDRESS 0x101A +#define ANTI_COG_OFFSET 7 +#define ANTI_COG_LENGTH 1 +#define ANTI_COG_MASK 0x0080 + +#define POSITION_RESERVED_ADDRESS 0x101A +#define POSITION_RESERVED_OFFSET 6 +#define POSITION_RESERVED_LENGTH 1 +#define POSITION_RESERVED_MASK 0x0040 + +#define FIRST_NON_FLAT_TIME_ADDRESS 0x101A +#define FIRST_NON_FLAT_TIME_OFFSET 0 +#define FIRST_NON_FLAT_TIME_LENGTH 6 +#define FIRST_NON_FLAT_TIME_MASK 0x003F + +#define ROUGH_REG_ADDRESS 0x1018 +#define ROUGH_REG_OFFSET 14 +#define ROUGH_REG_LENGTH 1 +#define ROUGH_REG_MASK 0x4000 + +#define ADC_FLAT_FILT_DEP_ADDRESS 0x1018 +#define ADC_FLAT_FILT_DEP_OFFSET 12 +#define ADC_FLAT_FILT_DEP_LENGTH 2 +#define ADC_FLAT_FILT_DEP_MASK 0x3000 + +#define EHP_REG_GAIN_ADDRESS 0x1018 +#define EHP_REG_GAIN_OFFSET 10 +#define EHP_REG_GAIN_LENGTH 2 +#define EHP_REG_GAIN_MASK 0x0C00 + +#define ROUGH_GAIN_ADDRESS 0x1018 +#define ROUGH_GAIN_OFFSET 9 +#define ROUGH_GAIN_LENGTH 1 +#define ROUGH_GAIN_MASK 0x0200 + +#define PWM_MOD_ADDRESS 0x1018 +#define PWM_MOD_OFFSET 8 +#define PWM_MOD_LENGTH 1 +#define PWM_MOD_MASK 0x0100 + +#define PWM_50K_ADDRESS 0x1018 +#define PWM_50K_OFFSET 7 +#define PWM_50K_LENGTH 1 +#define PWM_50K_MASK 0x0080 + +#define SS_RISE_MODE_ADDRESS 0x1018 +#define SS_RISE_MODE_OFFSET 3 +#define SS_RISE_MODE_LENGTH 3 +#define SS_RISE_MODE_MASK 0x0038 + +#define SS_FALL_MODE_ADDRESS 0x1018 +#define SS_FALL_MODE_OFFSET 0 +#define SS_FALL_MODE_LENGTH 3 +#define SS_FALL_MODE_MASK 0x0007 + +#define FG_SLOPECTRL_ADDRESS 0x1014 +#define FG_SLOPECTRL_OFFSET 14 +#define FG_SLOPECTRL_LENGTH 2 +#define FG_SLOPECTRL_MASK 0xC000 + +#define LVIO_SLOPECTRL_ADDRESS 0x1014 +#define LVIO_SLOPECTRL_OFFSET 12 +#define LVIO_SLOPECTRL_LENGTH 2 +#define LVIO_SLOPECTRL_MASK 0x3000 + +#define HVIO_SLOPECTRL_ADDRESS 0x1014 +#define HVIO_SLOPECTRL_OFFSET 10 +#define HVIO_SLOPECTRL_LENGTH 2 +#define HVIO_SLOPECTRL_MASK 0x0C00 + +#define I2C_SLAVE_ADDRESS_ADDRESS 0x1014 +#define I2C_SLAVE_ADDRESS_OFFSET 0 +#define I2C_SLAVE_ADDRESS_LENGTH 7 +#define I2C_SLAVE_ADDRESS_MASK 0x007F + +#define I2C_DEBUGGING_DISABLED_ADDRESS 0x1012 +#define I2C_DEBUGGING_DISABLED_OFFSET 15 +#define I2C_DEBUGGING_DISABLED_LENGTH 1 +#define I2C_DEBUGGING_DISABLED_MASK 0x8000 + +#define I2C_TOGGLE_ENTRY_ADDRESS 0x1012 +#define I2C_TOGGLE_ENTRY_OFFSET 14 +#define I2C_TOGGLE_ENTRY_LENGTH 1 +#define I2C_TOGGLE_ENTRY_MASK 0x4000 + +#define HVIO_PU_PD_CFG_ADDRESS 0x1012 +#define HVIO_PU_PD_CFG_OFFSET 12 +#define HVIO_PU_PD_CFG_LENGTH 2 +#define HVIO_PU_PD_CFG_MASK 0x3000 + +#define LVIO_PU_PD_CFG_ADDRESS 0x1012 +#define LVIO_PU_PD_CFG_OFFSET 10 +#define LVIO_PU_PD_CFG_LENGTH 2 +#define LVIO_PU_PD_CFG_MASK 0x0C00 + +#define PWM_PU_PD_CFG_ADDRESS 0x1012 +#define PWM_PU_PD_CFG_OFFSET 8 +#define PWM_PU_PD_CFG_LENGTH 2 +#define PWM_PU_PD_CFG_MASK 0x0300 + +#define SLEEP_MODE_ENABLED_ADDRESS 0x1012 +#define SLEEP_MODE_ENABLED_OFFSET 7 +#define SLEEP_MODE_ENABLED_LENGTH 1 +#define SLEEP_MODE_ENABLED_MASK 0x0080 + +#define SLEEP_MODE_POLARITY_ADDRESS 0x1012 +#define SLEEP_MODE_POLARITY_OFFSET 6 +#define SLEEP_MODE_POLARITY_LENGTH 1 +#define SLEEP_MODE_POLARITY_MASK 0x0040 + +#define DIAG_MODE_CFG_ADDRESS 0x1012 +#define DIAG_MODE_CFG_OFFSET 4 +#define DIAG_MODE_CFG_LENGTH 2 +#define DIAG_MODE_CFG_MASK 0x0030 + +#define FG_FILTERED_ADDRESS 0x1012 +#define FG_FILTERED_OFFSET 3 +#define FG_FILTERED_LENGTH 1 +#define FG_FILTERED_MASK 0x0008 + +#define FG_SPEED_ADDRESS 0x1012 +#define FG_SPEED_OFFSET 0 +#define FG_SPEED_LENGTH 3 +#define FG_SPEED_MASK 0x0007 + +#define FG_RD_ACTIVE_STATE_ADDRESS 0x1010 +#define FG_RD_ACTIVE_STATE_OFFSET 13 +#define FG_RD_ACTIVE_STATE_LENGTH 1 +#define FG_RD_ACTIVE_STATE_MASK 0x2000 + +#define FG_RD_INIT_LOW_ADDRESS 0x1010 +#define FG_RD_INIT_LOW_OFFSET 12 +#define FG_RD_INIT_LOW_LENGTH 1 +#define FG_RD_INIT_LOW_MASK 0x1000 + +#define SELECT_RD_FGB_ADDRESS 0x1010 +#define SELECT_RD_FGB_OFFSET 11 +#define SELECT_RD_FGB_LENGTH 1 +#define SELECT_RD_FGB_MASK 0x0800 + +#define HVIO_MODE_CFG_ADDRESS 0x1010 +#define HVIO_MODE_CFG_OFFSET 8 +#define HVIO_MODE_CFG_LENGTH 3 +#define HVIO_MODE_CFG_MASK 0x0700 + +#define LVIO_MODE_CFG_ADDRESS 0x1010 +#define LVIO_MODE_CFG_OFFSET 5 +#define LVIO_MODE_CFG_LENGTH 3 +#define LVIO_MODE_CFG_MASK 0x00E0 + +#define FG_MODE_CFG_ADDRESS 0x1010 +#define FG_MODE_CFG_OFFSET 3 +#define FG_MODE_CFG_LENGTH 2 +#define FG_MODE_CFG_MASK 0x0018 + +#define INPUT_MODE_CFG_ADDRESS 0x1010 +#define INPUT_MODE_CFG_OFFSET 0 +#define INPUT_MODE_CFG_LENGTH 3 +#define INPUT_MODE_CFG_MASK 0x0007 + +#define MOTOR_STATE_ADDRESS 0x100E +#define MOTOR_STATE_OFFSET 8 +#define MOTOR_STATE_LENGTH 8 +#define MOTOR_STATE_MASK 0xFF00 + +#define COMM_STATE_ADDRESS 0x100E +#define COMM_STATE_OFFSET 0 +#define COMM_STATE_LENGTH 8 +#define COMM_STATE_MASK 0x00FF + +#define I2C_RESERVED_2_ADDRESS 0x100C +#define I2C_RESERVED_2_OFFSET 0 +#define I2C_RESERVED_2_LENGTH 16 +#define I2C_RESERVED_2_MASK 0xFFFF + +#define TEMPERATURE_COUNTER_ADDRESS 0x100A +#define TEMPERATURE_COUNTER_OFFSET 12 +#define TEMPERATURE_COUNTER_LENGTH 4 +#define TEMPERATURE_COUNTER_MASK 0xF000 + +#define TEMPERATURE_VALUE_ADDRESS 0x100A +#define TEMPERATURE_VALUE_OFFSET 0 +#define TEMPERATURE_VALUE_LENGTH 12 +#define TEMPERATURE_VALUE_MASK 0x0FFF + +#define MOTOR_RUNNING_ADDRESS 0x1008 +#define MOTOR_RUNNING_OFFSET 15 +#define MOTOR_RUNNING_LENGTH 1 +#define MOTOR_RUNNING_MASK 0x8000 + +#define COMMAND_BUSY_ADDRESS 0x1008 +#define COMMAND_BUSY_OFFSET 4 +#define COMMAND_BUSY_LENGTH 1 +#define COMMAND_BUSY_MASK 0x0010 + +#define OTP_FREEZONES_ADDRESS 0x1008 +#define OTP_FREEZONES_OFFSET 2 +#define OTP_FREEZONES_LENGTH 2 +#define OTP_FREEZONES_MASK 0x000C + +#define MOTOR_STUCK_ADDRESS 0x1008 +#define MOTOR_STUCK_OFFSET 1 +#define MOTOR_STUCK_LENGTH 1 +#define MOTOR_STUCK_MASK 0x0002 + +#define OVERVOLTAGE_ADDRESS 0x1008 +#define OVERVOLTAGE_OFFSET 0 +#define OVERVOLTAGE_LENGTH 1 +#define OVERVOLTAGE_MASK 0x0001 + +#define FEEDBACK_ADDRESS 0x1006 +#define FEEDBACK_OFFSET 0 +#define FEEDBACK_LENGTH 16 +#define FEEDBACK_MASK 0xFFFF + +#define COMMAND_KEY_ADDRESS 0x1004 +#define COMMAND_KEY_OFFSET 0 +#define COMMAND_KEY_LENGTH 16 +#define COMMAND_KEY_MASK 0xFFFF + +#define COMMAND_CONTROL_ADDRESS 0x1002 +#define COMMAND_CONTROL_OFFSET 0 +#define COMMAND_CONTROL_LENGTH 16 +#define COMMAND_CONTROL_MASK 0xFFFF + +#define SPEED_DUTY_ADDRESS 0x1000 +#define SPEED_DUTY_OFFSET 0 +#define SPEED_DUTY_LENGTH 16 +#define SPEED_DUTY_MASK 0xFFFF + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nv_defaults.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,20 @@ +#define NV_POSITION_DEFAULT (17<<NV_POSITION_PULSE_TIME_OFFSET)|(3<<NV_POSITION_DUTY_OFFSET)|(0<<NV_POSI_MAJO_VOTE_OFFSET)|(0<<NV_ANTI_COG_OFFSET)|(1<<NV_FIRST_NON_FLAT_TIME_OFFSET) +#define NV_START_UP_DEFAULT (0<<NV_SOFT_START_OFFSET)|(0<<NV_SINGLE_PULSE_START_OFFSET)|(0<<NV_LONG_START_OFFSET)|(3<<NV_COMM_START_NUM_OFFSET)|(3<<NV_START_DUTY_OFFSET)|(3<<NV_SOFT_STEP_SIZE_OFFSET)|(36<<NV_START_UP_TIME_OFFSET) +#define NV_WIND_BRAKE_DEFAULT (1<<NV_QUICK_START_OFFSET)|(0<<NV_WIND_START_OFFSET)|(1<<NV_SOFT_NUM_STEP_OFFSET)|(1<<NV_WIND_WINDOW_OFFSET)|(0<<NV_BRAKE_WINDOW_OFFSET) +#define NV_SPD_CONTROL_1_DEFAULT 0 +#define NV_SPD_CONTROL_2_DEFAULT 0 +#define NV_GEN_CTRL_DEFAULT 0 +#define NV_APPLICATION_CFG_DEFAULT 0 +#define NV_I_ZC_TH_HIGH_DEFAULT 0 +#define NV_I_ZC_TH_LOW_DEFAULT 0 +#define NV_DI_TH_1ST_DEFAULT 0 +#define NV_DI_TH_2ND_DEFAULT 0 +#define NV_DIG_CONFIG_DEFAULT 0 +#define NV_CLIM_USER_1_DEFAULT 0 +#define NV_CLIM_USER_0_DEFAULT 0 +#define NV_CLIM_POSITIN2_DEFAULT 0 + +#define RAM_OPEN_DUTY_DEFAULT 65535 +#define RAM_DEBUG_CTRL_DEFAULT 0 + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scpi-def.cpp Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,504 @@ +/*- + * 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;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scpi-def.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,64 @@ +/*- + * 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. + */ + +#ifndef __SCPI_DEF_H_ +#define __SCPI_DEF_H_ + +#include "scpi/scpi.h" + +#define SCPI_INPUT_BUFFER_LENGTH 256 +#define SCPI_ERROR_QUEUE_SIZE 17 +//#define SCPI_IDN1 "MANUFACTURE" +//#define SCPI_IDN2 "INSTR2013" +//#define SCPI_IDN3 NULL +//#define SCPI_IDN4 "01-02" + +//extern const scpi_command_t scpi_commands[]; +//extern scpi_interface_t scpi_interface; +//extern char scpi_input_buffer[]; +extern scpi_t scpi_context; + +size_t SCPI_Write(scpi_t * context, const char * data, size_t len); +int SCPI_Error(scpi_t * context, int_fast16_t err); +scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val); +scpi_result_t SCPI_Reset(scpi_t * context); +scpi_result_t SCPI_Test(scpi_t * context); +scpi_result_t SCPI_Flush(scpi_t * context); +void configure_scpi(void); + +extern const scpi_command_t scpi_commands[]; +extern scpi_interface_t scpi_interface; +extern char scpi_input_buffer[]; +extern scpi_error_t scpi_error_queue_data[]; +extern scpi_t scpi_context; + + +scpi_result_t SCPI_SystemCommTcpipControlQ(scpi_t * context); + +#endif /* __SCPI_DEF_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/strnlen_copy.c Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,11 @@ +#include <stddef.h> + +size_t +strnlen (const char *s, size_t maxlen) +{ + size_t i; + for (i = 0; i < maxlen; ++i) + if (s[i] == '\0') + break; + return i; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_ehp_reg.cpp Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,153 @@ +#include "test_ehp_reg.h" +#include "main_init.h" +#include "mbed.h" + +#define EHP_BUFF_SIZE 1001 + +test_ehp_reg::test_ehp_reg(PinName timerCapturePin, PinName adcCapturePin) +: test_vector(timerCapturePin, rise_fall, EHP_BUFF_SIZE), _interruptTrigger(adcCapturePin) +{} + +void test_ehp_reg::_handleADCTriggerPinRiseIRQ() +{ + + _ADC_temp = _readADC(); /* sample ADC as quick as possible*/ + if(_ADC_idx <= EHP_BUFF_SIZE && !_ADCBufferFull) + { + startTimer(); /*important! timer starts only the ADC trigger starts!!!!!! */ + if(_ADC_idx == getPeriodIdx()) + { + _ADCperiodInSync = true; + led4 = 1; + _ptr_ADC_arr[_ADC_idx] = _ADC_temp; + /* re-assemble last result together with last captured non-flat+period*/ + _ptr_ADC_arr[_ADC_idx-1] = _ptr_ADC_arr[_ADC_idx-1] + (getCurrentTimerBufferValue() << 16); /* test */ + } + else + { + _ADCperiodInSync = false; + led4 = 0; + } + _ADC_idx++; + _ADCBufferFull = false; + + } + else + { + _ADCBufferFull = true; + led4 = 0; + } +} + +bool test_ehp_reg::_getADCBufferFull() +{ + return _ADCBufferFull; +} + + +void test_ehp_reg::configure() +{ + /****************** + GPIO input to capture ADC. + IO arrangement + + mbed_pin30 -> p0.4 -> ADC_OUT[0] + mbed_pin29 -> p0.5 -> ADC_OUT[1] + mbed_pin8 -> p0.6 -> ADC_OUT[2] + mbed_pin7 -> p0.7 -> ADC_OUT[3] + mbed_pin6 -> p0.8 -> ADC_OUT[4] + mbed_pin5 -> p0.9 -> ADC_OUT[5] + mbed_pin13 -> p0.15 -> ADC_OUT[6] + mbed_pin14 -> p0.16 -> ADC_OUT[7] + mbed_pin12 -> p0.17 -> ADC_OUT[8] + mbed_pin11 -> p0.18 -> ADC_OUT[9] + mbed_pin17 -> p0.25 -> ADC_OUT[10] + mbed_pin18 -> p0.26 -> ADC_OUT[11] + *******************/ + + /****Set the port to GPIO***/ + /*p0.4 p0.5 p0.6 p0.7 p0.8 p0.9 p0.15*/ + LPC_PINCON->PINSEL0 &= ~( (3UL << 8 ) | (3UL << 10) | (3UL << 12) | (3UL << 14) | + (3UL << 16) | (3UL << 18) | (3UL << 30) ); + /*p0.16 p0.17 p0.18 p0.25 p0.26*/ + LPC_PINCON->PINSEL1 &= ~( (3UL << 0) | (3UL << 2) | (3UL << 4) | (3UL << 18) | (3UL << 20) ); + + /****Set the GPIO as input***/ + LPC_GPIO0->FIODIR &= ~( (1UL << 4) | (1UL << 5) | (1UL << 6) | (1UL << 7) | + (1UL << 8) | (1UL << 9) | (1UL << 15) | (1UL << 16) | + (1UL << 17) | (1UL << 18) | (1UL << 25) | (1UL << 26) ); + + _ptr_ADC_arr = new uint32_t[EHP_BUFF_SIZE]; + _ADC_idx = 0; + _ADCBufferFull = false; + _ADCperiodInSync = false; + + setUpTimerBuffer(); + configureTimer(); + +} + + +uint32_t test_ehp_reg::_readADC() +{ + + uint32_t ioRead; + uint32_t adcRead; + ioRead = LPC_GPIO0->FIOPIN; + adcRead = ( ( ioRead & (1 << 4 ) ) >> 4 ) | + ( ( ioRead & (1 << 5 ) ) >> 4 ) | + ( ( ioRead & (1 << 6 ) ) >> 4 ) | + ( ( ioRead & (1 << 7 ) ) >> 4 ) | + ( ( ioRead & (1 << 8 ) ) >> 4 ) | + ( ( ioRead & (1 << 9 ) ) >> 4 ) | + ( ( ioRead & (1 << 15 ) ) >> 9 ) | + ( ( ioRead & (1 << 16 ) ) >> 9 ) | + ( ( ioRead & (1 << 17 ) ) >> 9 ) | + ( ( ioRead & (1 << 18 ) ) >> 9 ) | + ( ( ioRead & (1 << 25 ) ) >> 15 ) | + ( ( ioRead & (1 << 26 ) ) >> 15 ) ; + return adcRead; +} + +void test_ehp_reg::run() +{ + _interruptTrigger.rise(callback(this, &test_ehp_reg::_handleADCTriggerPinRiseIRQ)); /* rising edge IRQ routine enbale*/ + while( (!_getADCBufferFull()) || (!getTimerBufferFull())) + { + ; + } +} + +void test_ehp_reg::stop() +{ + stopTimer(); + _interruptTrigger.rise(NULL); /*disable pin interrupt*/ +// led4 = 0; +} + +void test_ehp_reg::release() +{ + releaseTimerBuffer(); + if( _ptr_ADC_arr != NULL) + { + delete []_ptr_ADC_arr; + _ptr_ADC_arr = NULL; + } +} + +uint32_t* test_ehp_reg::getResult() +{ +// return getTimerBufferPointer(); + return _ptr_ADC_arr; + +} + +uint32_t test_ehp_reg::getBufferSize() +{ + return EHP_BUFF_SIZE; +} + +char* test_ehp_reg::getResultStatus() +{ + return "Test PASS!!!"; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_ehp_reg.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,32 @@ +//Class delclarations + +#include "mbed.h" +#include "test_vector.h" + +class test_ehp_reg:public test_vector { + +public: + /*constructor*/ + test_ehp_reg(PinName timerCapturePin, PinName adcCapturePin); + virtual void configure(); + virtual void run(); + virtual void stop(); + virtual uint32_t* getResult(); + virtual char* getResultStatus(); + virtual void release(); + virtual uint32_t getBufferSize(); + +private: + InterruptIn _interruptTrigger; + uint32_t* _ptr_ADC_arr; + uint32_t _ADC_idx; + volatile uint32_t _ADC_temp; + bool _ADCperiodInSync; + + void _handleADCTriggerPinRiseIRQ(); + uint32_t _readADC(); + bool _ADCBufferFull; + bool _getADCBufferFull(); + + +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_fg.cpp Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,46 @@ +#include "test_fg.h" +#include "main_init.h" +#include "mbed.h" + +test_fg::test_fg(PinName pin): test_vector(pin, rise_rise, 1000) +{ + +} + +void test_fg::configure() +{ + configureTimer(); + setUpTimerBuffer(); +} + +void test_fg::run() +{ + startTimer(); + while(!getTimerBufferFull()){}; +} + +void test_fg::stop() +{ + stopTimer(); +} + +void test_fg::release() +{ + releaseTimerBuffer(); +} + +uint32_t* test_fg::getResult() +{ + return getTimerBufferPointer(); +} + + +char* test_fg::getResultStatus() +{ + return "Test PASS!!!"; +} + +uint32_t test_fg::getBufferSize() +{ + return 1000; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_fg.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,22 @@ +//Class delclarations + +#include "mbed.h" +#include "test_vector.h" + +class test_fg:public test_vector { + +public: + /*constructor*/ + test_fg(PinName pin); + virtual void configure(); + virtual void run(); + virtual void stop(); + virtual uint32_t* getResult(); + virtual char* getResultStatus(); + virtual void release(); + virtual uint32_t getBufferSize(); + +private: + +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_vector.cpp Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,194 @@ +#include "test_vector.h" +#include "main_init.h" + +test_vector::test_vector(PinName pin, captureMode mode, uint32_t bufferSize) : _interrupt(pin) +{ + _pinName = pin; + _bufferSize = bufferSize; + _mode = mode; +} + +test_vector::~test_vector() +{ +} + + + +void test_vector::_handlePinRiseIRQ() +{ + switch(_mode){ + case rise_rise: + _savePeriod(); + _sampleCaptureTimer(); + break; + case rise_fall: + _sampleCaptureTimer(); + break; + case fall_rise: + _savePeriod(); + break; + case fall_fall: + break; + case both: + _savePeriod(); + _sampleCaptureTimer(); + break; + default: + _savePeriod(); + _sampleCaptureTimer(); + } +} + +void test_vector::_handlePinFallIRQ() +{ + switch(_mode){ + case rise_rise: + break; + case rise_fall: + _savePeriod(); + break; + case fall_rise: + _sampleCaptureTimer(); + break; + case fall_fall: + _savePeriod(); + _sampleCaptureTimer(); + break; + case both: + _savePeriod(); + _sampleCaptureTimer(); + break; + default: + _savePeriod(); + _sampleCaptureTimer(); + } +} + + + + +void test_vector::configureTimer() +{ + + _timer_value = 0; + _period = 0; + + LPC_SC->PCONP |= (1UL << 23) | (1UL << 15); /* enable timer 3 power and the gpio*/ + LPC_SC->PCLKSEL1 |= (1UL << 14); /* Timer3 clock is SystemCLK */ + + LPC_TIM3->PR = SystemCoreClock/1000000; /* should increment once a microsecond. */ + LPC_TIM3->MR0 = 0; + LPC_TIM3->MR1 = 0; + LPC_TIM3->MR2 = 0; + LPC_TIM3->MR3 = 0; + LPC_TIM3->MCR = 0; + LPC_TIM3->CTCR &= ~(3 << 0); /* Timer mode */ + LPC_TIM3->CCR|=((1<<0)|(1<<1)); /* capture rising & falling without interrupt on channel 0 */ + + switch(_pinName){ + /* configure the pin ==> 2'11 at offset 14 is to enable CAP3.0 or p15 */ + case p15: + LPC_PINCON->PINSEL1 |= (3UL << 14); + LPC_TIM3->IR |= (1 << 4UL); //enbale cpature channel 0 event + break; + /* configure the pin ==> 2'11 at offset 16 is to enable CAP3.1 or p16 */ + case p16: + LPC_PINCON->PINSEL0 |= (3UL << 16); + LPC_TIM3->IR |= (1 << 5UL); /* enbale cpature channel 1 event */ + break; + /* default is p15 */ + default: + LPC_PINCON->PINSEL1 |= (3UL << 14); + LPC_TIM3->IR |= (1 << 4UL); /* enbale cpature channel 0 event */ + } + +} + +void test_vector::startTimer() +{ + + LPC_TIM3->TCR = 2; // reset + LPC_TIM3->TCR = 1; //start timer + _interrupt.rise(callback(this, &test_vector::_handlePinRiseIRQ)); /* rising edge IRQ routine*/ + _interrupt.fall(callback(this, &test_vector::_handlePinFallIRQ)); /* falling edge IRQ routine*/ + +} + +void test_vector::stopTimer() +{ + + LPC_TIM3->TCR = 2; // reset + _interrupt.rise(NULL); /*disable pin interrupt*/ + _interrupt.fall(NULL); /*disable pin interrupt*/ + led1 = 0; + led2 = 0; +} + +void test_vector::_sampleCaptureTimer() +{ + _timer_value = LPC_TIM3->CR0; +} + +void test_vector::_savePeriod() +{ + _period = LPC_TIM3->CR0 - _timer_value; + if( _period_idx <= _bufferSize && !_bufferFull) + { + _ptr_period_arr[_period_idx] = _period; +// _ptr_period_arr[_period_idx] = _bufferSize - _period_idx; /* to test */ + _period_idx++; + _bufferFull = false; + led1 = 1; + } + else + { + _bufferFull = true; + led1 = 0; + } +} + + +void test_vector::setUpTimerBuffer() +{ +// _ptr_period_arr = (uint32_t*) malloc(_bufferSize * sizeof(uint32_t)); /* always pre-allocate 1000 words buffer*/ + _ptr_period_arr = new uint32_t[_bufferSize]; + _period_idx = 0; + _bufferFull = false; +} + + +void test_vector::releaseTimerBuffer() +{ +// free(_ptr_period_arr); /*free up the memory*/ + if( _ptr_period_arr != NULL) + { + delete []_ptr_period_arr; + _ptr_period_arr = NULL; + } +} + + +bool test_vector:: getTimerBufferFull() +{ + return _bufferFull; +} + +uint32_t test_vector::getTimerBufferSize() +{ + return _bufferSize; +} + +uint32_t* test_vector::getTimerBufferPointer() +{ + return _ptr_period_arr; +} + +uint32_t test_vector::getPeriodIdx() +{ + return _period_idx; +} + +uint32_t test_vector::getCurrentTimerBufferValue() +{ + return *(_ptr_period_arr+_period_idx); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test_vector.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,54 @@ +#ifndef TEST_VECTOR_H +#define TEST_VECTOR_H + + +//base abstract class for all test vectors + +#include "mbed.h" + +enum captureMode { rise_rise, rise_fall, fall_rise, fall_fall, both }; + +class test_vector { + +public: + test_vector(PinName pin, captureMode mode, uint32_t bufferSize); + ~test_vector(); + virtual void configure()=0; + virtual void run()=0; + virtual void stop()=0; + virtual uint32_t* getResult()=0; + virtual char* getResultStatus()=0; + virtual void release()=0; + virtual uint32_t getBufferSize()=0; + + void configureTimer(); + void startTimer(); + void stopTimer(); + + void setUpTimerBuffer(); + void releaseTimerBuffer(); + uint32_t getTimerBufferSize(); + uint32_t* getTimerBufferPointer(); + bool getTimerBufferFull(); + uint32_t getPeriodIdx(); + uint32_t getCurrentTimerBufferValue(); + +private: + PinName _pinName; + InterruptIn _interrupt; + + uint32_t _timer_value; + uint32_t _period; + uint32_t* _ptr_period_arr; + uint32_t _period_idx; + captureMode _mode; + + uint32_t _bufferSize; + bool _bufferFull; + void _handlePinRiseIRQ(); + void _handlePinFallIRQ(); + void _sampleCaptureTimer(); + void _savePeriod(); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uart_mbed.cpp Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,79 @@ +#include "uart_mbed.h" +#include "mbed.h" +#include "scpi/scpi.h" + + +// Serial pc(USBTX, USBRX); // tx, rx + +void uart_print(char *buffer){ + printf("RAM_ADDR:%02X MByte:%02X LByte:%02X'\n", *buffer, *(buffer+1),*(buffer+2)); +} + +void uart_read(char *buffer){ + gets(buffer); +} + +void uart_write(char *buffer){ + printf(buffer); +} + +void uart_start(){ + printf("data_start\n"); +} + +void uart_I2C_test_pass(){ + printf("i2c_test_pass, ready!\n"); +} + +void uart_I2C_test_fail(){ + printf("i2c_test_fail\n"); +} + +void uart_ram_dump_finish(){ + printf("dump_finish\n"); +} + +int SCPI_Error(scpi_t * context, int_fast16_t err) { + (void) context; + + printf("**ERROR: %d, \"%s\"\r\n", (int32_t) err, SCPI_ErrorTranslate(err)); + return 0; +} + +size_t SCPI_Write(scpi_t * context, const char * data, size_t len) { + (void) context; + return fwrite(data, 1, len, stdout); +} + +scpi_result_t SCPI_Flush(scpi_t * context) { + fflush(stdout); + return SCPI_RES_OK; +} + +/** + * Return 0 as OK and other number as error + */ +scpi_result_t SCPI_Test(scpi_t * context) { + printf("**Test\r\n"); + return (scpi_result_t)0; +} + +extern "C" void mbed_reset(); + +scpi_result_t SCPI_Reset(scpi_t * context) +{ + mbed_reset(); + printf("**Reset\r\n"); + return SCPI_RES_OK; +} + +scpi_result_t SCPI_Control(scpi_t * context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { + if (SCPI_CTRL_SRQ == ctrl) { + printf("**SRQ: 0x%X (%d)\r\n", val, val); + } else { + printf("**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); + } + return SCPI_RES_OK; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uart_mbed.h Mon Jan 17 13:20:09 2022 +0000 @@ -0,0 +1,13 @@ +#ifndef UART_MBED_FPGA_H +#define UART_MBED_FPGA_H + +void uart_print(char *buffer); +void uart_write(char *buffer); +void uart_read(char *buffer); +void uart_start(); +void uart_I2C_test_pass(); +void uart_I2C_test_fail(); +void uart_ram_dump_finish(); + + +#endif