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