14 changed files with 686 additions and 7 deletions
-
11.vscode/settings.json
-
21iflytop_xsync/xs_gpio.c
-
92iflytop_xsync/xs_udp.c
-
39iflytop_xsync/xs_udp.h
-
23iflytop_xsync_protocol/iflytop_xsync_protocol.h
-
102usrc/base_service/fpga_if.c
-
59usrc/base_service/fpga_if.h
-
5usrc/project_dep.h
-
128usrc/service/extern_if_service.c
-
22usrc/service/extern_if_service.h
-
32usrc/service/reg_manager.c
-
17usrc/service/reg_manager.h
-
103usrc/service/report_generator_service.c
-
39usrc/service/report_generator_service.h
@ -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)); |
|||
} |
@ -0,0 +1,39 @@ |
|||
#pragma once |
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
#include <lwip/sockets.h> |
|||
#include <stdbool.h> |
|||
|
|||
#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 |
@ -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; } |
@ -0,0 +1,59 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
|
|||
#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(); |
@ -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 |
@ -0,0 +1,22 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
/** |
|||
* @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 |
@ -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; |
|||
} |
@ -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 |
@ -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; } |
@ -0,0 +1,39 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
|
|||
#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); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue