/* * Copyright (c) 2021 HPMicro * * SPDX-License-Identifier: BSD-3-Clause * */ #include "board.h" #include "hpm_debug_console.h" #include "hpm_clock_drv.h" #include "hpm_synt_drv.h" #include "hpm_sei_drv.h" static uint32_t mock_pos = 0xA5A5; static uint32_t mock_rev = 0x8888; static uint32_t sample_latch_tm1; static uint32_t sample_latch_tm2; int main(void) { sei_tranceiver_config_t tranceiver_config = {0}; sei_data_format_config_t data_format_config = {0}; sei_engine_config_t engine_config = {0}; sei_state_transition_config_t state_transition_config = {0}; sei_state_transition_latch_config_t state_transition_latch_config = {0}; sei_sample_config_t sample_config = {0}; sei_command_table_config_t command_table_config = {0}; uint8_t instr_idx; board_init(); board_init_sei_pins(BOARD_SEI, BOARD_SEI_CTRL); printf("SEI slave tamagawa sample\n"); sei_set_engine_enable(BOARD_SEI, BOARD_SEI_CTRL, false); /* [1] tranceiver config */ tranceiver_config.mode = sei_asynchronous_mode; tranceiver_config.tri_sample = false; tranceiver_config.src_clk_freq = clock_get_frequency(BOARD_MOTOR_CLK_NAME); tranceiver_config.asynchronous_config.wait_len = 0; tranceiver_config.asynchronous_config.data_len = 8; tranceiver_config.asynchronous_config.parity_enable = false; tranceiver_config.asynchronous_config.data_idle_high_z = false; tranceiver_config.asynchronous_config.data_idle_state = sei_idle_high_state; tranceiver_config.asynchronous_config.baudrate = 2500000; sei_tranceiver_config_init(BOARD_SEI, BOARD_SEI_CTRL, &tranceiver_config); /* [2] data register config */ /* cmd register : recv CF */ data_format_config.mode = sei_data_mode; data_format_config.signed_flag = false; data_format_config.bit_order = sei_bit_lsb_first; data_format_config.word_order = sei_word_nonreverse; data_format_config.word_len = 8; data_format_config.last_bit = 7; data_format_config.first_bit = 0; data_format_config.max_bit = 7; data_format_config.min_bit = 0; sei_cmd_data_format_config_init(BOARD_SEI, SEI_SELECT_CMD, BOARD_SEI_CTRL, &data_format_config); /* data register 4: send SF */ data_format_config.mode = sei_data_mode; data_format_config.signed_flag = false; data_format_config.bit_order = sei_bit_lsb_first; data_format_config.word_order = sei_word_nonreverse; data_format_config.word_len = 8; data_format_config.last_bit = 7; data_format_config.first_bit = 0; data_format_config.max_bit = 7; data_format_config.min_bit = 0; sei_cmd_data_format_config_init(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_4, &data_format_config); /* data register 5: send ABS0 ABS1 ABS2 */ data_format_config.mode = sei_data_mode; data_format_config.signed_flag = false; data_format_config.bit_order = sei_bit_lsb_first; data_format_config.word_order = sei_word_nonreverse; data_format_config.word_len = 24; data_format_config.last_bit = 23; data_format_config.first_bit = 0; data_format_config.max_bit = 23; data_format_config.min_bit = 0; sei_cmd_data_format_config_init(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_5, &data_format_config); /* data register 6: send ENID */ data_format_config.mode = sei_data_mode; data_format_config.signed_flag = false; data_format_config.bit_order = sei_bit_lsb_first; data_format_config.word_order = sei_word_nonreverse; data_format_config.word_len = 8; data_format_config.last_bit = 7; data_format_config.first_bit = 0; data_format_config.max_bit = 7; data_format_config.min_bit = 0; sei_cmd_data_format_config_init(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_6, &data_format_config); /* data register 7: send ABM0 ABM1 ABM2 */ data_format_config.mode = sei_data_mode; data_format_config.signed_flag = false; data_format_config.bit_order = sei_bit_lsb_first; data_format_config.word_order = sei_word_nonreverse; data_format_config.word_len = 24; data_format_config.last_bit = 23; data_format_config.first_bit = 0; data_format_config.max_bit = 23; data_format_config.min_bit = 0; sei_cmd_data_format_config_init(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_7, &data_format_config); /* data register 8: send ALMC */ data_format_config.mode = sei_data_mode; data_format_config.signed_flag = false; data_format_config.bit_order = sei_bit_lsb_first; data_format_config.word_order = sei_word_nonreverse; data_format_config.word_len = 8; data_format_config.last_bit = 7; data_format_config.first_bit = 0; data_format_config.max_bit = 7; data_format_config.min_bit = 0; sei_cmd_data_format_config_init(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_8, &data_format_config); /* data register 9: send crc */ data_format_config.mode = sei_crc_mode; data_format_config.signed_flag = false; data_format_config.bit_order = sei_bit_lsb_first; data_format_config.word_order = sei_word_nonreverse; data_format_config.word_len = 8; data_format_config.crc_invert = false; data_format_config.crc_shift_mode = false; data_format_config.crc_len = 8; data_format_config.last_bit = 7; data_format_config.first_bit = 0; data_format_config.max_bit = 7; data_format_config.min_bit = 0; data_format_config.crc_init_value = 0; data_format_config.crc_poly = 1; sei_cmd_data_format_config_init(BOARD_SEI, SEI_SELECT_DATA, SEI_DAT_9, &data_format_config); /* [3] instructions */ instr_idx = 0; sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_RECV_WDG, 0, SEI_DAT_0, SEI_DAT_1, 8); /* Recv CF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 1); /* halt 1 bit for update */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_HALT, 0, SEI_DAT_0, SEI_DAT_0, 6); /* halt some bits for waiting */ /* jump to cmd */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_CMD_TABLE_INSTR_IDX0); /* jump to cmd table instr_idx[0] */ /* Data ID0 : 0x02 */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8); /* CF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8); /* SF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_5, 24); /* ST(POS) */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8); /* CRC */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX); /* Data ID1 : 0x8A */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8); /* CF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8); /* SF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_7, 24); /* MT */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8); /* CRC */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX); /* Data ID2 : 0x92 */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8); /* CF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8); /* SF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_6, 8); /* ENID:0x17 */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8); /* CRC */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX); /* Data ID3 : 0x1A */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_1, 8); /* CF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_4, 8); /* SF */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_5, 24); /* ST(POS) */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_6, 8); /* ENID:0x17 */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_7, 24); /* MT */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_9, SEI_DAT_8, 8); /* ALMC */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_SEND, 0, SEI_DAT_0, SEI_DAT_9, 8); /* CRC */ sei_set_instr(BOARD_SEI, instr_idx++, SEI_INSTR_OP_JUMP, 0, SEI_DAT_0, SEI_DAT_0, SEI_JUMP_INIT_INSTR_IDX); /* [4] command table */ command_table_config.cmd_min_value = 0x02u; command_table_config.cmd_max_value = 0x02u; command_table_config.cmd_mask_value = 0xFFu; command_table_config.instr_idx[0] = 4; sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_0, &command_table_config); command_table_config.cmd_min_value = 0x8Au; command_table_config.cmd_max_value = 0x8Au; command_table_config.cmd_mask_value = 0xFFu; command_table_config.instr_idx[0] = 9; sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_1, &command_table_config); command_table_config.cmd_min_value = 0x92u; command_table_config.cmd_max_value = 0x92u; command_table_config.cmd_mask_value = 0xFFu; command_table_config.instr_idx[0] = 14; sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_2, &command_table_config); command_table_config.cmd_min_value = 0x1Au; command_table_config.cmd_max_value = 0x1Au; command_table_config.cmd_mask_value = 0xFFu; command_table_config.instr_idx[0] = 19; sei_cmd_table_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_CMD_TABLE_3, &command_table_config); /* [5] state transition config */ /* latch0 */ state_transition_config.disable_clk_check = true; state_transition_config.disable_txd_check = true; state_transition_config.disable_rxd_check = true; state_transition_config.disable_timeout_check = true; state_transition_config.disable_instr_ptr_check = false; state_transition_config.instr_ptr_cfg = sei_state_tran_condition_fall_leave; state_transition_config.instr_ptr_value = 1; sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_0_1, &state_transition_config); state_transition_config.disable_clk_check = true; state_transition_config.disable_txd_check = true; state_transition_config.disable_rxd_check = true; state_transition_config.disable_timeout_check = true; state_transition_config.disable_instr_ptr_check = true; sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_1_2, &state_transition_config); state_transition_config.disable_clk_check = true; state_transition_config.disable_txd_check = true; state_transition_config.disable_rxd_check = true; state_transition_config.disable_timeout_check = true; state_transition_config.disable_instr_ptr_check = true; sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_2_3, &state_transition_config); state_transition_config.disable_clk_check = true; state_transition_config.disable_txd_check = true; state_transition_config.disable_rxd_check = true; state_transition_config.disable_timeout_check = true; state_transition_config.disable_instr_ptr_check = true; sei_state_transition_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, SEI_CTRL_LATCH_TRAN_3_0, &state_transition_config); state_transition_latch_config.enable = true; state_transition_latch_config.output_select = SEI_CTRL_LATCH_TRAN_0_1; state_transition_latch_config.delay = 0; sei_state_transition_latch_config_init(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0, &state_transition_latch_config); /* [6] sample config*/ sample_config.pos_data_idx = SEI_DAT_5; sample_config.rev_data_idx = SEI_DAT_7; sample_config.pos_data_use_rx = false; sample_config.rev_data_use_rx = false; sample_config.sample_window = 0x5; sample_config.sample_once = true; sample_config.latch_select = SEI_LATCH_0; sample_config.data_register_select = BIT5_MASK | BIT7_MASK; /* SEI_DAT_5, SEI_DAT_7 */ sei_sample_config_init(BOARD_SEI, BOARD_SEI_CTRL, &sample_config); sei_set_sample_pos_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_pos); sei_set_sample_rev_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_rev); /* [7] interrupt config */ intc_m_enable_irq_with_priority(BOARD_SEI_IRQn, 1); sei_set_irq_enable(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event | sei_irq_wdog_event | sei_irq_trx_err_event, true); /* [8] enbale sync timer timestamp */ synt_enable_timestamp(HPM_SYNT, true); /* [9] engine config */ printf("Started sei engine!\n"); engine_config.arming_mode = sei_arming_direct_exec; engine_config.data_cdm_idx = 0; engine_config.data_base_idx = 0; engine_config.init_instr_idx = 0; engine_config.wdg_enable = true; engine_config.wdg_action = sei_wdg_exec_exception_instr; engine_config.wdg_instr_idx = 0; engine_config.wdg_time = 1000; /* 1000 bits time */ sei_engine_config_init(BOARD_SEI, BOARD_SEI_CTRL, &engine_config); sei_set_engine_enable(BOARD_SEI, BOARD_SEI_CTRL, true); while (1) { ; } } void isr_sei(void) { uint32_t delta; if (sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event)) { sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_latch0_event); sample_latch_tm1 = sei_get_latch_time(BOARD_SEI, BOARD_SEI_CTRL, SEI_LATCH_0); mock_pos++; if (mock_pos > 0x00FFFFFF) { mock_pos = 0; mock_rev++; if (mock_rev > 0x00FFFFFF) { mock_rev = 0; } } sei_set_sample_pos_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_pos); sei_set_sample_rev_override_value(BOARD_SEI, BOARD_SEI_CTRL, mock_rev); sei_set_data_value(BOARD_SEI, SEI_DAT_4, 0x00); sei_set_data_value(BOARD_SEI, SEI_DAT_6, 0x17); sei_set_data_value(BOARD_SEI, SEI_DAT_8, 0x00); delta = (sample_latch_tm1 > sample_latch_tm2) ? (sample_latch_tm1 - sample_latch_tm2) : (sample_latch_tm1 - sample_latch_tm2 + 0xFFFFFFFFu); printf("CMD:%#x, SF:%#x, ST:%#x, ENID:%#x, MT:%#x, ALMC:%#x, CRC:%#x, sample_tm1:%u, sample_tm2:%u, sample_interval:%d us\n", sei_get_command_value(BOARD_SEI, BOARD_SEI_CTRL), sei_get_data_value(BOARD_SEI, SEI_DAT_4), sei_get_data_value(BOARD_SEI, SEI_DAT_5), sei_get_data_value(BOARD_SEI, SEI_DAT_6), sei_get_data_value(BOARD_SEI, SEI_DAT_7), sei_get_data_value(BOARD_SEI, SEI_DAT_8), sei_get_data_value(BOARD_SEI, SEI_DAT_9), sample_latch_tm1, sample_latch_tm2, delta / (clock_get_frequency(BOARD_MOTOR_CLK_NAME) / 1000000)); sample_latch_tm2 = sample_latch_tm1; } if (sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_wdog_event)) { sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_wdog_event); sei_set_command_rewind(BOARD_SEI, BOARD_SEI_CTRL); } if (sei_get_irq_status(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_trx_err_event)) { sei_clear_irq_flag(BOARD_SEI, BOARD_SEI_CTRL, sei_irq_trx_err_event); printf("TRX Error!\n"); } } SDK_DECLARE_EXT_ISR_M(BOARD_SEI_IRQn, isr_sei)