diff --git a/adc_drv.c b/adc_drv.c index cf32633..cfedd04 100644 --- a/adc_drv.c +++ b/adc_drv.c @@ -83,4 +83,13 @@ int adc_read_milivolt(uint32_t channel, float *mv) return p_inst->read_milivolt(channel, mv); } +int adc_read_mutiple_channels_convert_milivolt(int32_t *p_val_14bit, float *p_val_f, uint32_t count) +{ + if (p_inst == NULL) + { + return ADC_DRV_ERROR; + } + return p_inst->adc_convert_multiple_milivolt(p_val_14bit, p_val_f, count); +} + #endif /* ! DEF_ADC_DRV_ENABLED */ diff --git a/adc_drv.h b/adc_drv.h index ac9fd1c..1905b86 100644 --- a/adc_drv.h +++ b/adc_drv.h @@ -29,6 +29,7 @@ int adc_read_milivolt(uint32_t channel, float *mv); int adc_read_mutiple_channels(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt); int adc_read_mutiple_channels_ex(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt, void (*preliminary_action)(void)); int adc_read_multiple_milivolt_ex(uint32_t *p_channel, float *p_val, uint32_t cnt, void (*preliminary_action)(void)); +int adc_read_mutiple_channels_convert_milivolt(int32_t *p_val_14bit, float *p_val_f, uint32_t count); #else #define adc_init() #define adc_reset() @@ -38,6 +39,7 @@ int adc_read_multiple_milivolt_ex(uint32_t *p_channel, float *p_val, uint32_t cn #define adc_read_mutiple_channels(x, y, z) #define adc_read_mutiple_channels_ex(x, y, z, a) #define adc_read_multiple_milivolt_ex(x, y, z, a) +#define adc_read_mutiple_channels_convert_milivolt(x, y, z) #endif /* ! DEF_ADC_DRV_ENABLED */ #ifdef __cplusplus diff --git a/adc_drv_if.h b/adc_drv_if.h index 49c7e47..6768496 100644 --- a/adc_drv_if.h +++ b/adc_drv_if.h @@ -38,6 +38,7 @@ typedef struct int (*read_multiple_channels)(uint32_t *p_channels, int32_t *adc_val, uint32_t count); int (*read_multiple_channels_ex)(uint32_t *p_channels, int32_t *adc_val, uint32_t count, void (*preliminary_action)(void)); int (*gain)(adc_gain_t gain); + int (*adc_convert_multiple_milivolt)(int32_t *p_val_14bit, float *p_val_f, uint32_t count); } adc_drv_if_t; #ifdef __cplusplus diff --git a/app_config.h b/app_config.h index 944889b..5274a88 100644 --- a/app_config.h +++ b/app_config.h @@ -109,8 +109,11 @@ extern "C" #define DEF_ELITE_CPG_V1_1 0x00080001 #define DEF_ELITE_MODEL DEF_ELITE_DEV +#define DEF_ELITE_DEMO_W_SOFTDEVICE 0 + #if (DEF_ELITE_MODEL == DEF_ELITE_DEV) #define ELITE_DEVICE_NAME "Elite-Dev" +#define ELITE_HW_NAME "Elite-Dev" #define MAJOR_PRODUCT_NUMBER 0 #define MINOR_PRODUCT_NUMBER 0 #define MAJOR_VERSION_NUMBER 0 @@ -143,6 +146,7 @@ extern "C" #elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_V2_0) #define ELITE_DEVICE_NAME "Elite-EDC" +#define ELITE_HW_NAME "Elite-EDCv2.0" #define MAJOR_PRODUCT_NUMBER 0 #define MINOR_PRODUCT_NUMBER 2 #define MAJOR_VERSION_NUMBER 1 @@ -174,7 +178,12 @@ extern "C" #define DEF_RTT_JSCOP_ENABLED 0 #elif (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0) +#define BOARD_IOPH 1 +#define BOARD_IOPL 0 + #define ELITE_DEVICE_NAME "Elite-PEL" +#define ELITE_HW_NAME "Elite-PELv2.0" +#define BOARD_IOPx BOARD_IOPL #define MAJOR_PRODUCT_NUMBER 0 #define MINOR_PRODUCT_NUMBER 7 #define MAJOR_VERSION_NUMBER 0 @@ -207,6 +216,7 @@ extern "C" #elif (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1) #define ELITE_DEVICE_NAME "Elite-CPG" +#define ELITE_HW_NAME "Elite-CPGv1.1" #define MAJOR_PRODUCT_NUMBER 0 #define MINOR_PRODUCT_NUMBER 8 #define MAJOR_VERSION_NUMBER 0 @@ -297,6 +307,11 @@ extern "C" #define COUNTOF(x) (sizeof(x) / sizeof(x[0])) #define UNCONNECTED_PIN 0xFFFFFFFF +#define u8_to_u32(a, b, c, d) (((uint32_t)(a) << 24) | ((uint32_t)(b) << 16) | ((uint32_t)(c) << 8) | (d)) +#define u8_to_u16(a, b) (((uint16_t)(a) << 8) | (b)) +#define u8_to_i32(a, b, c, d) (((int32_t)(a) << 24) | ((int32_t)(b) << 16) | ((int32_t)(c) << 8) | ((int32_t)(d))) +#define u8_to_i16(a, b) (((int16_t)(a) << 8) | (int16_t)(b)) + #ifdef __cplusplus } #endif diff --git a/bmd380_peripheral-Debug.vgdbsettings b/bmd380_peripheral-Debug.vgdbsettings index 262e7b6..4c3a3c5 100644 --- a/bmd380_peripheral-Debug.vgdbsettings +++ b/bmd380_peripheral-Debug.vgdbsettings @@ -25,6 +25,7 @@ bmd380_peripheral.vcxproj + 1 true @@ -110,6 +111,7 @@ 0 true false + true jlink-jtag diff --git a/bmd380_peripheral.vcxproj b/bmd380_peripheral.vcxproj index 9196222..31d24a7 100644 --- a/bmd380_peripheral.vcxproj +++ b/bmd380_peripheral.vcxproj @@ -32,13 +32,13 @@ Debug com.visualgdb.arm-eabi - 13.3.1/15.1/r2 + 13.3.1/15.1/r3 true $(ProjectDir)nrf5x.props com.visualgdb.arm-eabi - 13.3.1/15.1/r2 + 13.3.1/15.1/r3 true $(ProjectDir)nrf5x.props diff --git a/builtin_saadc.c b/builtin_saadc.c index 5866332..c6b6226 100644 --- a/builtin_saadc.c +++ b/builtin_saadc.c @@ -330,12 +330,26 @@ static int read_multiple_milivolt_ex(uint32_t *p_channels, float *p_val, uint32_ return 0; } +static int adc_convert_multiple_milivolt(int32_t *p_val_14bit, float *p_val_f, uint32_t count) +{ + int32_t int_val[16]; + + for (int i = 0; i < count; i++) + { + int_val[i] = p_val_14bit[i]; // copy values + p_val_f[i] = adc_convert_milivolt(m_gain, int_val[i], false); + } + + return 0; +} + const adc_drv_if_t builtin_saadc = { - .init = init, - .reset = reset, - .read = read, - .gain = gain, - .read_multiple_channels = read_channels, - .read_multiple_channels_ex = read_channels_ex, - .read_multiple_milivolt_ex = read_multiple_milivolt_ex, + .init = init, + .reset = reset, + .read = read, + .gain = gain, + .read_multiple_channels = read_channels, + .read_multiple_channels_ex = read_channels_ex, + .read_multiple_milivolt_ex = read_multiple_milivolt_ex, + .adc_convert_multiple_milivolt = adc_convert_multiple_milivolt, }; diff --git a/cpg.c b/cpg.c index 03e2e26..95b3853 100644 --- a/cpg.c +++ b/cpg.c @@ -28,8 +28,8 @@ static void cis_version(uint8_t *ins, uint16_t size) VERSION_DATE_HOUR, VERSION_DATE_MINUTE, }; - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)cis_ver, sizeof(cis_ver)); + extern ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + le_data_update((void *)cis_ver, sizeof(cis_ver)); } static void vis_rst(uint8_t *ins, uint16_t size) diff --git a/cpg11_dev_mode.c b/cpg11_dev_mode.c index ba9d9e2..b7f47a0 100644 --- a/cpg11_dev_mode.c +++ b/cpg11_dev_mode.c @@ -6,19 +6,14 @@ #if (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1) -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 - -#define u8_to_u32(a, b, c, d) (((uint32_t)(a) << 24) | ((uint32_t)(b) << 16) | ((uint32_t)(c) << 8) | (d)) -#define u8_to_u16(a, b) (((uint16_t)(a) << 8) | (b)) -#define u8_to_i32(a, b, c, d) (((int32_t)(a) << 24) | ((int32_t)(b) << 16) | ((int32_t)(c) << 8) | ((int32_t)(d))) -#define u8_to_i16(a, b) (((int16_t)(a) << 8) | (int16_t)(b)) +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 // The GPIO corresponding to the pin const uint32_t pin_to_gpio_table[] = { diff --git a/edc20.c b/edc20.c index d40665d..2d6ffb9 100644 --- a/edc20.c +++ b/edc20.c @@ -16,7 +16,7 @@ #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_V2_0) -extern ret_code_t le_event_upadate(uint8_t *p_value, uint16_t len); +extern ret_code_t le_event_update(uint8_t *p_value, uint16_t len); static void dummy(uint8_t *ins, uint16_t size) { @@ -419,7 +419,7 @@ static void dev_mode_read_output_pin(void) (output.cs_adc << 1) | output.cs_dac; - le_event_upadate((uint8_t *)&pin_out_status, sizeof(pin_out_status)); + le_event_update((uint8_t *)&pin_out_status, sizeof(pin_out_status)); NRF_LOG_INFO("pin_out_status = 0x%08X", pin_out_status); NRF_LOG_INFO("| %-32s | %d |", "pin_out_status[31:21] resvd", output.resvd); @@ -467,7 +467,7 @@ static void dev_mode_read_input_pin(void) (input.shut_down << 1) | input.int9466; - le_event_upadate((uint8_t *)&pin_input_status, sizeof(pin_input_status)); + le_event_update((uint8_t *)&pin_input_status, sizeof(pin_input_status)); NRF_LOG_INFO("pin_input_status = 0x%08X", pin_input_status); NRF_LOG_INFO("| %-32s | %d |", "pin_input_status[31:3] resvd", input.resvd); @@ -670,7 +670,7 @@ static void dev_mode_spi2_transfer(uint8_t *ins, uint16_t size) if (miso_data_len > 0) { - le_event_upadate(miso_data, miso_data_len); + le_event_update(miso_data, miso_data_len); } } @@ -845,8 +845,8 @@ static void cis_version(uint8_t *ins, uint16_t size) .hh = 22, .mm = 40, }; - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&cis_ver, sizeof(cis_ver)); + extern ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + le_data_update((void *)&cis_ver, sizeof(cis_ver)); } __WEAK uint16_t bat_volt_read(void) @@ -867,8 +867,8 @@ static void cis_volt(uint8_t *ins, uint16_t size) .opcode = CIS_VOLT, .volt = bat_volt_read(), }; - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&cis_volt, sizeof(cis_volt)); + extern ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + le_data_update((void *)&cis_volt, sizeof(cis_volt)); } __WEAK uint16_t temperature_read(void) @@ -890,8 +890,8 @@ static void cis_temperature(uint8_t *ins, uint16_t size) .opcode = CIS_TEMPERATURE, .temperature = __REV(temperature_read()), }; - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&cis_temperature, sizeof(cis_temperature)); + extern ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + le_data_update((void *)&cis_temperature, sizeof(cis_temperature)); } static void cis_cali(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); } diff --git a/elite.c b/elite.c index c717dfb..2d7eabf 100644 --- a/elite.c +++ b/elite.c @@ -120,8 +120,8 @@ void elite_init(void) void elite_instr_send(void *p, size_t size) { /* reply the instruction */ - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate(p, size); + extern ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + le_data_update(p, size); xMessageBufferSend(instr_msg, p, size, portMAX_DELAY); } diff --git a/elite.h b/elite.h index c29521f..3364fff 100644 --- a/elite.h +++ b/elite.h @@ -2,19 +2,17 @@ #define __ELITE_H__ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif +#include "app_config.h" +#include "app_error.h" + #include "elite_def.h" -#include "app_config.h" - -#include -#include -#include - -void elite_init(void); -void elite_instr_send(void *p, size_t size); + void elite_init(void); + void elite_instr_send(void *p, size_t size); #ifdef __cplusplus } diff --git a/elite_board.c b/elite_board.c index 25f6c60..8248ca1 100644 --- a/elite_board.c +++ b/elite_board.c @@ -18,7 +18,8 @@ void elite_board_demo(void) #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_V2_0) #elif (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0) - + extern void pel_pulse_gen_demo(void); + pel_pulse_gen_demo(); #elif (DEF_ELITE_MODEL == DEF_ELITE_CPG_V1_1) cpg_pulse_default_demo_ext(); #endif diff --git a/elite_dev.c b/elite_dev.c index b9f7adc..6701834 100644 --- a/elite_dev.c +++ b/elite_dev.c @@ -21,8 +21,8 @@ static void cis_version(uint8_t *ins, uint16_t size) VERSION_DATE_HOUR, VERSION_DATE_MINUTE, }; - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)cis_ver, sizeof(cis_ver)); + extern ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + le_data_update((void *)cis_ver, sizeof(cis_ver)); } static void vis_rst(uint8_t *ins, uint16_t size) @@ -30,7 +30,7 @@ static void vis_rst(uint8_t *ins, uint16_t size) NRF_LOG_INFO("%s", __FUNCTION__); } -#define UNDEF_GPIO 0xFFFFFFFF +#define UNDEF_GPIO 0xFFFFFFFF // The GPIO corresponding to the pin const uint32_t pin_to_gpio_table[] = { @@ -194,14 +194,10 @@ void dev_mode_gpio_function(uint8_t *ins) } case 0x01: { - uint32_t high_low = p_ins->param[0]; - uint32_t set_pin[44] = {6, 8, 9, 10, 11, 12, 13, 14, 16, 17, - 18, 20, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 59, 60, 61, 62}; + uint32_t high_low = p_ins->param[0]; + uint32_t set_pin[44] = { 6, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 20, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 59, 60, 61, 62 }; - for (int i=0; i -#include - #ifdef __cplusplus extern "C" { #endif #include "app_config.h" -#include "apply_old_config.h" -#include "sdk_config.h" +#include "app_error.h" -#include "nrf_log.h" -#include "nrf_log_ctrl.h" -#include "nrf_log_default_backends.h" - -#include "nrf_delay.h" -#include "nrf_gpio.h" - -#include "nrf_sdh.h" -#include "nrf_sdh_ble.h" -#include "nrf_sdh_freertos.h" - -#include "ble_advdata.h" #include "ble_advertising.h" -#include "ble_srv_common.h" + +#include "nrf_sdh_ble.h" #ifdef __cplusplus } diff --git a/le_dfu.c b/le_dfu.c index 4a295a7..3732e29 100644 --- a/le_dfu.c +++ b/le_dfu.c @@ -1,31 +1,15 @@ -#include -#include - #ifdef __cplusplus extern "C" { #endif #include "app_config.h" -#include "apply_old_config.h" -#include "sdk_config.h" - -#include "nrf_log.h" -#include "nrf_log_ctrl.h" -#include "nrf_log_default_backends.h" - -#include "nrf_delay.h" -#include "nrf_gpio.h" - -#include "nrf_sdh.h" -#include "nrf_sdh_ble.h" -#include "nrf_sdh_freertos.h" +#include "app_error.h" #include "ble_conn_state.h" - #include "ble_dfu.h" -#include "ble_dis.h" -#include "nrf_ble_gatt.h" + +#include "nrf_log.h" #ifdef __cplusplus } diff --git a/le_elite_srv.c b/le_elite_srv.c index e48950b..8f2c0ab 100644 --- a/le_elite_srv.c +++ b/le_elite_srv.c @@ -1,22 +1,26 @@ -#include "sdk_common.h" +#ifdef __cplusplus +extern "C" +{ +#endif +#include + +#include "app_config.h" #include "app_error.h" -#include "ble_conn_state.h" -#include "ble_gatts.h" + #include "ble_srv_common.h" -#include "elite.h" -#include "nrf_sdh_ble.h" #include "nrf_log.h" -#include "nrf_log_ctrl.h" -#include "nrf_log_default_backends.h" +#include "nrf_sdh_ble.h" #include "FreeRTOS.h" -#include "semphr.h" #include "task.h" -#include -#include +#include "elite.h" + +#ifdef __cplusplus +} +#endif #if NRF_MODULE_ENABLED(BLE_ELITE_SRV) @@ -100,6 +104,7 @@ static void on_write(elite_context_t *p_context, ble_evt_t const *p_ble_evt) break; case BLE_UUID_ELITE_INST_CHAR: + NRF_LOG_INFO(""); NRF_LOG_HEXDUMP_INFO(p_evt_write->data, p_evt_write->len); elite_instr_send((void *)p_evt_write->data, p_evt_write->len); break; @@ -233,7 +238,7 @@ ret_code_t le_data_notify(uint8_t *p_value, uint16_t len) return sd_ble_gatts_hvx(elite_context.conn_handle, &hvx_params); } -ret_code_t le_data_upadate(uint8_t *p_value, uint16_t len) +ret_code_t le_data_update(uint8_t *p_value, uint16_t len) { static uint8_t values[1 + NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3]; @@ -267,7 +272,7 @@ ret_code_t le_event_notify(uint8_t *p_value, uint16_t len) return sd_ble_gatts_hvx(elite_context.conn_handle, &hvx_params); } -ret_code_t le_event_upadate(uint8_t *p_value, uint16_t len) +ret_code_t le_event_update(uint8_t *p_value, uint16_t len) { // update database. ble_gatts_value_t gatts_value = { diff --git a/le_gap.c b/le_gap.c index 04f469e..7220cc0 100644 --- a/le_gap.c +++ b/le_gap.c @@ -1,22 +1,18 @@ -#include -#include -#include - #ifdef __cplusplus extern "C" { #endif -#include "app_config.h" -#include "apply_old_config.h" -#include "sdk_config.h" +#include -#include "nrf_sdh.h" -#include "nrf_sdh_ble.h" +#include "app_config.h" +#include "app_error.h" +#include "app_util.h" + +#include "ble_gap.h" #include "nrf_log.h" - -#include "app_error.h" +#include "nrf_sdh_ble.h" #ifdef __cplusplus } @@ -64,4 +60,4 @@ void le_gap_disconnect(uint16_t conn_handle, void *p_context) { NRF_LOG_DEBUG("Disconnected connection handle %d", conn_handle); } -} \ No newline at end of file +} diff --git a/le_gatt.c b/le_gatt.c index ebd2f15..67534ce 100644 --- a/le_gatt.c +++ b/le_gatt.c @@ -1,28 +1,13 @@ -#include -#include - #ifdef __cplusplus extern "C" { #endif #include "app_config.h" -#include "apply_old_config.h" -#include "sdk_config.h" +#include "app_error.h" -#include "nrf_log.h" -#include "nrf_log_ctrl.h" -#include "nrf_log_default_backends.h" - -#include "nrf_delay.h" -#include "nrf_gpio.h" - -#include "nrf_sdh.h" -#include "nrf_sdh_ble.h" -#include "nrf_sdh_freertos.h" - -#include "ble_gatt.h" #include "nrf_ble_gatt.h" +#include "nrf_sdh_ble.h" #ifdef __cplusplus } diff --git a/le_srv.c b/le_srv.c index 5bcb201..20abf04 100644 --- a/le_srv.c +++ b/le_srv.c @@ -1,41 +1,26 @@ -#include -#include #ifdef __cplusplus extern "C" { #endif +#include + #include "app_config.h" -#include "apply_old_config.h" -#include "sdk_config.h" +#include "app_error.h" -#include "nrf_log.h" -#include "nrf_log_ctrl.h" -#include "nrf_log_default_backends.h" - -#include "nrf_delay.h" -#include "nrf_gpio.h" - -#include "nrf_sdh.h" -#include "nrf_sdh_ble.h" -#include "nrf_sdh_freertos.h" - -#include "ble_conn_state.h" - -#include "ble_dfu.h" #include "ble_dis.h" -#include "nrf_ble_gatt.h" +#include "ble_srv_common.h" #ifdef __cplusplus } #endif -#define MANUFACTURER_NAME "MEMCHIP" /**< Manufacturer. Will be passed to Device Information Service. */ -#define HW_REV STRINGIFY(MAJOR_PRODUCT_NUMBER) "." STRINGIFY(MINOR_PRODUCT_NUMBER) "." STRINGIFY(MAJOR_VERSION_NUMBER) "." STRINGIFY(MINOR_VERSION_NUMBER) -#define FW_REV "0.1.0" -#define SER_NUM "0000-00-00-00001" -#define MODULE_NAME ELITE_DEVICE_NAME +#define MANUFACTURER_NAME "Wisetop Technology Co." /**< Manufacturer. Will be passed to Device Information Service. */ +#define SERIAL_NUMBER "0000-00-00-00001" +#define MODEL_NUMBER ELITE_HW_NAME +#define HARDWARE_REVISION STRINGIFY(MAJOR_PRODUCT_NUMBER) "." STRINGIFY(MINOR_PRODUCT_NUMBER) "." STRINGIFY(MAJOR_VERSION_NUMBER) "." STRINGIFY(MINOR_VERSION_NUMBER) +#define FIRMWARE_REVISION "0.1.0" static void le_dis_init(void) { @@ -46,10 +31,10 @@ static void le_dis_init(void) memset(&sys_id, 0, sizeof(sys_id)); ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, MANUFACTURER_NAME); - ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, FW_REV); - ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, HW_REV); - ble_srv_ascii_to_utf8(&dis_init.model_num_str, MODULE_NAME); - ble_srv_ascii_to_utf8(&dis_init.serial_num_str, SER_NUM); + ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, FIRMWARE_REVISION); + ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, HARDWARE_REVISION); + ble_srv_ascii_to_utf8(&dis_init.model_num_str, MODEL_NUMBER); + ble_srv_ascii_to_utf8(&dis_init.serial_num_str, SERIAL_NUMBER); dis_init.p_sys_id = &sys_id; dis_init.dis_char_rd_sec = SEC_OPEN; diff --git a/nrf5x.xml b/nrf5x.xml index 4d4ad47..5cd7efb 100644 --- a/nrf5x.xml +++ b/nrf5x.xml @@ -4,7 +4,7 @@ 13.3.1 15.1 - 2 + 3 com.sysprogs.arm.nordic.nrf5x 17.0 diff --git a/pel.c b/pel.c index 4278ab5..2aeecf4 100644 --- a/pel.c +++ b/pel.c @@ -1,5 +1,8 @@ -#include "pel.h" +#include "app_config.h" +#include "app_error.h" + #include "elite_board.h" +#include "pel.h" #include "elite_def.h" @@ -18,9 +21,24 @@ typedef struct uint32_t mask; } input_pin_t; -TaskHandle_t test_gpio_task_Handle = NULL; +typedef struct +{ + uint16_t pattern_id; + uint32_t pattern; +} resistor_combination_t; -static pel_output_t output_data = { 0 }; +typedef struct __PACKED +{ + uint32_t notify_period; + uint32_t total_notify_count; +} characteristic_param_t; + +static bool data_char_notify_running; +static bool event_char_notify_running; +TaskHandle_t test_gpio_task_Handle = NULL; +static pel_output_t output_data = { 0 }; +static resistor_combination_t global_resis = { 0 }; +uint8_t global_memoryboard_id = 0xFF; const input_pin_t input_pin_tab[] = { { 0.5, INPUT_1_PIN, PEL_0P5R_MASK}, @@ -39,13 +57,16 @@ const input_pin_t input_pin_tab[] = { static float _load_set(uint32_t mask) { - float ohms = 0; + float ohms = 0; + global_resis.pattern = mask; + for (int32_t i = COUNTOF(input_pin_tab) - 1; i >= 0; i--) { if (input_pin_tab[i].mask & mask) { nrf_gpio_pin_clear(input_pin_tab[i].pin); ohms += input_pin_tab[i].val; + NRF_LOG_INFO("enable R%-2d(" NRF_LOG_FLOAT_MARKER "ohm)", i + 1, NRF_LOG_FLOAT(input_pin_tab[i].val)); } else { @@ -55,17 +76,111 @@ static float _load_set(uint32_t mask) return ohms; } -static void set_resistor_to_default(void) +void set_high_z_state(void) { - const uint32_t resistor_to_default = 0b000000000000; - - _load_set(resistor_to_default); + NRF_LOG_INFO("high_z_state"); + _load_set(0); } -static float _load_set_by_ohms(float ohms) +void set_pattern_resistor(uint16_t pattern_id) { - // TODO... - return ohms; + const resistor_combination_t pattern_tab[] = { + { 1, 0b111}, + { 2, 0b011}, + { 3, 0b101}, + { 4, 0b001}, + { 5, 0b111 << 1}, + { 6, 0b011 << 1}, + { 7, 0b101 << 1}, + { 8, 0b001 << 1}, + { 9, 0b111 << 2}, + {10, 0b011 << 2}, + {11, 0b101 << 2}, + {12, 0b001 << 2}, + {13, 0b111 << 3}, + {14, 0b011 << 3}, + {15, 0b101 << 3}, + {16, 0b001 << 3}, + {17, 0b111 << 4}, + {18, 0b011 << 4}, + {19, 0b101 << 4}, + {20, 0b001 << 4}, + {21, 0b111 << 5}, + {22, 0b011 << 5}, + {23, 0b101 << 5}, + {24, 0b001 << 5}, + {25, 0b111 << 6}, + {26, 0b011 << 6}, + {27, 0b101 << 6}, + {28, 0b001 << 6}, + {29, 0b111 << 7}, + {30, 0b011 << 7}, + {31, 0b101 << 7}, + {32, 0b001 << 7}, + {33, 0b111 << 8}, + {34, 0b011 << 8}, + {35, 0b101 << 8}, + {36, 0b001 << 8}, + {37, 0b111 << 9}, + {38, 0b011 << 9}, + {39, 0b101 << 9}, + {40, 0b001 << 9}, + {41, 0b11 << 10}, + {42, 0b01 << 10}, + {43, 0b1 << 11}, + }; + + global_resis.pattern_id = pattern_id; + + for (int32_t i = 0; i < ARRAY_SIZE(pattern_tab); i++) + { + if (pattern_tab[i].pattern_id == pattern_id) + { + NRF_LOG_INFO("pattern_id[%d] = pattern:0x%08X", pattern_tab[i].pattern_id, pattern_tab[i].pattern); + _load_set(pattern_tab[i].pattern); + } + } +} + +void set_manual_resistor(uint16_t manual_val) +{ + typedef union + { + struct + { + uint32_t R1_en : 1; + uint32_t R2_en : 1; + uint32_t R3_en : 1; + uint32_t R4_en : 1; + uint32_t R5_en : 1; + uint32_t R6_en : 1; + uint32_t R7_en : 1; + uint32_t R8_en : 1; + uint32_t R9_en : 1; + uint32_t R10_en : 1; + uint32_t R11_en : 1; + uint32_t R12_en : 1; + uint32_t rsvd : 20; + }; + uint32_t val; + } resis_t; + + resis_t resis = { 0 }; + + resis.R1_en = (manual_val >> 15) & 1; + resis.R2_en = (manual_val >> 14) & 1; + resis.R3_en = (manual_val >> 13) & 1; + resis.R4_en = (manual_val >> 12) & 1; + resis.R5_en = (manual_val >> 11) & 1; + resis.R6_en = (manual_val >> 10) & 1; + resis.R7_en = (manual_val >> 9) & 1; + resis.R8_en = (manual_val >> 8) & 1; + resis.R9_en = (manual_val >> 7) & 1; + resis.R10_en = (manual_val >> 6) & 1; + resis.R11_en = (manual_val >> 5) & 1; + resis.R12_en = (manual_val >> 4) & 1; + + _load_set(resis.val); } static void _sample_measure_out_is_low(void) @@ -140,7 +255,7 @@ pel_output_t pel_smaple_and_convt_all(uint32_t measure_out, uint32_t load_mask) int32_t results[COUNTOF(ch_list)]; float f_results[COUNTOF(ch_list)]; /* config E-load */ - set_resistor_to_default(); + _load_set(0); _load_set(load_mask); /* send a pulse to sample and then read ADC channels */ if (measure_out) @@ -176,10 +291,10 @@ pel_output_t pel_smaple_and_convt_all(uint32_t measure_out, uint32_t load_mask) } #define VERSION_DATE_YEAR 24 -#define VERSION_DATE_MONTH 10 -#define VERSION_DATE_DAY 8 -#define VERSION_DATE_HOUR 12 -#define VERSION_DATE_MINUTE 31 +#define VERSION_DATE_MONTH 12 +#define VERSION_DATE_DAY 25 +#define VERSION_DATE_HOUR 17 +#define VERSION_DATE_MINUTE 50 static void cis_version(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); @@ -191,8 +306,8 @@ static void cis_version(uint8_t *ins, uint16_t size) VERSION_DATE_HOUR, VERSION_DATE_MINUTE, }; - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)cis_ver, sizeof(cis_ver)); + extern ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + le_data_update((void *)cis_ver, sizeof(cis_ver)); } static void vis_rst(uint8_t *ins, uint16_t size) @@ -256,345 +371,719 @@ void test_gpio_task(void *pArg) } } -void set_a_specific_resistor_combination(uint16_t resistor_combination) +static void decode_and_set_resistor_pattern(uint8_t *param) { - typedef struct - { - uint16_t val; - uint32_t mask; - } resistor_combination_t; + uint16_t pattern_id = u8_to_u16(param[0], param[1]); - const resistor_combination_t resis_combination_tab[] = { - { 1, 0b111}, - { 2, 0b011}, - { 3, 0b101}, - { 4, 0b001}, - { 5, 0b111 << 1}, - { 6, 0b011 << 1}, - { 7, 0b101 << 1}, - { 8, 0b001 << 1}, - { 9, 0b111 << 2}, - {10, 0b011 << 2}, - {11, 0b101 << 2}, - {12, 0b001 << 2}, - {13, 0b111 << 3}, - {14, 0b011 << 3}, - {15, 0b101 << 3}, - {16, 0b001 << 3}, - {17, 0b111 << 4}, - {18, 0b011 << 4}, - {19, 0b101 << 4}, - {20, 0b001 << 4}, - {21, 0b111 << 5}, - {22, 0b011 << 5}, - {23, 0b101 << 5}, - {24, 0b001 << 5}, - {25, 0b111 << 6}, - {26, 0b011 << 6}, - {27, 0b101 << 6}, - {28, 0b001 << 6}, - {29, 0b111 << 7}, - {30, 0b011 << 7}, - {31, 0b101 << 7}, - {32, 0b001 << 7}, - {33, 0b111 << 8}, - {34, 0b011 << 8}, - {35, 0b101 << 8}, - {36, 0b001 << 8}, - {37, 0b111 << 9}, - {38, 0b011 << 9}, - {39, 0b101 << 9}, - {40, 0b001 << 9}, - {41, 0b11 << 10}, - {42, 0b01 << 10}, - {43, 0b1 << 11}, - }; - - for (int32_t i = 0; i < COUNTOF(resis_combination_tab); i++) - { - if (resis_combination_tab[i].val == resistor_combination) - { - NRF_LOG_INFO("No.%d resistor_combination: 0x%03X(FW) ", resis_combination_tab[i].val, resis_combination_tab[i].mask); - NRF_LOG_INFO("Input | 1 | 2 | 3 | 4 | 5 | 6 |"); - NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", - (resis_combination_tab[i].mask & 1 << 0), - (resis_combination_tab[i].mask & 1 << 1) >> 1, - (resis_combination_tab[i].mask & 1 << 2) >> 2, - (resis_combination_tab[i].mask & 1 << 3) >> 3, - (resis_combination_tab[i].mask & 1 << 4) >> 4, - (resis_combination_tab[i].mask & 1 << 5) >> 5); - - NRF_LOG_INFO("Input | 7 | 8 | 9 | 10 | 11 | 12 |"); - NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", - (resis_combination_tab[i].mask & 1 << 6) >> 6, - (resis_combination_tab[i].mask & 1 << 7) >> 7, - (resis_combination_tab[i].mask & 1 << 8) >> 8, - (resis_combination_tab[i].mask & 1 << 9) >> 9, - (resis_combination_tab[i].mask & 1 << 10) >> 10, - (resis_combination_tab[i].mask & 1 << 11) >> 11); - set_resistor_to_default(); - _load_set(resis_combination_tab[i].mask); - } - } + set_pattern_resistor(pattern_id); } -void pel_select_resistor_combinations_mode(uint8_t *ins) +static void decode_and_set_manual_resistor(uint8_t *param) { -#define SET_A_SPECIFIC_RESISTOR_COMBINATION 0x00 -#define SET_ALL_RESISTORS_AT_ONCE 0x01 + uint16_t manual_val = u8_to_u16(param[0], param[1]); - uint16_t set_resistor_type = (ins[4] & 0xF0) >> 4; - uint16_t val = ((ins[4] & 0x0F) << 8) | ins[5]; - - if (set_resistor_type == 0) - { - set_a_specific_resistor_combination(val); - } - else if (set_resistor_type == 1) - { - typedef union - { - struct - { - uint32_t input1 : 1; - uint32_t input2 : 1; - uint32_t input3 : 1; - uint32_t input4 : 1; - uint32_t input5 : 1; - uint32_t input6 : 1; - uint32_t input7 : 1; - uint32_t input8 : 1; - uint32_t input9 : 1; - uint32_t input10 : 1; - uint32_t input11 : 1; - uint32_t input12 : 1; - }; - uint32_t val; - } resis_t; - - resis_t resis; - - resis.input1 = (val & 0b0000100000000000) >> 11; - resis.input2 = (val & 0b0000010000000000) >> 10; - resis.input3 = (val & 0b0000001000000000) >> 9; - resis.input4 = (val & 0b0000000100000000) >> 8; - resis.input5 = (val & 0b0000000010000000) >> 7; - resis.input6 = (val & 0b0000000001000000) >> 6; - resis.input7 = (val & 0b0000000000100000) >> 5; - resis.input8 = (val & 0b0000000000010000) >> 4; - resis.input9 = (val & 0b0000000000001000) >> 3; - resis.input10 = (val & 0b0000000000000100) >> 2; - resis.input11 = (val & 0b0000000000000010) >> 1; - resis.input12 = (val & 0b0000000000000001) >> 0; - - NRF_LOG_INFO("Set_all_resistors_at_once: 0x%03X(FW) ", resis.val); - NRF_LOG_INFO("Input | 1 | 2 | 3 | 4 | 5 | 6 |"); - NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", - (resis.val & 1 << 0), - (resis.val & 1 << 1) >> 1, - (resis.val & 1 << 2) >> 2, - (resis.val & 1 << 3) >> 3, - (resis.val & 1 << 4) >> 4, - (resis.val & 1 << 5) >> 5); - - NRF_LOG_INFO("Input | 7 | 8 | 9 | 10 | 11 | 12 |"); - NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", - (resis.val & 1 << 6) >> 6, - (resis.val & 1 << 7) >> 7, - (resis.val & 1 << 8) >> 8, - (resis.val & 1 << 9) >> 9, - (resis.val & 1 << 10) >> 10, - (resis.val & 1 << 11) >> 11); - - set_resistor_to_default(); - _load_set(resis.val); - } - else - { - printf("No this cmd..."); - } + set_manual_resistor(manual_val); } -#define MAGIC_NUM 0xFF00 -static pel_output_t dev_mode_pel_output; -static void dev_mode(uint8_t *ins, uint16_t size) +static void dev_mode_input_resistor(uint8_t *ins) { - NRF_LOG_INFO("%s", __FUNCTION__); + NRF_LOG_INFO("[DEV MODE] %s", __FUNCTION__); + struct __PACKED { - uint8_t id : 4; - uint8_t : 4; - uint16_t magic : 16; + uint8_t id : 4; + uint8_t ins_type : 4; + uint8_t pkg_size; + uint8_t mode; + uint8_t func_id; uint8_t opcode; uint8_t param[]; } *p_ins = (void *)ins; - if (p_ins->magic != MAGIC_NUM) + switch (p_ins->opcode) { + case 0x00: + set_high_z_state(); + break; + + case 0x01: + decode_and_set_resistor_pattern(p_ins->param); + break; + + case 0x02: + decode_and_set_manual_resistor(p_ins->param); + break; + + default: + break; + } +} + +static void data_char_update_once(void) +{ + ret_code_t le_data_update(uint8_t * p_value, uint16_t len); + + typedef struct __PACKED + { + int32_t val_1; + int32_t val_2; + int32_t val_3; + int32_t val_4; + int32_t val_5; + float val_6_f; + float val_7_f; + float val_8_f; + float val_9_f; + float val_10_f; + } test_val_t; + + static test_val_t data = { + .val_1 = 0, + .val_2 = 100, + .val_3 = 1000, + .val_4 = 10000, + .val_5 = 100000, + .val_6_f = 1.0, + .val_7_f = 5.0, + .val_8_f = 10.0, + .val_9_f = 15.0, + .val_10_f = 20.0, + }; + + { + char str[128]; + snprintf(str, sizeof(str), "val_1: 0x%08X, %d", data.val_1, data.val_1); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_2: 0x%08X, %d", data.val_2, data.val_2); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_3: 0x%08X, %d", data.val_3, data.val_3); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_4: 0x%08X, %d", data.val_4, data.val_4); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_5: 0x%08X, %d", data.val_5, data.val_5); + NRF_LOG_INFO("%s", str); + + snprintf(str, sizeof(str), "val_6_f: %.7f", data.val_6_f, data.val_6_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_7_f: %.7f", data.val_7_f, data.val_7_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_8_f: %.7f", data.val_8_f, data.val_8_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_9_f: %.7f", data.val_9_f, data.val_9_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_10_f: %.7f", data.val_10_f, data.val_10_f); + NRF_LOG_INFO("%s", str); + } + + le_data_update((void *)&data, sizeof(data)); + + data.val_1++; + data.val_2++; + data.val_3++; + data.val_4++; + data.val_5++; + data.val_6_f += 0.01; + data.val_7_f += 0.01; + data.val_8_f += 0.01; + data.val_9_f += 0.01; + data.val_10_f += 0.01; +} + +static ret_code_t _send_data_char_notify_start_packet(void *p_buf, uint16_t p_buf_size, uint32_t loops) +{ + memset(p_buf, 0x00, sizeof(p_buf)); + + for (uint32_t i = 0; i < loops; i++) + { + ret_code_t le_data_notify(uint8_t * p_value, uint16_t len); + ret_code_t ret = le_data_notify((void *)p_buf, p_buf_size); + + if (ret != NRF_SUCCESS) + { + return ret; + } + } + + return NRF_SUCCESS; +} + +static void start_data_char_notify_task(void *p_arg) +{ + typedef struct __PACKED + { + uint8_t mem_board_id; + uint32_t notify_time; + uint8_t packet_seq; + int32_t val_1; + int32_t val_2; + int32_t val_3; + int32_t val_4; + int32_t val_5; + float val_6_f; + float val_7_f; + float val_8_f; + float val_9_f; + float val_10_f; + uint16_t pattern_id; + uint32_t pattern; + } data_char_packet_t; + + bool first_data = true; + data_char_packet_t packet_buf; + characteristic_param_t *data_char_notify_param = (characteristic_param_t *)p_arg; + data_char_notify_running = true; + + memset(&packet_buf, 0x00, sizeof(packet_buf)); + _send_data_char_notify_start_packet(&packet_buf, sizeof(packet_buf), 4); + + for (;;) + { + if (data_char_notify_running) + { + if (first_data) + { + packet_buf.mem_board_id = global_memoryboard_id; + packet_buf.notify_time = xTaskGetTickCount(); + packet_buf.packet_seq = 0; + packet_buf.val_1 = 0; + packet_buf.val_2 = 100; + packet_buf.val_3 = 1000; + packet_buf.val_4 = 10000; + packet_buf.val_5 = 100000; + packet_buf.val_6_f = 1.0; + packet_buf.val_7_f = 5.0; + packet_buf.val_8_f = 10.0; + packet_buf.val_9_f = 15.0; + packet_buf.val_10_f = 20.0; + packet_buf.pattern_id = global_resis.pattern_id; + packet_buf.pattern = global_resis.pattern; + first_data = false; + } + else + { + packet_buf.mem_board_id = global_memoryboard_id; + packet_buf.notify_time = xTaskGetTickCount(); + packet_buf.packet_seq += 1; + packet_buf.val_1 += 1; + packet_buf.val_2 += 1; + packet_buf.val_3 += 1; + packet_buf.val_4 += 1; + packet_buf.val_5 += 1; + packet_buf.val_6_f += 0.01; + packet_buf.val_7_f += 0.01; + packet_buf.val_8_f += 0.01; + packet_buf.val_9_f += 0.01; + packet_buf.val_10_f += 0.01; + packet_buf.pattern_id = global_resis.pattern_id; + packet_buf.pattern = global_resis.pattern; + } + + ret_code_t le_data_notify(uint8_t * p_value, uint16_t len); + ret_code_t ret = le_data_notify((void *)&packet_buf, sizeof(packet_buf)); + + { + char str[128]; + snprintf(str, sizeof(str), "{%d, %d, %d, %d, %d, %d, %d, %d, %.7f, %.7f, %.7f, %.7f, %.7f, %d, 0x%08X}", packet_buf.mem_board_id, packet_buf.notify_time, packet_buf.packet_seq, packet_buf.val_1, packet_buf.val_2, packet_buf.val_3, packet_buf.val_4, packet_buf.val_5, packet_buf.val_6_f, packet_buf.val_7_f, packet_buf.val_8_f, packet_buf.val_9_f, packet_buf.val_10_f, packet_buf.pattern_id, packet_buf.pattern); + NRF_LOG_INFO("%s", str); + } + + vTaskDelay(pdMS_TO_TICKS(data_char_notify_param->notify_period)); + } + else // stop data update process + { + free(data_char_notify_param); + vTaskDelete(NULL); + } + } +} + +static void decode_start_data_char_notify(uint8_t *param) +{ + characteristic_param_t *data_char_notify_param = malloc(sizeof(characteristic_param_t)); + + if (data_char_notify_param == NULL) + { + NRF_LOG_ERROR("Failed to allocate memory for data_char_notify_param"); return; } + data_char_notify_param->notify_period = u8_to_u32(param[0], param[1], param[2], param[3]); + data_char_notify_param->total_notify_count = u8_to_u32(param[0], param[1], param[2], param[3]); + data_char_notify_param->notify_period = 100; + data_char_notify_param->total_notify_count = 5; + + xTaskCreate(start_data_char_notify_task, "start_data_char_notify_task", 2048, (void *)data_char_notify_param, 3, NULL); +} + +static void stop_data_char_notify(void) +{ + data_char_notify_running = false; +} + +static void event_char_update_once(void) +{ + ret_code_t le_event_update(uint8_t * p_value, uint16_t len); + + typedef struct __PACKED + { + int32_t val_1; + int32_t val_2; + int32_t val_3; + int32_t val_4; + int32_t val_5; + float val_6_f; + float val_7_f; + float val_8_f; + float val_9_f; + float val_10_f; + } test_val_t; + + static test_val_t data = { + .val_1 = 0, + .val_2 = 100, + .val_3 = 1000, + .val_4 = 10000, + .val_5 = 100000, + .val_6_f = 1.0, + .val_7_f = 5.0, + .val_8_f = 10.0, + .val_9_f = 15.0, + .val_10_f = 20.0, + }; + + { + char str[128]; + snprintf(str, sizeof(str), "val_1: 0x%08X, %d", data.val_1, data.val_1); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_2: 0x%08X, %d", data.val_2, data.val_2); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_3: 0x%08X, %d", data.val_3, data.val_3); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_4: 0x%08X, %d", data.val_4, data.val_4); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_5: 0x%08X, %d", data.val_5, data.val_5); + NRF_LOG_INFO("%s", str); + + snprintf(str, sizeof(str), "val_6_f: %.7f", data.val_6_f, data.val_6_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_7_f: %.7f", data.val_7_f, data.val_7_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_8_f: %.7f", data.val_8_f, data.val_8_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_9_f: %.7f", data.val_9_f, data.val_9_f); + NRF_LOG_INFO("%s", str); + snprintf(str, sizeof(str), "val_10_f: %.7f", data.val_10_f, data.val_10_f); + NRF_LOG_INFO("%s", str); + } + + le_event_update((void *)&data, sizeof(data)); + + data.val_1++; + data.val_2++; + data.val_3++; + data.val_4++; + data.val_5++; + data.val_6_f += 0.01; + data.val_7_f += 0.01; + data.val_8_f += 0.01; + data.val_9_f += 0.01; + data.val_10_f += 0.01; +} + +static ret_code_t _send_event_char_notify_start_packet(void *p_buf, uint16_t p_buf_size, uint32_t loops) +{ + memset(p_buf, 0x00, sizeof(p_buf)); + + for (uint32_t i = 0; i < loops; i++) + { + ret_code_t le_event_notify(uint8_t * p_value, uint16_t len); + ret_code_t ret = le_event_notify((void *)p_buf, p_buf_size); + + if (ret != NRF_SUCCESS) + { + return ret; + } + } + + return NRF_SUCCESS; +} + +static void start_event_char_notify_task(void *p_arg) +{ + typedef struct __PACKED + { + uint8_t mem_board_id; + uint32_t notify_time; + uint8_t packet_seq; + int32_t val_1; + int32_t val_2; + int32_t val_3; + int32_t val_4; + int32_t val_5; + float val_6_f; + float val_7_f; + float val_8_f; + float val_9_f; + float val_10_f; + uint16_t pattern_id; + uint32_t pattern; + } data_char_packet_t; + + bool first_data = true; + data_char_packet_t packet_buf; + characteristic_param_t *event_char_notify_param = (characteristic_param_t *)p_arg; + event_char_notify_running = true; + + memset(&packet_buf, 0x00, sizeof(packet_buf)); + _send_event_char_notify_start_packet(&packet_buf, sizeof(packet_buf), 4); + + for (;;) + { + if (event_char_notify_running) + { + if (first_data) + { + packet_buf.mem_board_id = global_memoryboard_id; + packet_buf.notify_time = xTaskGetTickCount(); + packet_buf.packet_seq = 0; + packet_buf.val_1 = 1; + packet_buf.val_2 = 2; + packet_buf.val_3 = 3; + packet_buf.val_4 = 4; + packet_buf.val_5 = 5; + packet_buf.val_6_f = 1.0; + packet_buf.val_7_f = 2.0; + packet_buf.val_8_f = 3.0; + packet_buf.val_9_f = 4.0; + packet_buf.val_10_f = 5.0; + packet_buf.pattern_id = global_resis.pattern_id; + packet_buf.pattern = global_resis.pattern; + first_data = false; + } + else + { + packet_buf.mem_board_id = global_memoryboard_id; + packet_buf.notify_time = xTaskGetTickCount(); + packet_buf.packet_seq += 1; + packet_buf.val_1 += 1; + packet_buf.val_2 += 1; + packet_buf.val_3 += 1; + packet_buf.val_4 += 1; + packet_buf.val_5 += 1; + packet_buf.val_6_f += 0.01; + packet_buf.val_7_f += 0.01; + packet_buf.val_8_f += 0.01; + packet_buf.val_9_f += 0.01; + packet_buf.val_10_f += 0.01; + packet_buf.pattern_id = global_resis.pattern_id; + packet_buf.pattern = global_resis.pattern; + } + + ret_code_t le_event_notify(uint8_t * p_value, uint16_t len); + ret_code_t ret = le_event_notify((void *)&packet_buf, sizeof(packet_buf)); + + { + char str[128]; + snprintf(str, sizeof(str), "{%d, %d, %d, %d, %d, %d, %d, %d, %.7f, %.7f, %.7f, %.7f, %.7f, %d, 0x%08X}", packet_buf.mem_board_id, packet_buf.notify_time, packet_buf.packet_seq, packet_buf.val_1, packet_buf.val_2, packet_buf.val_3, packet_buf.val_4, packet_buf.val_5, packet_buf.val_6_f, packet_buf.val_7_f, packet_buf.val_8_f, packet_buf.val_9_f, packet_buf.val_10_f, packet_buf.pattern_id, packet_buf.pattern); + NRF_LOG_INFO("%s", str); + } + + vTaskDelay(pdMS_TO_TICKS(event_char_notify_param->notify_period)); + } + else // stop data update process + { + free(event_char_notify_param); + vTaskDelete(NULL); + } + } +} + +static void decode_start_event_char_notify(uint8_t *param) +{ + characteristic_param_t *event_char_notify_param = malloc(sizeof(characteristic_param_t)); + + if (event_char_notify_param == NULL) + { + NRF_LOG_ERROR("Failed to allocate memory for event_char_notify_param"); + return; + } + + event_char_notify_param->notify_period = u8_to_u32(param[0], param[1], param[2], param[3]); + event_char_notify_param->total_notify_count = u8_to_u32(param[0], param[1], param[2], param[3]); + event_char_notify_param->notify_period = 1000; + event_char_notify_param->total_notify_count = 5; + + xTaskCreate(start_event_char_notify_task, "start_event_char_notify_task", 2048, (void *)event_char_notify_param, 3, NULL); +} + +static void stop_event_char_notify(void) +{ + event_char_notify_running = false; +} + +static void dev_mode_characteristic(uint8_t *ins) +{ + NRF_LOG_INFO("[DEV MODE] %s", __FUNCTION__); + + struct __PACKED + { + uint8_t id : 4; + uint8_t ins_type : 4; + uint8_t pkg_size; + uint8_t mode; + uint8_t func_id; + uint8_t opcode; + uint8_t param[]; + } *p_ins = (void *)ins; + switch (p_ins->opcode) { - case 0x60: { - struct - { - uint8_t status; - uint16_t mask; - } __PACKED *p_param = (void *)p_ins->param; - - pel_relays_set(p_param->status); - dev_mode_pel_output = pel_smaple_and_convt_all(p_param->status, __REVSH(p_param->mask)); + case 0x00: + data_char_update_once(); break; - } - case 0x61: { - struct - { - uint8_t channel; - } __PACKED *p_param = (void *)p_ins->param; - - if (p_param->channel == 0x01) - { - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&dev_mode_pel_output.output_r1, sizeof(dev_mode_pel_output.output_r1)); - } - else if (p_param->channel == 0x02) - { - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&dev_mode_pel_output.output_r2, sizeof(dev_mode_pel_output.output_r2)); - } - else if (p_param->channel == 0x03) - { - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&dev_mode_pel_output.output_vo, sizeof(dev_mode_pel_output.output_vo)); - } - else if (p_param->channel == 0x04) - { - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&dev_mode_pel_output.output_vc, sizeof(dev_mode_pel_output.output_vc)); - } - else if (p_param->channel == 0x05) - { - extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); - le_data_upadate((void *)&dev_mode_pel_output.output_ve, sizeof(dev_mode_pel_output.output_ve)); - } + case 0x01: + decode_start_data_char_notify(p_ins->param); break; - } - case 0x62: { - pel_select_resistor_combinations_mode(ins); + case 0x02: + stop_data_char_notify(); break; - } - case 0xF0: { - pel20_io_init(); + case 0x03: + event_char_update_once(); break; - } - case 0xF1: { - struct - { - uint8_t status; - } __PACKED *p_param = (void *)p_ins->param; + case 0x04: + decode_start_event_char_notify(p_ins->param); + break; - if (p_param->status == 0x01) + case 0x05: + stop_event_char_notify(); + break; + + default: + break; + } +} + +static void send_resis_and_sample_and_hold_data(void *p_arg) +{ + typedef struct __PACKED + { + uint8_t mem_board_id; + uint32_t notify_time; + uint8_t packet_seq; + int32_t val_1; + int32_t val_2; + int32_t val_3; + int32_t val_4; + int32_t val_5; + float val_1_f; + float val_2_f; + float val_3_f; + float val_4_f; + float val_5_f; + uint16_t pattern_id; + uint32_t pattern; + } data_char_packet_t; + + bool first_data = true; + data_char_packet_t packet_buf; + characteristic_param_t *event_char_notify_param = (characteristic_param_t *)p_arg; + event_char_notify_running = true; + + memset(&packet_buf, 0x00, sizeof(packet_buf)); + _send_event_char_notify_start_packet(&packet_buf, sizeof(packet_buf), 4); + int32_t adc_raw[COUNTOF(pel_hw.adc.results)] = { 0 }; + + for (;;) + { + if (event_char_notify_running) + { + if (first_data) { - if (test_gpio_task_Handle == NULL) + for (int i = 0; i < COUNTOF(pel_hw.adc.results); i++) { - NRF_LOG_INFO("[test] start test_gpio_task task"); - xTaskCreate(test_gpio_task, "test_gpio_task", 1024, NULL, 4, &test_gpio_task_Handle); + adc_raw[i] = pel_hw.adc.results[i]; } + + adc_read_mutiple_channels_convert_milivolt(adc_raw, pel_hw.adc.results_f, COUNTOF(pel_hw.adc.channels)); + + packet_buf.mem_board_id = global_memoryboard_id; + packet_buf.notify_time = xTaskGetTickCount(); + packet_buf.packet_seq = 0; + packet_buf.val_1 = pel_hw.adc.results[0]; + packet_buf.val_2 = pel_hw.adc.results[1]; + packet_buf.val_3 = pel_hw.adc.results[2]; + packet_buf.val_4 = pel_hw.adc.results[3]; + packet_buf.val_5 = pel_hw.adc.results[4]; + packet_buf.val_1_f = pel_hw.adc.results_f[0]; + packet_buf.val_2_f = pel_hw.adc.results_f[1]; + packet_buf.val_3_f = pel_hw.adc.results_f[2]; + packet_buf.val_4_f = pel_hw.adc.results_f[3]; + packet_buf.val_5_f = pel_hw.adc.results_f[4]; + packet_buf.pattern_id = global_resis.pattern_id; + packet_buf.pattern = global_resis.pattern; + first_data = false; } - else if (p_param->status == 0x00) + else { - if (test_gpio_task_Handle != NULL) + for (int i = 0; i < COUNTOF(pel_hw.adc.results); i++) { - NRF_LOG_INFO("[test] delete test_gpio_task task"); - vTaskDelete(test_gpio_task_Handle); - test_gpio_task_Handle = NULL; + adc_raw[i] = pel_hw.adc.results[i]; } + + adc_read_mutiple_channels_convert_milivolt(adc_raw, pel_hw.adc.results_f, COUNTOF(pel_hw.adc.channels)); + + packet_buf.mem_board_id = global_memoryboard_id; + packet_buf.notify_time = xTaskGetTickCount(); + packet_buf.packet_seq += 1; + packet_buf.val_1 = adc_raw[0]; + packet_buf.val_2 = adc_raw[1]; + packet_buf.val_3 = adc_raw[2]; + packet_buf.val_4 = adc_raw[3]; + packet_buf.val_5 = adc_raw[4]; + packet_buf.val_1_f = pel_hw.adc.results_f[0]; + packet_buf.val_2_f = pel_hw.adc.results_f[1]; + packet_buf.val_3_f = pel_hw.adc.results_f[2]; + packet_buf.val_4_f = pel_hw.adc.results_f[3]; + packet_buf.val_5_f = pel_hw.adc.results_f[4]; + packet_buf.pattern_id = global_resis.pattern_id; + packet_buf.pattern = global_resis.pattern; } - break; - } - case 0xF2: { - struct + ret_code_t le_event_notify(uint8_t * p_value, uint16_t len); + ret_code_t ret = le_event_notify((void *)&packet_buf, sizeof(packet_buf)); + + NRF_LOG_INFO("sizeof(packet_buf) %d", sizeof(packet_buf)); + { - uint8_t input_n; - uint8_t status; - } __PACKED *p_param = (void *)p_ins->param; - - uint32_t high_low = p_param->status; - - switch (p_param->input_n) - { - case 0x01: - nrf_gpio_pin_write(INPUT_1_PIN, high_low); - NRF_LOG_INFO("set INPUT_1_PIN = %d", high_low); - break; - - case 0x02: - nrf_gpio_pin_write(INPUT_2_PIN, high_low); - NRF_LOG_INFO("set INPUT_2_PIN = %d", high_low); - break; - - case 0x03: - nrf_gpio_pin_write(INPUT_3_PIN, high_low); - NRF_LOG_INFO("set INPUT_3_PIN = %d", high_low); - break; - - case 0x04: - nrf_gpio_pin_write(INPUT_4_PIN, high_low); - NRF_LOG_INFO("set INPUT_4_PIN = %d", high_low); - break; - - case 0x05: - nrf_gpio_pin_write(INPUT_5_PIN, high_low); - NRF_LOG_INFO("set INPUT_5_PIN = %d", high_low); - break; - - case 0x06: - nrf_gpio_pin_write(INPUT_6_PIN, high_low); - NRF_LOG_INFO("set INPUT_6_PIN = %d", high_low); - break; - - case 0x07: - nrf_gpio_pin_write(INPUT_7_PIN, high_low); - NRF_LOG_INFO("set INPUT_7_PIN = %d", high_low); - break; - - case 0x08: - nrf_gpio_pin_write(INPUT_8_PIN, high_low); - NRF_LOG_INFO("set INPUT_8_PIN = %d", high_low); - break; - - case 0x09: - nrf_gpio_pin_write(INPUT_9_PIN, high_low); - NRF_LOG_INFO("set INPUT_9_PIN = %d", high_low); - break; - - case 0x0A: - nrf_gpio_pin_write(INPUT_10_PIN, high_low); - NRF_LOG_INFO("set INPUT_10_PIN = %d", high_low); - break; - - case 0x0B: - nrf_gpio_pin_write(INPUT_11_PIN, high_low); - NRF_LOG_INFO("set INPUT_11_PIN = %d", high_low); - break; - - case 0x0C: - nrf_gpio_pin_write(INPUT_12_PIN, high_low); - NRF_LOG_INFO("set INPUT_12_PIN = %d", high_low); - break; + char str[128]; + snprintf(str, sizeof(str), "{%d, %d, %d, %d, %d, %d, %d, %d, %.7f, %.7f, %.7f, %.7f, %.7f, %d, 0x%08X}", packet_buf.mem_board_id, packet_buf.notify_time, packet_buf.packet_seq, packet_buf.val_1, packet_buf.val_2, packet_buf.val_3, packet_buf.val_4, packet_buf.val_5, packet_buf.val_1_f, packet_buf.val_2_f, packet_buf.val_3_f, packet_buf.val_4_f, packet_buf.val_5_f, packet_buf.pattern_id, packet_buf.pattern); + NRF_LOG_INFO("%s", str); } - break; - } - default: { - break; + vTaskDelay(pdMS_TO_TICKS(event_char_notify_param->notify_period)); } + else // stop data update process + { + free(event_char_notify_param); + vTaskDelete(NULL); + } + } +} + +void start_sample_and_hold_pulse_task(uint8_t *param) +{ + pel_config_t pel_cfg = { + .anode_pin = ANODE_PIN, + .cathode_pin = CATHODE_PIN, + .smaple_r_pin = SAMPLE_R_PIN, + .sample_v_pin = SAMPLE_V_PIN, + .test_pin = NRF_GPIO_PIN_MAP(0, 5), + .mode = BOARD_IOPx, + .point_us = { + 10000, + 3, + 5, + 2, + 0, + }, + .pulse_cnt = 0xFFFFFFFF, + .gain = NRF_SAADC_GAIN1_6, + .smaple_time = NRF_SAADC_ACQTIME_10US, + .adc_timing_shift = 0, + }; + + pel_pulse_gen_init(pel_cfg); + + pel_pulse_gen_start(); + + characteristic_param_t *event_char_notify_param = malloc(sizeof(characteristic_param_t)); + + if (event_char_notify_param == NULL) + { + NRF_LOG_ERROR("Failed to allocate memory for event_char_notify_param"); + return; + } + + event_char_notify_param->notify_period = u8_to_u32(param[0], param[1], param[2], param[3]); + // event_char_notify_param->total_notify_count = u8_to_u32(param[0], param[1], param[2], param[3]); + // event_char_notify_param->notify_period = 10; + event_char_notify_param->total_notify_count = 5; + NRF_LOG_INFO("event_char_notify_param->notify_period=%d", event_char_notify_param->notify_period); + + xTaskCreate(send_resis_and_sample_and_hold_data, "send_resis_and_sample_and_hold_data", 2048, (void *)event_char_notify_param, 3, NULL); +} + +void stop_sample_and_hold_pulse_task(void) +{ + pel_pulse_gen_stop(); + event_char_notify_running = false; +} + +static void dev_mode_sample_and_hold_pulse_task(uint8_t *ins) +{ + NRF_LOG_INFO("[DEV MODE] %s", __FUNCTION__); + + struct __PACKED + { + uint8_t id : 4; + uint8_t ins_type : 4; + uint8_t pkg_size; + uint8_t mode; + uint8_t func_id; + uint8_t opcode; + uint8_t param[]; + } *p_ins = (void *)ins; + + switch (p_ins->opcode) + { + case 0x00: + start_sample_and_hold_pulse_task(p_ins->param); + break; + + case 0x01: + stop_sample_and_hold_pulse_task(); + break; + + default: + break; + } +} + +static void dev_mode(uint8_t *ins, uint16_t size) +{ + struct __PACKED + { + uint8_t id : 4; + uint8_t ins_type : 4; + uint8_t pkg_size; + uint8_t mode; + uint8_t func_id; + uint8_t opcode; + uint8_t param[]; + } *p_ins = (void *)ins; + + global_memoryboard_id = p_ins->id; + + switch (p_ins->func_id) + { + case 0x00: + dev_mode_input_resistor(ins); + break; + + case 0x01: + dev_mode_sample_and_hold_pulse_task(ins); + break; + + case 0xA3: + dev_mode_characteristic(ins); + break; + + default: + break; } } @@ -612,6 +1101,8 @@ const elite_instance_t pel_elite_instance = { const elite_instance_t *pel_init(void) { + NRF_LOG_INFO("[Board] %s", BOARD_IOPx ? "IOPH" : "IOPL"); + return &pel_elite_instance; } diff --git a/pel20_io.c b/pel20_io.c index cc550f1..86e9d7a 100644 --- a/pel20_io.c +++ b/pel20_io.c @@ -2,6 +2,7 @@ #include "nrf_gpio.h" #include "nrf_gpiote.h" + #include "nrf_spim.h" #include "nrf_timer.h" @@ -9,8 +10,24 @@ #include "semphr.h" #include "task.h" +#include "SEGGER_RTT.h" + #if (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0) +pel_hw_t pel_hw = { + .pulse_tmr = NRF_TIMER3, + .pulse_irq_n = TIMER3_IRQn, + .pulse_cnt = 0, + .adc.channels = { + [OUTPUT_R1_IDX] = OUTPUT_R1_CHANNEL, + [OUTPUT_R2_IDX] = OUTPUT_R2_CHANNEL, + [OUTPUT_VO_IDX] = OUTPUT_VO_CHANNEL, + [OUTPUT_VC_IDX] = OUTPUT_VC_CHANNEL, + [OUTPUT_VE_IDX] = OUTPUT_VE_CHANNEL}, + .adc.gain = NRF_SAADC_GAIN1_6, + .adc.smaple_time = NRF_SAADC_ACQTIME_3US +}; + void spim_xfer(uint32_t cs_pin, nrf_spim_mode_t spi_mode, uint8_t *p_tx_buffer, @@ -75,111 +92,220 @@ void spim_xfer(uint32_t cs_pin, #define MAX_PULSE_WIDTH INT16_MAX #define MAX_PULSE_IDLE INT16_MAX -typedef struct +static void pel_saadc_init(pel_adc_t *p_adc) { - uint32_t anode_pin; - uint32_t cathode_pin; - uint32_t pulse_idle; // min: 2, max: 32767, unit: us - uint32_t pulse_width; // min: 2, max: 32767, unit: us, - uint32_t pulse_cnt; // min: 1, max: 0xFFFFFFFF -} pulse_gen_t; + /* stop ssadc */ + NRF_SAADC->EVENTS_STOPPED = 0; + NRF_SAADC->TASKS_STOP = 1; + do { + } while (NRF_SAADC->EVENTS_STOPPED == 0); -typedef struct -{ - uint32_t gpiote_idx[2]; - NRF_TIMER_Type *pulse_tmr; - uint32_t pulse_irq_n; - uint32_t pulse_cnt; -} pulse_gen_hw_t; + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; -pulse_gen_hw_t pulse_gen_hw = { - .gpiote_idx = {0, 1}, - .pulse_tmr = NRF_TIMER3, - .pulse_irq_n = TIMER3_IRQn, - .pulse_cnt = 0, -}; + /* + ref: p.381, nrf52840_PS_v1.1.pdf + Note: Oversampling should only be used when a single input channel is enabled, as averaging is + performed over all enabled channels. + */ + NRF_SAADC->OVERSAMPLE = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass; + NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit; + /* config analog inputs */ + for (uint32_t i = 0; i < COUNTOF(NRF_SAADC->CH); i++) + { + if (i < COUNTOF(p_adc->channels)) + { + NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_AIN0 + p_adc->channels[i]; + NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].CONFIG = + (NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) | + (NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) | + (p_adc->gain << SAADC_CH_CONFIG_GAIN_Pos) | + (NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) | + (p_adc->smaple_time << SAADC_CH_CONFIG_TACQ_Pos) | + (NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) | + (NRF_SAADC_BURST_DISABLED << SAADC_CH_CONFIG_BURST_Pos); + } + else + { + NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].CONFIG = 0; + } + } + /* enable ssadc */ + NRF_SAADC->ENABLE = 1; + NRF_SAADC->RESULT.PTR = (uint32_t)p_adc->results; + NRF_SAADC->RESULT.MAXCNT = COUNTOF(p_adc->results); +} void TIMER3_IRQHandler(void) { - if (pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[1]) + if (pel_hw.pulse_tmr->EVENTS_COMPARE[0]) { - pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[1] = 0; - pulse_gen_hw.pulse_cnt--; - if (pulse_gen_hw.pulse_cnt == 1) + pel_hw.pulse_tmr->EVENTS_COMPARE[0] = 0; + if (pel_hw.pulse_cnt) { - pulse_gen_hw.pulse_tmr->SHORTS |= NRF_TIMER_SHORT_COMPARE1_STOP_MASK; + pel_hw.pulse_cnt--; + } + } + else if (pel_hw.pulse_tmr->EVENTS_COMPARE[5]) + { + pel_hw.pulse_tmr->EVENTS_COMPARE[5] = 0; + if (pel_hw.pulse_cnt) + { + NRF_SAADC->RESULT.PTR = (uint32_t)pel_hw.adc.results; + NRF_SAADC->RESULT.MAXCNT = COUNTOF(pel_hw.adc.results); + } + else + { + pel_hw.pulse_tmr->TASKS_STOP = 1; } } } -bool pel_pulse_gen(pulse_gen_t *p_pulse_gen) +void pel_pulse_gen_init(pel_config_t cfg) { - /* hardware limitation */ - if (p_pulse_gen->pulse_cnt == 0 || - p_pulse_gen->pulse_idle < MIN_PULSE_IDLE || - p_pulse_gen->pulse_width < MIN_PULSE_WIDTH || - p_pulse_gen->pulse_idle > MAX_PULSE_IDLE || - p_pulse_gen->pulse_width > MAX_PULSE_WIDTH) + pel_hw.pulse_tmr->TASKS_STOP = 1; + + sd_nvic_DisableIRQ(pel_hw.pulse_irq_n); + sd_nvic_ClearPendingIRQ(pel_hw.pulse_irq_n); + + pel_hw.pulse_cnt = cfg.pulse_cnt; + pel_hw.adc.gain = cfg.gain; + pel_hw.adc.smaple_time = cfg.smaple_time; + + pel_saadc_init(&pel_hw.adc); + + switch (cfg.mode) { - return false; + default: + case 1: + nrf_gpiote_task_configure(0, cfg.anode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); + nrf_gpiote_task_enable(0); + nrf_gpiote_task_configure(1, cfg.cathode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_enable(1); + break; + case 0: + nrf_gpiote_task_configure(0, cfg.anode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_enable(0); + nrf_gpiote_task_configure(1, cfg.cathode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); + nrf_gpiote_task_enable(1); + break; } - pulse_gen_hw.pulse_cnt = p_pulse_gen->pulse_cnt; + nrf_gpiote_task_configure(2, cfg.smaple_r_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); + nrf_gpiote_task_enable(2); + nrf_gpiote_task_configure(3, cfg.sample_v_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); + nrf_gpiote_task_enable(3); - pulse_gen_hw.pulse_tmr->TASKS_STOP = 1; + if (cfg.test_pin != 0xFFFFFFFF) + { + nrf_gpiote_task_configure(4, cfg.test_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); + nrf_gpiote_task_enable(4); + } - sd_nvic_DisableIRQ(pulse_gen_hw.pulse_irq_n); - sd_nvic_ClearPendingIRQ(pulse_gen_hw.pulse_irq_n); - - nrf_gpiote_task_configure(pulse_gen_hw.gpiote_idx[0], p_pulse_gen->anode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(pulse_gen_hw.gpiote_idx[1], p_pulse_gen->cathode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); - - nrf_gpiote_task_enable(pulse_gen_hw.gpiote_idx[0]); - nrf_gpiote_task_enable(pulse_gen_hw.gpiote_idx[1]); - - NRF_PPI->CH[0].EEP = (uint32_t)&pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[0]; - NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[0]]; - NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[1]]; + NRF_PPI->CH[0].EEP = (uint32_t)&pel_hw.pulse_tmr->EVENTS_COMPARE[0]; + NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0]; + NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1]; NRF_PPI->CHENSET = (1 << (0)); - NRF_PPI->CH[1].EEP = (uint32_t)&pulse_gen_hw.pulse_tmr->EVENTS_COMPARE[1]; - NRF_PPI->CH[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[0]]; - NRF_PPI->FORK[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pulse_gen_hw.gpiote_idx[1]]; + NRF_PPI->CH[1].EEP = (uint32_t)&pel_hw.pulse_tmr->EVENTS_COMPARE[1]; + NRF_PPI->CH[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[2]; + NRF_PPI->FORK[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[3]; NRF_PPI->CHENSET = (1 << (1)); - pulse_gen_hw.pulse_tmr->TASKS_CLEAR = 1; + NRF_PPI->CH[2].EEP = (uint32_t)&pel_hw.pulse_tmr->EVENTS_COMPARE[2]; + NRF_PPI->CH[2].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[2]; + NRF_PPI->FORK[2].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[3]; + NRF_PPI->CHENSET = (1 << (2)); - pulse_gen_hw.pulse_tmr->PRESCALER = NRF_TIMER_FREQ_16MHz; - pulse_gen_hw.pulse_tmr->MODE = NRF_TIMER_MODE_TIMER; - pulse_gen_hw.pulse_tmr->BITMODE = NRF_TIMER_BIT_WIDTH_32; - pulse_gen_hw.pulse_tmr->CC[0] = p_pulse_gen->pulse_idle * 16; - pulse_gen_hw.pulse_tmr->CC[1] = pulse_gen_hw.pulse_tmr->CC[0] + p_pulse_gen->pulse_width * 16; - pulse_gen_hw.pulse_tmr->SHORTS = pulse_gen_hw.pulse_cnt > 1 ? NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK : NRF_TIMER_SHORT_COMPARE1_STOP_MASK; - pulse_gen_hw.pulse_tmr->INTENSET = NRF_TIMER_INT_COMPARE1_MASK; + NRF_PPI->CH[3].EEP = (uint32_t)&pel_hw.pulse_tmr->EVENTS_COMPARE[3]; + NRF_PPI->CH[3].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0]; + NRF_PPI->FORK[3].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1]; + NRF_PPI->CHENSET = (1 << (3)); - sd_nvic_SetPriority(pulse_gen_hw.pulse_irq_n, _PRIO_APP_HIGH); - sd_nvic_EnableIRQ(pulse_gen_hw.pulse_irq_n); + NRF_PPI->CH[4].EEP = (uint32_t)&pel_hw.pulse_tmr->EVENTS_COMPARE[4]; + NRF_PPI->CH[4].TEP = (uint32_t)&NRF_SAADC->TASKS_START; + NRF_PPI->CHENSET = (1 << (4)); - pulse_gen_hw.pulse_tmr->TASKS_START = 1; + if (cfg.test_pin != 0xFFFFFFFF) + { + NRF_PPI->CH[6].EEP = (uint32_t)&NRF_SAADC->EVENTS_STARTED; + NRF_PPI->CH[6].TEP = (uint32_t)&NRF_SAADC->TASKS_SAMPLE; + NRF_PPI->FORK[6].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[4]; + NRF_PPI->CHENSET = (1 << (6)); + NRF_PPI->CH[7].EEP = (uint32_t)&NRF_SAADC->EVENTS_END; + NRF_PPI->CH[7].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[4]; + NRF_PPI->CHENSET = (1 << (7)); + } - return true; + pel_hw.pulse_tmr->PRESCALER = NRF_TIMER_FREQ_16MHz; + pel_hw.pulse_tmr->MODE = NRF_TIMER_MODE_TIMER; + pel_hw.pulse_tmr->BITMODE = NRF_TIMER_BIT_WIDTH_32; + pel_hw.pulse_tmr->CC[0] = 1; + pel_hw.pulse_tmr->CC[1] = pel_hw.pulse_tmr->CC[0] + cfg.point_us[1] * 16; + pel_hw.pulse_tmr->CC[2] = pel_hw.pulse_tmr->CC[1] + cfg.point_us[2] * 16; + pel_hw.pulse_tmr->CC[3] = pel_hw.pulse_tmr->CC[2] + cfg.point_us[3] * 16; + pel_hw.pulse_tmr->CC[4] = pel_hw.pulse_tmr->CC[3] + cfg.point_us[4] * 16 + cfg.adc_timing_shift; + pel_hw.pulse_tmr->CC[5] = pel_hw.pulse_tmr->CC[4] + cfg.point_us[0] * 16; + pel_hw.pulse_tmr->SHORTS = NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK; + pel_hw.pulse_tmr->INTENSET = NRF_TIMER_INT_COMPARE0_MASK | NRF_TIMER_INT_COMPARE5_MASK; + + sd_nvic_SetPriority(pel_hw.pulse_irq_n, _PRIO_APP_HIGH); + sd_nvic_EnableIRQ(pel_hw.pulse_irq_n); +} + +void pel_pulse_gen_start(void) +{ + pel_hw.pulse_tmr->TASKS_START = 1; +} + +void pel_pulse_gen_stop(void) +{ + pel_hw.pulse_cnt = 0; +} + +#if (DEF_ELITE_DEMO_W_SOFTDEVICE == 1) || (DEF_ELITE_DEMO_WO_SOFTDEVICE == 1) +static void pel_pulse_gen_demo_task(void *p_arg) +{ + pel_config_t pel_cfg = { + .anode_pin = ANODE_PIN, + .cathode_pin = CATHODE_PIN, + .smaple_r_pin = SAMPLE_R_PIN, + .sample_v_pin = SAMPLE_V_PIN, + .test_pin = NRF_GPIO_PIN_MAP(0, 5), + .mode = 1, + .point_us = { + 10000, + 3, + 5, + 2, + 0, + }, + .pulse_cnt = 0xFFFFFFFF, + .gain = NRF_SAADC_GAIN1_6, + .smaple_time = NRF_SAADC_ACQTIME_10US, + .adc_timing_shift = 0, + }; + + pel_pulse_gen_init(pel_cfg); + + pel_pulse_gen_start(); + + for (;;) + { + static uint32_t i = 0; + vTaskDelay(pdMS_TO_TICKS(pel_cfg.point_us[0] / 1000)); + SEGGER_RTT_printf(0, "%d, %d, %d, %d, %d, %d\r\n", i++, pel_hw.adc.results[0], pel_hw.adc.results[1], pel_hw.adc.results[2], pel_hw.adc.results[3], pel_hw.adc.results[4]); + } } void pel_pulse_gen_demo(void) { - pulse_gen_t pulse_gen = { - .anode_pin = ANODE_PIN, - .cathode_pin = CATHODE_PIN, - .pulse_width = 10, - .pulse_idle = 1000, - .pulse_cnt = 0xFFFFFFFF - }; - - if (pel_pulse_gen(&pulse_gen) == false) - { - // fail handling - } + xTaskCreate(pel_pulse_gen_demo_task, "pel_demo", 256, NULL, 3, NULL); } +#endif void pel20_io_init(void) { @@ -241,8 +367,6 @@ void pel20_io_init(void) NRF_SPIM3->PSEL.MOSI = SPIM_MOSI_PIN; NRF_SPIM3->PSEL.MISO = SPIM_MISO_PIN; NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos; - - pel_pulse_gen_demo(); } #endif diff --git a/pel20_io.h b/pel20_io.h index 95a63a8..06c7d76 100644 --- a/pel20_io.h +++ b/pel20_io.h @@ -10,6 +10,7 @@ extern "C" #include "elite_board.h" #include "nrf_gpio.h" #include "nrf_spim.h" +#include "nrf_saadc.h" #if (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0) @@ -59,6 +60,40 @@ extern "C" #define SPIM_CLK_PIN NRF_GPIO_PIN_MAP(0, 4) #define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9) +typedef struct +{ + uint32_t anode_pin; + uint32_t cathode_pin; + uint32_t smaple_r_pin; + uint32_t sample_v_pin; + uint32_t test_pin; + uint32_t point_us[5]; // toggle point timestamp + uint32_t pulse_cnt; // min: 1, max: 0xFFFFFFFF + uint32_t mode; // 0: IOPL mode, 1: IOPH mode + nrf_saadc_gain_t gain; + nrf_saadc_acqtime_t smaple_time; + int32_t adc_timing_shift; +} pel_config_t; + +typedef struct +{ + nrf_saadc_gain_t gain; + nrf_saadc_acqtime_t smaple_time; + uint32_t channels[5]; + int16_t results[5]; + float results_f[5]; +} pel_adc_t; + +typedef struct +{ + NRF_TIMER_Type *pulse_tmr; + uint32_t pulse_irq_n; + uint32_t pulse_cnt; + pel_adc_t adc; +} pel_hw_t; + +extern pel_hw_t pel_hw; + void spim_xfer(uint32_t cs_pin, nrf_spim_mode_t spi_mode, uint8_t *p_tx_buffer, @@ -67,6 +102,9 @@ extern "C" uint16_t rx_buffer_length); void pel20_io_init(void); + void pel_pulse_gen_init(pel_config_t cfg); + void pel_pulse_gen_start(void); + void pel_pulse_gen_stop(void); #endif /* ! DEF_ELITE_MODEL */