From 52299f79a85f43c9eb48a8bb700a302c89bceaf3 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Tue, 2 Jan 2024 23:16:32 +0800 Subject: [PATCH] update --- .vscode/settings.json | 11 +- iflytop_xsync/xs_gpio.c | 21 ++++ iflytop_xsync/xs_udp.c | 92 +++++++++++++++++ iflytop_xsync/xs_udp.h | 39 ++++++++ iflytop_xsync_protocol/iflytop_xsync_protocol.h | 23 ++++- usrc/base_service/fpga_if.c | 102 +++++++++++++++++++ usrc/base_service/fpga_if.h | 59 +++++++++++ usrc/project_dep.h | 5 +- usrc/service/extern_if_service.c | 128 ++++++++++++++++++++++++ usrc/service/extern_if_service.h | 22 ++++ usrc/service/reg_manager.c | 32 ++++++ usrc/service/reg_manager.h | 17 ++++ usrc/service/report_generator_service.c | 103 +++++++++++++++++++ usrc/service/report_generator_service.h | 39 ++++++++ 14 files changed, 686 insertions(+), 7 deletions(-) create mode 100644 iflytop_xsync/xs_udp.c create mode 100644 iflytop_xsync/xs_udp.h create mode 100644 usrc/base_service/fpga_if.c create mode 100644 usrc/base_service/fpga_if.h create mode 100644 usrc/service/extern_if_service.c create mode 100644 usrc/service/extern_if_service.h create mode 100644 usrc/service/reg_manager.c create mode 100644 usrc/service/reg_manager.h create mode 100644 usrc/service/report_generator_service.c create mode 100644 usrc/service/report_generator_service.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 233b714..5633a45 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -85,7 +85,16 @@ "iflytop_xsync.h": "c", "config.h": "c", "config_service.h": "c", - "base_service.h": "c" + "base_service.h": "c", + "iflytop_xsync_protocol.h": "c", + "project_dep.h": "c", + "project_configs.h": "c", + "sockets.h": "c", + "xs_udp.h": "c", + "api.h": "c", + "sys.h": "c", + "reg_manager.h": "c", + "fpga_if.h": "c" }, "files.autoGuessEncoding": false, "files.encoding": "gbk" diff --git a/iflytop_xsync/xs_gpio.c b/iflytop_xsync/xs_gpio.c index fe487e9..4909c79 100644 --- a/iflytop_xsync/xs_gpio.c +++ b/iflytop_xsync/xs_gpio.c @@ -304,3 +304,24 @@ void xs_gpio_write(xs_gpio_t *gpio, bool level) { GPIO_PinState pinState = level ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(gpio->gpio, gpio->pinoff, pinState); } + +void EXTI0_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } +void EXTI1_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1); } +void EXTI2_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); } +void EXTI3_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); } +void EXTI4_IRQHandler() { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); } +void EXTI9_5_IRQHandler(void) { + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9); +} +void EXTI15_10_IRQHandler(void) { + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15); +} \ No newline at end of file diff --git a/iflytop_xsync/xs_udp.c b/iflytop_xsync/xs_udp.c new file mode 100644 index 0000000..c3ab8dd --- /dev/null +++ b/iflytop_xsync/xs_udp.c @@ -0,0 +1,92 @@ +#include "xs_udp.h" + +#define TAG "xs_udp" + +#define UDP_DEFAULT_SEND_PORT 5000 + +#define SOCKET_DO(function) \ + do { \ + int ret = function; \ + if (ret) { \ + ZLOGE(TAG, "do %s fail", #function); \ + return false; \ + } \ + } while (0) + +static void udp_server_receive_thread(void const *argument) { // + udp_t *udp_handler = (udp_t *)argument; + while (true) { + struct sockaddr_in sock; + socklen_t sock_len = sizeof(sock); + int recv_datalen = recvfrom(udp_handler->sock_fd, udp_handler->rxbuf, udp_handler->rxbuf_len, 0, (struct sockaddr *)&sock, &sock_len); + if (recv_datalen > 0) { + if (udp_handler->on_packet) udp_handler->on_packet(udp_handler, &sock, udp_handler->rxbuf, recv_datalen); + } + } +} + +bool udp_init(udp_t *udp_handler, uint16_t port, udp_on_packet_t on_packet, void *data) { + memset(udp_handler, 0, sizeof(udp_t)); + udp_handler->server.sin_family = AF_INET; + udp_handler->server.sin_addr.s_addr = inet_addr("0.0.0.0"); + udp_handler->server.sin_port = htons(port); + udp_handler->on_packet = on_packet; + udp_handler->data = data; + + // 创建客户端用于通信的Socket + udp_handler->sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (udp_handler->sock_fd < 0) { + ZLOGE(TAG, "create socket fail"); + return false; + } + // 设置超时 + struct timeval tv = {0, 1000}; + SOCKET_DO(lwip_setsockopt(udp_handler->sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))); + // 绑定 + SOCKET_DO(bind(udp_handler->sock_fd, (struct sockaddr *)&udp_handler->server, sizeof(udp_handler->server))); + + if (on_packet) { + // 创建接收线程 + osThreadDef(udp_server_rx_thread, udp_server_receive_thread, osPriorityBelowNormal, 0, 512); + udp_handler->rx_thread = osThreadCreate(osThread(udp_server_rx_thread), udp_handler); + ZASSERT(udp_handler->rx_thread != NULL); + } +} + +int udp_send_message(udp_t *udp_handler, const char *ip, int port, const char *data, int len) { // + struct sockaddr_in sockaddr; + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = inet_addr(ip); + sockaddr.sin_port = htons(port); + return sendto(udp_handler->sock_fd, data, len, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); +} +int udp_send_message2(udp_t *udp_handler, struct sockaddr_in *add, const char *data, int len) { // + return sendto(udp_handler->sock_fd, data, len, 0, (struct sockaddr *)add, sizeof(struct sockaddr_in)); +} + +bool udp_broadcast_init(udp_broadcast_handler_t *udp_handler, uint16_t localport) { + memset(udp_handler, 0, sizeof(udp_broadcast_handler_t)); + udp_handler->server.sin_family = AF_INET; + udp_handler->server.sin_addr.s_addr = inet_addr("0.0.0.0"); + udp_handler->server.sin_port = htons(localport); + + // 创建客户端用于通信的Socket + udp_handler->sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (udp_handler->sock_fd < 0) { + ZLOGE(TAG, "create socket fail"); + return false; + } + // 设置超时 + struct timeval tv = {0, 1000}; + SOCKET_DO(lwip_setsockopt(udp_handler->sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))); + // 绑定 + SOCKET_DO(bind(udp_handler->sock_fd, (struct sockaddr *)&udp_handler->server, sizeof(udp_handler->server))); + return true; +} +bool udp_broadcast(udp_broadcast_handler_t *handler, uint32_t remoteport, uint8_t *data, size_t datalen) { + struct sockaddr_in sockaddr; + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); + sockaddr.sin_port = htons(remoteport); + return sendto(handler->sock_fd, data, datalen, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); +} diff --git a/iflytop_xsync/xs_udp.h b/iflytop_xsync/xs_udp.h new file mode 100644 index 0000000..76e637b --- /dev/null +++ b/iflytop_xsync/xs_udp.h @@ -0,0 +1,39 @@ +#pragma once +#ifdef __cplusplus +extern "C" { +#endif +#include +#include + +#include "lwip/api.h" +#include "lwip/opt.h" +#include "lwip/sys.h" +#include "project_configs.h" + +typedef struct udp_s udp_t; +typedef void (*udp_on_packet_t)(udp_t *udp_handler, struct sockaddr_in *client, uint8_t *data, uint16_t len); +struct udp_s { + struct sockaddr_in server; + int sock_fd; + osThreadId rx_thread; + char *rxbuf; + int rxbuf_len; + udp_on_packet_t on_packet; + void *data; +}; + +typedef struct { + struct sockaddr_in server; + int sock_fd; +} udp_broadcast_handler_t; + +bool udp_init(udp_t *udp_handler, uint16_t port, udp_on_packet_t on_packet, void *data); +int udp_send_message(udp_t *udp_handler, const char *remoteip, int remoteport, const char *data, int len); +int udp_send_message2(udp_t *udp_handler, struct sockaddr_in *add, const char *data, int len); + +bool udp_broadcast_init(udp_broadcast_handler_t *handler, uint16_t localport); +bool udp_broadcast(udp_broadcast_handler_t *handler, uint32_t remoteport, uint8_t *data, size_t datalen); + +#ifdef __cplusplus +} +#endif diff --git a/iflytop_xsync_protocol/iflytop_xsync_protocol.h b/iflytop_xsync_protocol/iflytop_xsync_protocol.h index 4d262a6..0d97409 100644 --- a/iflytop_xsync_protocol/iflytop_xsync_protocol.h +++ b/iflytop_xsync_protocol/iflytop_xsync_protocol.h @@ -4,7 +4,13 @@ /** * @brief XSYNC协议端口 */ -#define IFLYTOP_XSYNC_PORT 19973 +#define IFLYTOP_XSYNC_SERVICE_PORT 19901 + +#define IFLYTOP_XSYNC_TIMECODE_REPORT_FROM_PORT 19902 +#define IFLYTOP_XSYNC_TIMECODE_REPORT_TO_PORT 19903 + +#define IFLYTOP_XSYNC_CAMERA_SYNC_PACKET_FROM_PORT 13013 +#define IFLYTOP_XSYNC_CAMERA_SYNC_PACKET_TO_PORT 13014 /** * @brief @@ -24,15 +30,17 @@ * */ typedef enum { - kxsync_packet_type_none = 0, - kxsync_packet_type_reg_read = 1, - kxsync_packet_type_reg_write = 2, - kxsync_packet_type_reg_read_regs = 3, + kxsync_packet_type_none = 0, + kxsync_packet_type_reg_read = 1, + kxsync_packet_type_reg_write = 2, + kxsync_packet_type_reg_read_regs = 3, + kxsync_packet_type_timecode_report = 4, } xsync_protocol_cmd_t; typedef enum { kxsync_packet_type_cmd = 0, kxsync_packet_type_receipt = 1, + kxsync_packet_type_report = 2, } xsync_protocol_packet_type_t; #pragma pack(1) @@ -46,6 +54,11 @@ typedef struct { /*uint8_t checksum*/ } iflytop_xsync_packet_header_t; +typedef struct { + uint32_t timecode0; + uint32_t timecode1; +} iflytop_timecode_report_packet_t; + #define XYSNC_REG_DEVICE_INFO_START_ADD 0 #define XYSNC_REG_STM32_CONFIG_START_ADD 16 diff --git a/usrc/base_service/fpga_if.c b/usrc/base_service/fpga_if.c new file mode 100644 index 0000000..3f4392b --- /dev/null +++ b/usrc/base_service/fpga_if.c @@ -0,0 +1,102 @@ +#include "fpga_if.h" + +/** + * @brief fpga_if初始化 + */ + +fpga_if_t fpga_if; +void fpga_if_init() { // + fpga_if.spi = &hspi1; + + xs_gpio_init_as_input(&fpga_if.camera_sync_code_irq_io, fpga_if.camera_sync_code_irq_pin, kxs_gpio_pulldown, kxs_gpio_rising_irq, false); + xs_gpio_init_as_input(&fpga_if.timecode_irq_io, fpga_if.timecode_irq_pin, kxs_gpio_pulldown, kxs_gpio_rising_irq, false); + + for (size_t i = 0; i < 4; i++) { + xs_gpio_init_as_output(&fpga_if.timecode_add[i], fpga_if.timecode_add_pin[i], kxs_gpio_nopull, false, false); + } + for (size_t i = 0; i < 8; i++) { + xs_gpio_init_as_input(&fpga_if.timecode_data[i], fpga_if.timecode_data_pin[i], kxs_gpio_nopull, kxs_gpio_no_irq, false); + } +} +/** + * @brief 读取当前timecode + * + * @param timecode0 + * @param timecode1 + */ + +uint8_t fpga_if_get_timecode_u8(uint8_t add) { + xs_gpio_write(&fpga_if.timecode_add[0], add & 0x01); + xs_gpio_write(&fpga_if.timecode_add[1], add & 0x02); + xs_gpio_write(&fpga_if.timecode_add[2], add & 0x04); + xs_gpio_write(&fpga_if.timecode_add[3], add & 0x08); + + xs_delay_us(2); + uint8_t data = 0; + for (size_t i = 0; i < 8; i++) { + data |= xs_gpio_read(&fpga_if.timecode_data[i]) << i; + } + return data; +} +void fpga_if_get_timecode(uint32_t *timecode0, uint32_t *timecode1) { + *timecode0 = 0; + *timecode1 = 0; + + *timecode0 |= fpga_if_get_timecode_u8(0) << 0; + *timecode0 |= fpga_if_get_timecode_u8(1) << 8; + *timecode0 |= fpga_if_get_timecode_u8(2) << 16; + *timecode0 |= fpga_if_get_timecode_u8(3) << 24; + + *timecode1 |= fpga_if_get_timecode_u8(4) << 0; + *timecode1 |= fpga_if_get_timecode_u8(5) << 8; + + return; +} +/** + * @brief SPI寄存器写指令 + * + * @param add + * @param txdata + * @param rxdata + */ +void fpga_if_spi_write_data(uint32_t add, uint32_t txdata, uint32_t *rxdata) { + uint8_t txbuf[2 + 4] = {0}; + txbuf[0] = add & 0xFF; + txbuf[1] = (add >> 8) & 0xFF; + txbuf[1] |= 0x80; // write flag + txbuf[2] = txdata & 0xFF; + txbuf[3] = (txdata >> 8) & 0xFF; + txbuf[4] = (txdata >> 16) & 0xFF; + txbuf[5] = (txdata >> 24) & 0xFF; + + xs_gpio_write(&fpga_if.cs_gpio, 0); // cs_gpio + xs_delay_us(1); + HAL_SPI_TransmitReceive(fpga_if.spi, txbuf, txbuf, 2 + 4, 1000); + xs_gpio_write(&fpga_if.cs_gpio, 1); // cs_gpio + + *rxdata = txbuf[2] | (txbuf[3] << 8) | (txbuf[4] << 16) | (txbuf[5] << 24); +} +/** + * @brief SPI寄存器读指令 + * + * @param add + * @param rxdata + */ +void fpga_if_spi_read_data(uint32_t add, uint32_t *rxdata) { + uint8_t txbuf[2 + 4] = {0}; + txbuf[0] = add & 0xFF; + txbuf[1] = (add >> 8) & 0xFF; + txbuf[2] = 0; + txbuf[3] = 0; + txbuf[4] = 0; + txbuf[5] = 0; + + xs_gpio_write(&fpga_if.cs_gpio, 0); // cs_gpio + xs_delay_us(1); + HAL_SPI_TransmitReceive(fpga_if.spi, txbuf, txbuf, 2 + 4, 1000); + xs_gpio_write(&fpga_if.cs_gpio, 1); // cs_gpio + + *rxdata = txbuf[2] | (txbuf[3] << 8) | (txbuf[4] << 16) | (txbuf[5] << 24); +} + +fpga_if_t *fpga_if_get_instance() { return &fpga_if; } diff --git a/usrc/base_service/fpga_if.h b/usrc/base_service/fpga_if.h new file mode 100644 index 0000000..3648b76 --- /dev/null +++ b/usrc/base_service/fpga_if.h @@ -0,0 +1,59 @@ +#pragma once +#include + +#include "project_dep.h" + +typedef struct { + /** + * @brief 指令SPI 接口 + */ + SPI_HandleTypeDef *spi; + xs_gpio_t cs_gpio; + Pin_t cs_pin; + + /** + * @brief timecode并口 + */ + + xs_gpio_t timecode_add[4]; + xs_gpio_t timecode_data[8]; + + Pin_t timecode_add_pin[4]; + Pin_t timecode_data_pin[8]; + + Pin_t timecode_irq_pin; + Pin_t camera_sync_code_irq_pin; + + xs_gpio_t timecode_irq_io; + xs_gpio_t camera_sync_code_irq_io; + +} fpga_if_t; +/** + * @brief fpga_if初始化 + * + */ +void fpga_if_init(); +/** + * @brief 读取当前timecode + * + * @param timecode0 + * @param timecode1 + */ +void fpga_if_get_timecode(uint32_t *timecode0, uint32_t *timecode1); +/** + * @brief SPI寄存器写指令 + * + * @param add + * @param txdata + * @param rxdata + */ +void fpga_if_spi_write_data(uint32_t add, uint32_t txdata, uint32_t *rxdata); +/** + * @brief SPI寄存器读指令 + * + * @param add + * @param rxdata + */ +void fpga_if_spi_read_data(uint32_t add, uint32_t *rxdata); + +fpga_if_t *fpga_if_get_instance(); \ No newline at end of file diff --git a/usrc/project_dep.h b/usrc/project_dep.h index a176aa6..3d29f43 100644 --- a/usrc/project_dep.h +++ b/usrc/project_dep.h @@ -9,4 +9,7 @@ #include "lwip/sys.h" #include "iflytop_xsync_protocol\iflytop_xsync_protocol.h" -#include "iflytop_xsync\iflytop_xsync.h" \ No newline at end of file +#include "iflytop_xsync\iflytop_xsync.h" + +#include "main.h" +#include "spi.h" diff --git a/usrc/service/extern_if_service.c b/usrc/service/extern_if_service.c new file mode 100644 index 0000000..f52e15a --- /dev/null +++ b/usrc/service/extern_if_service.c @@ -0,0 +1,128 @@ +#include "iflytop_xsync_protocol\iflytop_xsync_protocol.h" +#include "project_configs.h" +#include "project_dep.h" +// +#include "iflytop_xsync\xs_udp.h" +#include "reg_manager.h" + +udp_t m_udp_cmd_server; // +udp_broadcast_handler_t m_udp_camera_sync_sender; // + +static struct sockaddr_in m_last_rxpacket_client; +static bool m_last_rxpacket_client_valid = false; +static uint8_t txbuf[2048]; + +/******************************************************************************* + * 上位机下发指令回执服务 * + *******************************************************************************/ +typedef struct { + udp_t *server; + struct sockaddr_in *client; + iflytop_xsync_packet_header_t *rxpacket; +} extern_if_service_context_t; + +/** + * @brief 创建并发送回执数据包 + * + * @param context + * @param data + * @param ndata + */ +static void create_and_send_receipt(extern_if_service_context_t *context, uint32_t *data, size_t ndata) { + iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txbuf; + + txpacket->type = kxsync_packet_type_receipt; + txpacket->index = context->rxpacket->index; + txpacket->cmd = context->rxpacket->cmd; + txpacket->ndata = ndata; + memcpy(txpacket->data, data, ndata * sizeof(uint32_t)); + udp_send_message2(context->server, context->client, txbuf, sizeof(iflytop_xsync_packet_header_t) + ndata * sizeof(uint32_t)); +} +#if 0 +/** + * @brief 构建并发送时间码数据包 + * + * @param client + * @param timecode0 + * @param timecode1 + */ +static void create_and_send_timecode(struct sockaddr_in client, uint32_t timecode0, uint32_t timecode1) { + iflytop_xsync_packet_header_t *txpacket = (iflytop_xsync_packet_header_t *)txbuf; + + txpacket->type = kxsync_packet_type_report; + txpacket->index = 0; + txpacket->cmd = kxsync_packet_type_timecode_report; + txpacket->ndata = 2; + txpacket->data[0] = timecode0; + txpacket->data[1] = timecode1; + udp_send_message2(&m_udp_cmd_server, &client, txbuf, sizeof(iflytop_xsync_packet_header_t) + 2 * sizeof(uint32_t)); +} +#endif + +/** + * @brief 接收并解析从上位机下发下来的数据包 + * + * @param server + * @param client + * @param data + * @param len + */ +static void udp_on_packet(udp_t *server, struct sockaddr_in *client, uint8_t *data, uint16_t len) { + /** + * @brief + */ + iflytop_xsync_packet_header_t *rxpacket = (iflytop_xsync_packet_header_t *)data; + extern_if_service_context_t cx = {0}; + cx.client = client; + cx.server = server; + cx.rxpacket = rxpacket; + + if (rxpacket->type != kxsync_packet_type_cmd) return; + + m_last_rxpacket_client_valid = true; + memcpy(&m_last_rxpacket_client, client, sizeof(struct sockaddr_in)); + + if (rxpacket->cmd == kxsync_packet_type_reg_read) { + uint32_t regadd = rxpacket->data[0]; + uint32_t receipt[2]; + + receipt[0] = 0; // receipt + receipt[1] = reg_manager_read_reg(regadd); // regdata + create_and_send_receipt(&cx, receipt, 2); + } else if (rxpacket->cmd == kxsync_packet_type_reg_write) { + uint32_t regadd = rxpacket->data[0]; + uint32_t regval = rxpacket->data[1]; + uint32_t receipt[2]; + + receipt[0] = 0; // + receipt[1] = reg_manager_read_reg(regadd); // regdata + create_and_send_receipt(&cx, receipt, 2); + + } else if (rxpacket->cmd == kxsync_packet_type_reg_read_regs) { + uint32_t start_regadd = rxpacket->data[0]; + uint32_t nreg = rxpacket->data[1]; + + static uint32_t regcache[MAX_REG_NUM + 1]; + uint32_t len = MAX_REG_NUM; + regcache[0] = 0; + reg_manager_read_regs(start_regadd, nreg, ®cache[1], &len); + create_and_send_receipt(&cx, regcache, len); + } +} + +static void udp_server_receive_thread(void const *argument) { // + udp_t *udp_handler = (udp_t *)argument; + while (true) { + struct sockaddr_in sock; + socklen_t sock_len = sizeof(sock); + int recv_datalen = recvfrom(udp_handler->sock_fd, udp_handler->rxbuf, udp_handler->rxbuf_len, 0, (struct sockaddr *)&sock, &sock_len); + if (recv_datalen > 0) { + if (udp_handler->on_packet) udp_handler->on_packet(udp_handler, &sock, udp_handler->rxbuf, recv_datalen); + } + } +} + +void extern_if_service_init() { ZASSERT(udp_init(&m_udp_cmd_server, IFLYTOP_XSYNC_SERVICE_PORT, udp_on_packet, NULL)); } +#if 0 +void extern_if_service_send_timecode(struct sockaddr_in client, uint32_t timecode0, uint32_t timecode1) { create_and_send_timecode(client, timecode0, timecode1); } +#endif diff --git a/usrc/service/extern_if_service.h b/usrc/service/extern_if_service.h new file mode 100644 index 0000000..46824a1 --- /dev/null +++ b/usrc/service/extern_if_service.h @@ -0,0 +1,22 @@ +#pragma once +#include +/** + * @brief + * 该模块主要处理来自上位机的消息 + */ + +/** + * @brief 模块初始化 + * + */ +void extern_if_service_init(); +#if 0 +/** + * @brief 上报时间码 + * + * @param client + * @param timecode0 + * @param timecode1 + */ +void extern_if_service_send_timecode(struct sockaddr_in client, uint32_t timecode0, uint32_t timecode1); +#endif \ No newline at end of file diff --git a/usrc/service/reg_manager.c b/usrc/service/reg_manager.c new file mode 100644 index 0000000..47fd922 --- /dev/null +++ b/usrc/service/reg_manager.c @@ -0,0 +1,32 @@ +#include "reg_manager.h" + +uint32_t reg[MAX_REG_NUM]; + +uint32_t reg_manager_read_reg(uint32_t addr) { + if (addr < MAX_REG_NUM) return reg[addr]; + return 0; +} +uint32_t reg_manager_write_reg(uint32_t addr, uint32_t value) { + if (addr < MAX_REG_NUM) { + reg[addr] = value; + return reg[addr]; + } + return 0; +} + +void reg_manager_read_regs(uint32_t start_addr, uint32_t nreg, uint32_t* datacache, uint32_t* len) { + uint32_t _nreg = nreg; + if (start_addr + nreg > MAX_REG_NUM) { + _nreg = MAX_REG_NUM - start_addr; + } + + if (*len < _nreg) { + _nreg = *len; + } + + for (size_t i = start_addr; i < _nreg; i++) { + datacache[i] = reg_manager_read_reg(i); + } + *len = _nreg; + return; +} diff --git a/usrc/service/reg_manager.h b/usrc/service/reg_manager.h new file mode 100644 index 0000000..9ae3ba8 --- /dev/null +++ b/usrc/service/reg_manager.h @@ -0,0 +1,17 @@ +#pragma once +#ifdef __cplusplus +extern "C" { +#endif +#include "iflytop_xsync/iflytop_xsync.h" +#include "project_configs.h" + +#define MAX_REG_NUM 256 + +uint32_t reg_manager_read_reg(uint32_t addr); +uint32_t reg_manager_write_reg(uint32_t addr, uint32_t value); + +void reg_manager_read_regs(uint32_t start_addr, uint32_t nreg, uint32_t* datacache, uint32_t* len); + +#ifdef __cplusplus +} +#endif diff --git a/usrc/service/report_generator_service.c b/usrc/service/report_generator_service.c new file mode 100644 index 0000000..186fb4e --- /dev/null +++ b/usrc/service/report_generator_service.c @@ -0,0 +1,103 @@ +#include "iflytop_xsync_protocol\iflytop_xsync_protocol.h" +#include "project_configs.h" +#include "project_dep.h" +// +#include "base_service/fpga_if.h" +#include "iflytop_xsync\xs_udp.h" +#include "reg_manager.h" + +udp_broadcast_handler_t m_udp_camera_sync_sender; // +udp_broadcast_handler_t m_udp_camera_timecode_sender; // + +osThreadId timecode_report_thread_id; +osThreadId xync_signal_report_thread_id; + +static volatile bool m_timecode_signal_notify_flag = false; +static volatile bool m_xync_signal_notify_flag = false; +static uint32_t m_sync_count = 0; + +static uint32_t m_timecode_trigger_input_off; +static uint32_t m_xync_trigger_input_off; + +/** + * @brief 构建并发送时间码数据包 + * + * @param client + * @param timecode0 + * @param timecode1 + */ +static void create_and_send_timecode(uint32_t timecode0, uint32_t timecode1) { + static uint8_t txbuf[256]; + iflytop_timecode_report_packet_t *txpacket = (iflytop_timecode_report_packet_t *)txbuf; + txpacket->timecode0 = timecode0; + txpacket->timecode1 = timecode1; + udp_broadcast(&m_udp_camera_timecode_sender, IFLYTOP_XSYNC_TIMECODE_REPORT_TO_PORT, txpacket, sizeof(iflytop_timecode_report_packet_t)); +} +/** + * @brief 构建并发送相机同步数据包 + * + * @param count + */ +static void create_and_send_camera_sync_msg(uint32_t count) { + static txbuf[] = { + 0xF0, 0x00, 0x20, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xF0, 0x42, 0x17, 0x00, 0x00, 0x00, 0xE1, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + txbuf[7] = count & 0xFF; + txbuf[6] = (count >> 8) & 0xFF; + txbuf[5] = (count >> 16) & 0xFF; + txbuf[4] = (count >> 24) & 0xFF; + + udp_broadcast(&m_udp_camera_sync_sender, IFLYTOP_XSYNC_CAMERA_SYNC_PACKET_TO_PORT, txbuf, sizeof(txbuf)); +} + +static void timecode_report_thread(void const *argument) { + while (true) { + ulTaskNotifyTake(timecode_report_thread_id, portMAX_DELAY); + if (m_timecode_signal_notify_flag) { + uint32_t timecode0, timecode1; + fpga_if_get_timecode(&timecode0, &timecode1); + create_and_send_timecode(timecode0, timecode1); + } + m_timecode_signal_notify_flag = false; + } +} +static void xync_signal_report_thread(void const *argument) { + while (true) { + ulTaskNotifyTake(xync_signal_report_thread_id, portMAX_DELAY); + if (m_xync_signal_notify_flag) create_and_send_camera_sync_msg(m_sync_count++); + m_xync_signal_notify_flag = false; + } +} + +void report_generator_service_irq_trigger(uint16_t gpiopin) { + if (gpiopin == m_timecode_trigger_input_off) { + m_timecode_signal_notify_flag = true; + vTaskNotifyGiveFromISR(timecode_report_thread_id, NULL); + } + if (gpiopin == m_xync_trigger_input_off) { + m_xync_signal_notify_flag = true; + vTaskNotifyGiveFromISR(xync_signal_report_thread_id, NULL); + } +} + +void report_generator_service_init() { + ZASSERT(udp_broadcast_init(&m_udp_camera_sync_sender, IFLYTOP_XSYNC_CAMERA_SYNC_PACKET_FROM_PORT)); + ZASSERT(udp_broadcast_init(&m_udp_camera_timecode_sender, IFLYTOP_XSYNC_TIMECODE_REPORT_FROM_PORT)); + + osThreadDef(timecode_report_thread, timecode_report_thread, osPriorityNormal, 0, 512); + timecode_report_thread_id = osThreadCreate(osThread(timecode_report_thread), NULL); + + osThreadDef(xync_signal_report_thread, xync_signal_report_thread, osPriorityRealtime, 0, 512); + xync_signal_report_thread_id = osThreadCreate(osThread(xync_signal_report_thread), NULL); + + ZASSERT(timecode_report_thread_id != NULL); + ZASSERT(xync_signal_report_thread_id != NULL); + + m_timecode_trigger_input_off = fpga_if_get_instance()->timecode_irq_io.pinoff; + m_xync_trigger_input_off = fpga_if_get_instance()->camera_sync_code_irq_io.pinoff; +} + +void report_generator_service_xsync_clear_count(void) { m_sync_count = 0; } +uint32_t report_generator_service_xsync_get_count(void) { return m_sync_count; } \ No newline at end of file diff --git a/usrc/service/report_generator_service.h b/usrc/service/report_generator_service.h new file mode 100644 index 0000000..e6549df --- /dev/null +++ b/usrc/service/report_generator_service.h @@ -0,0 +1,39 @@ +#pragma once +#include + +#include "iflytop_xsync\pin.h" + +/** + * @brief 模块说明 + * 该模块监听FPGA秒时钟中断,和timecode中断 + * 当中断发生时,上报相应的数据。 + * + * 该模块依赖: + * fpag_if.c + * config_service.c + */ + +/** + * @brief 初始化上报模块 + * + * @param timecode_trigger_pin + * @param xync_trigger_pin + */ +void report_generator_service_init(Pin_t timecode_trigger_pin, Pin_t xync_trigger_pin); + +/** + * @brief 中断触发函数,当IO中断触发时,调用此方法 + * + * @param gpiopin + */ +void report_generator_service_irq_trigger(uint16_t gpiopin); +/** + * @brief 清除xync计数 + */ +void report_generator_service_xsync_clear_count(void); +/** + * @brief 获取xync计数 + * + * @return uint32_t + */ +uint32_t report_generator_service_xsync_get_count(void); \ No newline at end of file