From 85fe5a27df25e24da14a60ffcbd355e7930330da Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Sat, 10 Feb 2024 16:19:51 +0800 Subject: [PATCH 1/8] =?UTF-8?q?pref:=20=E6=94=B9=E8=BF=9B=E6=8C=89?= =?UTF-8?q?=E9=94=AE=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/by_buzzer.c | 10 +++++++ app/by_buzzer.h | 1 + app/isr.c | 80 ++++++++++++++++++++++++++++--------------------- app/main.c | 9 +++--- 4 files changed, 61 insertions(+), 39 deletions(-) diff --git a/app/by_buzzer.c b/app/by_buzzer.c index 6af01c9..b4df4d0 100644 --- a/app/by_buzzer.c +++ b/app/by_buzzer.c @@ -51,3 +51,13 @@ void by_buzzer_add(uint16_t tone) { queue_add_element(tone); } + +void by_buzzer_run(void) +{ + if (queue_long != 0) { + pwm_init(BUZZER_PIN, a[0], 5000); + queue_pop_element(); + system_delay_ms(100); + pwm_set_duty(BUZZER_PIN, 0); + } +} \ No newline at end of file diff --git a/app/by_buzzer.h b/app/by_buzzer.h index 060c1b8..b58c9a6 100644 --- a/app/by_buzzer.h +++ b/app/by_buzzer.h @@ -20,4 +20,5 @@ extern void queue_pop_element(void); extern void queue_pop_read(void); extern void by_buzzer_init(void); extern void by_buzzer_add(uint16_t tone); +extern void by_buzzer_run(void); #endif \ No newline at end of file diff --git a/app/isr.c b/app/isr.c index 4c57fb0..e0f81ac 100644 --- a/app/isr.c +++ b/app/isr.c @@ -202,61 +202,73 @@ void EXTI9_5_IRQHandler(void) void EXTI15_10_IRQHandler(void) { if (SET == EXTI_GetITStatus(EXTI_Line10)) { - system_delay_ms(10); - if (RESET == gpio_get_level(BUTTON_LEFT_PIN)) { - button_event = button_event_left; + if (button_event == button_event_none) { + system_delay_ms(10); + if (RESET == gpio_get_level(BUTTON_LEFT_PIN)) { + button_event = button_event_left; + } + by_buzzer_add(1250); } - by_buzzer_add(1250); EXTI_ClearITPendingBit(EXTI_Line10); } if (SET == EXTI_GetITStatus(EXTI_Line11)) { - system_delay_ms(10); - if (RESET == gpio_get_level(BUTTON_DOWN_PIN)) { - button_event = button_event_down; + if (button_event == button_event_none) { + system_delay_ms(10); + if (RESET == gpio_get_level(BUTTON_DOWN_PIN)) { + button_event = button_event_down; + } + by_buzzer_add(1250); } - by_buzzer_add(1250); EXTI_ClearITPendingBit(EXTI_Line11); } if (SET == EXTI_GetITStatus(EXTI_Line12)) { - system_delay_ms(10); - if (RESET == gpio_get_level(BUTTON_UP_PIN)) { - button_event = button_event_up; + if (button_event == button_event_none) { + system_delay_ms(10); + if (RESET == gpio_get_level(BUTTON_UP_PIN)) { + button_event = button_event_up; + } + by_buzzer_add(1250); } - by_buzzer_add(1250); EXTI_ClearITPendingBit(EXTI_Line12); } if (SET == EXTI_GetITStatus(EXTI_Line13)) { - static uint64_t time_via = 0; - system_delay_ms(10); - if (RESET == gpio_get_level(BUTTON_CENTER_PIN)) { - time_via = system_get_tick(); - } else if (SET == gpio_get_level(BUTTON_CENTER_PIN)) { - time_via = system_get_tick() - time_via; - if (time_via > LONG_PRESS_THRESHOLD_TICK) { - button_event = button_event_center_lp; - by_buzzer_add(2000); - } else { - button_event = button_event_center_sp; - by_buzzer_add(1800); + if (button_event == button_event_none) { + static uint64_t time_via = 0; + system_delay_ms(10); + if (RESET == gpio_get_level(BUTTON_CENTER_PIN)) { + time_via = system_get_tick(); + } else if (SET == gpio_get_level(BUTTON_CENTER_PIN)) { + time_via = system_get_tick() - time_via; + if (time_via > LONG_PRESS_THRESHOLD_TICK) { + button_event = button_event_center_lp; + by_buzzer_add(2000); + } else { + button_event = button_event_center_sp; + by_buzzer_add(1800); + } + time_via = 0; } - time_via = 0; } EXTI_ClearITPendingBit(EXTI_Line13); } if (SET == EXTI_GetITStatus(EXTI_Line14)) { - system_delay_ms(10); - if (RESET == gpio_get_level(BUTTON_RIGHT_PIN)) { - button_event = button_event_right; - by_buzzer_add(1250); + if (button_event == button_event_none) { + system_delay_ms(10); + if (RESET == gpio_get_level(BUTTON_RIGHT_PIN)) { + button_event = button_event_right; + by_buzzer_add(1250); + } } EXTI_ClearITPendingBit(EXTI_Line14); } if (SET == EXTI_GetITStatus(EXTI_Line15)) { - system_delay_ms(10); - if (RESET == gpio_get_level(BUTTON_SIDE_PIN)) { - button_event = button_event_side; - by_buzzer_add(2000); - by_buzzer_add(1500); + if (button_event == button_event_none) { + system_delay_ms(10); + if (RESET == gpio_get_level(BUTTON_SIDE_PIN)) { + button_event = button_event_side; + by_buzzer_add(2000); + by_buzzer_add(1500); + } } EXTI_ClearITPendingBit(EXTI_Line15); } diff --git a/app/main.c b/app/main.c index 8e69e41..8b712e3 100644 --- a/app/main.c +++ b/app/main.c @@ -36,23 +36,22 @@ int main(void) debug_init(); // mt9v03x_init(); ips200_init(IPS200_TYPE_SPI); - usb_cdc_init(); by_led_init(); by_buzzer_init(); by_button_init(); - jj_bt_init(); + // jj_bt_init(); // jj_param_eeprom_init(); Page_Init(); - pit_ms_init(TIM6_PIT, 2); - pit_ms_init(TIM1_PIT, 2); + // pit_ms_init(TIM6_PIT, 2); + // pit_ms_init(TIM1_PIT, 2); while (1) { Page_Run(); - queue_pop_read(); + by_buzzer_run(); if (mt9v03x_finish_flag) { // 该操作消耗大概 1970 个 tick,折合约 110us memcpy(mt9v03x_image_copy[0], mt9v03x_image[0], (sizeof(mt9v03x_image_copy) / sizeof(uint8_t))); From 1e982b4954e05cd3a001a01e31b20004be2a988d Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Thu, 15 Feb 2024 22:50:20 +0800 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E5=B8=A7=E6=8F=90=E5=8F=96=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eide/eide.json | 10 +- 3rd-lib/crc16/crc16.c | 137 ++++++ 3rd-lib/crc16/crc16.h | 9 + 3rd-lib/lwrb/inc/lwrb.h | 149 ++++++ 3rd-lib/lwrb/src/lwrb.c | 645 ++++++++++++++++++++++++++ app/gl_headfile.h | 1 - app/isr.c | 12 +- app/main.c | 43 +- app/main.h | 6 - app/tiny_frame/by_tiny_frame.c | 16 + app/tiny_frame/by_tiny_frame.h | 8 + app/tiny_frame/by_tiny_frame_config.h | 11 + app/tiny_frame/by_tiny_frame_parse.c | 97 ++++ app/tiny_frame/by_tiny_frame_parse.h | 25 + app/tiny_frame/by_tiny_frame_read.c | 0 app/tiny_frame/by_tiny_frame_read.h | 6 + app/tiny_frame/by_tiny_frame_write.c | 2 + app/tiny_frame/by_tiny_frame_write.h | 6 + 18 files changed, 1154 insertions(+), 29 deletions(-) create mode 100644 3rd-lib/crc16/crc16.c create mode 100644 3rd-lib/crc16/crc16.h create mode 100644 3rd-lib/lwrb/inc/lwrb.h create mode 100644 3rd-lib/lwrb/src/lwrb.c delete mode 100644 app/main.h create mode 100644 app/tiny_frame/by_tiny_frame.c create mode 100644 app/tiny_frame/by_tiny_frame.h create mode 100644 app/tiny_frame/by_tiny_frame_config.h create mode 100644 app/tiny_frame/by_tiny_frame_parse.c create mode 100644 app/tiny_frame/by_tiny_frame_parse.h create mode 100644 app/tiny_frame/by_tiny_frame_read.c create mode 100644 app/tiny_frame/by_tiny_frame_read.h create mode 100644 app/tiny_frame/by_tiny_frame_write.c create mode 100644 app/tiny_frame/by_tiny_frame_write.h diff --git a/.eide/eide.json b/.eide/eide.json index a9a788f..21b0c8d 100644 --- a/.eide/eide.json +++ b/.eide/eide.json @@ -7,7 +7,9 @@ "libraries/sdk", "libraries/zf_common", "libraries/zf_device", - "libraries/zf_driver" + "libraries/zf_driver", + "3rd-lib/crc16", + "3rd-lib/lwrb" ], "virtualFolder": { "name": "", @@ -55,7 +57,11 @@ "libraries/sdk/Core", "libraries/zf_common", "libraries/zf_device", - "libraries/zf_driver" + "libraries/zf_driver", + "3rd-lib/crc16", + "app/page", + "3rd-lib/lwrb/inc", + "app/tiny_frame" ], "libList": [ "libraries/zf_device" diff --git a/3rd-lib/crc16/crc16.c b/3rd-lib/crc16/crc16.c new file mode 100644 index 0000000..637c435 --- /dev/null +++ b/3rd-lib/crc16/crc16.c @@ -0,0 +1,137 @@ + +#include "crc16.h" + +//ModBUS CRC-16 码(modbus)校验 + +/* +1、实时计算 CRC16 +该种方式耗时比较多,但占用 FLASH、RAM 小 + +1)CRC 寄存器初始值为 FFFF;即 16 个字节全为 1; +2)CRC-16 / MODBUS 的多项式 A001H (1010 0000 0000 0001B) ‘H’表示 16 进制数,‘B’表示二进制数 + +计算步骤为: +(1).预置 16 位寄存器为十六进制 FFFF(即全为 1) ,称此寄存器为 CRC 寄存器; +(2).把第一个 8 位数据与 16 位 CRC 寄存器的低位相异或,把结果放于 CRC 寄存器; +(3).检测相异或后的 CRC 寄存器的最低位,若最低位为 1:CRC 寄存器先右移 1 位,再与多项式 A001H 进行异或;若为 0,则 CRC 寄存器右移 1 位,无需与多项式进行异或。 +(4).重复步骤 3,直到右移 8 次,这样整个 8 位数据全部进行了处理; +(5).重复步骤 2 到步骤 4,进行下一个 8 位数据的处理; +(6).最后得到的 CRC 寄存器即为 CRC 码。 + +addr:需要校验的字节数组 +num:需要校验的字节数 +返回值:16 位的 CRC 校验码 +*/ +uint16_t crc16(uint8_t *addr,uint32_t num) +{ + int i,j,temp; + uint16_t crc=0xFFFF; + for(i=0;i>1; + if(temp) + { + crc=crc^0xA001; + } + } + addr++; + } + return crc; + + //将 CRC 校验的高低位对换位置 +// uint16_t crc1; +// crc1 = crc >> 8; +// crc1 = crc1 | (crc << 8); +// return crc1; +} + +/* +2、查表计算 CRC16(耗时少) +从上面代码中,可以看出 CRC-16 的漏洞。无非是将待计算的数组,从头到尾单个字节按照同一算法反复计算。每个元素只有 0~255 的输入可能性,算法固定,所以算出来的值也是固定的。 +于是可以提前计算出校验值,按照输入为 0~255,排列为一组校验输出表。计算过程中根据输入数据进行查表,从头查到尾得到最终校验值。 +这样的计算方式省去了单片机的反复计算,极大缩短了计算耗时。而且可以将查表的数组类型定义为 const,存放在 Flash 中,运行时不占用 RAM。虽然都是空间换时间的策略,但这种方式只占用 Flash 不占用珍贵的 RAM。 + +addr:需要校验的字节数组 +num:需要校验的字节数 +返回值:16 位的 CRC 校验码 +说 明:计算结果是高位在前,需要转换才能发送 +*/ +uint16_t crc16_check(uint8_t* addr, uint32_t num) +{ + // CRC 高位字节值表 + static const uint8_t auchCRCHi[] = + { + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, + 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, + 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 + } ; + // CRC 低位字节值表 + static const uint8_t auchCRCLo[] = + { + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, + 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, + 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, + 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, + 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, + 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, + 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, + 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, + 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, + 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, + 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, + 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, + 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, + 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, + 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, + 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, + 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, + 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, + 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, + 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, + 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, + 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, + 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, + 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, + 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 + }; + + uint8_t uchCRCHi = 0xFF; + uint8_t uchCRCLo = 0xFF; + uint16_t uIndex; + while(num--) + { + uIndex = uchCRCLo ^ *addr++; + uchCRCLo = uchCRCHi^auchCRCHi[uIndex]; + uchCRCHi = auchCRCLo[uIndex]; + } + return (uchCRCHi<<8|uchCRCLo); + +} diff --git a/3rd-lib/crc16/crc16.h b/3rd-lib/crc16/crc16.h new file mode 100644 index 0000000..9ce89ed --- /dev/null +++ b/3rd-lib/crc16/crc16.h @@ -0,0 +1,9 @@ +#ifndef __CRC_16_H +#define __CRC_16_H + +#include + +extern uint16_t crc16(uint8_t *addr,uint32_t num); // 实时计算方式 +extern uint16_t crc16_check(uint8_t* addr, uint32_t num); // 查表计算方式 + +#endif diff --git a/3rd-lib/lwrb/inc/lwrb.h b/3rd-lib/lwrb/inc/lwrb.h new file mode 100644 index 0000000..0339e03 --- /dev/null +++ b/3rd-lib/lwrb/inc/lwrb.h @@ -0,0 +1,149 @@ +/** + * \file lwrb.h + * \brief LwRB - Lightweight ring buffer + */ + +/* + * Copyright (c) 2023 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwRB - Lightweight ring buffer library. + * + * Author: Tilen MAJERLE + * Version: v3.0.0-rc1 + */ +#ifndef LWRB_HDR_H +#define LWRB_HDR_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \defgroup LWRB Lightweight ring buffer manager + * \brief Lightweight ring buffer manager + * \{ + */ + +#if !defined(LWRB_DISABLE_ATOMIC) || __DOXYGEN__ +#include + +/** + * \brief Atomic type for size variable. + * Default value is set to be `unsigned 32-bits` type + */ +typedef atomic_ulong lwrb_sz_atomic_t; + +/** + * \brief Size variable for all library operations. + * Default value is set to be `unsigned 32-bits` type + */ +typedef unsigned long lwrb_sz_t; +#else +typedef unsigned long lwrb_sz_atomic_t; +typedef unsigned long lwrb_sz_t; +#endif + +/** + * \brief Event type for buffer operations + */ +typedef enum { + LWRB_EVT_READ, /*!< Read event */ + LWRB_EVT_WRITE, /*!< Write event */ + LWRB_EVT_RESET, /*!< Reset event */ +} lwrb_evt_type_t; + +/** + * \brief Buffer structure forward declaration + */ +struct lwrb; + +/** + * \brief Event callback function type + * \param[in] buff: Buffer handle for event + * \param[in] evt: Event type + * \param[in] bp: Number of bytes written or read (when used), depends on event type + */ +typedef void (*lwrb_evt_fn)(struct lwrb* buff, lwrb_evt_type_t evt, lwrb_sz_t bp); + +/* List of flags */ +#define LWRB_FLAG_READ_ALL ((uint16_t)0x0001) +#define LWRB_FLAG_WRITE_ALL ((uint16_t)0x0001) + +/** + * \brief Buffer structure + */ +typedef struct lwrb { + uint8_t* buff; /*!< Pointer to buffer data. Buffer is considered initialized when `buff != NULL` and `size > 0` */ + lwrb_sz_t size; /*!< Size of buffer data. Size of actual buffer is `1` byte less than value holds */ + lwrb_sz_atomic_t r; /*!< Next read pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ + lwrb_sz_atomic_t w; /*!< Next write pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ + lwrb_evt_fn evt_fn; /*!< Pointer to event callback function */ +} lwrb_t; + +uint8_t lwrb_init(lwrb_t* buff, void* buffdata, lwrb_sz_t size); +uint8_t lwrb_is_ready(lwrb_t* buff); +void lwrb_free(lwrb_t* buff); +void lwrb_reset(lwrb_t* buff); +void lwrb_set_evt_fn(lwrb_t* buff, lwrb_evt_fn fn); + +/* Read/Write functions */ +lwrb_sz_t lwrb_write(lwrb_t* buff, const void* data, lwrb_sz_t btw); +lwrb_sz_t lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr); +lwrb_sz_t lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp); + +/* Extended read/write functions */ +uint8_t lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint16_t flags); +uint8_t lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t flags); + +/* Buffer size information */ +lwrb_sz_t lwrb_get_free(const lwrb_t* buff); +lwrb_sz_t lwrb_get_full(const lwrb_t* buff); + +/* Read data block management */ +void* lwrb_get_linear_block_read_address(const lwrb_t* buff); +lwrb_sz_t lwrb_get_linear_block_read_length(const lwrb_t* buff); +lwrb_sz_t lwrb_skip(lwrb_t* buff, lwrb_sz_t len); + +/* Write data block management */ +void* lwrb_get_linear_block_write_address(const lwrb_t* buff); +lwrb_sz_t lwrb_get_linear_block_write_length(const lwrb_t* buff); +lwrb_sz_t lwrb_advance(lwrb_t* buff, lwrb_sz_t len); + +/* Search in buffer */ +uint8_t lwrb_find(const lwrb_t* buff, const void* bts, lwrb_sz_t len, lwrb_sz_t start_offset, lwrb_sz_t* found_idx); +lwrb_sz_t lwrb_overwrite(lwrb_t* buff, const void* data, lwrb_sz_t btw); +lwrb_sz_t lwrb_move(lwrb_t* dest, lwrb_t* src); + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LWRB_HDR_H */ diff --git a/3rd-lib/lwrb/src/lwrb.c b/3rd-lib/lwrb/src/lwrb.c new file mode 100644 index 0000000..348432c --- /dev/null +++ b/3rd-lib/lwrb/src/lwrb.c @@ -0,0 +1,645 @@ +/** + * \file lwrb.c + * \brief Lightweight ring buffer + */ + +/* + * Copyright (c) 2023 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwRB - Lightweight ring buffer library. + * + * Author: Tilen MAJERLE + * Version: v3.0.0 + */ +#include "lwrb.h" + +/* Memory set and copy functions */ +#define BUF_MEMSET memset +#define BUF_MEMCPY memcpy + +#define BUF_IS_VALID(b) ((b) != NULL && (b)->buff != NULL && (b)->size > 0) +#define BUF_MIN(x, y) ((x) < (y) ? (x) : (y)) +#define BUF_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define BUF_SEND_EVT(b, type, bp) \ + do { \ + if ((b)->evt_fn != NULL) { \ + (b)->evt_fn((void*)(b), (type), (bp)); \ + } \ + } while (0) + +/* Optional atomic opeartions */ +#ifdef LWRB_DISABLE_ATOMIC +#define LWRB_INIT(var, val) (var) = (val) +#define LWRB_LOAD(var, type) (var) +#define LWRB_STORE(var, val, type) (var) = (val) +#else +#define LWRB_INIT(var, val) atomic_init(&(var), (val)) +#define LWRB_LOAD(var, type) atomic_load_explicit(&(var), (type)) +#define LWRB_STORE(var, val, type) atomic_store_explicit(&(var), (val), (type)) +#endif + +/** + * \brief Initialize buffer handle to default values with size and buffer data array + * \param[in] buff: Ring buffer instance + * \param[in] buffdata: Pointer to memory to use as buffer data + * \param[in] size: Size of `buffdata` in units of bytes + * Maximum number of bytes buffer can hold is `size - 1` + * \return `1` on success, `0` otherwise + */ +uint8_t +lwrb_init(lwrb_t* buff, void* buffdata, lwrb_sz_t size) { + if (buff == NULL || buffdata == NULL || size == 0) { + return 0; + } + + buff->evt_fn = NULL; + buff->size = size; + buff->buff = buffdata; + LWRB_INIT(buff->w, 0); + LWRB_INIT(buff->r, 0); + return 1; +} + +/** + * \brief Check if buff is initialized and ready to use + * \param[in] buff: Ring buffer instance + * \return `1` if ready, `0` otherwise + */ +uint8_t +lwrb_is_ready(lwrb_t* buff) { + return BUF_IS_VALID(buff); +} + +/** + * \brief Free buffer memory + * \note Since implementation does not use dynamic allocation, + * it just sets buffer handle to `NULL` + * \param[in] buff: Ring buffer instance + */ +void +lwrb_free(lwrb_t* buff) { + if (BUF_IS_VALID(buff)) { + buff->buff = NULL; + } +} + +/** + * \brief Set event function callback for different buffer operations + * \param[in] buff: Ring buffer instance + * \param[in] evt_fn: Callback function + */ +void +lwrb_set_evt_fn(lwrb_t* buff, lwrb_evt_fn evt_fn) { + if (BUF_IS_VALID(buff)) { + buff->evt_fn = evt_fn; + } +} + +/** + * \brief Write data to buffer. + * Copies data from `data` array to buffer and marks buffer as full for maximum `btw` number of bytes + * + * \param[in] buff: Ring buffer instance + * \param[in] data: Pointer to data to write into buffer + * \param[in] btw: Number of bytes to write + * \return Number of bytes written to buffer. + * When returned value is less than `btw`, there was no enough memory available + * to copy full data array. + */ +lwrb_sz_t +lwrb_write(lwrb_t* buff, const void* data, lwrb_sz_t btw) { + lwrb_sz_t written = 0; + + if (lwrb_write_ex(buff, data, btw, &written, 0)) { + return written; + } + return 0; +} + +/** + * \brief Write extended functionality + * + * \param buff: Ring buffer instance + * \param data: Pointer to data to write into buffer + * \param btw: Number of bytes to write + * \param bw: Output pointer to write number of bytes written + * \param flags: Optional flags. + * \ref LWRB_FLAG_WRITE_ALL: Request to write all data (up to btw). + * Will early return if no memory available + * \return `1` if write operation OK, `0` otherwise + */ +uint8_t +lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint16_t flags) { + lwrb_sz_t tocopy, free, buff_w_ptr; + const uint8_t* d = data; + + if (!BUF_IS_VALID(buff) || data == NULL || btw == 0) { + return 0; + } + + /* Calculate maximum number of bytes available to write */ + free = lwrb_get_free(buff); + /* If no memory, or if user wants to write ALL data but no enough space, exit early */ + if (free == 0 || (free < btw && flags & LWRB_FLAG_WRITE_ALL)) { + return 0; + } + btw = BUF_MIN(free, btw); + buff_w_ptr = LWRB_LOAD(buff->w, memory_order_acquire); + + /* Step 1: Write data to linear part of buffer */ + tocopy = BUF_MIN(buff->size - buff_w_ptr, btw); + BUF_MEMCPY(&buff->buff[buff_w_ptr], d, tocopy); + buff_w_ptr += tocopy; + btw -= tocopy; + + /* Step 2: Write data to beginning of buffer (overflow part) */ + if (btw > 0) { + BUF_MEMCPY(buff->buff, &d[tocopy], btw); + buff_w_ptr = btw; + } + + /* Step 3: Check end of buffer */ + if (buff_w_ptr >= buff->size) { + buff_w_ptr = 0; + } + + /* + * Write final value to the actual running variable. + * This is to ensure no read operation can access intermediate data + */ + LWRB_STORE(buff->w, buff_w_ptr, memory_order_release); + + BUF_SEND_EVT(buff, LWRB_EVT_WRITE, tocopy + btw); + if (bw != NULL) { + *bw = tocopy + btw; + } + return 1; +} + +/** + * \brief Read data from buffer. + * Copies data from buffer to `data` array and marks buffer as free for maximum `btr` number of bytes + * + * \param[in] buff: Ring buffer instance + * \param[out] data: Pointer to output memory to copy buffer data to + * \param[in] btr: Number of bytes to read + * \return Number of bytes read and copied to data array + */ +lwrb_sz_t +lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr) { + lwrb_sz_t read = 0; + + if (lwrb_read_ex(buff, data, btr, &read, 0)) { + return read; + } + return 0; +} + +/** + * \brief Write extended functionality + * + * \param buff: Ring buffer instance + * \param data: Pointer to memory to write read data from buffer + * \param btr: Number of bytes to read + * \param br: Output pointer to write number of bytes read + * \param flags: Optional flags + * \ref LWRB_FLAG_READ_ALL: Request to read all data (up to btr). + * Will early return if no enough bytes in the buffer + * \return `1` if read operation OK, `0` otherwise + */ +uint8_t +lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t flags) { + lwrb_sz_t tocopy, full, buff_r_ptr; + uint8_t* d = data; + + if (!BUF_IS_VALID(buff) || data == NULL || btr == 0) { + return 0; + } + + /* Calculate maximum number of bytes available to read */ + full = lwrb_get_full(buff); + if (full == 0 || (full < btr && (flags & LWRB_FLAG_READ_ALL))) { + return 0; + } + btr = BUF_MIN(full, btr); + buff_r_ptr = LWRB_LOAD(buff->r, memory_order_acquire); + + /* Step 1: Read data from linear part of buffer */ + tocopy = BUF_MIN(buff->size - buff_r_ptr, btr); + BUF_MEMCPY(d, &buff->buff[buff_r_ptr], tocopy); + buff_r_ptr += tocopy; + btr -= tocopy; + + /* Step 2: Read data from beginning of buffer (overflow part) */ + if (btr > 0) { + BUF_MEMCPY(&d[tocopy], buff->buff, btr); + buff_r_ptr = btr; + } + + /* Step 3: Check end of buffer */ + if (buff_r_ptr >= buff->size) { + buff_r_ptr = 0; + } + + /* + * Write final value to the actual running variable. + * This is to ensure no write operation can access intermediate data + */ + LWRB_STORE(buff->r, buff_r_ptr, memory_order_release); + + BUF_SEND_EVT(buff, LWRB_EVT_READ, tocopy + btr); + if (br != NULL) { + *br = tocopy + btr; + } + return 1; +} + +/** + * \brief Read from buffer without changing read pointer (peek only) + * \param[in] buff: Ring buffer instance + * \param[in] skip_count: Number of bytes to skip before reading data + * \param[out] data: Pointer to output memory to copy buffer data to + * \param[in] btp: Number of bytes to peek + * \return Number of bytes peeked and written to output array + */ +lwrb_sz_t +lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp) { + lwrb_sz_t full, tocopy, r; + uint8_t* d = data; + + if (!BUF_IS_VALID(buff) || data == NULL || btp == 0) { + return 0; + } + + /* + * Calculate maximum number of bytes available to read + * and check if we can even fit to it + */ + full = lwrb_get_full(buff); + if (skip_count >= full) { + return 0; + } + r = LWRB_LOAD(buff->r, memory_order_relaxed); + r += skip_count; + full -= skip_count; + if (r >= buff->size) { + r -= buff->size; + } + + /* Check maximum number of bytes available to read after skip */ + btp = BUF_MIN(full, btp); + if (btp == 0) { + return 0; + } + + /* Step 1: Read data from linear part of buffer */ + tocopy = BUF_MIN(buff->size - r, btp); + BUF_MEMCPY(d, &buff->buff[r], tocopy); + btp -= tocopy; + + /* Step 2: Read data from beginning of buffer (overflow part) */ + if (btp > 0) { + BUF_MEMCPY(&d[tocopy], buff->buff, btp); + } + return tocopy + btp; +} + +/** + * \brief Get available size in buffer for write operation + * \param[in] buff: Ring buffer instance + * \return Number of free bytes in memory + */ +lwrb_sz_t +lwrb_get_free(const lwrb_t* buff) { + lwrb_sz_t size, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Copy buffer pointers to local variables with atomic access. + * + * To ensure thread safety (only when in single-entry, single-exit FIFO mode use case), + * it is important to write buffer r and w values to local w and r variables. + * + * Local variables will ensure below if statements will always use the same value, + * even if buff->w or buff->r get changed during interrupt processing. + * + * They may change during load operation, important is that + * they do not change during if-elseif-else operations following these assignments. + * + * lwrb_get_free is only called for write purpose, and when in FIFO mode, then: + * - buff->w pointer will not change by another process/interrupt because we are in write mode just now + * - buff->r pointer may change by another process. If it gets changed after buff->r has been loaded to local variable, + * buffer will see "free size" less than it actually is. This is not a problem, application can + * always try again to write more data to remaining free memory that was read just during copy operation + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w == r) { + size = buff->size; + } else if (r > w) { + size = r - w; + } else { + size = buff->size - (w - r); + } + + /* Buffer free size is always 1 less than actual size */ + return size - 1; +} + +/** + * \brief Get number of bytes currently available in buffer + * \param[in] buff: Ring buffer instance + * \return Number of bytes ready to be read + */ +lwrb_sz_t +lwrb_get_full(const lwrb_t* buff) { + lwrb_sz_t size, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Copy buffer pointers to local variables. + * + * To ensure thread safety (only when in single-entry, single-exit FIFO mode use case), + * it is important to write buffer r and w values to local w and r variables. + * + * Local variables will ensure below if statements will always use the same value, + * even if buff->w or buff->r get changed during interrupt processing. + * + * They may change during load operation, important is that + * they do not change during if-elseif-else operations following these assignments. + * + * lwrb_get_full is only called for read purpose, and when in FIFO mode, then: + * - buff->r pointer will not change by another process/interrupt because we are in read mode just now + * - buff->w pointer may change by another process. If it gets changed after buff->w has been loaded to local variable, + * buffer will see "full size" less than it really is. This is not a problem, application can + * always try again to read more data from remaining full memory that was written just during copy operation + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w == r) { + size = 0; + } else if (w > r) { + size = w - r; + } else { + size = buff->size - (r - w); + } + return size; +} + +/** + * \brief Resets buffer to default values. Buffer size is not modified + * \note This function is not thread safe. + * When used, application must ensure there is no active read/write operation + * \param[in] buff: Ring buffer instance + */ +void +lwrb_reset(lwrb_t* buff) { + if (BUF_IS_VALID(buff)) { + LWRB_STORE(buff->w, 0, memory_order_release); + LWRB_STORE(buff->r, 0, memory_order_release); + BUF_SEND_EVT(buff, LWRB_EVT_RESET, 0); + } +} + +/** + * \brief Get linear address for buffer for fast read + * \param[in] buff: Ring buffer instance + * \return Linear buffer start address + */ +void* +lwrb_get_linear_block_read_address(const lwrb_t* buff) { + if (!BUF_IS_VALID(buff)) { + return NULL; + } + return &buff->buff[buff->r]; +} + +/** + * \brief Get length of linear block address before it overflows for read operation + * \param[in] buff: Ring buffer instance + * \return Linear buffer size in units of bytes for read operation + */ +lwrb_sz_t +lwrb_get_linear_block_read_length(const lwrb_t* buff) { + lwrb_sz_t len, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Use temporary values in case they are changed during operations. + * See lwrb_buff_free or lwrb_buff_full functions for more information why this is OK. + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w > r) { + len = w - r; + } else if (r > w) { + len = buff->size - r; + } else { + len = 0; + } + return len; +} + +/** + * \brief Skip (ignore; advance read pointer) buffer data + * Marks data as read in the buffer and increases free memory for up to `len` bytes + * + * \note Useful at the end of streaming transfer such as DMA + * \param[in] buff: Ring buffer instance + * \param[in] len: Number of bytes to skip and mark as read + * \return Number of bytes skipped + */ +lwrb_sz_t +lwrb_skip(lwrb_t* buff, lwrb_sz_t len) { + lwrb_sz_t full, r; + + if (!BUF_IS_VALID(buff) || len == 0) { + return 0; + } + + full = lwrb_get_full(buff); + len = BUF_MIN(len, full); + r = LWRB_LOAD(buff->r, memory_order_acquire); + r += len; + if (r >= buff->size) { + r -= buff->size; + } + LWRB_STORE(buff->r, r, memory_order_release); + BUF_SEND_EVT(buff, LWRB_EVT_READ, len); + return len; +} + +/** + * \brief Get linear address for buffer for fast read + * \param[in] buff: Ring buffer instance + * \return Linear buffer start address + */ +void* +lwrb_get_linear_block_write_address(const lwrb_t* buff) { + if (!BUF_IS_VALID(buff)) { + return NULL; + } + return &buff->buff[buff->w]; +} + +/** + * \brief Get length of linear block address before it overflows for write operation + * \param[in] buff: Ring buffer instance + * \return Linear buffer size in units of bytes for write operation + */ +lwrb_sz_t +lwrb_get_linear_block_write_length(const lwrb_t* buff) { + lwrb_sz_t len, w, r; + + if (!BUF_IS_VALID(buff)) { + return 0; + } + + /* + * Use temporary values in case they are changed during operations. + * See lwrb_buff_free or lwrb_buff_full functions for more information why this is OK. + */ + w = LWRB_LOAD(buff->w, memory_order_relaxed); + r = LWRB_LOAD(buff->r, memory_order_relaxed); + + if (w >= r) { + len = buff->size - w; + /* + * When read pointer is 0, + * maximal length is one less as if too many bytes + * are written, buffer would be considered empty again (r == w) + */ + if (r == 0) { + /* + * Cannot overflow: + * - If r is not 0, statement does not get called + * - buff->size cannot be 0 and if r is 0, len is greater 0 + */ + --len; + } + } else { + len = r - w - 1; + } + return len; +} + +/** + * \brief Advance write pointer in the buffer. + * Similar to skip function but modifies write pointer instead of read + * + * \note Useful when hardware is writing to buffer and application needs to increase number + * of bytes written to buffer by hardware + * \param[in] buff: Ring buffer instance + * \param[in] len: Number of bytes to advance + * \return Number of bytes advanced for write operation + */ +lwrb_sz_t +lwrb_advance(lwrb_t* buff, lwrb_sz_t len) { + lwrb_sz_t free, w; + + if (!BUF_IS_VALID(buff) || len == 0) { + return 0; + } + + /* Use local variables before writing back to main structure */ + free = lwrb_get_free(buff); + len = BUF_MIN(len, free); + w = LWRB_LOAD(buff->w, memory_order_acquire); + w += len; + if (w >= buff->size) { + w -= buff->size; + } + LWRB_STORE(buff->w, w, memory_order_release); + BUF_SEND_EVT(buff, LWRB_EVT_WRITE, len); + return len; +} + +/** + * \brief Searches for a *needle* in an array, starting from given offset. + * + * \note This function is not thread-safe. + * + * \param buff: Ring buffer to search for needle in + * \param bts: Constant byte array sequence to search for in a buffer + * \param len: Length of the \arg bts array + * \param start_offset: Start offset in the buffer + * \param found_idx: Pointer to variable to write index in array where bts has been found + * Must not be set to `NULL` + * \return `1` if \arg bts found, `0` otherwise + */ +uint8_t +lwrb_find(const lwrb_t* buff, const void* bts, lwrb_sz_t len, lwrb_sz_t start_offset, lwrb_sz_t* found_idx) { + lwrb_sz_t full, r, max_x; + uint8_t found = 0; + const uint8_t* needle = bts; + + if (!BUF_IS_VALID(buff) || needle == NULL || len == 0 || found_idx == NULL) { + return 0; + } + *found_idx = 0; + + full = lwrb_get_full(buff); + /* Verify initial conditions */ + if (full < (len + start_offset)) { + return 0; + } + + /* Max number of for loops is buff_full - input_len - start_offset of buffer length */ + max_x = full - len; + for (lwrb_sz_t skip_x = start_offset; !found && skip_x <= max_x; ++skip_x) { + found = 1; /* Found by default */ + + /* Prepare the starting point for reading */ + r = buff->r + skip_x; + if (r >= buff->size) { + r -= buff->size; + } + + /* Search in the buffer */ + for (lwrb_sz_t i = 0; i < len; ++i) { + if (buff->buff[r] != needle[i]) { + found = 0; + break; + } + if (++r >= buff->size) { + r = 0; + } + } + if (found) { + *found_idx = skip_x; + } + } + return found; +} diff --git a/app/gl_headfile.h b/app/gl_headfile.h index 1482de7..08c361b 100644 --- a/app/gl_headfile.h +++ b/app/gl_headfile.h @@ -4,7 +4,6 @@ #include "gl_state.h" #include "gl_img_process.h" #include "gl_common.h" -#include "main.h" #include "gl_handle_img.h" #include "gl_transform_table.h" #include "gl_get_corners.h" diff --git a/app/isr.c b/app/isr.c index e0f81ac..cf9dd1c 100644 --- a/app/isr.c +++ b/app/isr.c @@ -34,9 +34,12 @@ ********************************************************************************************************************/ #include "zf_common_headfile.h" +#include "by_tiny_frame.h" #include "by_button.h" #include "by_buzzer.h" +#include "by_tiny_frame_parse.h" + void NMI_Handler(void) __attribute__((interrupt())); void HardFault_Handler(void) __attribute__((interrupt())); @@ -96,9 +99,12 @@ void USART2_IRQHandler(void) void USART3_IRQHandler(void) { if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { -#if DEBUG_UART_USE_INTERRUPT // debug ж - debug_interrupr_handler(); // debug ڽմ ݻᱻ debug λȡ -#endif // ޸ DEBUG_UART_INDEX δҪŵӦĴжȥ +#if DEBUG_UART_USE_INTERRUPT // debug ж + // debug_interrupr_handler(); // debug ڽմ ݻᱻ debug λȡ +#endif // ޸ DEBUG_UART_INDEX δҪŵӦĴжȥ + uint8_t data_s = 0; + uart_query_byte(UART_3, &data_s); + by_tiny_frame_parse_uart_handle(data_s); USART_ClearITPendingBit(USART3, USART_IT_RXNE); } } diff --git a/app/main.c b/app/main.c index 8b712e3..eb72219 100644 --- a/app/main.c +++ b/app/main.c @@ -21,13 +21,17 @@ * 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件 * 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明) ********************************************************************************************************************/ +#include "zf_common_headfile.h" #include "gl_headfile.h" -#include "./page/page.h" +#include "page.h" +#include "by_tiny_frame.h" #include "by_buzzer.h" #include "by_led.h" #include "jj_param.h" #include "jj_blueteeth.h" +#include "by_tiny_frame_parse.h" + int main(void) { @@ -49,25 +53,30 @@ int main(void) // pit_ms_init(TIM6_PIT, 2); // pit_ms_init(TIM1_PIT, 2); + by_tiny_frame_init(); + printf("start running\r\n"); + while (1) { Page_Run(); by_buzzer_run(); - if (mt9v03x_finish_flag) { - // 该操作消耗大概 1970 个 tick,折合约 110us - memcpy(mt9v03x_image_copy[0], mt9v03x_image[0], (sizeof(mt9v03x_image_copy) / sizeof(uint8_t))); - // adaptiveThreshold((uint8_t*)mt9v03x_image_copy, (uint8_t*)mt9v03x_image_copy, 188, 120, 7, 17); - // ips200_show_gray_image(0, 0, mt9v03x_image_copy[0], MT9V03X_W, MT9V03X_H, MT9V03X_W, MT9V03X_H, 0); - mt9v03x_finish_flag = 0; - by_led_info_blink(); - state_type = COMMON_STATE; - img_processing(); - get_corners(); - aim_distance = COMMON_AIM; - tracking(); - ElementJudge(); - ElementRun(); - MidLineTrack(); - } + by_tiny_frame_parse_run(); + system_delay_ms(100); + // if (mt9v03x_finish_flag) { + // // 该操作消耗大概 1970 个 tick,折合约 110us + // memcpy(mt9v03x_image_copy[0], mt9v03x_image[0], (sizeof(mt9v03x_image_copy) / sizeof(uint8_t))); + // // adaptiveThreshold((uint8_t*)mt9v03x_image_copy, (uint8_t*)mt9v03x_image_copy, 188, 120, 7, 17); + // // ips200_show_gray_image(0, 0, mt9v03x_image_copy[0], MT9V03X_W, MT9V03X_H, MT9V03X_W, MT9V03X_H, 0); + // mt9v03x_finish_flag = 0; + // by_led_info_blink(); + // state_type = COMMON_STATE; + // img_processing(); + // get_corners(); + // aim_distance = COMMON_AIM; + // tracking(); + // ElementJudge(); + // ElementRun(); + // MidLineTrack(); + // } } } diff --git a/app/main.h b/app/main.h deleted file mode 100644 index 1741eaa..0000000 --- a/app/main.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef MAIN_H -#define MAIN_H - -#include "zf_common_headfile.h" - -#endif // MAIN_H \ No newline at end of file diff --git a/app/tiny_frame/by_tiny_frame.c b/app/tiny_frame/by_tiny_frame.c new file mode 100644 index 0000000..6b2ccc5 --- /dev/null +++ b/app/tiny_frame/by_tiny_frame.c @@ -0,0 +1,16 @@ +#include "by_tiny_frame.h" + +#include +#include + +#include "by_tiny_frame_parse.h" +#include "crc16.h" +#include "zf_common_headfile.h" + +void by_tiny_frame_init(void) +{ + uart_init(BY_TF_UART_INDEX, BY_TF_UART_BAUDRATE, BY_TF_UART_TX_PIN, BY_TF_UART_RX_PIN); + uart_rx_interrupt(BY_TF_UART_INDEX, ENABLE); + + by_tiny_frame_parse_init(); +} diff --git a/app/tiny_frame/by_tiny_frame.h b/app/tiny_frame/by_tiny_frame.h new file mode 100644 index 0000000..630f0cf --- /dev/null +++ b/app/tiny_frame/by_tiny_frame.h @@ -0,0 +1,8 @@ +#ifndef _BY_TINY_FRAME_H__ +#define _BY_TINY_FRAME_H__ + +#include "by_tiny_frame_config.h" + +extern void by_tiny_frame_init(void); + +#endif diff --git a/app/tiny_frame/by_tiny_frame_config.h b/app/tiny_frame/by_tiny_frame_config.h new file mode 100644 index 0000000..2d14a89 --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_config.h @@ -0,0 +1,11 @@ +#ifndef _BY_TINY_FRAME_CONFIG_H__ +#define _BY_TINY_FRAME_CONFIG_H__ + +#define BY_TF_UART_TX_PIN (UART3_MAP0_TX_B10) +#define BY_TF_UART_RX_PIN (UART3_MAP0_RX_B11) +#define BY_TF_UART_INDEX (UART_3) +#define BY_TF_UART_BAUDRATE (115200) + +#define BY_TF_PARSE_BUFFER_SIZE (50) + +#endif diff --git a/app/tiny_frame/by_tiny_frame_parse.c b/app/tiny_frame/by_tiny_frame_parse.c new file mode 100644 index 0000000..9a67111 --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_parse.c @@ -0,0 +1,97 @@ +#include "by_tiny_frame_parse.h" + +#include "crc16.h" +#include "lwrb.h" + +lwrb_t lwrb_struct; +uint8_t buffer_rb[BY_TF_PARSE_BUFFER_SIZE]; +uint8_t buffer_out; +by_tf_parse_frame_t frame_now; + +void by_tiny_frame_parse_init(void) +{ + lwrb_init(&lwrb_struct, buffer_rb, 40); +} + +uint8_t by_tiny_frame_parse_listening(by_tf_parse_frame_t *frame_s, const uint8_t slave_id, const uint8_t buff) +{ + + static uint8_t cnt_s = 0; + static uint8_t cnt_rest_s = 0; + + printf("%0.2X\r\n", buff); + + do { + if ((0 == cnt_s) && (((slave_id << 1) + 1) == buff)) { + memset(frame_s, 0, sizeof(*frame_s)); + cnt_s = 1; + cnt_rest_s = 9; + frame_s->frame[0] = buff; + break; + } + + if (1 <= cnt_s) { + frame_s->frame[cnt_s] = buff; + cnt_s++; + } + + if (0 == --cnt_rest_s) { + cnt_s = 0; + + frame_s->cmd = frame_s->frame[1]; + frame_s->reg_addr |= ((uint16_t)frame_s->frame[2] << 8); + frame_s->reg_addr |= (uint16_t)frame_s->frame[3]; + frame_s->data |= ((uint32_t)frame_s->frame[4] << 24); + frame_s->data |= ((uint32_t)frame_s->frame[5] << 16); + frame_s->data |= ((uint32_t)frame_s->frame[6] << 8); + frame_s->data |= (uint32_t)frame_s->frame[7]; + return 0; + } + } while (0); + + return 1; +} + +void by_tiny_frame_parse_uart_handle(uint8_t buff) +{ + lwrb_write(&lwrb_struct, &buff, 1); +} + +void by_tiny_frame_parse_run(void) +{ + for (uint8_t i = 0; i < lwrb_get_full(&lwrb_struct); i++) { + + if (!lwrb_read(&lwrb_struct, &buffer_out, 1)) { + break; + } + + if (!by_tiny_frame_parse_listening(&frame_now, 127, buffer_out)) { + if (!by_tiny_frame_parse_crc(&frame_now)) { + printf("frame parsed!\r\n"); + } + // 解析帧 + } + // if (!mp_cmd_parse_modbus_handle(data)) { + // mp_cmd_mb_parse(&mp_cmd_mb_now, &mp_cmd_parsed_now); + // } + } +} + +uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s) +{ + uint16_t calc_crc_val = 0; + + calc_crc_val = crc16_check(frame_s->frame, (sizeof(frame_s->frame) - 2)); + + printf("get: %0.2X", frame_s->crc_val); + printf("\r\n"); + + printf("cal: %0.2X", calc_crc_val); + printf("\r\n"); + + if ((frame_s->crc_val == calc_crc_val) || (frame_s->crc_val == 0xFFFF)) { + return 0; + } + + return 1; +} \ No newline at end of file diff --git a/app/tiny_frame/by_tiny_frame_parse.h b/app/tiny_frame/by_tiny_frame_parse.h new file mode 100644 index 0000000..ed1801c --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_parse.h @@ -0,0 +1,25 @@ +#ifndef _BY_TINY_FRAME_PARSE_H__ +#define _BY_TINY_FRAME_PARSE_H__ + +#include +#include + +#include "by_tiny_frame_config.h" + +// 从机地址 (1b) - 功能码 (1b) - 寄存器地址 (2b) - 数据 (4b) - CRC(2b) +// 从机地址 (1b) 0-127, 最低位表示发送方,主机请求低位为 0,从机应答低位为 1 + +typedef struct by_tf_parse_frame_t { + uint8_t frame[10]; + uint8_t cmd; + uint16_t reg_addr; + uint16_t crc_val; + uint32_t data; +} by_tf_parse_frame_t; + +extern void by_tiny_frame_parse_init(void); +extern void by_tiny_frame_parse_uart_handle(uint8_t buff); +extern void by_tiny_frame_parse_run(void); +extern uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s); + +#endif diff --git a/app/tiny_frame/by_tiny_frame_read.c b/app/tiny_frame/by_tiny_frame_read.c new file mode 100644 index 0000000..e69de29 diff --git a/app/tiny_frame/by_tiny_frame_read.h b/app/tiny_frame/by_tiny_frame_read.h new file mode 100644 index 0000000..ca4081f --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_read.h @@ -0,0 +1,6 @@ +#ifndef _BY_TINY_FRAME_READ_H__ +#define _BY_TINY_FRAME_READ_H__ + +#define BY_TINY_FRAME_WRITE_CMD_CODE (0x03) + +#endif diff --git a/app/tiny_frame/by_tiny_frame_write.c b/app/tiny_frame/by_tiny_frame_write.c new file mode 100644 index 0000000..acca88c --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_write.c @@ -0,0 +1,2 @@ +#include "by_tiny_frame_write.h" + diff --git a/app/tiny_frame/by_tiny_frame_write.h b/app/tiny_frame/by_tiny_frame_write.h new file mode 100644 index 0000000..20093c5 --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_write.h @@ -0,0 +1,6 @@ +#ifndef _BY_TINY_FRAME_WRITE_H__ +#define _BY_TINY_FRAME_WRITE_H__ + +#define BY_TINY_FRAME_WRITE_CMD_CODE (0x06) + +#endif From 3a68f98635796322a0c0e08c7e86286d097f14f9 Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Fri, 23 Feb 2024 18:56:53 +0800 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E5=B8=A7=E7=BB=84=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.c | 17 ++++++++++++ app/tiny_frame/by_tiny_frame.c | 1 + app/tiny_frame/by_tiny_frame_config.h | 12 +++++++++ app/tiny_frame/by_tiny_frame_pack.c | 39 +++++++++++++++++++++++++++ app/tiny_frame/by_tiny_frame_pack.h | 24 +++++++++++++++++ app/tiny_frame/by_tiny_frame_parse.c | 20 ++++++++++++-- app/tiny_frame/by_tiny_frame_parse.h | 1 + 7 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 app/tiny_frame/by_tiny_frame_pack.c create mode 100644 app/tiny_frame/by_tiny_frame_pack.h diff --git a/app/main.c b/app/main.c index eb72219..645cb7a 100644 --- a/app/main.c +++ b/app/main.c @@ -30,7 +30,10 @@ #include "jj_param.h" #include "jj_blueteeth.h" +/** 测试完成后移除 **/ #include "by_tiny_frame_parse.h" +#include "by_tiny_frame_pack.h" +/** 测试完成后移除 **/ int main(void) { @@ -56,11 +59,25 @@ int main(void) by_tiny_frame_init(); printf("start running\r\n"); + /** 测试完成后移除 **/ + by_tf_pack_frame_t frame_now; + + frame_now.cmd = 0x06; + frame_now.data = 0x19260817; + frame_now.reg_addr = 0x4059; + frame_now.slave_id = 0x0D; + /** 测试完成后移除 **/ + while (1) { Page_Run(); by_buzzer_run(); + + /** 测试完成后移除 **/ by_tiny_frame_parse_run(); + // by_tiny_frame_pack_send(&frame_now); system_delay_ms(100); + /** 测试完成后移除 **/ + // if (mt9v03x_finish_flag) { // // 该操作消耗大概 1970 个 tick,折合约 110us // memcpy(mt9v03x_image_copy[0], mt9v03x_image[0], (sizeof(mt9v03x_image_copy) / sizeof(uint8_t))); diff --git a/app/tiny_frame/by_tiny_frame.c b/app/tiny_frame/by_tiny_frame.c index 6b2ccc5..f59e6c1 100644 --- a/app/tiny_frame/by_tiny_frame.c +++ b/app/tiny_frame/by_tiny_frame.c @@ -9,6 +9,7 @@ void by_tiny_frame_init(void) { + /*** 初始化相关外设 ***/ uart_init(BY_TF_UART_INDEX, BY_TF_UART_BAUDRATE, BY_TF_UART_TX_PIN, BY_TF_UART_RX_PIN); uart_rx_interrupt(BY_TF_UART_INDEX, ENABLE); diff --git a/app/tiny_frame/by_tiny_frame_config.h b/app/tiny_frame/by_tiny_frame_config.h index 2d14a89..295678f 100644 --- a/app/tiny_frame/by_tiny_frame_config.h +++ b/app/tiny_frame/by_tiny_frame_config.h @@ -1,6 +1,8 @@ #ifndef _BY_TINY_FRAME_CONFIG_H__ #define _BY_TINY_FRAME_CONFIG_H__ +#define BY_TF_DEBUG (1) + #define BY_TF_UART_TX_PIN (UART3_MAP0_TX_B10) #define BY_TF_UART_RX_PIN (UART3_MAP0_RX_B11) #define BY_TF_UART_INDEX (UART_3) @@ -8,4 +10,14 @@ #define BY_TF_PARSE_BUFFER_SIZE (50) +/** 注释此项则为主机,否则为从机 **/ +// #define BY_TF_DEVICE_SLAVE + +#if defined(BY_TF_DEVICE_SLAVE) +/** 多从机通信时注意修改地址,避免冲突 **/ +#define BY_TF_DEVICE_SLAVE_ADDRESS (0x0D) +#else +#define BY_TF_DEVICE_MASTER +#endif + #endif diff --git a/app/tiny_frame/by_tiny_frame_pack.c b/app/tiny_frame/by_tiny_frame_pack.c new file mode 100644 index 0000000..78107f0 --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_pack.c @@ -0,0 +1,39 @@ +#include "by_tiny_frame_pack.h" + +#include +#include "zf_common_headfile.h" +#include "crc16.h" + +void by_tiny_frame_pack_init(void) +{ + /** nothing to init **/ +} + +void by_tiny_frame_pack_send(by_tf_pack_frame_t *frame_s) +{ + uint16_t calc_crc_val = 0; + +#if defined(BY_TF_DEVICE_SLAVE) + frame_s->frame[0] = ((frame_s->slave_id << 1) + 1); +#else + frame_s->frame[0] = (frame_s->slave_id << 1); +#endif + + // 填充指令段 + frame_s->frame[1] = frame_s->cmd; + // 填充寄存器地址段 + frame_s->frame[2] = (uint8_t)((frame_s->reg_addr >> 8) & 0xFF); + frame_s->frame[3] = (uint8_t)(frame_s->reg_addr & 0xFF); + // 填充数据段 + frame_s->frame[4] = (uint8_t)((frame_s->data >> 24) & 0xFF); + frame_s->frame[5] = (uint8_t)((frame_s->data >> 16) & 0xFF); + frame_s->frame[6] = (uint8_t)((frame_s->data >> 8) & 0xFF); + frame_s->frame[7] = (uint8_t)(frame_s->data & 0xFF); + // 填充 CRC 段 + calc_crc_val = crc16_check(frame_s->frame, (sizeof(frame_s->frame) - 2)); + frame_s->frame[8] = (uint8_t)((calc_crc_val >> 8) & 0xFF); + frame_s->frame[9] = (uint8_t)(calc_crc_val & 0xFF); + + /** 从串口发送 **/ + uart_write_buffer(BY_TF_UART_INDEX, frame_s->frame, sizeof(frame_s->frame)); +} diff --git a/app/tiny_frame/by_tiny_frame_pack.h b/app/tiny_frame/by_tiny_frame_pack.h new file mode 100644 index 0000000..70fbb9d --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_pack.h @@ -0,0 +1,24 @@ +#ifndef _BY_TINY_FRAME_PACK_H__ +#define _BY_TINY_FRAME_PACK_H__ + +#include +#include + +#include "by_tiny_frame_config.h" + +// 从机地址 (1b) - 功能码 (1b) - 寄存器地址 (2b) - 数据 (4b) - CRC(2b) +// 从机地址 (1b) 0-127, 最低位表示发送方,主机请求低位为 0,从机应答低位为 1 +// 高字节在前 + +typedef struct by_tf_pack_frame_t { + uint8_t frame[10]; + uint8_t slave_id; + uint8_t cmd; + uint16_t reg_addr; + uint32_t data; +} by_tf_pack_frame_t; + +extern void by_tiny_frame_pack_init(void); +extern void by_tiny_frame_pack_send(by_tf_pack_frame_t *frame_s); + +#endif diff --git a/app/tiny_frame/by_tiny_frame_parse.c b/app/tiny_frame/by_tiny_frame_parse.c index 9a67111..1c44b6d 100644 --- a/app/tiny_frame/by_tiny_frame_parse.c +++ b/app/tiny_frame/by_tiny_frame_parse.c @@ -10,6 +10,7 @@ by_tf_parse_frame_t frame_now; void by_tiny_frame_parse_init(void) { + /** 初始化环形缓冲区 **/ lwrb_init(&lwrb_struct, buffer_rb, 40); } @@ -19,10 +20,17 @@ uint8_t by_tiny_frame_parse_listening(by_tf_parse_frame_t *frame_s, const uint8_ static uint8_t cnt_s = 0; static uint8_t cnt_rest_s = 0; +#if (BY_TF_DEBUG) printf("%0.2X\r\n", buff); +#endif do { + +#if defined(BY_TF_DEVICE_SLAVE) + if ((0 == cnt_s) && ((slave_id << 1) == buff)) { +#else if ((0 == cnt_s) && (((slave_id << 1) + 1) == buff)) { +#endif memset(frame_s, 0, sizeof(*frame_s)); cnt_s = 1; cnt_rest_s = 9; @@ -45,6 +53,8 @@ uint8_t by_tiny_frame_parse_listening(by_tf_parse_frame_t *frame_s, const uint8_ frame_s->data |= ((uint32_t)frame_s->frame[5] << 16); frame_s->data |= ((uint32_t)frame_s->frame[6] << 8); frame_s->data |= (uint32_t)frame_s->frame[7]; + frame_s->crc_val |= ((uint16_t)frame_s->frame[8] << 8); + frame_s->crc_val |= (uint16_t)frame_s->frame[9]; return 0; } } while (0); @@ -65,11 +75,15 @@ void by_tiny_frame_parse_run(void) break; } - if (!by_tiny_frame_parse_listening(&frame_now, 127, buffer_out)) { + // TODO 待结合 read&wirte 部分修改监听的从机地址 + if (!by_tiny_frame_parse_listening(&frame_now, 0x0D, buffer_out)) { if (!by_tiny_frame_parse_crc(&frame_now)) { + +#if (BY_TF_DEBUG) printf("frame parsed!\r\n"); +#endif + // 解析帧 } - // 解析帧 } // if (!mp_cmd_parse_modbus_handle(data)) { // mp_cmd_mb_parse(&mp_cmd_mb_now, &mp_cmd_parsed_now); @@ -83,11 +97,13 @@ uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s) calc_crc_val = crc16_check(frame_s->frame, (sizeof(frame_s->frame) - 2)); +#if (BY_TF_DEBUG) printf("get: %0.2X", frame_s->crc_val); printf("\r\n"); printf("cal: %0.2X", calc_crc_val); printf("\r\n"); +#endif if ((frame_s->crc_val == calc_crc_val) || (frame_s->crc_val == 0xFFFF)) { return 0; diff --git a/app/tiny_frame/by_tiny_frame_parse.h b/app/tiny_frame/by_tiny_frame_parse.h index ed1801c..6047fdd 100644 --- a/app/tiny_frame/by_tiny_frame_parse.h +++ b/app/tiny_frame/by_tiny_frame_parse.h @@ -8,6 +8,7 @@ // 从机地址 (1b) - 功能码 (1b) - 寄存器地址 (2b) - 数据 (4b) - CRC(2b) // 从机地址 (1b) 0-127, 最低位表示发送方,主机请求低位为 0,从机应答低位为 1 +// 高字节在前 typedef struct by_tf_parse_frame_t { uint8_t frame[10]; From a1c047f15a78983bd6bba6a044f09c27dd966b28 Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Fri, 23 Feb 2024 20:13:34 +0800 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E5=B8=A7=E8=A7=A3=E6=9E=90=E8=B6=85=E6=97=B6=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.c | 11 ++++- app/tiny_frame/by_tiny_frame_config.h | 8 +++- app/tiny_frame/by_tiny_frame_parse.c | 65 ++++++++++++++++++++++++++- app/tiny_frame/by_tiny_frame_parse.h | 5 +++ 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/app/main.c b/app/main.c index 645cb7a..af00836 100644 --- a/app/main.c +++ b/app/main.c @@ -35,6 +35,11 @@ #include "by_tiny_frame_pack.h" /** 测试完成后移除 **/ +void test(void) +{ + printf("hhhhhhok\r\n"); +} + int main(void) { @@ -60,6 +65,9 @@ int main(void) printf("start running\r\n"); /** 测试完成后移除 **/ + by_tiny_frame_parse_handle_register(test); + by_tiny_frame_parse_start_listern(); + by_tf_pack_frame_t frame_now; frame_now.cmd = 0x06; @@ -75,7 +83,8 @@ int main(void) /** 测试完成后移除 **/ by_tiny_frame_parse_run(); // by_tiny_frame_pack_send(&frame_now); - system_delay_ms(100); + system_delay_ms(10); + by_tiny_frame_parse_timer_handle(); /** 测试完成后移除 **/ // if (mt9v03x_finish_flag) { diff --git a/app/tiny_frame/by_tiny_frame_config.h b/app/tiny_frame/by_tiny_frame_config.h index 295678f..a302e29 100644 --- a/app/tiny_frame/by_tiny_frame_config.h +++ b/app/tiny_frame/by_tiny_frame_config.h @@ -10,14 +10,18 @@ #define BY_TF_PARSE_BUFFER_SIZE (50) -/** 注释此项则为主机,否则为从机 **/ +// 注释此项则为主机,否则为从机 // #define BY_TF_DEVICE_SLAVE +/********** 从机模式配置选项 **********/ #if defined(BY_TF_DEVICE_SLAVE) -/** 多从机通信时注意修改地址,避免冲突 **/ +// 从机地址 (多从机通信时注意修改地址,避免冲突) #define BY_TF_DEVICE_SLAVE_ADDRESS (0x0D) +/********** 主机模式配置选项 **********/ #else #define BY_TF_DEVICE_MASTER +// 监听/解析 超时时间 单位毫秒 +#define BY_TF_PARSE_TIMEOUT (200) #endif #endif diff --git a/app/tiny_frame/by_tiny_frame_parse.c b/app/tiny_frame/by_tiny_frame_parse.c index 1c44b6d..d5f627f 100644 --- a/app/tiny_frame/by_tiny_frame_parse.c +++ b/app/tiny_frame/by_tiny_frame_parse.c @@ -6,10 +6,18 @@ lwrb_t lwrb_struct; uint8_t buffer_rb[BY_TF_PARSE_BUFFER_SIZE]; uint8_t buffer_out; +uint8_t listern_flag; +uint16_t listern_timeout; +uint16_t listern_timevia; by_tf_parse_frame_t frame_now; +by_tf_parse_success_handle_func parse_success_handle; void by_tiny_frame_parse_init(void) { +#if defined(BY_TF_DEVICE_MASTER) + listern_timeout = BY_TF_PARSE_TIMEOUT; +#endif + /** 初始化环形缓冲区 **/ lwrb_init(&lwrb_struct, buffer_rb, 40); } @@ -62,23 +70,63 @@ uint8_t by_tiny_frame_parse_listening(by_tf_parse_frame_t *frame_s, const uint8_ return 1; } +/** + * @brief by_tf_parse 串口回调函数,在对应串口中断函数中调用 + * + * @param buff + */ void by_tiny_frame_parse_uart_handle(uint8_t buff) { lwrb_write(&lwrb_struct, &buff, 1); } +/** + * @brief by_tf_parse 定时回调函数,要求触发周期为 1ms + * + */ +void by_tiny_frame_parse_timer_handle(void) +{ +#if defined(BY_TF_DEVICE_MASTER) + if (listern_flag) { + listern_timevia++; + } else { + listern_timevia = 0; + } +#endif +} + void by_tiny_frame_parse_run(void) { + +#if defined(BY_TF_DEVICE_MASTER) + if (0 == listern_flag) { + return; + } else { + if (listern_timeout <= listern_timevia) { + // 接收超时,停止监听 + by_tiny_frame_parse_end_listern(); +#if (BY_TF_DEBUG) + printf("by_tf_listern timeout\r\n"); +#endif + } + } +#endif + for (uint8_t i = 0; i < lwrb_get_full(&lwrb_struct); i++) { if (!lwrb_read(&lwrb_struct, &buffer_out, 1)) { break; } + // TODO 目前接收校验错误也会等待直至超时 // TODO 待结合 read&wirte 部分修改监听的从机地址 if (!by_tiny_frame_parse_listening(&frame_now, 0x0D, buffer_out)) { if (!by_tiny_frame_parse_crc(&frame_now)) { + // 接收成功后停止监听 + by_tiny_frame_parse_end_listern(); + // 解析成功回调 + parse_success_handle(); #if (BY_TF_DEBUG) printf("frame parsed!\r\n"); #endif @@ -110,4 +158,19 @@ uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s) } return 1; -} \ No newline at end of file +} + +void by_tiny_frame_parse_handle_register(by_tf_parse_success_handle_func func) +{ + parse_success_handle = func; +} + +void by_tiny_frame_parse_start_listern(void) +{ + listern_flag = 1; +} + +void by_tiny_frame_parse_end_listern(void) +{ + listern_flag = 0; +} diff --git a/app/tiny_frame/by_tiny_frame_parse.h b/app/tiny_frame/by_tiny_frame_parse.h index 6047fdd..eeb41a0 100644 --- a/app/tiny_frame/by_tiny_frame_parse.h +++ b/app/tiny_frame/by_tiny_frame_parse.h @@ -18,9 +18,14 @@ typedef struct by_tf_parse_frame_t { uint32_t data; } by_tf_parse_frame_t; +typedef void (*by_tf_parse_success_handle_func)(void); + extern void by_tiny_frame_parse_init(void); extern void by_tiny_frame_parse_uart_handle(uint8_t buff); extern void by_tiny_frame_parse_run(void); extern uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s); +extern void by_tiny_frame_parse_handle_register(by_tf_parse_success_handle_func func); +extern void by_tiny_frame_parse_start_listern(void); +extern void by_tiny_frame_parse_end_listern(void); #endif From 8a573170e0513f0f90a051c80451a4897bd2ade4 Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Fri, 23 Feb 2024 20:41:40 +0800 Subject: [PATCH 5/8] =?UTF-8?q?pref:=20=E6=9B=B4=E6=94=B9=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E5=B8=A7=E6=8E=A5=E6=94=B6=E5=AE=8C=E6=88=90=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=87=BD=E6=95=B0=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.c | 8 ++++++-- app/tiny_frame/by_tiny_frame_parse.c | 9 +++++---- app/tiny_frame/by_tiny_frame_parse.h | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/main.c b/app/main.c index af00836..028d67c 100644 --- a/app/main.c +++ b/app/main.c @@ -35,9 +35,13 @@ #include "by_tiny_frame_pack.h" /** 测试完成后移除 **/ -void test(void) +void test(uint8_t status) { - printf("hhhhhhok\r\n"); + if (status) { + printf("noooooooo!\r\n"); + } else { + printf("hhhhhhok\r\n"); + } } int main(void) diff --git a/app/tiny_frame/by_tiny_frame_parse.c b/app/tiny_frame/by_tiny_frame_parse.c index d5f627f..0432c14 100644 --- a/app/tiny_frame/by_tiny_frame_parse.c +++ b/app/tiny_frame/by_tiny_frame_parse.c @@ -10,7 +10,7 @@ uint8_t listern_flag; uint16_t listern_timeout; uint16_t listern_timevia; by_tf_parse_frame_t frame_now; -by_tf_parse_success_handle_func parse_success_handle; +by_tf_parse_done_handle_func parse_done_handle; void by_tiny_frame_parse_init(void) { @@ -104,6 +104,7 @@ void by_tiny_frame_parse_run(void) } else { if (listern_timeout <= listern_timevia) { // 接收超时,停止监听 + parse_done_handle(1); by_tiny_frame_parse_end_listern(); #if (BY_TF_DEBUG) printf("by_tf_listern timeout\r\n"); @@ -126,7 +127,7 @@ void by_tiny_frame_parse_run(void) // 接收成功后停止监听 by_tiny_frame_parse_end_listern(); // 解析成功回调 - parse_success_handle(); + parse_done_handle(0); #if (BY_TF_DEBUG) printf("frame parsed!\r\n"); #endif @@ -160,9 +161,9 @@ uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s) return 1; } -void by_tiny_frame_parse_handle_register(by_tf_parse_success_handle_func func) +void by_tiny_frame_parse_handle_register(by_tf_parse_done_handle_func func) { - parse_success_handle = func; + parse_done_handle = func; } void by_tiny_frame_parse_start_listern(void) diff --git a/app/tiny_frame/by_tiny_frame_parse.h b/app/tiny_frame/by_tiny_frame_parse.h index eeb41a0..2d7a7ac 100644 --- a/app/tiny_frame/by_tiny_frame_parse.h +++ b/app/tiny_frame/by_tiny_frame_parse.h @@ -18,13 +18,13 @@ typedef struct by_tf_parse_frame_t { uint32_t data; } by_tf_parse_frame_t; -typedef void (*by_tf_parse_success_handle_func)(void); +typedef void (*by_tf_parse_done_handle_func)(uint8_t); extern void by_tiny_frame_parse_init(void); extern void by_tiny_frame_parse_uart_handle(uint8_t buff); extern void by_tiny_frame_parse_run(void); extern uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s); -extern void by_tiny_frame_parse_handle_register(by_tf_parse_success_handle_func func); +extern void by_tiny_frame_parse_handle_register(by_tf_parse_done_handle_func func); extern void by_tiny_frame_parse_start_listern(void); extern void by_tiny_frame_parse_end_listern(void); From 1c5c78976fcad094bd51bc9cd945e36e0270fa33 Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Fri, 23 Feb 2024 21:13:31 +0800 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=E4=B8=BA=E9=80=9A=E4=BF=A1?= =?UTF-8?q?=E5=B8=A7=E8=A7=A3=E6=9E=90=E5=AE=8C=E6=88=90=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=B7=BB=E5=8A=A0=E5=B8=A7=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=85=A5=E5=8F=82(=E4=BB=A5=E4=BE=BF=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=A0=A1=E9=AA=8C=E6=88=90=E5=8A=9F=E4=B8=8E?= =?UTF-8?q?=E5=90=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.c | 4 +++- app/tiny_frame/by_tiny_frame_parse.c | 25 ++++++++++++++++++++----- app/tiny_frame/by_tiny_frame_parse.h | 2 +- app/tiny_frame/by_tiny_frame_write.h | 10 ++++++++++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/app/main.c b/app/main.c index 028d67c..93718f8 100644 --- a/app/main.c +++ b/app/main.c @@ -35,8 +35,10 @@ #include "by_tiny_frame_pack.h" /** 测试完成后移除 **/ -void test(uint8_t status) +void test(by_tf_parse_frame_t frame_s, uint8_t status) { + printf("parse done\r\n"); + printf("--cmd: %0.2X\n--reg_addr: %0.4X\n--data: %0.8X\r\n", frame_s.cmd, frame_s.reg_addr, frame_s.data); if (status) { printf("noooooooo!\r\n"); } else { diff --git a/app/tiny_frame/by_tiny_frame_parse.c b/app/tiny_frame/by_tiny_frame_parse.c index 0432c14..bc0ce92 100644 --- a/app/tiny_frame/by_tiny_frame_parse.c +++ b/app/tiny_frame/by_tiny_frame_parse.c @@ -6,6 +6,7 @@ lwrb_t lwrb_struct; uint8_t buffer_rb[BY_TF_PARSE_BUFFER_SIZE]; uint8_t buffer_out; +uint8_t listern_slave_id; uint8_t listern_flag; uint16_t listern_timeout; uint16_t listern_timevia; @@ -95,6 +96,10 @@ void by_tiny_frame_parse_timer_handle(void) #endif } +/** + * @brief + * + */ void by_tiny_frame_parse_run(void) { @@ -104,7 +109,7 @@ void by_tiny_frame_parse_run(void) } else { if (listern_timeout <= listern_timevia) { // 接收超时,停止监听 - parse_done_handle(1); + parse_done_handle(frame_now, 1); by_tiny_frame_parse_end_listern(); #if (BY_TF_DEBUG) printf("by_tf_listern timeout\r\n"); @@ -119,15 +124,20 @@ void by_tiny_frame_parse_run(void) break; } - // TODO 目前接收校验错误也会等待直至超时 - // TODO 待结合 read&wirte 部分修改监听的从机地址 - if (!by_tiny_frame_parse_listening(&frame_now, 0x0D, buffer_out)) { +// TODO 目前接收校验错误也会等待直至超时 +// TODO 待结合 read&wirte 部分修改监听的从机地址 +#if defined(BY_TF_DEVICE_SLAVE) + if (!by_tiny_frame_parse_listening(&frame_now, BY_TF_DEVICE_SLAVE_ADDRESS, buffer_out)) +#else + if (!by_tiny_frame_parse_listening(&frame_now, listern_slave_id, buffer_out)) +#endif + { if (!by_tiny_frame_parse_crc(&frame_now)) { // 接收成功后停止监听 by_tiny_frame_parse_end_listern(); // 解析成功回调 - parse_done_handle(0); + parse_done_handle(frame_now, 0); #if (BY_TF_DEBUG) printf("frame parsed!\r\n"); #endif @@ -158,11 +168,16 @@ uint8_t by_tiny_frame_parse_crc(by_tf_parse_frame_t *frame_s) return 0; } + // 校验错误则直接结束监听 + by_tiny_frame_parse_end_listern(); + parse_done_handle(frame_now, 1); + return 1; } void by_tiny_frame_parse_handle_register(by_tf_parse_done_handle_func func) { + // FIXME 未校验是否传入非空值,另外假设未执行注册,也会产生非法访问 parse_done_handle = func; } diff --git a/app/tiny_frame/by_tiny_frame_parse.h b/app/tiny_frame/by_tiny_frame_parse.h index 2d7a7ac..800d80c 100644 --- a/app/tiny_frame/by_tiny_frame_parse.h +++ b/app/tiny_frame/by_tiny_frame_parse.h @@ -18,7 +18,7 @@ typedef struct by_tf_parse_frame_t { uint32_t data; } by_tf_parse_frame_t; -typedef void (*by_tf_parse_done_handle_func)(uint8_t); +typedef void (*by_tf_parse_done_handle_func)(by_tf_parse_frame_t, uint8_t); extern void by_tiny_frame_parse_init(void); extern void by_tiny_frame_parse_uart_handle(uint8_t buff); diff --git a/app/tiny_frame/by_tiny_frame_write.h b/app/tiny_frame/by_tiny_frame_write.h index 20093c5..5a84cae 100644 --- a/app/tiny_frame/by_tiny_frame_write.h +++ b/app/tiny_frame/by_tiny_frame_write.h @@ -1,6 +1,16 @@ #ifndef _BY_TINY_FRAME_WRITE_H__ #define _BY_TINY_FRAME_WRITE_H__ +#include "by_tiny_frame_config.h" +#include "by_tiny_frame_parse.h" +#include "by_tiny_frame_pack.h" + #define BY_TINY_FRAME_WRITE_CMD_CODE (0x06) +#if defined(BY_TF_DEVICE_MASTER) +extern void by_tiny_frame_write(uint8_t slave_id, uint16_t reg_addr, uint32_t data); +#elif + +#endif + #endif From 3a4c25dc4d49f5f1771308e46c32903640dac73e Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Fri, 23 Feb 2024 21:25:55 +0800 Subject: [PATCH 7/8] =?UTF-8?q?refact:=20=E5=B0=86=E8=AF=BB=E5=86=99?= =?UTF-8?q?=E7=9A=84=E5=BA=94=E7=94=A8=E5=B1=82=E6=8E=A5=E5=8F=A3=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E4=B8=BB=E4=BB=8E=E5=88=86=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tiny_frame_read.c => by_tiny_frame_master_read.c} | 0 app/tiny_frame/by_tiny_frame_master_read.h | 11 +++++++++++ ...ny_frame_write.c => by_tiny_frame_master_write.c} | 0 ...ny_frame_write.h => by_tiny_frame_master_write.h} | 12 +++++++----- app/tiny_frame/by_tiny_frame_read.h | 6 ------ app/tiny_frame/by_tiny_frame_slave_read_write.c | 2 ++ app/tiny_frame/by_tiny_frame_slave_read_write.h | 12 ++++++++++++ 7 files changed, 32 insertions(+), 11 deletions(-) rename app/tiny_frame/{by_tiny_frame_read.c => by_tiny_frame_master_read.c} (100%) create mode 100644 app/tiny_frame/by_tiny_frame_master_read.h rename app/tiny_frame/{by_tiny_frame_write.c => by_tiny_frame_master_write.c} (100%) rename app/tiny_frame/{by_tiny_frame_write.h => by_tiny_frame_master_write.h} (77%) delete mode 100644 app/tiny_frame/by_tiny_frame_read.h create mode 100644 app/tiny_frame/by_tiny_frame_slave_read_write.c create mode 100644 app/tiny_frame/by_tiny_frame_slave_read_write.h diff --git a/app/tiny_frame/by_tiny_frame_read.c b/app/tiny_frame/by_tiny_frame_master_read.c similarity index 100% rename from app/tiny_frame/by_tiny_frame_read.c rename to app/tiny_frame/by_tiny_frame_master_read.c diff --git a/app/tiny_frame/by_tiny_frame_master_read.h b/app/tiny_frame/by_tiny_frame_master_read.h new file mode 100644 index 0000000..b0453bc --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_master_read.h @@ -0,0 +1,11 @@ +#ifndef _BY_TINY_FRAME_MASTER_READ_H__ +#define _BY_TINY_FRAME_MASTER_READ_H__ + +#include "by_tiny_frame_config.h" + +#if defined(BY_TF_DEVICE_MASTER) + +#define BY_TINY_FRAME_WRITE_CMD_CODE (0x03) + +#endif +#endif diff --git a/app/tiny_frame/by_tiny_frame_write.c b/app/tiny_frame/by_tiny_frame_master_write.c similarity index 100% rename from app/tiny_frame/by_tiny_frame_write.c rename to app/tiny_frame/by_tiny_frame_master_write.c diff --git a/app/tiny_frame/by_tiny_frame_write.h b/app/tiny_frame/by_tiny_frame_master_write.h similarity index 77% rename from app/tiny_frame/by_tiny_frame_write.h rename to app/tiny_frame/by_tiny_frame_master_write.h index 5a84cae..fd1499a 100644 --- a/app/tiny_frame/by_tiny_frame_write.h +++ b/app/tiny_frame/by_tiny_frame_master_write.h @@ -1,16 +1,18 @@ -#ifndef _BY_TINY_FRAME_WRITE_H__ -#define _BY_TINY_FRAME_WRITE_H__ +#ifndef _BY_TINY_FRAME_MASTER_WRITE_H__ +#define _BY_TINY_FRAME_MASTER_WRITE_H__ #include "by_tiny_frame_config.h" + +#if defined(BY_TF_DEVICE_MASTER) + #include "by_tiny_frame_parse.h" #include "by_tiny_frame_pack.h" #define BY_TINY_FRAME_WRITE_CMD_CODE (0x06) -#if defined(BY_TF_DEVICE_MASTER) + extern void by_tiny_frame_write(uint8_t slave_id, uint16_t reg_addr, uint32_t data); -#elif + #endif - #endif diff --git a/app/tiny_frame/by_tiny_frame_read.h b/app/tiny_frame/by_tiny_frame_read.h deleted file mode 100644 index ca4081f..0000000 --- a/app/tiny_frame/by_tiny_frame_read.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _BY_TINY_FRAME_READ_H__ -#define _BY_TINY_FRAME_READ_H__ - -#define BY_TINY_FRAME_WRITE_CMD_CODE (0x03) - -#endif diff --git a/app/tiny_frame/by_tiny_frame_slave_read_write.c b/app/tiny_frame/by_tiny_frame_slave_read_write.c new file mode 100644 index 0000000..f906eb5 --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_slave_read_write.c @@ -0,0 +1,2 @@ +#include "by_tiny_frame_slave_read_write.h" + diff --git a/app/tiny_frame/by_tiny_frame_slave_read_write.h b/app/tiny_frame/by_tiny_frame_slave_read_write.h new file mode 100644 index 0000000..35f790e --- /dev/null +++ b/app/tiny_frame/by_tiny_frame_slave_read_write.h @@ -0,0 +1,12 @@ +#ifndef _BY_TINY_FRAME_SLAVE_READ_WRITE_H__ +#define _BY_TINY_FRAME_SLAVE_READ_WRITE_H__ + +#include "by_tiny_frame_config.h" + +#if defined(BY_TF_DEVICE_SLAVE) + +#define BY_TINY_FRAME_WRITE_CMD_CODE (0x03) +#define BY_TINY_FRAME_WRITE_CMD_CODE (0x06) + +#endif +#endif From 399ebeea1a3c67658c514dc5cf5163553113855a Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Fri, 23 Feb 2024 22:25:47 +0800 Subject: [PATCH 8/8] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E5=B8=A7=E4=BB=8E=E6=9C=BA=E5=BA=94=E7=94=A8=E5=B1=82?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.c | 4 +- app/tiny_frame/by_tiny_frame.c | 24 ++++++++++- app/tiny_frame/by_tiny_frame.h | 1 + app/tiny_frame/by_tiny_frame_config.h | 2 +- app/tiny_frame/by_tiny_frame_master_read.c | 5 +++ app/tiny_frame/by_tiny_frame_master_read.h | 4 +- app/tiny_frame/by_tiny_frame_master_write.c | 5 ++- app/tiny_frame/by_tiny_frame_master_write.h | 3 +- .../by_tiny_frame_slave_read_write.c | 42 +++++++++++++++++++ .../by_tiny_frame_slave_read_write.h | 7 +++- 10 files changed, 87 insertions(+), 10 deletions(-) diff --git a/app/main.c b/app/main.c index 93718f8..b1a9fb4 100644 --- a/app/main.c +++ b/app/main.c @@ -71,7 +71,7 @@ int main(void) printf("start running\r\n"); /** 测试完成后移除 **/ - by_tiny_frame_parse_handle_register(test); + // by_tiny_frame_parse_handle_register(test); by_tiny_frame_parse_start_listern(); by_tf_pack_frame_t frame_now; @@ -87,7 +87,7 @@ int main(void) by_buzzer_run(); /** 测试完成后移除 **/ - by_tiny_frame_parse_run(); + by_tiny_frame_run(); // by_tiny_frame_pack_send(&frame_now); system_delay_ms(10); by_tiny_frame_parse_timer_handle(); diff --git a/app/tiny_frame/by_tiny_frame.c b/app/tiny_frame/by_tiny_frame.c index f59e6c1..86acd75 100644 --- a/app/tiny_frame/by_tiny_frame.c +++ b/app/tiny_frame/by_tiny_frame.c @@ -3,15 +3,35 @@ #include #include -#include "by_tiny_frame_parse.h" #include "crc16.h" #include "zf_common_headfile.h" +#include "by_tiny_frame_config.h" +#include "by_tiny_frame_parse.h" +#include "by_tiny_frame_master_read.h" +#include "by_tiny_frame_master_write.h" +#include "by_tiny_frame_slave_read_write.h" void by_tiny_frame_init(void) { /*** 初始化相关外设 ***/ uart_init(BY_TF_UART_INDEX, BY_TF_UART_BAUDRATE, BY_TF_UART_TX_PIN, BY_TF_UART_RX_PIN); uart_rx_interrupt(BY_TF_UART_INDEX, ENABLE); - + by_tiny_frame_parse_init(); + +#if defined(BY_TF_DEVICE_SLAVE) + by_tiny_frame_parse_handle_register(by_tiny_frame_read_write_handle); +#endif } + +void by_tiny_frame_run(void) +{ + by_tiny_frame_parse_run(); + +#if defined(BY_TF_DEVICE_MASTER) + by_tiny_frame_read_run(); + by_tiny_frame_write_run(); +#elif defined(BY_TF_DEVICE_SLAVE) + by_tiny_frame_read_write_run(); +#endif +} \ No newline at end of file diff --git a/app/tiny_frame/by_tiny_frame.h b/app/tiny_frame/by_tiny_frame.h index 630f0cf..2bd0e82 100644 --- a/app/tiny_frame/by_tiny_frame.h +++ b/app/tiny_frame/by_tiny_frame.h @@ -4,5 +4,6 @@ #include "by_tiny_frame_config.h" extern void by_tiny_frame_init(void); +void by_tiny_frame_run(void); #endif diff --git a/app/tiny_frame/by_tiny_frame_config.h b/app/tiny_frame/by_tiny_frame_config.h index a302e29..ebc3549 100644 --- a/app/tiny_frame/by_tiny_frame_config.h +++ b/app/tiny_frame/by_tiny_frame_config.h @@ -11,7 +11,7 @@ #define BY_TF_PARSE_BUFFER_SIZE (50) // 注释此项则为主机,否则为从机 -// #define BY_TF_DEVICE_SLAVE +#define BY_TF_DEVICE_SLAVE /********** 从机模式配置选项 **********/ #if defined(BY_TF_DEVICE_SLAVE) diff --git a/app/tiny_frame/by_tiny_frame_master_read.c b/app/tiny_frame/by_tiny_frame_master_read.c index e69de29..443a8c2 100644 --- a/app/tiny_frame/by_tiny_frame_master_read.c +++ b/app/tiny_frame/by_tiny_frame_master_read.c @@ -0,0 +1,5 @@ +#include "by_tiny_frame_master_read.h" + +void by_tiny_frame_read_run(void) +{ +} \ No newline at end of file diff --git a/app/tiny_frame/by_tiny_frame_master_read.h b/app/tiny_frame/by_tiny_frame_master_read.h index b0453bc..d1b2d71 100644 --- a/app/tiny_frame/by_tiny_frame_master_read.h +++ b/app/tiny_frame/by_tiny_frame_master_read.h @@ -5,7 +5,9 @@ #if defined(BY_TF_DEVICE_MASTER) -#define BY_TINY_FRAME_WRITE_CMD_CODE (0x03) +#define BY_TINY_FRAME_READ_CMD_CODE (0x03) + +extern void by_tiny_frame_read_run(void); #endif #endif diff --git a/app/tiny_frame/by_tiny_frame_master_write.c b/app/tiny_frame/by_tiny_frame_master_write.c index acca88c..9fc7047 100644 --- a/app/tiny_frame/by_tiny_frame_master_write.c +++ b/app/tiny_frame/by_tiny_frame_master_write.c @@ -1,2 +1,5 @@ -#include "by_tiny_frame_write.h" +#include "by_tiny_frame_master_write.h" +void by_tiny_frame_write_run(void) +{ +} \ No newline at end of file diff --git a/app/tiny_frame/by_tiny_frame_master_write.h b/app/tiny_frame/by_tiny_frame_master_write.h index fd1499a..9e4a237 100644 --- a/app/tiny_frame/by_tiny_frame_master_write.h +++ b/app/tiny_frame/by_tiny_frame_master_write.h @@ -10,9 +10,8 @@ #define BY_TINY_FRAME_WRITE_CMD_CODE (0x06) - extern void by_tiny_frame_write(uint8_t slave_id, uint16_t reg_addr, uint32_t data); - +extern void by_tiny_frame_write_run(void); #endif #endif diff --git a/app/tiny_frame/by_tiny_frame_slave_read_write.c b/app/tiny_frame/by_tiny_frame_slave_read_write.c index f906eb5..9883ce6 100644 --- a/app/tiny_frame/by_tiny_frame_slave_read_write.c +++ b/app/tiny_frame/by_tiny_frame_slave_read_write.c @@ -1,2 +1,44 @@ #include "by_tiny_frame_slave_read_write.h" +#include "by_tiny_frame_parse.h" +#include "by_tiny_frame_pack.h" + +void by_tiny_frame_read_write_run(void) +{ + // empty +} + +void by_tiny_frame_read_write_handle(by_tf_parse_frame_t frame_s, uint8_t status) +{ + by_tf_pack_frame_t frame_pack_s; + + frame_pack_s.slave_id = BY_TF_DEVICE_SLAVE_ADDRESS; + frame_pack_s.cmd = frame_s.cmd; + frame_pack_s.reg_addr = frame_s.reg_addr; + + if (status) { + // 接收出错,一般为 CRC 校验错误 + return; + } + + switch (frame_s.cmd) { + case 0x03: + // 添加查询接口,操作完成后应答 + frame_pack_s.data = 0XFFFFFFFF; // 示例 + by_tiny_frame_pack_send(&frame_pack_s); + break; + case 0x06: + // 添加写入接口,操作完成后应答 + frame_pack_s.data = frame_s.data; + by_tiny_frame_pack_send(&frame_pack_s); + break; + default: + break; + } + +#if (BY_TF_DEBUG) + printf("****** EXECUTE CMD SUCCESSFUL ******\r\n"); + printf("Device ID: 0x%0.2X\r\n", BY_TF_DEVICE_SLAVE_ADDRESS); + printf("--cmd: %0.2X\n--reg_addr: %0.4X\n--data: %0.8X\r\n", frame_s.cmd, frame_s.reg_addr, frame_s.data); +#endif +} diff --git a/app/tiny_frame/by_tiny_frame_slave_read_write.h b/app/tiny_frame/by_tiny_frame_slave_read_write.h index 35f790e..b71901c 100644 --- a/app/tiny_frame/by_tiny_frame_slave_read_write.h +++ b/app/tiny_frame/by_tiny_frame_slave_read_write.h @@ -5,8 +5,13 @@ #if defined(BY_TF_DEVICE_SLAVE) -#define BY_TINY_FRAME_WRITE_CMD_CODE (0x03) +#include "by_tiny_frame_parse.h" + +#define BY_TINY_FRAME_READ_CMD_CODE (0x03) #define BY_TINY_FRAME_WRITE_CMD_CODE (0x06) +extern void by_tiny_frame_read_write_run(void); +extern void by_tiny_frame_read_write_handle(by_tf_parse_frame_t frame_s, uint8_t status); + #endif #endif