diff --git a/.cproject b/.cproject index 1501fb4..98e2564 100644 --- a/.cproject +++ b/.cproject @@ -40,7 +40,7 @@ - + @@ -66,7 +66,7 @@ - + diff --git a/.settings/stm32cubeide.project.prefs b/.settings/stm32cubeide.project.prefs index 7e5e08c..e5db33a 100644 --- a/.settings/stm32cubeide.project.prefs +++ b/.settings/stm32cubeide.project.prefs @@ -1,6 +1,6 @@ -2F62501ED4689FB349E356AB974DBE57=04980315A9C90A386CC08C1FEA19B581 +2F62501ED4689FB349E356AB974DBE57=9EAEC6679BAC0D8865B6DE2AD9864DCE 635E684B79701B039C64EA45C3F84D30=C8B026EBE17C208F17FB66CE4235156C 66BE74F758C12D739921AEA421D593D3=1 -8DF89ED150041C4CBC7CB9A9CAA90856=04980315A9C90A386CC08C1FEA19B581 +8DF89ED150041C4CBC7CB9A9CAA90856=9EAEC6679BAC0D8865B6DE2AD9864DCE DC22A860405A8BF2F2C095E5B6529F12=EC6C4D369FD4F7EABFE17B3222B5F3A0 eclipse.preferences.version=1 diff --git a/Core/Inc/FreeRTOSConfig.h b/Core/Inc/FreeRTOSConfig.h index 4e6a824..11bf23c 100644 --- a/Core/Inc/FreeRTOSConfig.h +++ b/Core/Inc/FreeRTOSConfig.h @@ -68,7 +68,7 @@ #define configTICK_RATE_HZ ((TickType_t)1000) #define configMAX_PRIORITIES ( 7 ) #define configMINIMAL_STACK_SIZE ((uint16_t)512) -#define configTOTAL_HEAP_SIZE ((size_t)50000) +#define configTOTAL_HEAP_SIZE ((size_t)40000) #define configMAX_TASK_NAME_LEN ( 16 ) #define configGENERATE_RUN_TIME_STATS 1 #define configUSE_TRACE_FACILITY 1 diff --git a/README.md b/README.md index c343462..feec27d 100644 --- a/README.md +++ b/README.md @@ -52,11 +52,6 @@ ID地址: PE2 调试指示灯 - - - - - ``` diff --git a/STM32F407VETX_FLASH.ld b/STM32F407VETX_FLASH.ld index c8ddbb0..b35accf 100644 --- a/STM32F407VETX_FLASH.ld +++ b/STM32F407VETX_FLASH.ld @@ -39,15 +39,15 @@ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ -_Min_Heap_Size = 0x2000; /* required amount of heap */ -_Min_Stack_Size = 0x1001; /* required amount of stack */ +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x0F01; /* required amount of stack */ /* Memories definition */ MEMORY { CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K - FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 384K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K } /* Sections */ diff --git a/STM32F407VETX_RAM.ld b/STM32F407VETX_RAM.ld index d10e01a..a170483 100644 --- a/STM32F407VETX_RAM.ld +++ b/STM32F407VETX_RAM.ld @@ -39,8 +39,8 @@ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ -_Min_Heap_Size = 0x2000; /* required amount of heap */ -_Min_Stack_Size = 0x1000; /* required amount of stack */ +_Min_Heap_Size = 0x1000; /* required amount of heap */ +_Min_Stack_Size = 0x0F01; /* required amount of stack */ /* Memories definition */ MEMORY diff --git a/a8000_protocol b/a8000_protocol index 3887bd1..4f4db27 160000 --- a/a8000_protocol +++ b/a8000_protocol @@ -1 +1 @@ -Subproject commit 3887bd1636c93701b8041dce9f1c29dddd0b01f3 +Subproject commit 4f4db2708e7503d5369c7b5f9bdc7781fcca1be9 diff --git a/sdk b/sdk index 59e0029..453c09f 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit 59e0029690e8b097ee03bd65083ec4b8f1974ce2 +Subproject commit 453c09f80bc5f51b5285d9f8b12df86c973a3515 diff --git a/usrc/subboards/subboard20_plate_clamp_case/plate_code_scaner_module.cpp b/usrc/subboards/subboard20_plate_clamp_case/plate_code_scaner_module.cpp new file mode 100644 index 0000000..75b1930 --- /dev/null +++ b/usrc/subboards/subboard20_plate_clamp_case/plate_code_scaner_module.cpp @@ -0,0 +1,375 @@ +#include "plate_code_scaner_module.hpp" + +#include +#include +#include + +using namespace iflytop; +using namespace std; +#define RAW_SECTION_SIZE 10 + +#define ONE_BIT_WIDTH 12 // 12*.0.1mm +#define BIT_NUM 15 +#define MAX_POINT (12 * 15 + 2) // 最多12*15+2个点,多扫描的两个点用于对齐使用 + +#define TAG "PlateCodeScaner" +#define LOGI(fmt, ...) ZLOGI(TAG, fmt, ##__VA_ARGS__) + +#define DO(func) \ + { \ + int32_t ecode = func; \ + if (ecode != 0) { \ + ZLOGE(TAG, "do %s fail, error %s(%d)", #func, err::error2str(ecode), ecode); \ + return ecode; \ + } \ + } + +#define DO_IN_THREAD(func) \ + { \ + int32_t ecode = func; \ + if (ecode != 0) { \ + ZLOGE(TAG, "do %s fail, error %s(%d)", #func, err::error2str(ecode), ecode); \ + creg.module_errorcode = ecode; \ + return; \ + } \ + } + +#define BITVAL(code, off) ((code & (1 << off)) >> off) +static void decode(uint32_t rawcode, int32_t* pitem, int32_t* plot) { // + // Lot:3:6 + // bit3->bit3, bit4->bit2, bit5->bit1, bit6->bit0 + uint32_t lot = 0; + lot = BITVAL(rawcode, 3) << 3 | BITVAL(rawcode, 4) << 2 | BITVAL(rawcode, 5) << 1 | BITVAL(rawcode, 6) << 0; + + // =(bit1)*2^6+(bit2)*2^5+(bit11)*2^4+(bit10)*2^0+(bit9)*2^1+(bit8)*2^2+(bit7)*2^3 + uint32_t item = 0; + item = (BITVAL(rawcode, 1) << 6) // + | (BITVAL(rawcode, 2) << 5) // + | (BITVAL(rawcode, 11) << 4) // + | (BITVAL(rawcode, 10) << 0) // + | (BITVAL(rawcode, 9) << 1) // + | (BITVAL(rawcode, 8) << 2) // + | (BITVAL(rawcode, 7) << 3); + + ZLOGI(TAG, "item-lot: %d-%d\n", item, lot); + *pitem = item; + *plot = lot; +} + +static int32_t t_detector_gain_to_potentiometer_val(float scan_gain) { + int32_t potentiometer_val = 0; + potentiometer_val = (scan_gain * 4.7 - 2.4) * 256. / 100. + 0.5; + if (potentiometer_val < 1) potentiometer_val = 1; + if (potentiometer_val > 255) potentiometer_val = 255; + return potentiometer_val; +} + +void PlateCodeScanerModule::initialize(int32_t moduleid, hardware_config_t* hardwarecfg) { // + m_id = moduleid; + m_hardwarecfg = *hardwarecfg; + + m_t_optical_amp_mcp41_ohm.initialize(&m_hardwarecfg.t_optical_amp_mcp41); + m_t_optical_scaner_mcp41_ohm.initialize(&m_hardwarecfg.t_optical_scaner_mcp41); + m_f_optical_amp_mcp41_ohm.initialize(&m_hardwarecfg.f_optical_amp_mcp41); + m_f_optical_scaner_mcp41_ohm.initialize(&m_hardwarecfg.f_optical_scaner_mcp41); + + m_t_laster_enable_io.initAsOutput(&m_hardwarecfg.t_laster_enable_io); + m_f_opt_laster_enable_io.initAsOutput(&m_hardwarecfg.f_opt_laster_enable_io); + m_channel_select_io_red_led3.initAsOutput(&m_hardwarecfg.channel_select_io_red_led3); + m_channel_select_io_blue_led1.initAsOutput(&m_hardwarecfg.channel_select_io_blue_led1); + m_channel_select_io_green_led1.initAsOutput(&m_hardwarecfg.channel_select_io_green_led1); + m_amp_negative_5v_gpio.initAsOutput(&m_hardwarecfg.amp_negative_5v_gpio); + + m_t_amp_sw_io.initAsOutput(&m_hardwarecfg.t_amp_sw_io); + m_f_amp_sw_io.initAsOutput(&m_hardwarecfg.f_amp_sw_io); + + t_laster_adc.initialize(&m_hardwarecfg.t_laster_adc); + t_result_adc.initialize(&m_hardwarecfg.t_result_adc); + f_laster_adc.initialize(&m_hardwarecfg.f_laster_adc); + f_result_adc.initialize(&m_hardwarecfg.f_result_adc); + + m_motor = (StepMotorCtrlModule*)m_hardwarecfg.motor; + ZASSERT(m_motor); + + adc_capture_buf = (int16_t*)calloc(2, MAX_POINT); + ZASSERT(adc_capture_buf); + + m_reg.laster_intensity = 1; + m_reg.scan_gain = 10; + m_thread.init("PlateCodeScanerModule", 1024, osPriorityNormal); +} +int32_t PlateCodeScanerModule::module_xxx_reg(int32_t param_id, bool read, int32_t& val) { + switch (param_id) { + PROCESS_REG(kreg_plate_code_scaner_laster_intensity, REG_GET(m_reg.laster_intensity), REG_SET(m_reg.laster_intensity)); + PROCESS_REG(kreg_plate_code_scaner_scan_gain, REG_GET(m_reg.scan_gain), REG_SET(m_reg.scan_gain)); + // PROCESS_REG(kreg_plate_code_scaner_scan_step_interval, REG_GET(m_reg.scan_step_interval), REG_SET(m_reg.scan_step_interval)); + // PROCESS_REG(kreg_plate_code_scaner_scan_point_num, REG_GET(m_reg.scan_point_num), REG_SET(m_reg.scan_point_num)); + default: + return err::kmodule_not_find_reg; + break; + } + if (!read) module_active_cfg(); + return 0; +}; +int32_t PlateCodeScanerModule::module_stop() { + m_thread.stop(); + return 0; +}; + +int32_t PlateCodeScanerModule::plate_code_scaner_push_card_and_scan(int32_t final_stop_pos) { + ZLOGI(TAG, "plate_code_scaner_push_card_and_scan: %d", final_stop_pos); + /** + * @brief + */ + m_thread.stop(); + creg.module_status = 1; + m_thread.start( + + [this, final_stop_pos]() { // + DO_IN_THREAD(before_run()); + ZLOGI(TAG, "plate_code_scaner_open_laser"); + plate_code_scaner_open_laser(); + + /*********************************************************************************************************************** + * 移动电机到扫描启动位置 * + ***********************************************************************************************************************/ + ZLOGI(TAG, "step_motor_easy_move_to start pos: %d", m_reg.scan_start_pos); + m_motor->step_motor_easy_move_to(m_reg.scan_start_pos); + while (true) { + if (!check_when_run() || m_thread.getExitFlag()) break; + + int32_t status = 0; + m_motor->module_get_status(&status); + if (status == 0) break; // 电机停止 + if (status == 2) return; // 电机异常 + osDelay(5); + } + ZLOGI(TAG, "has moved to start pos"); + /*********************************************************************************************************************** + * 开始扫码 * + ***********************************************************************************************************************/ + ZLOGI(TAG, "start scan"); + + m_reg.item = -1; + m_reg.lot = -1; + m_reg.rawcode = 0; + m_reg.code_legal = -1; + + auto _motor = m_motor->getMotor(); + int32_t targetpos = 0; + targetpos = m_reg.scan_start_pos + ONE_BIT_WIDTH * BIT_NUM; + ZLOGI(TAG, "move to: %d", targetpos); + _motor->moveTo(targetpos, m_reg.scan_velocity); + + reset_capture_buf(); + chip_critical_enter(); + while (true) { + if (m_thread.getExitFlag()) break; + if (_motor->isReachTarget()) break; + + // 读取ADC + int32_t pos = _motor->getXACTUAL(); + int16_t adcv = read_adc_val(); + int32_t dpos = abs(pos - m_reg.scan_start_pos); + push_one_point(dpos, adcv); + } + chip_critical_exit(); + + /*********************************************************************************************************************** + * 移动到扫码结束位置 * + ***********************************************************************************************************************/ + + ZLOGI(TAG, "step_motor_easy_move_to end pos: %d", final_stop_pos); + m_motor->step_motor_easy_move_to(final_stop_pos); + while (true) { + if (!check_when_run() || m_thread.getExitFlag()) break; + + int32_t status = 0; + m_motor->module_get_status(&status); + if (status == 0) break; // 电机停止 + if (status == 2) return; // 电机异常 + osDelay(5); + } + ZLOGI(TAG, "has moved to start pos"); + dumppoint(); + parsepoint(); + + }, + [this]() { // exit fn + after_run(); + m_motor->step_motor_stop(0); + plate_code_scaner_close_laser(); + } // + ); + + return 0; +} + +int32_t PlateCodeScanerModule::plate_code_scaner_stop_scan() { + ZLOGI(TAG, "plate_code_scaner_stop_scan"); + m_thread.stop(); + return 0; +} + +void PlateCodeScanerModule::push_one_point(int32_t pos, int16_t pointval) { + if (pos >= MAX_POINT) { + return; + } + if (pos < 0) { + return; + } + + for (int32_t i = adc_capture_last_point_index + 1; i < pos; i++) { + adc_capture_buf[i] = adc_capture_buf[adc_capture_last_point_index]; + } + + adc_capture_buf[pos] = pointval; + adc_capture_point_num = pos + 1; + adc_capture_last_point_index = pos; +} +void PlateCodeScanerModule::reset_capture_buf() { + adc_capture_point_num = 0; + adc_capture_last_point_index = 0; + for (int32_t i = 0; i < MAX_POINT; i++) { + adc_capture_buf[i] = 0; + } +} + +void PlateCodeScanerModule::dumppoint() { + ZLOGI(TAG, " ===== capture points: %d ==== ", adc_capture_point_num); + for (int32_t i = 0; i < adc_capture_point_num; i++) { + ZLOGI(TAG, "%5d %5d", i, adc_capture_buf[i]); + } +} +void PlateCodeScanerModule::parsepoint() { + // + uint8_t code[15]; + for (int32_t i = 0; i < 15; i++) { + int pos = i * 12 + 6; + // 黑色数值更小,黑色1,白色0 + if (adc_capture_buf[i] < m_reg.code_judgment_threshold) { + code[i] = 1; + } else { + code[i] = 0; + } + } + + uint32_t rawcode = 0; + + for (int32_t i = 0; i < 15; i++) { + rawcode |= code[i] << i; + } + + int32_t item = 0; + int32_t lot = 0; + decode(rawcode, &item, &lot); + + m_reg.item = item; + m_reg.lot = lot; + m_reg.rawcode = rawcode; + + if (code[14] == 1 && code[13] == 0 && code[12] == 0) { + m_reg.code_legal = 1; + } else { + m_reg.code_legal = 0; + } + + ZLOGI(TAG, "rawcode:%x code: %d-%d (legal:%d)", rawcode, m_reg.item, m_reg.lot, m_reg.code_legal); +} + +int32_t PlateCodeScanerModule::before_run() { return 0; } +int32_t PlateCodeScanerModule::after_run() { return 0; } +bool PlateCodeScanerModule::check_when_run() { return true; } + +int32_t PlateCodeScanerModule::plate_code_scaner_read_result(int32_t packetIndex, uint8_t* data, int32_t* len) { + // 每次传10个点 + int32_t start = packetIndex * RAW_SECTION_SIZE; + int32_t end = start + RAW_SECTION_SIZE; + if (end > adc_capture_point_num) { + end = adc_capture_point_num; + } + + int32_t size = end - start; + if (size <= 0) { + *len = 0; + return 0; + } + + memcpy(data, adc_capture_buf + start, size * 2); + *len = size * 2; + + return 0; +} +int32_t PlateCodeScanerModule::plate_code_scaner_read_result_point_num(int32_t* packetNum) { + *packetNum = adc_capture_point_num; + return 0; +} + +int32_t PlateCodeScanerModule::plate_code_scaner_adc_readraw(int32_t* val) { + *val = read_adc_val(); + return 0; +} +int32_t PlateCodeScanerModule::plate_code_scaner_read_code(int32_t* rawcode, int32_t* legal, int32_t* item, int32_t* lot) { + *item = m_reg.item; + *lot = m_reg.lot; + *rawcode = m_reg.rawcode; + *legal = m_reg.code_legal; + return 0; +} + +int32_t PlateCodeScanerModule::plate_code_scaner_open_laser() { + scaner_set_gain(m_reg.scan_gain / 10.0); + laser_set_intensity(m_reg.laster_intensity); + m_t_laster_enable_io.setState(true); + m_amp_negative_5v_gpio.setState(true); + m_t_amp_sw_io.setState(true); + m_f_amp_sw_io.setState(true); + m_lasterIsOn = true; + return 0; +} + +void PlateCodeScanerModule::scaner_set_gain(float gain) { + int32_t potentiometer_val = 0; + potentiometer_val = t_detector_gain_to_potentiometer_val(gain); + ZLOGI(TAG, "scaner_set_gain: %.2f(potentiometer_val: %d)", gain, potentiometer_val); + m_t_optical_scaner_mcp41_ohm.setPotentiometerValue_0(potentiometer_val); +} +void PlateCodeScanerModule::laser_set_intensity(float intensity) { + int32_t potentiometer_val = 0; + potentiometer_val = intensity / 100.0 * 255.0; + ZLOGI(TAG, "laser_set_intensity: %.2f(potentiometer_val: %d)", intensity, potentiometer_val); +} + +int32_t PlateCodeScanerModule::plate_code_scaner_close_laser() { + m_t_laster_enable_io.setState(false); + m_lasterIsOn = false; + return 0; +} + +int32_t PlateCodeScanerModule::read_adc_val() { + int32_t val = 0; + t_result_adc.get_adc_value(val); +#define CAPTURE_NUM 3 + + int32_t cache[CAPTURE_NUM]; + for (int i = 0; i < CAPTURE_NUM; i++) { + f_result_adc.get_adc_value(cache[i]); + } + + // 先排序,取中间10个数的中值 + for (int i = 0; i < CAPTURE_NUM; i++) { + for (int j = i + 1; j < CAPTURE_NUM; j++) { + if (cache[i] > cache[j]) { + int temp = cache[i]; + cache[i] = cache[j]; + cache[j] = temp; + } + } + } + + for (int i = 1; i < CAPTURE_NUM - 1; i++) { + val += cache[i]; + } + + return val / (CAPTURE_NUM - 2); +} \ No newline at end of file diff --git a/usrc/subboards/subboard20_plate_clamp_case/plate_code_scaner_module.hpp b/usrc/subboards/subboard20_plate_clamp_case/plate_code_scaner_module.hpp new file mode 100644 index 0000000..f19764c --- /dev/null +++ b/usrc/subboards/subboard20_plate_clamp_case/plate_code_scaner_module.hpp @@ -0,0 +1,145 @@ +#pragma once +#include "sdk\components\sensors\mcp41xxx\mcp41xxx.hpp" +#include "sdk\os\zos.hpp" +// +#include "a8000_protocol\api\zi_plate_code_scaner_module.hpp" +#include "a8000_protocol\protocol.hpp" +#include "sdk\chip\api\zi_adc.hpp" +#include "sdk\components\hardware\adc\z_simple_adc.hpp" +#include "sdk\components\step_motor_ctrl_module\step_motor_ctrl_module.hpp" + +namespace iflytop { +using namespace std; + +class PlateCodeScanerModule : public ZIModule, public ZI_PlateCodeScanerModule { + ENABLE_MODULE(PlateCodeScanerModule, ka8000_plate_code_scaner, PC_VERSION); + + typedef enum { + kf_optical = 0, + kt_optical = 1, + ktest_optical = 2, + } optical_type_t; + + public: + typedef struct { + ZGPIO::OutputGpioCfg_t amp_negative_5v_gpio; + + ZADC::adc_config_t t_laster_adc; + ZADC::adc_config_t t_result_adc; + MCP41XXX::hardware_config_t t_optical_amp_mcp41; + MCP41XXX::hardware_config_t t_optical_scaner_mcp41; + ZGPIO::OutputGpioCfg_t t_laster_enable_io; + ZGPIO::OutputGpioCfg_t t_amp_sw_io; + + MCP41XXX::hardware_config_t f_optical_amp_mcp41; + MCP41XXX::hardware_config_t f_optical_scaner_mcp41; + ZADC::adc_config_t f_laster_adc; + ZADC::adc_config_t f_result_adc; + ZGPIO::OutputGpioCfg_t f_opt_laster_enable_io; + ZGPIO::OutputGpioCfg_t f_amp_sw_io; + + ZGPIO::OutputGpioCfg_t channel_select_io_red_led3; // 引脚命名来源于巴迪泰原理图 + ZGPIO::OutputGpioCfg_t channel_select_io_blue_led1; // 引脚命名来源于巴迪泰原理图 + ZGPIO::OutputGpioCfg_t channel_select_io_green_led1; // 引脚命名来源于巴迪泰原理图 + + StepMotorCtrlModule* motor; + + } hardware_config_t; + + typedef struct { + int32_t laster_intensity; // 0->100 + int32_t scan_gain; // 1 = 0.1倍增益 + int32_t scan_velocity; // 扫描速度 + int32_t scan_start_pos; // 扫描开始位置 + int32_t final_stop_pos; // 扫描结束停止位置 + int32_t code_judgment_threshold; // 编码解析时,判断当前位置的编码是0还是1的阈值 + int32_t item; // + int32_t lot; // + int32_t rawcode; // + int32_t code_legal; // + } reg_table_t; + + private: + int32_t m_id = 0; + hardware_config_t m_hardwarecfg; + reg_table_t m_reg = {0}; + + MCP41XXX m_t_optical_amp_mcp41_ohm; + MCP41XXX m_t_optical_scaner_mcp41_ohm; + MCP41XXX m_f_optical_amp_mcp41_ohm; + MCP41XXX m_f_optical_scaner_mcp41_ohm; + // amp_negative_5v + ZGPIO m_amp_negative_5v_gpio; + + ZGPIO m_t_laster_enable_io; + ZGPIO m_f_opt_laster_enable_io; + ZGPIO m_channel_select_io_red_led3; + ZGPIO m_channel_select_io_blue_led1; + ZGPIO m_channel_select_io_green_led1; + + ZGPIO m_t_amp_sw_io; + ZGPIO m_f_amp_sw_io; + + ZADC t_laster_adc; + ZADC t_result_adc; + ZADC f_laster_adc; + ZADC f_result_adc; + + StepMotorCtrlModule* m_motor = nullptr; + + ZThread m_thread; + + int16_t* adc_capture_buf = nullptr; + int32_t adc_capture_point_num = 0; + int32_t adc_capture_last_point_index = 0; + + int32_t f_adc_cache[20]; + + bool m_lasterIsOn = false; + + public: + virtual ~PlateCodeScanerModule(){}; + + void initialize(int32_t moduleid, hardware_config_t* hardwarecfg); + + public: + /*********************************************************************************************************************** + * ZIModule * + ***********************************************************************************************************************/ + virtual int32_t getid(int32_t* id) { + *id = m_id; + return 0; + } + + virtual int32_t module_xxx_reg(int32_t param_id, bool read, int32_t& val) override; + virtual int32_t module_stop() override; + + /*********************************************************************************************************************** + * ZI_PlateCodeScanerModule * + ***********************************************************************************************************************/ + virtual int32_t plate_code_scaner_push_card_and_scan(int32_t final_stop_pos) override; + virtual int32_t plate_code_scaner_stop_scan() override; + virtual int32_t plate_code_scaner_read_result(int32_t packetIndex, uint8_t* data, int32_t* len) override; + virtual int32_t plate_code_scaner_read_result_point_num(int32_t* packetNum) override; + virtual int32_t plate_code_scaner_read_code(int32_t* rawcode, int32_t* legal, int32_t* item, int32_t* lot) override; + + virtual int32_t plate_code_scaner_adc_readraw(int32_t* val) override; + virtual int32_t plate_code_scaner_open_laser() override; + virtual int32_t plate_code_scaner_close_laser() override; + + private: + void push_one_point(int32_t pos, int16_t pointval); + void reset_capture_buf(); + void dumppoint(); + void parsepoint(); + + private: + int32_t before_run(); + int32_t after_run(); + bool check_when_run(); + + int32_t read_adc_val(); + void scaner_set_gain(float gain); + void laser_set_intensity(float intensity); +}; +} // namespace iflytop diff --git a/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case.cpp b/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case.cpp index ee8807f..ba7ff9b 100644 --- a/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case.cpp +++ b/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case.cpp @@ -2,6 +2,7 @@ extern "C" { #include "subboard20_plate_clamp_case_board.h" } +#include "plate_code_scaner_module.hpp" #include "pri_board.h" #include "public_service/instance_init.hpp" #include "public_service/public_service.hpp" @@ -22,11 +23,129 @@ using namespace iflytop; void Subboard20PlateClampCase::initialize() { IO_INIT(); GService::inst()->getZCanProtocolParser()->registerModule(this); + + static StepMotorCtrlModule* push_rod_motor = nullptr; + #if 1 /*********************************************************************************************************************** * ID1 * ***********************************************************************************************************************/ { TMC5130_MOTOR_INITER(1, 1); } { TMC5130_MOTOR_INITER(2, 2); } + + push_rod_motor = // + dynamic_cast(GService::inst()->getZCanProtocolParser()->getModule(getmoduleId(2))); + + { + PlateCodeScanerModule::hardware_config_t cfg = { + .amp_negative_5v_gpio = + { + .pin = PC5, + .mode = ZGPIO::kMode_nopull, + .mirror = true, + .initLevel = false, + .log_when_setstate = true, + }, + /******************************************************************************* + * T光学 * + *******************************************************************************/ + .t_laster_adc = + { + .hadc1 = &hadc1, + .channel = ADC_CHANNEL_13, + .samplingTime = ADC_SAMPLETIME_480CYCLES, + }, + .t_result_adc = + { + .hadc1 = &hadc1, + .channel = ADC_CHANNEL_12, + .samplingTime = ADC_SAMPLETIME_56CYCLES, // 注意这里必须要使用112周期采样时间,否则optical_module中的单次采样时间会大于1ms + }, + .t_optical_amp_mcp41 = + { + .spihandler = &hspi2, + .ncspin = PE15, + .mark = "t_optical_amp_mcp41", + }, + .t_optical_scaner_mcp41 = + { + .spihandler = &hspi2, + .ncspin = PE14, + .mark = "t_optical_scaner_mcp41", + }, + .t_laster_enable_io = + { + .pin = PB0, + .mode = ZGPIO::kMode_nopull, + .mirror = false, + .initLevel = false, + .log_when_setstate = true, + + }, + .t_amp_sw_io = + { + .pin = PinNull, + }, + /******************************************************************************* + * F光学 * + *******************************************************************************/ + .f_optical_amp_mcp41 = + { + .spihandler = &hspi3, + .ncspin = PC13, + .mark = "f_optical_amp_mcp41", + }, + .f_optical_scaner_mcp41 = + { + .spihandler = &hspi2, + .ncspin = PE13, + .mark = "f_optical_scaner_mcp41", + }, + // 激光亮度反馈ADC PC0 + .f_laster_adc = + { + .hadc1 = &hadc1, + .channel = ADC_CHANNEL_10, + .samplingTime = ADC_SAMPLETIME_480CYCLES, + }, + .f_result_adc = + { + .hadc1 = &hadc1, + .channel = ADC_CHANNEL_11, + .samplingTime = ADC_SAMPLETIME_480CYCLES, + }, + .f_opt_laster_enable_io = + { + .pin = PA8, + .mode = ZGPIO::kMode_nopull, + .mirror = false, + .initLevel = false, + .log_when_setstate = true, + }, + .f_amp_sw_io = + { + .pin = PD6, + .mode = ZGPIO::kMode_nopull, + .mirror = true, + .initLevel = false, + .log_when_setstate = true, + }, + + /******************************************************************************* + * F_CHANNEL_SELECT * + *******************************************************************************/ + .channel_select_io_red_led3 = {.pin = PB11, .mode = ZGPIO::kMode_nopull, .mirror = false, .initLevel = false, .log_when_setstate = true}, + .channel_select_io_blue_led1 = {.pin = PA15, .mode = ZGPIO::kMode_nopull, .mirror = false, .initLevel = false, .log_when_setstate = true}, + .channel_select_io_green_led1 = {.pin = PB10, .mode = ZGPIO::kMode_nopull, .mirror = false, .initLevel = false, .log_when_setstate = true}, + /******************************************************************************* + * 电机 * + *******************************************************************************/ + .motor = push_rod_motor, + + }; + static PlateCodeScanerModule module; + module.initialize(getmoduleId(3), &cfg); + GService::inst()->getZCanProtocolParser()->registerModule(&module); + } #endif } diff --git a/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case_board.c b/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case_board.c index 9828f4e..c8156f2 100644 --- a/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case_board.c +++ b/usrc/subboards/subboard20_plate_clamp_case/subboard20_plate_clamp_case_board.c @@ -62,6 +62,97 @@ static void MX_SPI2_Init(void) { hspi2_enable = true; } +static void MX_SPI3_Init(void) { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + __HAL_RCC_SPI3_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + + hspi3.Instance = SPI3; + hspi3.Init.Mode = SPI_MODE_MASTER; + hspi3.Init.Direction = SPI_DIRECTION_2LINES; + hspi3.Init.DataSize = SPI_DATASIZE_8BIT; + hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi3.Init.NSS = SPI_NSS_SOFT; + hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; + hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi3.Init.TIMode = SPI_TIMODE_DISABLE; + hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi3.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi3) != HAL_OK) { + Error_Handler(); + } + + /**SPI3 GPIO Configuration + PC10 ------> SPI3_SCK + PC11 ------> SPI3_MISO + PC12 ------> SPI3_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + hspi3_enable = true; +} + +/* ADC1 init function */ +static void ADC1_Init(void) { + __HAL_RCC_ADC1_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + */ + hadc1.Instance = ADC1; + hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; + hadc1.Init.Resolution = ADC_RESOLUTION_12B; + hadc1.Init.ScanConvMode = DISABLE; + hadc1.Init.ContinuousConvMode = DISABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + hadc1.Init.DMAContinuousRequests = DISABLE; + hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + if (HAL_ADC_Init(&hadc1) != HAL_OK) { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_10; + sConfig.Rank = 1; + sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { + Error_Handler(); + } + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /**ADC1 GPIO Configuration + PC0 ------> ADC1_IN10 + PC1 ------> ADC1_IN11 + PC2 ------> ADC1_IN12 + PC3 ------> ADC1_IN13 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + hadc1_enable = true; +} + /** * @brief 板夹仓初始化 */ @@ -70,4 +161,6 @@ void subboard20_plate_clamp_case_board_init() { common_hardware_init(); MX_SPI1_Init(); MX_SPI2_Init(); + MX_SPI3_Init(); + ADC1_Init(); }