#include "cpg11_dev_mode.h" #include "tw1508.h" #include "nrf_gpio.h" #include "nrf_log.h" #if (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_11) #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)) // The GPIO corresponding to the pin const uint32_t pin_to_gpio_table[] = { [0] = UNDEF_GPIO, [1] = UNDEF_GPIO, [2] = UNDEF_GPIO, [3] = UNDEF_GPIO, [4] = UNDEF_GPIO, [5] = UNDEF_GPIO, [6] = NRF_GPIO_PIN_MAP(0, 22), [7] = UNDEF_GPIO, [8] = NRF_GPIO_PIN_MAP(0, 25), [9] = NRF_GPIO_PIN_MAP(0, 19), [10] = NRF_GPIO_PIN_MAP(0, 21), [11] = NRF_GPIO_PIN_MAP(1, 0), [12] = NRF_GPIO_PIN_MAP(0, 18), [13] = NRF_GPIO_PIN_MAP(0, 17), [14] = NRF_GPIO_PIN_MAP(0, 20), [15] = UNDEF_GPIO, [16] = NRF_GPIO_PIN_MAP(0, 14), [17] = NRF_GPIO_PIN_MAP(0, 13), [18] = NRF_GPIO_PIN_MAP(0, 11), [19] = UNDEF_GPIO, [20] = NRF_GPIO_PIN_MAP(0, 15), [21] = UNDEF_GPIO, [22] = UNDEF_GPIO, [23] = UNDEF_GPIO, [24] = UNDEF_GPIO, [25] = NRF_GPIO_PIN_MAP(1, 8), [26] = NRF_GPIO_PIN_MAP(0, 12), [27] = NRF_GPIO_PIN_MAP(0, 7), [28] = NRF_GPIO_PIN_MAP(1, 9), [29] = NRF_GPIO_PIN_MAP(0, 8), [30] = NRF_GPIO_PIN_MAP(0, 6), [31] = NRF_GPIO_PIN_MAP(0, 5), [32] = NRF_GPIO_PIN_MAP(0, 27), [33] = NRF_GPIO_PIN_MAP(0, 26), [34] = NRF_GPIO_PIN_MAP(0, 4), [35] = UNDEF_GPIO, [36] = NRF_GPIO_PIN_MAP(0, 1), [37] = NRF_GPIO_PIN_MAP(0, 29), [38] = NRF_GPIO_PIN_MAP(0, 0), [39] = NRF_GPIO_PIN_MAP(0, 31), [40] = NRF_GPIO_PIN_MAP(1, 15), [41] = NRF_GPIO_PIN_MAP(0, 2), [42] = NRF_GPIO_PIN_MAP(0, 30), [43] = NRF_GPIO_PIN_MAP(0, 28), [44] = NRF_GPIO_PIN_MAP(1, 12), [45] = NRF_GPIO_PIN_MAP(1, 14), [46] = NRF_GPIO_PIN_MAP(0, 3), [47] = NRF_GPIO_PIN_MAP(1, 13), [48] = NRF_GPIO_PIN_MAP(1, 3), [49] = NRF_GPIO_PIN_MAP(1, 10), [50] = NRF_GPIO_PIN_MAP(1, 6), [51] = NRF_GPIO_PIN_MAP(1, 11), [52] = NRF_GPIO_PIN_MAP(0, 10), [53] = NRF_GPIO_PIN_MAP(0, 9), [54] = UNDEF_GPIO, [55] = UNDEF_GPIO, [56] = UNDEF_GPIO, [57] = UNDEF_GPIO, [58] = UNDEF_GPIO, [59] = NRF_GPIO_PIN_MAP(1, 2), [60] = NRF_GPIO_PIN_MAP(0, 24), [61] = NRF_GPIO_PIN_MAP(0, 23), [62] = NRF_GPIO_PIN_MAP(0, 16), [63] = UNDEF_GPIO, }; float u8_to_float(const uint8_t *ins, uint32_t start_idx) { float result; uint32_t temp_u32 = ((uint32_t)ins[start_idx + 0] << 24) | ((uint32_t)ins[start_idx + 1] << 16) | ((uint32_t)ins[start_idx + 2] << 8) | ((uint32_t)ins[start_idx + 3]); memcpy(&result, &temp_u32, sizeof(result)); return result; } double u8_to_double(const uint8_t *ins, uint32_t start_idx) { double result; uint64_t temp_u64 = ((uint64_t)ins[start_idx + 0] << 56) | ((uint64_t)ins[start_idx + 1] << 48) | ((uint64_t)ins[start_idx + 2] << 40) | ((uint64_t)ins[start_idx + 3] << 32) | ((uint64_t)ins[start_idx + 4] << 24) | ((uint64_t)ins[start_idx + 5] << 16) | ((uint64_t)ins[start_idx + 6] << 8) | ((uint64_t)ins[start_idx + 7]); memcpy(&result, &temp_u64, sizeof(result)); return result; } #define PULSE_GEN_A_NUMB 2 #define PULSE_GEN_B_NUMB 2 static pulse_gen_t p_pulse_genA[PULSE_GEN_A_NUMB]; static pulse_gen_t p_pulse_genB[PULSE_GEN_B_NUMB]; static pulse_gen_t pulse_gen[PULSE_GEN_A_NUMB + PULSE_GEN_B_NUMB]; static void set_bmd380_pin_signal(uint8_t pin_number, uint8_t high_low) { uint32_t gpio = pin_to_gpio_table[pin_number]; const char *str_pin_to_gpio_table[] = { [0] = "UNDEF_GPIO", [1] = "UNDEF_GPIO", [2] = "UNDEF_GPIO", [3] = "UNDEF_GPIO", [4] = "UNDEF_GPIO", [5] = "UNDEF_GPIO", [6] = "GPIO(0, 22)", [7] = "UNDEF_GPIO", [8] = "GPIO(0, 25)", [9] = "GPIO(0, 19)", [10] = "GPIO(0, 21)", [11] = "GPIO(1, 0)", [12] = "GPIO(0, 18)", [13] = "GPIO(0, 17)", [14] = "GPIO(0, 20)", [15] = "UNDEF_GPIO", [16] = "GPIO(0, 14)", [17] = "GPIO(0, 13)", [18] = "GPIO(0, 11)", [19] = "UNDEF_GPIO", [20] = "GPIO(0, 15)", [21] = "UNDEF_GPIO", [22] = "UNDEF_GPIO", [23] = "UNDEF_GPIO", [24] = "UNDEF_GPIO", [25] = "GPIO(1, 8)", [26] = "GPIO(0, 12)", [27] = "GPIO(0, 7)", [28] = "GPIO(1, 9)", [29] = "GPIO(0, 8)", [30] = "GPIO(0, 6)", [31] = "GPIO(0, 5)", [32] = "GPIO(0, 27)", [33] = "GPIO(0, 26)", [34] = "GPIO(0, 4)", [35] = "UNDEF_GPIO", [36] = "GPIO(0, 1)", [37] = "GPIO(0, 29)", [38] = "GPIO(0, 0)", [39] = "GPIO(0, 31)", [40] = "GPIO(1, 15)", [41] = "GPIO(0, 2)", [42] = "GPIO(0, 30)", [43] = "GPIO(0, 28)", [44] = "GPIO(1, 12)", [45] = "GPIO(1, 14)", [46] = "GPIO(0, 3)", [47] = "GPIO(1, 13)", [48] = "GPIO(1, 3)", [49] = "GPIO(1, 10)", [50] = "GPIO(1, 6)", [51] = "GPIO(1, 11)", [52] = "GPIO(0, 10)", [53] = "GPIO(0, 9)", [54] = "UNDEF_GPIO", [55] = "UNDEF_GPIO", [56] = "UNDEF_GPIO", [57] = "UNDEF_GPIO", [58] = "UNDEF_GPIO", [59] = "GPIO(1, 2)", [60] = "GPIO(0, 24)", [61] = "GPIO(0, 23)", [62] = "GPIO(0, 16)", [63] = "UNDEF_GPIO", }; if (pin_number == 0 || pin_number > 63 || gpio == UNDEF_GPIO) { NRF_LOG_INFO("UNDEF_GPIO: pin(%d) can't convert to gpio number", pin_number); } else { nrf_gpio_cfg_output(gpio); nrf_gpio_pin_write(gpio, high_low); NRF_LOG_INFO("set pin(%d) = %d //%s", pin_number, high_low, str_pin_to_gpio_table[pin_number]); } } static void set_bmd380_all_pin_signal(uint8_t high_low) { for (int i = 1; i < sizeof(pin_to_gpio_table) / sizeof(pin_to_gpio_table[0]); i++) { set_bmd380_pin_signal(i, high_low); } } static void electrode_pulse_channel(uint8_t electrode_mode) { #define ELECTRODE_E1_IDLE 0x00 #define ELECTRODE_E2_IDLE 0x01 #define ELECTRODE_E3_IDLE 0x02 #define ELECTRODE_E4_IDLE 0x03 #define ELECTRODE_ALL_HIGHZ 0x04 #define ELECTRODE_E1P_ENABLE 0x05 #define ELECTRODE_E1P_DISABLE 0x06 #define ELECTRODE_E1N_ENABLE 0x07 #define ELECTRODE_E1N_DISABLE 0x08 #define ELECTRODE_E2P_ENABLE 0x09 #define ELECTRODE_E2P_DISABLE 0x0A #define ELECTRODE_E2N_ENABLE 0x0B #define ELECTRODE_E2N_DISABLE 0x0C #define ELECTRODE_E3P_ENABLE 0x0D #define ELECTRODE_E3P_DISABLE 0x0E #define ELECTRODE_E3N_ENABLE 0x0F #define ELECTRODE_E3N_DISABLE 0x10 #define ELECTRODE_E4P_ENABLE 0x11 #define ELECTRODE_E4P_DISABLE 0x12 #define ELECTRODE_E4N_ENABLE 0x13 #define ELECTRODE_E4N_DISABLE 0x14 switch (electrode_mode) { case ELECTRODE_E1_IDLE: NRF_LOG_INFO("ELECTRODE_E1_IDLE()"); nrf_gpio_pin_write(VB1L_PIN, 0); nrf_gpio_pin_write(VB1H_PIN, 1); nrf_gpio_pin_write(VA1L_PIN, 0); nrf_gpio_pin_write(VA1H_PIN, 1); break; case ELECTRODE_E2_IDLE: NRF_LOG_INFO("ELECTRODE_E2_IDLE()"); nrf_gpio_pin_write(VB2L_PIN, 0); nrf_gpio_pin_write(VB2H_PIN, 1); nrf_gpio_pin_write(VA2L_PIN, 0); nrf_gpio_pin_write(VA2H_PIN, 1); break; case ELECTRODE_E3_IDLE: NRF_LOG_INFO("ELECTRODE_E3_IDLE()"); nrf_gpio_pin_write(VB3L_PIN, 0); nrf_gpio_pin_write(VB3H_PIN, 1); nrf_gpio_pin_write(VA3L_PIN, 0); nrf_gpio_pin_write(VA3H_PIN, 1); break; case ELECTRODE_E4_IDLE: NRF_LOG_INFO("ELECTRODE_E4_IDLE()"); nrf_gpio_pin_write(VB4L_PIN, 0); nrf_gpio_pin_write(VB4H_PIN, 1); nrf_gpio_pin_write(VA4L_PIN, 0); nrf_gpio_pin_write(VA4H_PIN, 1); break; case ELECTRODE_ALL_HIGHZ: NRF_LOG_INFO("ELECTRODE_ALL_HIGHZ()"); nrf_gpio_pin_write(VB1L_PIN, 0); nrf_gpio_pin_write(VB1H_PIN, 0); nrf_gpio_pin_write(VA1L_PIN, 0); nrf_gpio_pin_write(VA1H_PIN, 0); nrf_gpio_pin_write(VB2L_PIN, 0); nrf_gpio_pin_write(VB2H_PIN, 0); nrf_gpio_pin_write(VA2L_PIN, 0); nrf_gpio_pin_write(VA2H_PIN, 0); nrf_gpio_pin_write(VB3L_PIN, 0); nrf_gpio_pin_write(VB3H_PIN, 0); nrf_gpio_pin_write(VA3L_PIN, 0); nrf_gpio_pin_write(VA3H_PIN, 0); nrf_gpio_pin_write(VB4L_PIN, 0); nrf_gpio_pin_write(VB4H_PIN, 0); nrf_gpio_pin_write(VA4L_PIN, 0); nrf_gpio_pin_write(VA4H_PIN, 0); break; case ELECTRODE_E1P_ENABLE: NRF_LOG_INFO("ELECTRODE_E1P_ENABLE()"); nrf_gpio_pin_write(VB1H_PIN, 0); nrf_gpio_pin_write(VB1L_PIN, 1); break; case ELECTRODE_E1P_DISABLE: NRF_LOG_INFO("ELECTRODE_E1P_DISABLE()"); nrf_gpio_pin_write(VB1L_PIN, 0); nrf_gpio_pin_write(VB1H_PIN, 1); break; case ELECTRODE_E1N_ENABLE: NRF_LOG_INFO("ELECTRODE_E1N_ENABLE()"); nrf_gpio_pin_write(VA1H_PIN, 0); nrf_gpio_pin_write(VA1L_PIN, 1); break; case ELECTRODE_E1N_DISABLE: NRF_LOG_INFO("ELECTRODE_E1N_DISABLE()"); nrf_gpio_pin_write(VA1L_PIN, 0); nrf_gpio_pin_write(VA1H_PIN, 1); break; case ELECTRODE_E2P_ENABLE: NRF_LOG_INFO("ELECTRODE_E2P_ENABLE()"); nrf_gpio_pin_write(VB2H_PIN, 0); nrf_gpio_pin_write(VB2L_PIN, 1); break; case ELECTRODE_E2P_DISABLE: NRF_LOG_INFO("ELECTRODE_E2P_DISABLE()"); nrf_gpio_pin_write(VB2L_PIN, 0); nrf_gpio_pin_write(VB2H_PIN, 1); break; case ELECTRODE_E2N_ENABLE: NRF_LOG_INFO("ELECTRODE_E2N_ENABLE()"); nrf_gpio_pin_write(VA2H_PIN, 0); nrf_gpio_pin_write(VA2L_PIN, 1); break; case ELECTRODE_E2N_DISABLE: NRF_LOG_INFO("ELECTRODE_E2N_DISABLE()"); nrf_gpio_pin_write(VA2L_PIN, 0); nrf_gpio_pin_write(VA2H_PIN, 1); break; case ELECTRODE_E3P_ENABLE: NRF_LOG_INFO("ELECTRODE_E3P_ENABLE()"); nrf_gpio_pin_write(VB3H_PIN, 0); nrf_gpio_pin_write(VB3L_PIN, 1); break; case ELECTRODE_E3P_DISABLE: NRF_LOG_INFO("ELECTRODE_E3P_DISABLE()"); nrf_gpio_pin_write(VB3L_PIN, 0); nrf_gpio_pin_write(VB3H_PIN, 1); break; case ELECTRODE_E3N_ENABLE: NRF_LOG_INFO("ELECTRODE_E3N_ENABLE()"); nrf_gpio_pin_write(VA3H_PIN, 0); nrf_gpio_pin_write(VA3L_PIN, 1); break; case ELECTRODE_E3N_DISABLE: NRF_LOG_INFO("ELECTRODE_E3N_DISABLE()"); nrf_gpio_pin_write(VA3L_PIN, 0); nrf_gpio_pin_write(VA3H_PIN, 1); break; case ELECTRODE_E4P_ENABLE: NRF_LOG_INFO("ELECTRODE_E4P_ENABLE()"); nrf_gpio_pin_write(VB4H_PIN, 0); nrf_gpio_pin_write(VB4L_PIN, 1); break; case ELECTRODE_E4P_DISABLE: NRF_LOG_INFO("ELECTRODE_E4P_DISABLE()"); nrf_gpio_pin_write(VB4L_PIN, 0); nrf_gpio_pin_write(VB4H_PIN, 1); break; case ELECTRODE_E4N_ENABLE: NRF_LOG_INFO("ELECTRODE_E4N_ENABLE()"); nrf_gpio_pin_write(VA4H_PIN, 0); nrf_gpio_pin_write(VA4L_PIN, 1); break; case ELECTRODE_E4N_DISABLE: NRF_LOG_INFO("ELECTRODE_E4N_DISABLE()"); nrf_gpio_pin_write(VA4L_PIN, 0); nrf_gpio_pin_write(VA4H_PIN, 1); break; default: NRF_LOG_INFO("electrode_mode: 0x%X is unsupported", electrode_mode); break; } } void reset_pulse(pulse_gen_t *p_pulse_gen) { p_pulse_gen->VAxH = 0xFFFFFFFF; p_pulse_gen->VAxL = 0xFFFFFFFF; p_pulse_gen->VBxH = 0xFFFFFFFF; p_pulse_gen->VBxL = 0xFFFFFFFF; p_pulse_gen->idle_us = 0; p_pulse_gen->point_us[0] = 0; p_pulse_gen->point_us[1] = 0; p_pulse_gen->point_us[2] = 0; p_pulse_gen->point_us[3] = 0; p_pulse_gen->point_us[4] = 0; p_pulse_gen->point_us[5] = 0; p_pulse_gen->point_us[6] = 0; p_pulse_gen->pulse_cnt = 1; p_pulse_gen->pulse_id = PULSE_ID_NULL; } void set_cpg_pulse_parameter(uint8_t *ins) { NRF_LOG_INFO("%s", __FUNCTION__); uint8_t electrodes1_pulse_gen_sel = (ins[5] & 0b10000000) >> 7; uint8_t electrodes2_pulse_gen_sel = (ins[5] & 0b01000000) >> 6; uint8_t electrodes3_pulse_gen_sel = (ins[5] & 0b00100000) >> 5; uint8_t electrodes4_pulse_gen_sel = (ins[5] & 0b00010000) >> 4; uint32_t pulse_width_us = ins[6] << 24 | ins[7] << 16 | ins[8] << 8 | ins[9]; uint32_t freq_hz = ins[10] << 24 | ins[11] << 16 | ins[12] << 8 | ins[13]; reset_pulse(&p_pulse_genA[0]); reset_pulse(&p_pulse_genA[1]); reset_pulse(&p_pulse_genB[0]); reset_pulse(&p_pulse_genB[1]); if (electrodes1_pulse_gen_sel) { pulse_gen[0] = (pulse_gen_t) { .VBxH = VB1H_PIN, .VBxL = VB1L_PIN, .VAxH = VA1H_PIN, .VAxL = VA1L_PIN, .point_us[0] = 1, .point_us[1] = pulse_width_us, .point_us[2] = 1, .point_us[3] = 0, .point_us[4] = 1, .point_us[5] = pulse_width_us, .point_us[6] = 1, .idle_us = 0, .pulse_cnt = UINT32_MAX, .pulse_id = PULSE_ID_NULL, }; NRF_LOG_INFO("[%d]user pulse_width = %u us", 1, pulse_width_us); NRF_LOG_INFO("[%d]user freq_hz = %u Hz", 1, freq_hz); if (freq_hz == 0) { pulse_gen[0].idle_us = 0; } else { pulse_gen[0].idle_us = 1000000 / freq_hz - (pulse_gen[0].point_us[0] + pulse_gen[0].point_us[1] + pulse_gen[0].point_us[2] + pulse_gen[0].point_us[3] + pulse_gen[0].point_us[4] + pulse_gen[0].point_us[5] + pulse_gen[0].point_us[6]); NRF_LOG_INFO("[%d]user idle = %u us", 1, pulse_gen[0].idle_us); if (electrodes1_pulse_gen_sel && electrodes2_pulse_gen_sel) { pulse_gen[0].idle_us = (1000000 / freq_hz - (pulse_gen[0].point_us[0] + pulse_gen[0].point_us[1] + pulse_gen[0].point_us[2] + pulse_gen[0].point_us[3] + pulse_gen[0].point_us[4] + pulse_gen[0].point_us[5] + pulse_gen[0].point_us[6]) * 2) / 2; } } NRF_LOG_INFO("[%d]a = %u us", 1, pulse_gen[0].point_us[0]); NRF_LOG_INFO("[%d]b = %u us", 1, pulse_gen[0].point_us[1]); NRF_LOG_INFO("[%d]c = %u us", 1, pulse_gen[0].point_us[2]); NRF_LOG_INFO("[%d]d = %u us", 1, pulse_gen[0].point_us[3]); NRF_LOG_INFO("[%d]e = %u us", 1, pulse_gen[0].point_us[4]); NRF_LOG_INFO("[%d]f = %u us", 1, pulse_gen[0].point_us[5]); NRF_LOG_INFO("[%d]g = %u us", 1, pulse_gen[0].point_us[6]); NRF_LOG_INFO("[%d]idle = %u us", 1, pulse_gen[0].idle_us); } if (electrodes2_pulse_gen_sel) { pulse_gen[1] = (pulse_gen_t) { .VBxH = VB2H_PIN, .VBxL = VB2L_PIN, .VAxH = VA2H_PIN, .VAxL = VA2L_PIN, .point_us[0] = 1, .point_us[1] = pulse_width_us, .point_us[2] = 1, .point_us[3] = 0, .point_us[4] = 1, .point_us[5] = pulse_width_us, .point_us[6] = 1, .idle_us = 0, .pulse_cnt = UINT32_MAX, .pulse_id = PULSE_ID_NULL, }; NRF_LOG_INFO("[%d]user pulse_width = %u us", 2, pulse_width_us); NRF_LOG_INFO("[%d]user freq_hz = %u Hz", 2, freq_hz); if (freq_hz == 0) { pulse_gen[0].idle_us = 0; } else { pulse_gen[1].idle_us = (1000000 / freq_hz) - (pulse_gen[1].point_us[0] + pulse_gen[1].point_us[1] + pulse_gen[1].point_us[2] + pulse_gen[1].point_us[3] + pulse_gen[1].point_us[4] + pulse_gen[1].point_us[5] + pulse_gen[1].point_us[6]); NRF_LOG_INFO("[%d]user idle = %u us", 2, pulse_gen[1].idle_us); if (electrodes1_pulse_gen_sel && electrodes2_pulse_gen_sel) { pulse_gen[1].idle_us = (1000000 / freq_hz - (pulse_gen[1].point_us[0] + pulse_gen[1].point_us[1] + pulse_gen[1].point_us[2] + pulse_gen[1].point_us[3] + pulse_gen[1].point_us[4] + pulse_gen[1].point_us[5] + pulse_gen[1].point_us[6]) * 2) / 2; } } NRF_LOG_INFO("[%d]a = %u us", 2, pulse_gen[1].point_us[0]); NRF_LOG_INFO("[%d]b = %u us", 2, pulse_gen[1].point_us[1]); NRF_LOG_INFO("[%d]c = %u us", 2, pulse_gen[1].point_us[2]); NRF_LOG_INFO("[%d]d = %u us", 2, pulse_gen[1].point_us[3]); NRF_LOG_INFO("[%d]e = %u us", 2, pulse_gen[1].point_us[4]); NRF_LOG_INFO("[%d]f = %u us", 2, pulse_gen[1].point_us[5]); NRF_LOG_INFO("[%d]g = %u us", 2, pulse_gen[1].point_us[6]); NRF_LOG_INFO("[%d]idle = %u us", 2, pulse_gen[1].idle_us); } if (electrodes3_pulse_gen_sel) { pulse_gen[2] = (pulse_gen_t) { .VBxH = VB3H_PIN, .VBxL = VB3L_PIN, .VAxH = VA3H_PIN, .VAxL = VA3L_PIN, .point_us[0] = 1, .point_us[1] = pulse_width_us, .point_us[2] = 1, .point_us[3] = 0, .point_us[4] = 1, .point_us[5] = pulse_width_us, .point_us[6] = 1, .idle_us = 0, .pulse_cnt = UINT32_MAX, .pulse_id = PULSE_ID_NULL, }; NRF_LOG_INFO("[%d]user pulse_width = %u us", 3, pulse_width_us); NRF_LOG_INFO("[%d]user freq_hz = %u Hz", 3, freq_hz); if (freq_hz == 0) { pulse_gen[0].idle_us = 0; } else { pulse_gen[2].idle_us = 1000000 / freq_hz - (pulse_gen[2].point_us[0] + pulse_gen[2].point_us[1] + pulse_gen[2].point_us[2] + pulse_gen[2].point_us[3] + pulse_gen[2].point_us[4] + pulse_gen[2].point_us[5] + pulse_gen[2].point_us[6]); NRF_LOG_INFO("[%d]user idle = %u us", 3, pulse_gen[2].idle_us); if (electrodes3_pulse_gen_sel && electrodes4_pulse_gen_sel) { pulse_gen[2].idle_us = (1000000 / freq_hz - (pulse_gen[2].point_us[0] + pulse_gen[2].point_us[1] + pulse_gen[2].point_us[2] + pulse_gen[2].point_us[3] + pulse_gen[2].point_us[4] + pulse_gen[2].point_us[5] + pulse_gen[2].point_us[6]) * 2) / 2; } } NRF_LOG_INFO("[%d]a = %u us", 3, pulse_gen[2].point_us[0]); NRF_LOG_INFO("[%d]b = %u us", 3, pulse_gen[2].point_us[1]); NRF_LOG_INFO("[%d]c = %u us", 3, pulse_gen[2].point_us[2]); NRF_LOG_INFO("[%d]d = %u us", 3, pulse_gen[2].point_us[3]); NRF_LOG_INFO("[%d]e = %u us", 3, pulse_gen[2].point_us[4]); NRF_LOG_INFO("[%d]f = %u us", 3, pulse_gen[2].point_us[5]); NRF_LOG_INFO("[%d]g = %u us", 3, pulse_gen[2].point_us[6]); NRF_LOG_INFO("[%d]idle = %u us", 3, pulse_gen[2].idle_us); } if (electrodes4_pulse_gen_sel) { pulse_gen[3] = (pulse_gen_t) { .VBxH = VB4H_PIN, .VBxL = VB4L_PIN, .VAxH = VA4H_PIN, .VAxL = VA4L_PIN, .point_us[0] = 1, .point_us[1] = pulse_width_us, .point_us[2] = 1, .point_us[3] = 0, .point_us[4] = 1, .point_us[5] = pulse_width_us, .point_us[6] = 1, .idle_us = 0, .pulse_cnt = UINT32_MAX, .pulse_id = PULSE_ID_NULL, }; NRF_LOG_INFO("[%d]user pulse_width = %u us", 4, pulse_width_us); NRF_LOG_INFO("[%d]user freq_hz = %u Hz", 4, freq_hz); if (freq_hz == 0) { pulse_gen[0].idle_us = 0; } else { pulse_gen[3].idle_us = (1000000 / freq_hz) - (pulse_gen[3].point_us[0] + pulse_gen[3].point_us[1] + pulse_gen[3].point_us[2] + pulse_gen[3].point_us[3] + pulse_gen[3].point_us[4] + pulse_gen[3].point_us[5] + pulse_gen[3].point_us[6]); NRF_LOG_INFO("[%d]user idle = %u us", 4, pulse_gen[3].idle_us); if (electrodes3_pulse_gen_sel && electrodes4_pulse_gen_sel) { pulse_gen[3].idle_us = (1000000 / freq_hz - (pulse_gen[3].point_us[0] + pulse_gen[3].point_us[1] + pulse_gen[3].point_us[2] + pulse_gen[3].point_us[3] + pulse_gen[3].point_us[4] + pulse_gen[3].point_us[5] + pulse_gen[3].point_us[6]) * 2) / 2; } } NRF_LOG_INFO("[%d]a = %u us", 4, pulse_gen[3].point_us[0]); NRF_LOG_INFO("[%d]b = %u us", 4, pulse_gen[3].point_us[1]); NRF_LOG_INFO("[%d]c = %u us", 4, pulse_gen[3].point_us[2]); NRF_LOG_INFO("[%d]d = %u us", 4, pulse_gen[3].point_us[3]); NRF_LOG_INFO("[%d]e = %u us", 4, pulse_gen[3].point_us[4]); NRF_LOG_INFO("[%d]f = %u us", 4, pulse_gen[3].point_us[5]); NRF_LOG_INFO("[%d]g = %u us", 4, pulse_gen[3].point_us[6]); NRF_LOG_INFO("[%d]idle = %u us", 4, pulse_gen[3].idle_us); } NRF_LOG_INFO("set ok......"); } static void start_which_electrodes(uint8_t *ins) { NRF_LOG_INFO("%s", __FUNCTION__); uint8_t electrodes1_pulse_gen_en = (ins[5] & 0b10000000) >> 7; uint8_t electrodes2_pulse_gen_en = (ins[5] & 0b01000000) >> 6; uint8_t electrodes3_pulse_gen_en = (ins[5] & 0b00100000) >> 5; uint8_t electrodes4_pulse_gen_en = (ins[5] & 0b00010000) >> 4; uint32_t inum = 0; inum = 0; if (electrodes1_pulse_gen_en) { p_pulse_genA[inum] = pulse_gen[0]; p_pulse_genA[inum].pulse_id = PULSE_ID_A; nrf_gpio_pin_clear(p_pulse_genA[inum].VBxL); nrf_gpio_pin_set(p_pulse_genA[inum].VBxH); nrf_gpio_pin_clear(p_pulse_genA[inum].VAxL); nrf_gpio_pin_set(p_pulse_genA[inum].VAxH); NRF_LOG_INFO("start electrodes1_pulse_gen"); } else { p_pulse_genA[inum].VBxL = 0xFFFFFFFF; p_pulse_genA[inum].VBxH = 0xFFFFFFFF; p_pulse_genA[inum].VAxL = 0xFFFFFFFF; p_pulse_genA[inum].VAxH = 0xFFFFFFFF; } inum = 1; if (electrodes2_pulse_gen_en) { p_pulse_genA[inum] = pulse_gen[1]; p_pulse_genA[inum].pulse_id = PULSE_ID_B; nrf_gpio_pin_clear(p_pulse_genA[inum].VBxL); nrf_gpio_pin_set(p_pulse_genA[inum].VBxH); nrf_gpio_pin_clear(p_pulse_genA[inum].VAxL); nrf_gpio_pin_set(p_pulse_genA[inum].VAxH); NRF_LOG_INFO("start electrodes2_pulse_gen"); } else { p_pulse_genA[inum].VBxL = 0xFFFFFFFF; p_pulse_genA[inum].VBxH = 0xFFFFFFFF; p_pulse_genA[inum].VAxL = 0xFFFFFFFF; p_pulse_genA[inum].VAxH = 0xFFFFFFFF; } if (electrodes1_pulse_gen_en || electrodes2_pulse_gen_en) { cpg11_pulse_init(0, &p_pulse_genA[0], 2); cpg11_pulse_start(0, &p_pulse_genA[0]); } inum = 0; if (electrodes3_pulse_gen_en) { p_pulse_genB[inum] = pulse_gen[2]; p_pulse_genB[inum].pulse_id = PULSE_ID_C; nrf_gpio_pin_clear(p_pulse_genB[inum].VBxL); nrf_gpio_pin_set(p_pulse_genB[inum].VBxH); nrf_gpio_pin_clear(p_pulse_genB[inum].VAxL); nrf_gpio_pin_set(p_pulse_genB[inum].VAxH); NRF_LOG_INFO("start electrodes3_pulse_gen"); } else { p_pulse_genB[inum].VBxL = 0xFFFFFFFF; p_pulse_genB[inum].VBxH = 0xFFFFFFFF; p_pulse_genB[inum].VAxL = 0xFFFFFFFF; p_pulse_genB[inum].VAxH = 0xFFFFFFFF; } inum = 1; if (electrodes4_pulse_gen_en) { p_pulse_genB[inum] = pulse_gen[3]; p_pulse_genB[inum].pulse_id = PULSE_ID_D; nrf_gpio_pin_clear(p_pulse_genB[inum].VBxL); nrf_gpio_pin_set(p_pulse_genB[inum].VBxH); nrf_gpio_pin_clear(p_pulse_genB[inum].VAxL); nrf_gpio_pin_set(p_pulse_genB[inum].VAxH); NRF_LOG_INFO("start electrodes4_pulse_gen"); } else { p_pulse_genB[inum].VBxL = 0xFFFFFFFF; p_pulse_genB[inum].VBxH = 0xFFFFFFFF; p_pulse_genB[inum].VAxL = 0xFFFFFFFF; p_pulse_genB[inum].VAxH = 0xFFFFFFFF; } if (electrodes3_pulse_gen_en || electrodes4_pulse_gen_en) { cpg11_pulse_init(1, &p_pulse_genB[0], 2); cpg11_pulse_start(1, &p_pulse_genB[0]); } for (int i = 0; i < 2; i++) { NRF_LOG_INFO("p_pulse_genA[%d]VAxH = %d", i, p_pulse_genA[i].VAxH); NRF_LOG_INFO("p_pulse_genA[%d]VAxL = %d", i, p_pulse_genA[i].VAxL); NRF_LOG_INFO("p_pulse_genA[%d]VBxH = %d", i, p_pulse_genA[i].VBxH); NRF_LOG_INFO("p_pulse_genA[%d]VBxL = %d", i, p_pulse_genA[i].VBxL); NRF_LOG_INFO("p_pulse_genA[%d]a = %u us", i, p_pulse_genA[i].point_us[0]); NRF_LOG_INFO("p_pulse_genA[%d]b = %u us", i, p_pulse_genA[i].point_us[1]); NRF_LOG_INFO("p_pulse_genA[%d]c = %u us", i, p_pulse_genA[i].point_us[2]); NRF_LOG_INFO("p_pulse_genA[%d]d = %u us", i, p_pulse_genA[i].point_us[3]); NRF_LOG_INFO("p_pulse_genA[%d]e = %u us", i, p_pulse_genA[i].point_us[4]); NRF_LOG_INFO("p_pulse_genA[%d]f = %u us", i, p_pulse_genA[i].point_us[5]); NRF_LOG_INFO("p_pulse_genA[%d]g = %u us", i, p_pulse_genA[i].point_us[6]); NRF_LOG_INFO("p_pulse_genA[%d]idle = %u us", i, p_pulse_genA[i].idle_us); NRF_LOG_INFO("p_pulse_genA[%d]pulse_cnt = 0x%08X cnt", i, p_pulse_genA[i].pulse_cnt); NRF_LOG_INFO("p_pulse_genA[%d]pulse_id = %u", i, p_pulse_genA[i].pulse_id); } for (int i = 0; i < 2; i++) { NRF_LOG_INFO("p_pulse_genB[%d]VAxH = %d", i, p_pulse_genB[i].VAxH); NRF_LOG_INFO("p_pulse_genB[%d]VAxL = %d", i, p_pulse_genB[i].VAxL); NRF_LOG_INFO("p_pulse_genB[%d]VBxH = %d", i, p_pulse_genB[i].VBxH); NRF_LOG_INFO("p_pulse_genB[%d]VBxL = %d", i, p_pulse_genB[i].VBxL); NRF_LOG_INFO("p_pulse_genB[%d]a = %u us", i, p_pulse_genB[i].point_us[0]); NRF_LOG_INFO("p_pulse_genB[%d]b = %u us", i, p_pulse_genB[i].point_us[1]); NRF_LOG_INFO("p_pulse_genB[%d]c = %u us", i, p_pulse_genB[i].point_us[2]); NRF_LOG_INFO("p_pulse_genB[%d]d = %u us", i, p_pulse_genB[i].point_us[3]); NRF_LOG_INFO("p_pulse_genB[%d]e = %u us", i, p_pulse_genB[i].point_us[4]); NRF_LOG_INFO("p_pulse_genB[%d]f = %u us", i, p_pulse_genB[i].point_us[5]); NRF_LOG_INFO("p_pulse_genB[%d]g = %u us", i, p_pulse_genB[i].point_us[6]); NRF_LOG_INFO("p_pulse_genB[%d]idle = %u us", i, p_pulse_genB[i].idle_us); NRF_LOG_INFO("p_pulse_genB[%d]pulse_cnt = 0x%08X cnt", i, p_pulse_genB[i].pulse_cnt); NRF_LOG_INFO("p_pulse_genB[%d]pulse_id = %u", i, p_pulse_genB[i].pulse_id); } } static void stop_which_electrodes(uint8_t *ins) { NRF_LOG_INFO("%s", __FUNCTION__); uint8_t electrodes1_pulse_gen_dis = (ins[5] & 0b10000000) >> 7; uint8_t electrodes2_pulse_gen_dis = (ins[5] & 0b01000000) >> 6; uint8_t electrodes3_pulse_gen_dis = (ins[5] & 0b00100000) >> 5; uint8_t electrodes4_pulse_gen_dis = (ins[5] & 0b00010000) >> 4; if (electrodes1_pulse_gen_dis || electrodes2_pulse_gen_dis) { cpg11_pulse_stop(0); NRF_LOG_INFO("stop electrodes1_pulse_gen"); NRF_LOG_INFO("stop electrodes2_pulse_gen"); p_pulse_genA[0].pulse_id = PULSE_ID_NULL; p_pulse_genA[1].pulse_id = PULSE_ID_NULL; } if (electrodes3_pulse_gen_dis || electrodes4_pulse_gen_dis) { cpg11_pulse_stop(1); NRF_LOG_INFO("stop electrodes3_pulse_gen"); NRF_LOG_INFO("stop electrodes4_pulse_gen"); p_pulse_genB[0].pulse_id = PULSE_ID_NULL; p_pulse_genB[1].pulse_id = PULSE_ID_NULL; } for (int i = 0; i < 2; i++) { NRF_LOG_INFO("pulse_genA[%d]pulse_id: %d", i, p_pulse_genA[i].pulse_id); } for (int i = 0; i < 2; i++) { NRF_LOG_INFO("pulse_genB[%d]pulse_id: %d", i, p_pulse_genB[i].pulse_id); } NRF_LOG_INFO("\n\n") } static void suspend_which_electrodes(uint8_t *ins) { NRF_LOG_INFO("%s", __FUNCTION__); uint8_t electrodes1_pulse_gen_dis = (ins[5] & 0b10000000) >> 7; uint8_t electrodes2_pulse_gen_dis = (ins[5] & 0b01000000) >> 6; uint8_t electrodes3_pulse_gen_dis = (ins[5] & 0b00100000) >> 5; uint8_t electrodes4_pulse_gen_dis = (ins[5] & 0b00010000) >> 4; if (electrodes1_pulse_gen_dis) { cpg11_pulse_suspend_by_pulse_id(p_pulse_genA[0].pulse_id); NRF_LOG_INFO("suspend electrodes1_pulse_gen"); } if (electrodes2_pulse_gen_dis) { cpg11_pulse_suspend_by_pulse_id(p_pulse_genA[1].pulse_id); NRF_LOG_INFO("suspend electrodes2_pulse_gen"); } if (electrodes3_pulse_gen_dis) { cpg11_pulse_suspend_by_pulse_id(p_pulse_genB[0].pulse_id); NRF_LOG_INFO("suspend electrodes3_pulse_gen"); } if (electrodes4_pulse_gen_dis) { cpg11_pulse_suspend_by_pulse_id(p_pulse_genB[1].pulse_id); NRF_LOG_INFO("suspend electrodes4_pulse_gen"); } } static void resume_which_electrodes(uint8_t *ins) { NRF_LOG_INFO("%s", __FUNCTION__); uint8_t electrodes1_pulse_gen_dis = (ins[5] & 0b10000000) >> 7; uint8_t electrodes2_pulse_gen_dis = (ins[5] & 0b01000000) >> 6; uint8_t electrodes3_pulse_gen_dis = (ins[5] & 0b00100000) >> 5; uint8_t electrodes4_pulse_gen_dis = (ins[5] & 0b00010000) >> 4; if (electrodes1_pulse_gen_dis) { cpg11_pulse_resume_by_pulse_id(p_pulse_genA[0].pulse_id); NRF_LOG_INFO("resume electrodes1_pulse_gen"); } if (electrodes2_pulse_gen_dis) { cpg11_pulse_resume_by_pulse_id(p_pulse_genA[1].pulse_id); NRF_LOG_INFO("resume electrodes2_pulse_gen"); } if (electrodes3_pulse_gen_dis) { cpg11_pulse_resume_by_pulse_id(p_pulse_genB[0].pulse_id); NRF_LOG_INFO("resume electrodes3_pulse_gen"); } if (electrodes4_pulse_gen_dis) { cpg11_pulse_resume_by_pulse_id(p_pulse_genB[1].pulse_id); NRF_LOG_INFO("resume electrodes4_pulse_gen"); } } static void set_cpg_pulse_cnt(uint8_t *ins) { NRF_LOG_INFO("%s", __FUNCTION__); uint8_t electrodes1_pulse_gen_sel = (ins[5] & 0b10000000) >> 7; uint8_t electrodes2_pulse_gen_sel = (ins[5] & 0b01000000) >> 6; uint8_t electrodes3_pulse_gen_sel = (ins[5] & 0b00100000) >> 5; uint8_t electrodes4_pulse_gen_sel = (ins[5] & 0b00010000) >> 4; uint32_t pulse_cnt = (uint32_t)ins[6] << 24 | (uint32_t)ins[7] << 16 | (uint32_t)ins[8] << 8 | (uint32_t)ins[9]; if (electrodes1_pulse_gen_sel) { pulse_gen[0].pulse_cnt = pulse_cnt; NRF_LOG_INFO("[1] pulse_cnt = %u cnt", pulse_gen[0].pulse_cnt); } if (electrodes2_pulse_gen_sel) { pulse_gen[1].pulse_cnt = pulse_cnt; NRF_LOG_INFO("[2] pulse_cnt = %u cnt", pulse_gen[1].pulse_cnt); } if (electrodes3_pulse_gen_sel) { pulse_gen[2].pulse_cnt = pulse_cnt; NRF_LOG_INFO("[3] pulse_cnt = %u cnt", pulse_gen[2].pulse_cnt); } if (electrodes4_pulse_gen_sel) { pulse_gen[3].pulse_cnt = pulse_cnt; NRF_LOG_INFO("[4] pulse_cnt = %u cnt", pulse_gen[3].pulse_cnt); } } #define TW1508_REXR 1.5 // 1.5kohm #define TW1508_BOUNDARY_GAIN0 13.3 #define TW1508_BOUNDARY_GAIN1 26.6 #define TW1508_BOUNDARY_GAIN2 39.9 #define TW1508_BOUNDARY_GAIN3 53.3 #define TW1508_BOUNDARY_GAIN4 66.6 #define TW1508_BOUNDARY_GAIN5 79.9 #define TW1508_BOUNDARY_GAIN6 93.3 #define TW1508_BOUNDARY_GAIN7 106.6 uint32_t current_convert_tw1508(float current_mA) { uint32_t tw1508_value; uint32_t dac_7bit; uint8_t dac_3bit; float rext; if (current_mA > TW1508_BOUNDARY_GAIN7) { current_mA = TW1508_BOUNDARY_GAIN7; NRF_LOG_INFO("current is too large"); } if (current_mA <= TW1508_BOUNDARY_GAIN0) { dac_3bit = 0b000; rext = TW1508_REXR; } else if (current_mA <= TW1508_BOUNDARY_GAIN1) { dac_3bit = 0b001; rext = TW1508_REXR; } else if (current_mA <= TW1508_BOUNDARY_GAIN2) { dac_3bit = 0b010; rext = TW1508_REXR; } else if (current_mA <= TW1508_BOUNDARY_GAIN3) { dac_3bit = 0b011; rext = TW1508_REXR; } else if (current_mA <= TW1508_BOUNDARY_GAIN4) { dac_3bit = 0b100; rext = TW1508_REXR; } else if (current_mA <= TW1508_BOUNDARY_GAIN5) { dac_3bit = 0b101; rext = TW1508_REXR; } else if (current_mA <= TW1508_BOUNDARY_GAIN6) { dac_3bit = 0b110; rext = TW1508_REXR; } else if (current_mA <= TW1508_BOUNDARY_GAIN7) { dac_3bit = 0b111; rext = TW1508_REXR; } dac_7bit = current_mA * 8 * TW1508_REXR / 1.25 / (dac_3bit + 1); tw1508_value = dac_3bit << 7 | dac_7bit; NRF_LOG_INFO("dac_3bit = %u", dac_3bit); NRF_LOG_INFO("dac_7bit = %u", dac_7bit); NRF_LOG_INFO("tw1508_value = %u", tw1508_value); return tw1508_value; } /* dev_mode_electrode_switch (1) Command Format: 0x3000FF0000nn - feat: electrode_pulse_channel() ExN: electrode x negative ExP: electrode x positive - nn: electrode_mode selection (0x00 to 0x14) 0x00: ELECTRODE_E1_IDLE 0x01: ELECTRODE_E2_IDLE 0x02: ELECTRODE_E3_IDLE 0x03: ELECTRODE_E4_IDLE 0x04: ELECTRODE_ALL_HIGHZ 0x05: ELECTRODE_E1P_ENABLE 0x06: ELECTRODE_E1P_DISABLE 0x07: ELECTRODE_E1N_ENABLE 0x08: ELECTRODE_E1N_DISABLE 0x09: ELECTRODE_E2P_ENABLE 0x0A: ELECTRODE_E2P_DISABLE 0x0B: ELECTRODE_E2N_ENABLE 0x0C: ELECTRODE_E2N_DISABLE 0x0D: ELECTRODE_E3P_ENABLE 0x0E: ELECTRODE_E3P_DISABLE 0x0F: ELECTRODE_E3N_ENABLE 0x10: ELECTRODE_E3N_DISABLE 0x11: ELECTRODE_E4P_ENABLE 0x12: ELECTRODE_E4P_DISABLE 0x13: ELECTRODE_E4N_ENABLE 0x14: ELECTRODE_E4N_DISABLE */ void dev_mode_electrode_switch(uint8_t *ins) { struct __PACKED { uint8_t id : 4; uint8_t : 4; uint16_t magic : 16; uint8_t func_id; uint8_t switch_opcode; uint8_t param[]; } *p_ins = (void *)ins; switch (p_ins->switch_opcode) { case 0x00: { uint8_t electrode_mode = ins[5]; electrode_pulse_channel(electrode_mode); break; } default: NRF_LOG_INFO("switch_opcode: 0x%X is unsupported", p_ins->switch_opcode); break; } } /* dev_mode_set_cpg11_tw1508 (1) 0x3000FF0100 - func: tw1508_init() out_0 = 0, out_1 = 0 (2) 0x3000FF0101aaaabbbb - func: tw1508_set() - aaaa: out_0 value (0x0000 to 0x03FF [LSB]) - bbbb: out_1 value (0x0000 to 0x03FF [LSB]) (3) 0x3000FF0102aaaaaaaabbbbbbbb - func: set and output current(mA)(float) - aaaaaaaa: out_0 current (0x00000000 to 0xFFFFFFFF) - bbbbbbbb: out_1 current (0x00000000 to 0xFFFFFFFF) */ void dev_mode_set_cpg11_tw1508(uint8_t *ins) { struct __PACKED { uint8_t id : 4; uint8_t : 4; uint16_t magic : 16; uint8_t dev_opcode; uint8_t tw1508_opcode; uint8_t param[]; } *p_ins = (void *)ins; switch (p_ins->tw1508_opcode) { case 0x00: { tw1508_init(); NRF_LOG_INFO("tw1508_init()"); break; } case 0x01: { uint16_t out_0; uint16_t out_1; memcpy(&out_0, &p_ins->param[0], sizeof(out_0)); memcpy(&out_1, &p_ins->param[2], sizeof(out_1)); NRF_LOG_INFO("tw1508_set(%d, %d)", out_0, out_1); tw1508_set(out_0, out_1); break; } case 0x02: { float out_0_current_mA; float out_1_current_mA; uint16_t out_0; uint16_t out_1; uint32_t out_0_u32 = (ins[5] << 24) | (ins[6] << 16) | (ins[7] << 8) | (ins[8]); uint32_t out_1_u32 = (ins[9] << 24) | (ins[10] << 16) | (ins[11] << 8) | (ins[12]); memcpy(&out_0_current_mA, &out_0_u32, sizeof(out_0_current_mA)); memcpy(&out_1_current_mA, &out_1_u32, sizeof(out_1_current_mA)); { char str[128]; snprintf(str, sizeof(str), "%s: 0x%08lX, %.3f", "out_0 float", out_0_u32, out_0_current_mA); NRF_LOG_INFO("%s", str); } out_0 = current_convert_tw1508(out_0_current_mA); { char str[128]; snprintf(str, sizeof(str), "%s: 0x%08lX, %.3f", "out_1 float", out_1_u32, out_1_current_mA); NRF_LOG_INFO("%s", str); } out_1 = current_convert_tw1508(out_1_current_mA); NRF_LOG_INFO("tw1508_set(%d, %d)", out_0, out_1); tw1508_set(out_0, out_1); break; } } } void start_electrodes_api(uint8_t *ins) { struct __PACKED { uint8_t dev_opcode; uint8_t item_opcode; uint8_t e1_e2_which_to_set; uint32_t e1_e2_amplitude_mA; uint32_t e1_e2_pulse_width_us; uint32_t e1_e2_freq_hz; uint8_t e3_e4_which_to_set; uint32_t e3_e4_amplitude_mA; uint32_t e3_e4_pulse_width_us; uint32_t e3_e4_freq_hz; uint32_t countdown_timer_seconds; uint8_t enable_which_electrode; } params; // parse start_electrodes_api_params params.e1_e2_which_to_set = ins[5]; params.e1_e2_amplitude_mA = (ins[6] << 24) | (ins[7] << 16) | (ins[8] << 8) | ins[9]; params.e1_e2_pulse_width_us = (ins[10] << 24) | (ins[11] << 16) | (ins[12] << 8) | ins[13]; params.e1_e2_freq_hz = (ins[14] << 24) | (ins[15] << 16) | (ins[16] << 8) | ins[17]; params.e3_e4_which_to_set = ins[18]; params.e3_e4_amplitude_mA = (ins[19] << 24) | (ins[20] << 16) | (ins[21] << 8) | ins[22]; params.e3_e4_pulse_width_us = (ins[23] << 24) | (ins[24] << 16) | (ins[25] << 8) | ins[26]; params.e3_e4_freq_hz = (ins[27] << 24) | (ins[28] << 16) | (ins[29] << 8) | ins[30]; params.countdown_timer_seconds = (ins[31] << 24) | (ins[32] << 16) | (ins[33] << 8) | ins[34]; params.enable_which_electrode = ins[35]; uint8_t ins_temp[14]; ins_temp[0] = 0x30; ins_temp[1] = 0x00; ins_temp[2] = 0xFF; params.dev_opcode = 0x01; params.item_opcode = 0x02; ins_temp[3] = params.dev_opcode; ins_temp[4] = params.item_opcode; ins_temp[5] = params.e1_e2_amplitude_mA >> 24; ins_temp[6] = params.e1_e2_amplitude_mA >> 16; ins_temp[7] = params.e1_e2_amplitude_mA >> 8; ins_temp[8] = params.e1_e2_amplitude_mA; ins_temp[9] = params.e3_e4_amplitude_mA >> 24; ins_temp[10] = params.e3_e4_amplitude_mA >> 16; ins_temp[11] = params.e3_e4_amplitude_mA >> 8; ins_temp[12] = params.e3_e4_amplitude_mA; NRF_LOG_INFO("parse:"); NRF_LOG_HEXDUMP_INFO(ins_temp, 13); dev_mode_set_cpg11_tw1508(ins_temp); NRF_LOG_INFO("..........................."); params.dev_opcode = 0x02; params.item_opcode = 0x01; ins_temp[3] = params.dev_opcode; ins_temp[4] = params.item_opcode; ins_temp[5] = params.e1_e2_which_to_set; ins_temp[6] = params.e1_e2_pulse_width_us >> 24; ins_temp[7] = params.e1_e2_pulse_width_us >> 16; ins_temp[8] = params.e1_e2_pulse_width_us >> 8; ins_temp[9] = params.e1_e2_pulse_width_us; ins_temp[10] = params.e1_e2_freq_hz >> 24; ins_temp[11] = params.e1_e2_freq_hz >> 16; ins_temp[12] = params.e1_e2_freq_hz >> 8; ins_temp[13] = params.e1_e2_freq_hz; NRF_LOG_INFO("parse:"); NRF_LOG_HEXDUMP_INFO(ins_temp, 14); set_cpg_pulse_parameter(ins_temp); NRF_LOG_INFO("..........................."); params.dev_opcode = 0x02; params.item_opcode = 0x01; ins_temp[3] = params.dev_opcode; ins_temp[4] = params.item_opcode; ins_temp[5] = params.e3_e4_which_to_set; ins_temp[6] = params.e3_e4_pulse_width_us >> 24; ins_temp[7] = params.e3_e4_pulse_width_us >> 16; ins_temp[8] = params.e3_e4_pulse_width_us >> 8; ins_temp[9] = params.e3_e4_pulse_width_us; ins_temp[10] = params.e3_e4_freq_hz >> 24; ins_temp[11] = params.e3_e4_freq_hz >> 16; ins_temp[12] = params.e3_e4_freq_hz >> 8; ins_temp[13] = params.e3_e4_freq_hz; NRF_LOG_INFO("parse:"); NRF_LOG_HEXDUMP_INFO(ins_temp, 14); set_cpg_pulse_parameter(ins_temp); NRF_LOG_INFO("..........................."); params.dev_opcode = 0xA0; params.item_opcode = 0x00; ins_temp[3] = params.dev_opcode; ins_temp[4] = params.item_opcode; ins_temp[5] = 0x19; ins_temp[6] = 0x01; NRF_LOG_INFO("parse:"); NRF_LOG_HEXDUMP_INFO(ins_temp, 7); dev_mode_gpio(ins_temp); NRF_LOG_INFO("..........................."); params.dev_opcode = 0x02; params.item_opcode = 0x03; ins_temp[3] = params.dev_opcode; ins_temp[4] = params.item_opcode; ins_temp[5] = params.enable_which_electrode; NRF_LOG_INFO("parse:"); NRF_LOG_HEXDUMP_INFO(ins_temp, 6); start_which_electrodes(ins_temp); NRF_LOG_INFO("..........................."); } void stop_electrodes_api(uint8_t *ins) { struct __PACKED { uint8_t dev_opcode; uint8_t item_opcode; uint8_t disable_which_electrode; } params; uint8_t ins_temp[14]; ins_temp[0] = 0x30; ins_temp[1] = 0x00; ins_temp[2] = 0xFF; params.dev_opcode = 0x02; params.item_opcode = 0x04; params.disable_which_electrode = ins[5]; ins_temp[3] = params.dev_opcode; ins_temp[4] = params.item_opcode; ins_temp[5] = params.disable_which_electrode; NRF_LOG_INFO("parse:"); NRF_LOG_HEXDUMP_INFO(ins_temp, 6); stop_which_electrodes(ins_temp); NRF_LOG_INFO("..........................."); params.dev_opcode = 0xA0; params.item_opcode = 0x00; ins_temp[3] = params.dev_opcode; ins_temp[4] = params.item_opcode; ins_temp[5] = 0x19; ins_temp[6] = 0x00; NRF_LOG_INFO("parse:"); NRF_LOG_HEXDUMP_INFO(ins_temp, 7); dev_mode_gpio(ins_temp); NRF_LOG_INFO("..........................."); } /* dev_mode_ctrl_cpg11_electrodes_task (1) 0x3000FF0201nnwwwwwwwwffffffff - func: set_cpg_pulse_parameter value - nn: set which group of electrodes (0x00 to 0xF0) 0x80 = 0b10000000: select electrode 1 0x40 = 0b01000000: select electrode 2 0x20 = 0b00100000: select electrode 3 0x10 = 0b00010000: select electrode 4 ...... 0xF0 = 0b11110000: select electrode 1~4 - wwwwwwww: pulse_width_us (0x00000000 to 0xFFFFFFFF) - ffffffff: freq_hz (0x00000000 to 0xFFFFFFFF) (2) 0x3000FF0202nncccccccc - func: set_cpg_pulse_cnt - nn: set which group of electrodes (0x00 to 0xF0) 0x80 = 0b10000000: select electrode 1 0x40 = 0b01000000: select electrode 2 0x20 = 0b00100000: select electrode 3 0x10 = 0b00010000: select electrode 4 ...... 0xF0 = 0b11110000: select electrode 1~4 - cccccccc: pulse_cnt (0x00000001 to 0xFFFFFFFF) (3) 0x3000FF0203nn - func: select which electrode's pulse to enable - nn: which electrodes (0x00 to 0xF0) 0x80 = 0b10000000: electrode 1 enable pulse 0x40 = 0b01000000: electrode 2 enable pulse 0x20 = 0b00100000: electrode 3 enable pulse 0x10 = 0b00010000: electrode 4 enable pulse ...... 0xF0 = 0b11110000: electrode 1~4 enable pulse (4) 0x3000FF0204nn - func: select which electrode's pulse to stop - nn: which electrodes (0x00 to 0xF0) 0x80 = 0b10000000: electrode 1 stops pulsing 0x40 = 0b01000000: electrode 2 stops pulsing 0x20 = 0b00100000: electrode 3 stops pulsing 0x10 = 0b00010000: electrode 4 stops pulsing ...... 0xF0 = 0b11110000: electrode 1~4 stops pulsing (5) 0x3000FF0205nn - func: select which electrode's pulse to suspend - nn: which electrodes (0x00 to 0xF0) 0x80 = 0b10000000: electrode 1 suspend pulsing 0x40 = 0b01000000: electrode 2 suspend pulsing 0x20 = 0b00100000: electrode 3 suspend pulsing 0x10 = 0b00010000: electrode 4 suspend pulsing ...... 0xF0 = 0b11110000: electrode 1~4 suspend pulsing (6) 0x3000FF0206nn - func: select which electrode's pulse to resume - nn: which electrodes (0x00 to 0xF0) 0x80 = 0b10000000: electrode 1 resume pulsing 0x40 = 0b01000000: electrode 2 resume pulsing 0x20 = 0b00100000: electrode 3 resume pulsing 0x10 = 0b00010000: electrode 4 resume pulsing ...... 0xF0 = 0b11110000: electrode 1~4 resume pulsing */ void dev_mode_ctrl_cpg11_electrodes_task(uint8_t *ins) { struct __PACKED { uint8_t id : 4; uint8_t : 4; uint16_t magic : 16; uint8_t dev_opcode; uint8_t electrodes_task_opcode; uint8_t param[]; } *p_ins = (void *)ins; switch (p_ins->electrodes_task_opcode) { case 0x01: set_cpg_pulse_parameter(ins); break; case 0x02: set_cpg_pulse_cnt(ins); break; case 0x03: start_which_electrodes(ins); break; case 0x04: stop_which_electrodes(ins); break; case 0x05: suspend_which_electrodes(ins); break; case 0x06: resume_which_electrodes(ins); break; case 0xA0: start_electrodes_api(ins); break; case 0xA1: stop_electrodes_api(ins); break; } } /* dev_mode_gpio (1) Command Format: 0x3000FFA000ppss - feat: set_bmd380_pin_signal() - pp: pin number (0x06 to 0x3E) 0x06: pin06 = P0.22_GPIO 0x08: pin08 = P0.25_GPIO 0x09: pin09 = P0.19_GPIO 0x0A: pin10 = P0.21_GPIO 0x0B: pin11 = P1.00_GPIO/TRACEDATA[0]/SWO 0x0C: pin12 = P0.18_GPIO/RESET 0x0D: pin13 = P0.17_GPIO 0x0E: pin14 = P0.20_GPIO 0x10: pin16 = P0.14_GPIO 0x11: pin17 = P0.13_GPIO 0x12: pin18 = P0.11_GPIO/TRACEDATA[2] 0x14: pin20 = P0.15_GPIO 0x19: pin25 = P1.08_GPIO_slow 0x1A: pin26 = P0.12_GPIO/TRACEDATA[1] 0x1B: pin27 = P0.07_GPIO/TRACECLK 0x1C: pin28 = P1.09_GPIO/TRACEDATA[3] 0x1D: pin29 = P0.08_GPIO 0x1E: pin30 = P0.06_GPIO 0x1F: pin31 = P0.05_GPIO/AIN3 0x20: pin32 = P0.27_GPIO 0x21: pin33 = P0.26_GPIO 0x22: pin34 = P0.04_GPIO/AIN2 0x24: pin36 = P0.01_GPIO/XTAL2 0x25: pin37 = P0.29_GPIO_slow/AIN5 0x26: pin38 = P0.00_GPIO/XTAL1 0x27: pin39 = P0.31_GPIO_slow/AIN7 0x28: pin40 = P1.15_GPIO_slow 0x29: pin41 = P0.02_GPIO_slow/AIN0 0x2A: pin42 = P0.30_GPIO_slow/AIN6 0x2B: pin43 = P0.28_GPIO_slow/AIN4 0x2C: pin44 = P1.12_GPIO_slow 0x2D: pin45 = P1.14_GPIO_slow 0x2E: pin46 = P0.03_GPIO_slow/AIN1 0x2F: pin47 = P1.13_GPIO_slow 0x30: pin48 = P1.03_GPIO_slow 0x31: pin49 = P1.10_GPIO_slow 0x32: pin50 = P1.06_GPIO_slow 0x33: pin51 = P1.11_GPIO_slow 0x34: pin52 = P0.10_GPIO_slow/NFC2 0x35: pin53 = P0.09_GPIO_slow/NFC1 0x3B: pin59 = P1.02_GPIO_slow 0x3C: pin60 = P0.24_GPIO 0x3D: pin61 = P0.23_GPIO 0x3E: pin62 = P0.16_GPIO - ss: signal (0x00 or 0x01) 0x00: low 0x01: high (2) Command Format: 0x3000FFA001ss - feat: set_bmd380_all_pin_signal() - ss: signal (0x00 or 0x01) 0x00: low 0x01: high */ void dev_mode_gpio(uint8_t *ins) { struct __PACKED { uint8_t id : 4; uint8_t : 4; uint16_t magic : 16; uint8_t func_id; uint8_t gpio_opcode; uint8_t param[]; } *p_ins = (void *)ins; switch (p_ins->gpio_opcode) { case 0x00: { uint8_t pin_number = ins[5]; uint8_t high_low = ins[6]; set_bmd380_pin_signal(pin_number, high_low); break; } case 0x01: { uint8_t high_low = ins[5]; set_bmd380_all_pin_signal(high_low); break; } } } #endif