From 04fa269bfb2989afd6b9f01ff8a5b43e22474129 Mon Sep 17 00:00:00 2001 From: tianjialong Date: Wed, 15 Feb 2023 17:43:20 +0800 Subject: [PATCH] update --- app/MDK-ARM/app.uvguix.29643 | 54 ++++- app/MDK-ARM/app.uvoptx | 48 ++++- app/MDK-ARM/app.uvprojx | 19 +- src/encoder_acquistion.c | 75 +++++++ src/encoder_acquistion.h | 20 ++ src/encoder_acquistion_service.c | 434 +++++++++++++++++++++++++++++++++++++++ src/encoder_acquistion_service.h | 14 ++ src/port.c | 84 -------- src/port.h | 35 ---- src/protocol.h | 2 +- src/usermain.c | 10 +- src/zassert.h | 6 + src/zport.c | 84 ++++++++ src/zport.h | 35 ++++ src/zthread.c | 96 +++++++++ src/zthread.h | 46 +++++ 16 files changed, 924 insertions(+), 138 deletions(-) create mode 100644 src/encoder_acquistion.c create mode 100644 src/encoder_acquistion.h create mode 100644 src/encoder_acquistion_service.c create mode 100644 src/encoder_acquistion_service.h delete mode 100644 src/port.c delete mode 100644 src/port.h create mode 100644 src/zassert.h create mode 100644 src/zport.c create mode 100644 src/zport.h create mode 100644 src/zthread.c create mode 100644 src/zthread.h diff --git a/app/MDK-ARM/app.uvguix.29643 b/app/MDK-ARM/app.uvguix.29643 index d66ee78..21c153c 100644 --- a/app/MDK-ARM/app.uvguix.29643 +++ b/app/MDK-ARM/app.uvguix.29643 @@ -110,8 +110,8 @@ 0 - 1164 - 0100000004000000010000000100000001000000010000000000000002000000000000000100000001000000000000002800000028000000010000000800000007000000010000004E433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C757365726D61696E2E63000000000A757365726D61696E2E6300000000C5D4F200FFFFFFFF53433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C6170705C436F72655C5372635C6D61696E2E6300000000066D61696E2E6300000000FFDC7800FFFFFFFF6C433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C73646B5C73746D33325C73746D333273646B2E68000000000A73746D333273646B2E6800000000F0A0A100FFFFFFFF67433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C73646B5C73746D33325C70776D2E68000000000570776D2E6800000000BCA8E100FFFFFFFF76433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C7A6D6F646275735C7374645C6D6F646275735F70726F6365737365722E6800000000126D6F646275735F70726F6365737365722E6800000000F7B88600FFFFFFFF70433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C66616E636F6E74726F6C65725C73746D33325C66616E2E68000000000566616E2E6800000000D9ADC200FFFFFFFF4C433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C636F6E6669672E630000000008636F6E6669672E6300000000A5C2D700FFFFFFFF67433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C73646B5C73746D33325C70776D2E63000000000570776D2E6300000000D9ADC200FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD5000100000000000000020000007408000066000000000F000075020000 + 1618 + 0100000004000000010000000100000001000000010000000000000002000000000000000100000001000000000000002800000028000000010000000C00000008000000010000004E433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C757365726D61696E2E63000000000A757365726D61696E2E6300000000C5D4F200FFFFFFFF53433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C6170705C436F72655C5372635C6D61696E2E6300000000066D61696E2E6300000000FFDC7800FFFFFFFF6C433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C73646B5C73746D33325C73746D333273646B2E68000000000A73746D333273646B2E6800000000F0A0A100FFFFFFFF67433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C73646B5C73746D33325C70776D2E68000000000570776D2E6800000000BCA8E100FFFFFFFF76433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C7A6D6F646275735C7374645C6D6F646275735F70726F6365737365722E6800000000126D6F646275735F70726F6365737365722E6800000000F7B88600FFFFFFFF70433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C69666C79746F705F6D6963726F636F6E74726F6C6C65725C66616E636F6E74726F6C65725C73746D33325C66616E2E68000000000566616E2E6800000000D9ADC200FFFFFFFF4C433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C636F6E6669672E630000000008636F6E6669672E6300000000A5C2D700FFFFFFFF4D433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C7A7468726561642E6800000000097A7468726561642E6800000000D9ADC200FFFFFFFF4D433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C7A7468726561642E6300000000097A7468726561642E6300000000A5C2D700FFFFFFFF58433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C656E636F6465725F61637175697374696F6E2E630000000014656E636F6465725F61637175697374696F6E2E6300000000B3A6BE00FFFFFFFF4D433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C7A6173736572742E6800000000097A6173736572742E6800000000EAD6A300FFFFFFFF60433A5C55736572735C32393634335C4465736B746F705C465A4D6F74696F6E5F636170747572655F73797374656D5F6163636573736F726965735F7061636B5C7372635C656E636F6465725F61637175697374696F6E5F736572766963652E63000000001C656E636F6465725F61637175697374696F6E5F736572766963652E6300000000F6FA7D00FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD5000100000000000000020000007408000066000000000F000075020000 @@ -1862,11 +1862,11 @@ 0 100 - 7 + 8 ..\..\src\usermain.c 3 - 1 + 8 26 1 @@ -1883,9 +1883,9 @@ ../Core/Inc/../../../iflytop_microcontroller/sdk/stm32/stm32sdk.h - 0 + 32 15 - 42 + 32 1 0 @@ -1927,10 +1927,46 @@ 0 - ..\..\iflytop_microcontroller\sdk\stm32\pwm.c + ..\..\src\zthread.h + 20 + 1 + 6 + 1 + + 0 + + + ..\..\src\zthread.c + 8 + 1 + 19 + 1 + + 0 + + + ..\..\src\encoder_acquistion.c + 38 + 38 + 65 + 1 + + 0 + + + ..\..\src\zassert.h 0 - 8 - 89 + 1 + 3 + 1 + + 0 + + + ..\..\src\encoder_acquistion_service.c + 43 + 240 + 253 1 0 diff --git a/app/MDK-ARM/app.uvoptx b/app/MDK-ARM/app.uvoptx index 7746efc..92ac21f 100644 --- a/app/MDK-ARM/app.uvoptx +++ b/app/MDK-ARM/app.uvoptx @@ -1766,8 +1766,44 @@ 0 0 0 - ..\..\src\port.c - port.c + ..\..\src\encoder_acquistion.c + encoder_acquistion.c + 0 + 0 + + + 10 + 127 + 1 + 0 + 0 + 0 + ..\..\src\encoder_acquistion_service.c + encoder_acquistion_service.c + 0 + 0 + + + 10 + 128 + 1 + 0 + 0 + 0 + ..\..\src\zthread.c + zthread.c + 0 + 0 + + + 10 + 129 + 1 + 0 + 0 + 0 + ..\..\src\zport.c + zport.c 0 0 @@ -1781,7 +1817,7 @@ 0 11 - 127 + 130 1 0 0 @@ -1793,7 +1829,7 @@ 11 - 128 + 131 1 0 0 @@ -1805,7 +1841,7 @@ 11 - 129 + 132 1 0 0 @@ -1817,7 +1853,7 @@ 11 - 130 + 133 1 0 0 diff --git a/app/MDK-ARM/app.uvprojx b/app/MDK-ARM/app.uvprojx index dea26cb..9bce264 100644 --- a/app/MDK-ARM/app.uvprojx +++ b/app/MDK-ARM/app.uvprojx @@ -1105,9 +1105,24 @@ ..\..\src\protocol.c - port.c + encoder_acquistion.c + 1 + ..\..\src\encoder_acquistion.c + + + encoder_acquistion_service.c + 1 + ..\..\src\encoder_acquistion_service.c + + + zthread.c + 1 + ..\..\src\zthread.c + + + zport.c 1 - ..\..\src\port.c + ..\..\src\zport.c diff --git a/src/encoder_acquistion.c b/src/encoder_acquistion.c new file mode 100644 index 0000000..2d172be --- /dev/null +++ b/src/encoder_acquistion.c @@ -0,0 +1,75 @@ +#include "encoder_acquistion.h" + +#include "config.h" +#include "stdlib.h" +#include "zassert.h" +#include "zboard.h" +#include "zthread.h" + +#define REPORT_BUF_SIZE 1000 + +#define TAG "aencoder_acquistion_driver" +static zthread_t s_workingthread; +uint8_t *s_reportbuf; +uint32_t s_reportbufsize; +encoder_acquisition_cb_t s_cb; + +/** + * @brief 在这里上报语音 + * + * @param arg + * + * PS: + * 函数效率在240MHZ的情况下,1s的语音数据(32bit,16k)大概需要2ms的处理时间 + */ + +static void prv_workingthread(void *arg) { + while (!zthread_is_expect_stop(&s_workingthread)) { + size_t bytes_read; + // ESP_LOGI(TAG, "read %d ", bytes_read); + if (s_cb) { +#if 0 + //测试放大方法效率 + uint32_t sticket = xTaskGetTickCount(); + for(unsigned i = 0; i < 16*4; ++i) { + amf_voice(s_reportbuf, bytes_read); + } + uint32_t endticket = xTaskGetTickCount(); + ESP_LOGI(TAG, " %d use %d", bytes_read,endticket - sticket); +#else + // amf_voice(s_reportbuf, bytes_read); +#endif + + // 因为MIC最大响度能够达到的幅值为0.316v,和3.3v差了3.3/0.316倍, + // 又因为PCM1808位宽为24bit,32位中低八位为零,已经默认放大 + // 则可以保证数据放大3.3/0.316后数据是无损的. + for (size_t i = 0; i < bytes_read; i += 4) { + int32_t *rxdata = (int32_t *)&s_reportbuf[i]; + (*rxdata) = (*rxdata) * 3.3 / 0.316; + } + + // 对音频按照配置进行放大 + for (size_t i = 0; i < bytes_read; i += 4) { + int32_t *rxdata = (int32_t *)&s_reportbuf[i]; + } + + s_cb(s_reportbuf, bytes_read); + } + } +} +void encoder_acquisition_init(encoder_acquisition_cb_t cb) { + // s_workingthread + + // s_workingthread + + s_reportbuf = malloc(REPORT_BUF_SIZE); + s_reportbufsize = REPORT_BUF_SIZE; + s_cb = cb; + Z_ASSERT(s_reportbuf); + Z_ASSERT(s_reportbufsize); + Z_ASSERT(s_cb); + + zthread_init(&s_workingthread, "encoder_acquistion_driver", prv_workingthread); +} +void encoder_acquisition_start_cauture() { zthread_start(&s_workingthread); } +void encoder_acquisition_stop_cauture() { zthread_stop(&s_workingthread); } diff --git a/src/encoder_acquistion.h b/src/encoder_acquistion.h new file mode 100644 index 0000000..3f7ca86 --- /dev/null +++ b/src/encoder_acquistion.h @@ -0,0 +1,20 @@ +#pragma once +#include + +//采集端配置 +#define CONFIG_MODE (I2S_MODE_SLAVE | I2S_MODE_RX) //模式 +#define CONFIG_SAMPLE_RATE 48000 //采样率 +#define CONFIG_BITS_PER_SAMPLE I2S_BITS_PER_SAMPLE_24BIT //采样位数 +#define CONFIG_CHANNEL_FORMAT I2S_CHANNEL_FMT_RIGHT_LEFT // I2S格式 +#define CONFIG_COMMUNICATION_FORMAT (I2S_COMM_FORMAT_STAND_MSB) // I2S标准 +#define CONFIG_INTR_ALLOC_FLAGS ESP_INTR_FLAG_LEVEL1 // +//上报端格式配置 +#define CONFIG_REPORT_BITS_PER_SAMPLE I2S_BITS_PER_SAMPLE_16BIT //上报数据 采样位数 +#define CONFIG_REPORT_SAMPLE_RATE CONFIG_SAMPLE_RATE //上报数据 采样率 +#define CONFIG_REPORT_BUF_SIZE 600 //每次上报的字节数(注意需要和采样位数存在倍数关系) + +typedef void (*encoder_acquisition_cb_t)(uint8_t *data, uint32_t size); + +void encoder_acquisition_init(encoder_acquisition_cb_t cb); +void encoder_acquisition_start_cauture(); +void encoder_acquisition_stop_cauture(); \ No newline at end of file diff --git a/src/encoder_acquistion_service.c b/src/encoder_acquistion_service.c new file mode 100644 index 0000000..db9d11c --- /dev/null +++ b/src/encoder_acquistion_service.c @@ -0,0 +1,434 @@ +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include + +#include "zboard.h" +#include "config.h" +#include "FreeRTOS.h" +#include "event_groups.h" +#include "task.h" +#include "protocol.h" +#include "encoder_acquistion.h" +//#include "sys/time.h" +#include "zassert.h" +#include "zthread.h" + +#define TAG "encoder_acquistion_service" + +__attribute__((weak)) void hook_before_restart_device(); + +int sock = -1; + +static zthread_t s_workingthread; +static struct sockaddr_storage now_source_addr; +static struct sockaddr_storage + s_request_encoder_acquist_udp_add; // 请求语音传输的端口 + +static bool s_report_voice_flag = false; +static protocol_header_t s_report_receipt_buf; +static uint32_t s_voice_index = 0; + +static void do_restart_device() { + ZLOGE(TAG, "we doon't kown why it happen,so restart device"); + ZLOGE(TAG, "restart device"); + + hook_before_restart_device(); +// esp_restart(); +} + +bool protocol_check_packet(char *data, uint32_t size) { + + protocol_header_t *rxcmd = (protocol_header_t *)data; + if (rxcmd->packet_type != PROTOCOL_HEADER || + rxcmd->minus_packet_type != PROTOCOL_HEADER_MINUS) { + ZLOGE(TAG, "rx error packet,header is ilegal header a = 0x%02x 0x%02x", + rxcmd->packet_type, rxcmd->minus_packet_type); + return false; + } + + uint8_t sum8 = 0; + + for (unsigned i = 0; i < size - 1; ++i) { + sum8 += data[i]; + } + + if (sum8 != data[size - 1]) { + ZLOGE(TAG, "rx error packet,sumcheck fail,real:0x%02x != expect:0x%02x", + data[size - 1], sum8); + return false; + } + + return true; +} + +uint8_t computesum8(char *data, size_t size) { + uint8_t sum8 = 0; + for (unsigned i = 0; i < size; ++i) { + sum8 += data[i]; + // ZLOGI(TAG, "%d", sum8); + } + return sum8; +} + +static void report_packet(uint8_t *data, uint32_t size) { + int err = sendto(sock, data, size, 0, (struct sockaddr *)&now_source_addr, + sizeof(now_source_addr)); + if (err < 0) { + ZLOGE(TAG, "report_packet fail: errno %d", errno); + return; + } +} +static void report_voice(uint8_t *data, uint32_t size) { + int err = sendto(sock, data, size, 0, + (struct sockaddr *)&s_request_encoder_acquist_udp_add, + sizeof(s_request_encoder_acquist_udp_add)); + if (err < 0) { + ZLOGE(TAG, "report_voice fail: errno %d", errno); + return; + } +} + +/** + * @brief 语音上报控制寄存器 + * + * @param data + * @param size + */ + +int create_receipt(char *data, size_t size, uint32_t regvalue, + uint32_t errocode) { + protocol_header_t *rxcmd = (protocol_header_t *)data; + s_report_receipt_buf.packet_type = rxcmd->packet_type; + s_report_receipt_buf.minus_packet_type = rxcmd->minus_packet_type; + s_report_receipt_buf.index = rxcmd->index; + s_report_receipt_buf.action_type = rxcmd->action_type; + s_report_receipt_buf.reg = rxcmd->reg; + + int receiptlen = 0; + + s_report_receipt_buf.value.receipt.regvalue = regvalue; + s_report_receipt_buf.value.receipt.error = errocode; + + //计算包长 + receiptlen = sizeof(protocol_header_t) - sizeof(rxcmd->value) + 4 + 4 + 1; + + //计算sum8 + ((char *)&s_report_receipt_buf)[receiptlen - 1] = + computesum8((char *)&s_report_receipt_buf, receiptlen - 1); + + return receiptlen; +} + +void create_and_send_receipt(char *data, size_t size, uint32_t regvalue, + uint32_t errocode) { + int len = create_receipt(data, size, regvalue, 0); + ZLOGI(TAG, "create_and_send_receipt-->"); + // ZLOG_BUFFER_HEX(TAG, (uint8_t *)&s_report_receipt_buf, len); + ZLOGI(TAG, "<-"); + + report_packet((uint8_t *)&s_report_receipt_buf, len); +} + +/*************************************************************************************/ +/*************************************指令处理**************************************/ +/*************************************************************************************/ + +void encoder_acquisition_cb(uint8_t *data, uint32_t size) { + // lock socket + + /** + * @brief 在这里上报语音 + */ + + // clang-format off + /* + | packetlen = 1+1+4+2+1+ voicelen = 9 + voicelen + | packet_type(8bit) | minus_packet_type(8bit) | voice_index(32bit) | voice_length(16bit) | voice_payload(0->1024byte) | checksum(8bit) | + | ------------ | ------------------ | ------------------ | ------------------- | -------------------------- | -------------- | + | 0x55 | 0xAA | 0 | 0 | 1 | | + | | | | | | | + */ + // clang-format on + + //测试模式直接上报 + // Z_ASSERT(size <= REPORT_VOICE_SIZE); + + if (!s_report_voice_flag) { + return; + } + + /** + * @brief 按照协议封包上报 + */ + // ZLOGI(TAG, "report voice %d", size); + + static uint8_t * reportvoicebuf = NULL; + + if(reportvoicebuf == NULL){ + reportvoicebuf = malloc(size+100); + } + + reportvoicebuf[0] = 0x55; + reportvoicebuf[1] = 0xAA; + *(uint32_t *)(&reportvoicebuf[2]) = s_voice_index; + *(uint16_t *)(&reportvoicebuf[6]) = (uint16_t)size; + memcpy(&reportvoicebuf[8], data, size); + + reportvoicebuf[9 + size - 1] = + computesum8((char *)reportvoicebuf, 9 + size - 1); + + // for (unsigned i = 0; i < config_get()->encoder_report_times; ++i) { + report_voice(reportvoicebuf, 9 + size); + // } + s_voice_index++; + ZLOGI(TAG,"%d",s_voice_index); + // unlocksocket +} +void process_reg_report_voice(char *data, size_t size) { + protocol_header_t *rxcmd = (protocol_header_t *)data; + if (rxcmd->action_type == PROTOCOL_PACKET_TYPE_WRITE) { + + if (rxcmd->value.regvalue == 1) { + /** + * @brief 开始采集语音 + */ + ZLOGI(TAG, "processs packet:encoder_acquisition_start_cauture"); + s_request_encoder_acquist_udp_add = + now_source_addr; //拷贝当前指令对应的端口号进行上报 + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + s_voice_index = 0; + s_report_voice_flag = true; + + } else if (rxcmd->value.regvalue == 0) { + /** + * @brief 停止采集语音 + */ + ZLOGI(TAG, "processs packet:encoder_acquisition_stop_cauture"); + ZLOGI(TAG, "has report voice packet %u", s_voice_index); + s_voice_index = 0; + s_report_voice_flag = false; + //简单延时,等待本次上报结束 + vTaskDelay(10); + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + } + } +} + +/** + * @brief 语音上报次数设置寄存器 + * + * @param data + * @param size + */ +void process_reg_report_voice_repect_times(char *data, size_t size) { + protocol_header_t *rxcmd = (protocol_header_t *)data; + if (rxcmd->action_type == PROTOCOL_PACKET_TYPE_WRITE) { + // config_get()->encoder_report_times = rxcmd->value.regvalue; + // config_update(); + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + } +} + +/**************************************************************/ +/**************************************************************/ +/**************************************************************/ + +/** + * @brief 处理接收到消息 + * + * @param data + * @param size + */ +static void prv_process_rx(char *data, size_t size) { + ZLOGI(TAG, "process rx data packet [...]%d->", size); + // ZLOG_BUFFER_HEX(TAG, (uint8_t *)data, size); + ZLOGI(TAG, "<-"); + + /** + * @brief 这里处理接收到的消息,并进行回复 + */ + + protocol_header_t *rxcmd = (protocol_header_t *)data; + if (!protocol_check_packet(data, size)) { + return; + } + + ZLOGI(TAG, "processs packet:reg %d", rxcmd->reg); + if (rxcmd->reg == REG_RESTART_DEVICE) { // 0 + // restart device + ZLOGI(TAG, "do restart device order"); +// esp_restart(); + } else if (rxcmd->reg == REG_REPORT_VOICE) { // 1 + process_reg_report_voice(data, size); + } else if (rxcmd->reg == REG_REPORT_VOICE_REPECT_TIMES) { // 2 + process_reg_report_voice_repect_times(data, size); + } else if (rxcmd->reg == REG_OBTAINING_IP_MODE) { // 3 + + /** + * @brief 设置获取IP模式 + */ + if (rxcmd->action_type == PROTOCOL_PACKET_TYPE_WRITE) { + config_get()->obtaining_ip_mode = rxcmd->value.regvalue; + // config_update(); + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + } + + } else if (rxcmd->reg == REG_STATIC_IP) { // 4 + + /** + * @brief 设置静态IP + */ + if (rxcmd->action_type == PROTOCOL_PACKET_TYPE_WRITE) { + config_get()->ip = rxcmd->value.regvalue; + // config_update(); + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + } + } else if (rxcmd->reg == REG_IP_MASK) { // 5 + + /** + * @brief 设置掩码 + */ + if (rxcmd->action_type == PROTOCOL_PACKET_TYPE_WRITE) { + config_get()->netmask = rxcmd->value.regvalue; + // config_update(); + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + } + } else if (rxcmd->reg == REG_ROUTER_IP) { // 6 + + /** + * @brief 设置gateway ip + */ + if (rxcmd->action_type == PROTOCOL_PACKET_TYPE_WRITE) { + config_get()->gw = rxcmd->value.regvalue; + // config_update(); + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + } + + } else if (rxcmd->reg == REG_ENCODER_AMPLIFY_FACTOR) { // 10 + + /** + * @brief 设置音频方法倍数 + */ + if (rxcmd->action_type == PROTOCOL_PACKET_TYPE_WRITE) { + // config_get()->encoder_magnification_factors = rxcmd->value.regvalue; + // config_update(); + create_and_send_receipt(data, size, rxcmd->value.regvalue, 0); + } + } +} + +static void prv_workingthread(void *arg) { + + // static struct sockaddr_in6 dest_addr; + // memset(&dest_addr, 0, sizeof(dest_addr)); + + // struct sockaddr_in *dest_addr_ip4 = (struct sockaddr_in *)&dest_addr; + // dest_addr_ip4->sin_addr.s_addr = htonl(INADDR_ANY); + // dest_addr_ip4->sin_family = AF_INET; + // dest_addr_ip4->sin_port = htons(SERVICE_PORT); + + // /** + // * @brief 创建socket + // * + // */ + // sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + + // if (sock < 0) { + // /** + // * @brief 当socket创建失败的时候可能有很多原因, + // * 但这里没有很好的解决办法,所以打印一个日志直接结束 + // */ + // ZLOGE(TAG, "unable to create socket: errno %d", errno); + // do_restart_device(); + // } + + // /** + // * @brief 绑定端口号 + // * + // */ + // ZLOGI(TAG, "socket created"); + // int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); + // if (err < 0) { + // /** + // * @brief 当绑定失败的时候可能有很多原因, + // * 但这里没有很好的解决办法,所以打印一个日志直接结束 + // */ + // ZLOGE(TAG, "socket unable to bind: errno %d", errno); + // do_restart_device(); + // } + // ZLOGI(TAG, "socket bound, port %d", SERVICE_PORT); + + // //设置recvfrom超时时间 + // struct timeval tv = {1, 0}; + // int32_t b = + // setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); + + // while (!zthread_is_expect_stop(&s_workingthread)) { + // // static 是为了节省栈空间 + // static char rx_buffer[1024]; + // static char clientip[128]; + + // socklen_t socklen = sizeof(now_source_addr); + // int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0 /*flag */, + // (struct sockaddr *)&now_source_addr, &socklen); + + // // Error occurred during receiving + // if (len < 0) { + + // if (errno == EAGAIN || errno == EINTR) { + // //超时,或者被信号量打断 + // continue; + // } + + // ZLOGE(TAG, "recvfrom failed: errno %d", errno); + // continue; + // } + // if (len == 0) { + // continue; + // } + + // // Get the sender's ip address as string + // inet_ntoa_r(((struct sockaddr_in *)&now_source_addr)->sin_addr, clientip, + // sizeof(clientip) - 1); + // ZLOGI(TAG, "Received %d bytes from %s:", len, clientip); + // /** + // * @brief 处理接收到的消息 + // * + // */ + // prv_process_rx(rx_buffer, len); + // } + + // /** + // * @brief 如果停止服务,要同时停止语音采集 + // */ + // s_report_voice_flag = false; + // encoder_acquisition_stop_cauture(); + + // if (sock != -1) { + // ZLOGI(TAG, "Shutting down socket and restarting..."); + // shutdown(sock, 0); + // close(sock); + // } + // sock = -1; +} +void encoder_acquistion_service_init() { + encoder_acquisition_init( + encoder_acquisition_cb); + zthread_init(&s_workingthread, "encoder_acquistion_service", prv_workingthread); +} + +void encoder_acquistion_service_start() { + ZLOGI(TAG, "call encoder_acquistion_service_start"); + encoder_acquisition_start_cauture(); + zthread_start(&s_workingthread); +} +void encoder_acquistion_service_stop() { + ZLOGI(TAG, "call encoder_acquistion_service_stop"); + zthread_stop(&s_workingthread); +} +void encoder_acquistion_enter_test_mode() {} + +bool encoder_acquistion_service_is_working() { + return s_workingthread.threadisworking; +} \ No newline at end of file diff --git a/src/encoder_acquistion_service.h b/src/encoder_acquistion_service.h new file mode 100644 index 0000000..206d45b --- /dev/null +++ b/src/encoder_acquistion_service.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include +#include +/** + * @brief + * 声音采集服务,主要用于接收来自上位机的指令,并对其做出相应的处理 + * + */ + +void encoder_acquistion_service_init(); +void encoder_acquistion_service_start(); +void encoder_acquistion_service_stop(); +bool encoder_acquistion_service_is_working(); \ No newline at end of file diff --git a/src/port.c b/src/port.c deleted file mode 100644 index f1776a5..0000000 --- a/src/port.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "port.h" - -#include -#include - -#include "main.h" -// #include "modbus_processer.h" -#include "tim.h" -#include "usart.h" - -// -#include "../../../iflytop_microcontroller/sdk/stm32/pwm.h" -#include "../../../iflytop_microcontroller/sdk/stm32/stm32sdk.h" - -/********************************************************************************************************************** - * ===================================================printf重定向=================================================== * - **********************************************************************************************************************/ -int fputc(int ch, FILE* stream) { - uint8_t c = ch; - HAL_UART_Transmit(&DEBUG_UART, &c, 1, 100); - return ch; -} -/*********************************************************************************************************************** - * ====================================================调试指示灯===================================================== * - ***********************************************************************************************************************/ -void port_do_debug_light_state(void) { - static uint32_t lastprocess = 0; - if (sys_haspassedms(lastprocess) > 300) { - lastprocess = HAL_GetTick(); - HAL_GPIO_TogglePin(DEBUG_LIGHT_PORT, DEBUG_LIGHT_PIN); - } -} -/*********************************************************************************************************************** - * =====================================================串口相关====================================================== * - ***********************************************************************************************************************/ - -static uart_t m_uarts[] = { - {&DEBUG_UART, 0}, - // {&MODBUS_UART, 0}, -}; -__weak void port_mock_on_uart_rx(uart_t* uart) {} -static void uarts_start_receive(uart_t* uart) { HAL_UART_Receive_IT(uart->uarthandler, &uart->rxbuf, 1); } -void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart) { - for (size_t i = 0; i < sizeof(m_uarts) / sizeof(uart_t); i++) { - if (m_uarts[i].uarthandler == huart) { - port_mock_on_uart_rx(&m_uarts[i]); - uarts_start_receive(&m_uarts[i]); - return; - } - } -} -void HAL_UART_ErrorCallback(UART_HandleTypeDef* huart) { - for (size_t i = 0; i < sizeof(m_uarts) / sizeof(uart_t); i++) { - if (m_uarts[i].uarthandler == huart) { - uarts_start_receive(&m_uarts[i]); - return; - } - } -} -// export -void port_uart_start_all_uart_receive(void) { - for (size_t i = 0; i < sizeof(m_uarts) / sizeof(uart_t); i++) { - uarts_start_receive(&m_uarts[i]); - } -} - -bool port_electric_relay_get_state(int relayindex) { - /* - example: - if (relayindex == 1) { - return GPIO_GET(C, 8, !!); - } - */ - - return false; -} -void port_electric_relay_set_state(int relayindex, bool state) { - /* - example: - if (relayindex == 1) { - GPIO_SET(C, 8, !!, state); - } - */ -} \ No newline at end of file diff --git a/src/port.h b/src/port.h deleted file mode 100644 index 3efb706..0000000 --- a/src/port.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include -#include -#include - -#include "tim.h" -#include "usart.h" -#include "zboard.h" - -#define GPIO_SET(port, pin, mirror, _state) \ - HAL_GPIO_WritePin(GPIO##port, GPIO_PIN_##pin, mirror _state ? GPIO_PIN_SET : GPIO_PIN_RESET); - -#define GPIO_GET(port, pin, mirror) (mirror(HAL_GPIO_ReadPin(GPIO##port, GPIO_PIN_##pin) == GPIO_PIN_SET)) - -/*********************************************************************************************************************** - * ====================================================调试指示灯===================================================== * - ***********************************************************************************************************************/ -void port_do_debug_light_state(void); - -/*********************************************************************************************************************** - * =======================================================UART======================================================== * - ***********************************************************************************************************************/ -typedef struct { - UART_HandleTypeDef* uarthandler; - uint8_t rxbuf; -} uart_t; -void port_mock_on_uart_rx(uart_t* uart); -void port_uart_start_all_uart_receive(void); - -bool port_electric_relay_get_state(int relayindex); -void port_electric_relay_set_state(int relayindex, bool state); - -static inline bool port_get_gpio_int(int index) { - return false; -} diff --git a/src/protocol.h b/src/protocol.h index 9df23ef..94132fc 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -42,7 +42,7 @@ typedef struct { #define REG_STATIC_IP 4 #define REG_IP_MASK 5 #define REG_ROUTER_IP 6 -#define REG_SOUND_AMPLIFY_FACTOR 10 +#define REG_ENCODER_AMPLIFY_FACTOR 10 #define REG_INTER_OTA_BY_HTTP 102 diff --git a/src/usermain.c b/src/usermain.c index 7dd4b0f..73a4ddb 100644 --- a/src/usermain.c +++ b/src/usermain.c @@ -8,9 +8,11 @@ #include "iwdg.h" #include "lwip.h" #include "main.h" -#include "port.h" +#include "zport.h" #include "usart.h" #include "zboard.h" +#include "protocol.h" +#include "encoder_acquistion_service.h" // #include "iflytop_microcontroller/sdk/stm32/stm32sdk.h" @@ -20,6 +22,12 @@ void user_main() { ZLOGI(TAG, "==============ethernet_sound_acquisition_card============="); ZLOGI(TAG, "version %d.%d", VERSION_MAIN_ID, VERSION_SUB_ID); config_init(); + + /** + * @brief 初始化编码器采集UDP服务 + */ + encoder_acquistion_service_init(); + while (1) { port_do_debug_light_state(); HAL_IWDG_Refresh(&hiwdg); diff --git a/src/zassert.h b/src/zassert.h new file mode 100644 index 0000000..4c8137c --- /dev/null +++ b/src/zassert.h @@ -0,0 +1,6 @@ +#pragma once +#include "iflytop_microcontroller/sdk/stm32/stm32sdk.h" +#define Z_ASSERT(condition) \ + if (!(condition)) { \ + ZLOGI(TAG, "do " #condition " fail") \ + } diff --git a/src/zport.c b/src/zport.c new file mode 100644 index 0000000..92f89c0 --- /dev/null +++ b/src/zport.c @@ -0,0 +1,84 @@ +#include "zport.h" + +#include +#include + +#include "main.h" +// #include "modbus_processer.h" +#include "tim.h" +#include "usart.h" + +// +#include "../../../iflytop_microcontroller/sdk/stm32/pwm.h" +#include "../../../iflytop_microcontroller/sdk/stm32/stm32sdk.h" + +/********************************************************************************************************************** + * ===================================================printf重定向=================================================== * + **********************************************************************************************************************/ +int fputc(int ch, FILE* stream) { + uint8_t c = ch; + HAL_UART_Transmit(&DEBUG_UART, &c, 1, 100); + return ch; +} +/*********************************************************************************************************************** + * ====================================================调试指示灯===================================================== * + ***********************************************************************************************************************/ +void port_do_debug_light_state(void) { + static uint32_t lastprocess = 0; + if (sys_haspassedms(lastprocess) > 300) { + lastprocess = HAL_GetTick(); + HAL_GPIO_TogglePin(DEBUG_LIGHT_PORT, DEBUG_LIGHT_PIN); + } +} +/*********************************************************************************************************************** + * =====================================================串口相关====================================================== * + ***********************************************************************************************************************/ + +static uart_t m_uarts[] = { + {&DEBUG_UART, 0}, + // {&MODBUS_UART, 0}, +}; +__weak void port_mock_on_uart_rx(uart_t* uart) {} +static void uarts_start_receive(uart_t* uart) { HAL_UART_Receive_IT(uart->uarthandler, &uart->rxbuf, 1); } +void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart) { + for (size_t i = 0; i < sizeof(m_uarts) / sizeof(uart_t); i++) { + if (m_uarts[i].uarthandler == huart) { + port_mock_on_uart_rx(&m_uarts[i]); + uarts_start_receive(&m_uarts[i]); + return; + } + } +} +void HAL_UART_ErrorCallback(UART_HandleTypeDef* huart) { + for (size_t i = 0; i < sizeof(m_uarts) / sizeof(uart_t); i++) { + if (m_uarts[i].uarthandler == huart) { + uarts_start_receive(&m_uarts[i]); + return; + } + } +} +// export +void port_uart_start_all_uart_receive(void) { + for (size_t i = 0; i < sizeof(m_uarts) / sizeof(uart_t); i++) { + uarts_start_receive(&m_uarts[i]); + } +} + +bool port_electric_relay_get_state(int relayindex) { + /* + example: + if (relayindex == 1) { + return GPIO_GET(C, 8, !!); + } + */ + + return false; +} +void port_electric_relay_set_state(int relayindex, bool state) { + /* + example: + if (relayindex == 1) { + GPIO_SET(C, 8, !!, state); + } + */ +} \ No newline at end of file diff --git a/src/zport.h b/src/zport.h new file mode 100644 index 0000000..3efb706 --- /dev/null +++ b/src/zport.h @@ -0,0 +1,35 @@ +#pragma once +#include +#include +#include + +#include "tim.h" +#include "usart.h" +#include "zboard.h" + +#define GPIO_SET(port, pin, mirror, _state) \ + HAL_GPIO_WritePin(GPIO##port, GPIO_PIN_##pin, mirror _state ? GPIO_PIN_SET : GPIO_PIN_RESET); + +#define GPIO_GET(port, pin, mirror) (mirror(HAL_GPIO_ReadPin(GPIO##port, GPIO_PIN_##pin) == GPIO_PIN_SET)) + +/*********************************************************************************************************************** + * ====================================================调试指示灯===================================================== * + ***********************************************************************************************************************/ +void port_do_debug_light_state(void); + +/*********************************************************************************************************************** + * =======================================================UART======================================================== * + ***********************************************************************************************************************/ +typedef struct { + UART_HandleTypeDef* uarthandler; + uint8_t rxbuf; +} uart_t; +void port_mock_on_uart_rx(uart_t* uart); +void port_uart_start_all_uart_receive(void); + +bool port_electric_relay_get_state(int relayindex); +void port_electric_relay_set_state(int relayindex, bool state); + +static inline bool port_get_gpio_int(int index) { + return false; +} diff --git a/src/zthread.c b/src/zthread.c new file mode 100644 index 0000000..68b2a51 --- /dev/null +++ b/src/zthread.c @@ -0,0 +1,96 @@ +#include "zthread.h" +#include "stdbool.h" +#include "iflytop_microcontroller/sdk/stm32/stm32sdk.h" +// #include "Middlewares\Third_Party\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.h" +#include "zassert.h" + +#define TAG "zthread" + +extern __asm uint32_t vPortGetIPSR(void); + +static __inline bool IS_IRQ(void) +{ + if (vPortGetIPSR()) + return true; + + return false; +} + +static void tasksleep(uint32_t ms) { ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(ms)); } + +static void taskwake(zthread_t *thread) { + BaseType_t state; + if (IS_IRQ()) + vTaskNotifyGiveFromISR(thread->handler, &state); + else + xTaskNotifyGive(thread->handler); +} + +static void prvtaskfunction(void *_taskhandler) { + zthread_t *thread = (zthread_t *)_taskhandler; + Z_ASSERT(_taskhandler); + + while (true) { + thread->threadisworking = false; + + // 等待taskworking + xEventGroupWaitBits(thread->zthreadstartworkevent, 0x01, pdTRUE, pdTRUE, portMAX_DELAY); + // ZLOGI(TAG, "thread %s startwork", thread->name); + ZLOGI(TAG, "thread %s startwork", thread->name); + thread->threadisworking = true; + thread->taskfunction(NULL); + ZLOGI(TAG, "thread %s end work", thread->name); + } +}; + +void zthread_init(zthread_t *thread, const char *name, TaskFunction_t taskfunction) { + Z_ASSERT(thread); + Z_ASSERT(taskfunction); + Z_ASSERT(name); + + thread->lock = xSemaphoreCreateMutex(); + Z_ASSERT(thread->lock); + + if (thread->stacksize == 0) { + thread->stacksize = ZTHREAD_DEFAULT_STACK_SIZE; + } + if (thread->uxPriority == 0) { + thread->uxPriority = ZTHREAD_DEFAULT_PRIORITY; + } + thread->taskfunction = taskfunction; + thread->zthreadstartworkevent = xEventGroupCreate(); + thread->name = name; + + xTaskCreate(prvtaskfunction, name, thread->stacksize, (void *)thread, thread->uxPriority, &thread->handler); +} +void zthread_start(zthread_t *thread) { + /** + * @brief + */ + + Z_ASSERT(thread); + xSemaphoreTake(thread->lock, portMAX_DELAY); + xEventGroupSetBits(thread->zthreadstartworkevent, 0x01); + while (thread->threadisworking != true) { + vTaskDelay(10); + } + xSemaphoreGive(thread->lock); +} + +bool zthread_is_expect_stop(zthread_t *thread) { return thread->_expect_stop; } + +void zthread_stop(zthread_t *thread) { + Z_ASSERT(thread); + xSemaphoreTake(thread->lock, portMAX_DELAY); + + thread->_expect_stop = true; + while (thread->threadisworking == true) { + taskwake(thread); + vTaskDelay(10); + } + thread->_expect_stop = false; + xSemaphoreGive(thread->lock); +} + +void zthread_sleep(uint32_t ms) { tasksleep(ms); } +void zthread_weak(zthread_t *thread) { taskwake(thread); } \ No newline at end of file diff --git a/src/zthread.h b/src/zthread.h new file mode 100644 index 0000000..2b8d75e --- /dev/null +++ b/src/zthread.h @@ -0,0 +1,46 @@ +#pragma once +#include "FreeRTOS.h" +#include "event_groups.h" +#include "semphr.h" +#include "task.h" +#include "stdbool.h" + +#if 0 +static inline IRAM_ATTR BaseType_t +xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, + const uint32_t usStackDepth, void *const pvParameters, + UBaseType_t uxPriority, TaskHandle_t *const pvCreatedTask) { + return xTaskCreatePinnedToCore(pvTaskCode, pcName, usStackDepth, pvParameters, + uxPriority, pvCreatedTask, tskNO_AFFINITY); +} +#endif + +#define ZTHREAD_DEFAULT_STACK_SIZE 4096 +#define ZTHREAD_DEFAULT_PRIORITY 5 + +typedef struct { + + const char *name; + + size_t stacksize; + int uxPriority; + + TaskFunction_t taskfunction; + + TaskHandle_t handler; + EventGroupHandle_t zthreadstartworkevent; + + bool threadisworking; + bool _expect_stop; + SemaphoreHandle_t lock; + +} zthread_t; + +void zthread_init(zthread_t *thread, const char *name, + TaskFunction_t taskfunction); +void zthread_start(zthread_t *thread); +void zthread_stop(zthread_t *thread); +bool zthread_is_expect_stop(zthread_t *thread); + +void zthread_sleep(uint32_t ms); +void zthread_weak(zthread_t *thread);