refactor(app, drv): 移植下位机的应用程序到新的通信协议
1. 应用程序实现了心跳包 2. 应用程序实现了4个相机的单独设置 3. 应用程序去除了有关喷阀、接收处理mask和硬件fifo相关的代码 4. 删除了fifo相关驱动程序 5. 修正了encoder驱动程序中的清除缓存逻辑 Co-authored-by: lyz <1942503466@qq.com>
This commit is contained in:
parent
fe7b3308bc
commit
6449ebeeac
@ -307,10 +307,11 @@ $ make CROSS_COMPILE=交叉编译工具链前缀
|
||||
8. 安装编译得到的驱动文件`encode.ko`,并设置自动加载,对应自启脚本可以如下方式写入,也可以直接上传[script/loadencoder.sh](../script/loadencoder.sh),ssh方式,`root`登录:
|
||||
|
||||
```shell
|
||||
上传encoder.ko到/lib/modules/[内核版本]/kernel/drivers/
|
||||
$ cd /lib/modules/[内核版本]; depmod
|
||||
上传encoder.ko到/lib/modules/[内核版本]/extra/
|
||||
$ cd /lib/modules/[内核版本]/extra/; depmod
|
||||
$ set +H
|
||||
$ echo -e "#!/bin/sh\nmodprobe encoder" > /etc/init.d/loadencoder.sh
|
||||
$ chmod 755 /etc/init.d/loadencoder.sh
|
||||
$ cd /etc/rc5.d
|
||||
$ ln -s ../init.d/loadencoder.sh S20loadencoder.sh
|
||||
```
|
||||
|
||||
@ -1 +1 @@
|
||||
1.5
|
||||
1.6
|
||||
@ -1,17 +1,19 @@
|
||||
/**
|
||||
* @file encoder_dev.c
|
||||
* @brief Manage the hardware encoder unit
|
||||
* @author miaow (3703781@qq.com)
|
||||
* @version 1.0
|
||||
* @date 2022/06/11
|
||||
* @author miaow, lyz (3703781@qq.com)
|
||||
* @version 0.11
|
||||
* @date 2022/04/26
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
*
|
||||
* @copyright Copyright (c) 2022 miaow
|
||||
* @copyright Copyright (c) 2023 miaow, lyz
|
||||
*
|
||||
* @par Changelog:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2022/06/11 <td>0.9 <td>Miaow <td>Write this module
|
||||
* <tr><td>2022/04/11 <td>0.10 <td>lyz <td>Add seprate dividers up to 4 cameras
|
||||
* <tr><td>2023/04/26 <td>0.11 <td>Miaow <td>Add Clear mode
|
||||
* </table>
|
||||
*/
|
||||
|
||||
@ -31,9 +33,13 @@
|
||||
static int encoder_dev_fd = -1;
|
||||
static char perror_buffer[128];
|
||||
|
||||
static struct {
|
||||
unsigned int valve_divide_value;
|
||||
unsigned int camera_divide_value;
|
||||
static struct
|
||||
{
|
||||
uint32_t valve_divide_value;
|
||||
uint32_t camera_a_divide_value;
|
||||
uint32_t camera_b_divide_value;
|
||||
uint32_t camera_c_divide_value;
|
||||
uint32_t camera_d_divide_value;
|
||||
} encoder_dev_divide_value_structure;
|
||||
|
||||
/**
|
||||
@ -45,22 +51,37 @@ int encoder_dev_init()
|
||||
{
|
||||
encoder_dev_fd = open(ENCODER_DEV_PATH, O_RDWR);
|
||||
ON_ERROR_RET(encoder_dev_fd, "", "", -1);
|
||||
encoder_dev_set_divide( 100, 100, 100, 100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the two divider in the hareware encoder unit.
|
||||
* @param valve_divide the frequency division factor between the encoder signal and valve output
|
||||
* @param camera_a_divide the frequency division factor between the encoder signal and camera a triggle signal
|
||||
* Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter
|
||||
* @param camera_divide the frequency division factor between the encoder signal and camera triggle signal
|
||||
* @param camera_b_divide the frequency division factor between the encoder signal and camera b triggle signal
|
||||
* Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter
|
||||
* @param camera_c_divide the frequency division factor between the encoder signal and camera c triggle signal
|
||||
* Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter
|
||||
* @param camera_d_divide the frequency division factor between the encoder signal and camera d triggle signal
|
||||
* Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter
|
||||
*
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int encoder_dev_set_divide(int valve_divide, int camera_divide)
|
||||
int encoder_dev_set_divide(int camera_a_divide,
|
||||
int camera_b_divide,
|
||||
int camera_c_divide,
|
||||
int camera_d_divide)
|
||||
{
|
||||
encoder_dev_divide_value_structure.valve_divide_value = valve_divide;
|
||||
encoder_dev_divide_value_structure.camera_divide_value = camera_divide;
|
||||
encoder_dev_divide_value_structure.valve_divide_value = 2;
|
||||
if (camera_a_divide != ENCODER_DEV_DIVIDE_NOT_TO_SET)
|
||||
encoder_dev_divide_value_structure.camera_a_divide_value = camera_a_divide;
|
||||
if (camera_b_divide != ENCODER_DEV_DIVIDE_NOT_TO_SET)
|
||||
encoder_dev_divide_value_structure.camera_b_divide_value = camera_b_divide;
|
||||
if (camera_c_divide != ENCODER_DEV_DIVIDE_NOT_TO_SET)
|
||||
encoder_dev_divide_value_structure.camera_c_divide_value = camera_c_divide;
|
||||
if (camera_d_divide != ENCODER_DEV_DIVIDE_NOT_TO_SET)
|
||||
encoder_dev_divide_value_structure.camera_d_divide_value = camera_d_divide;
|
||||
|
||||
ssize_t size = write(encoder_dev_fd, &encoder_dev_divide_value_structure, sizeof(encoder_dev_divide_value_structure));
|
||||
int res = -(size != sizeof(encoder_dev_divide_value_structure));
|
||||
ON_ERROR_RET(res, "size=", "", -1);
|
||||
@ -70,12 +91,12 @@ int encoder_dev_set_divide(int valve_divide, int camera_divide)
|
||||
|
||||
/**
|
||||
* @brief Set the trig signal to internal or external.
|
||||
* @param mode ENCODER_TRIG_MODE_EXTERNEL for externally trig, or ENCODER_TRIG_MODE_INTERNEL for internally trig
|
||||
* @param count the count of virtual trig cycles.
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int encoder_dev_virtual_trig(int count)
|
||||
{
|
||||
int res = ioctl(encoder_dev_fd, _IOW('D', ENCODER_CMD_FUNCTION_VIRT_INPUT, 4), count);
|
||||
int res = ioctl(encoder_dev_fd, _IOW('D', ENCODER_CMD_FUNCTION_VIRT_INPUT, int), count);
|
||||
ON_ERROR_RET(res, "", "", -1);
|
||||
return 0;
|
||||
}
|
||||
@ -85,9 +106,20 @@ int encoder_dev_virtual_trig(int count)
|
||||
* @param mode ENCODER_TRIG_MODE_EXTERNEL for externally trig, or ENCODER_TRIG_MODE_INTERNEL for internally trig
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int encoder_dev_set_trigmod(int mode)
|
||||
int encoder_dev_set_trigmod(encoder_dev_trig_mode_enum mode)
|
||||
{
|
||||
int res = ioctl(encoder_dev_fd, _IOW('D', mode, 0));
|
||||
int res = ioctl(encoder_dev_fd, _IOW('D', mode, int));
|
||||
ON_ERROR_RET(res, "", "", -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the clr signal to internal or both external and internal.
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int encoder_dev_set_clrmod(encoder_dev_clear_mode_enum mode)
|
||||
{
|
||||
int res = ioctl(encoder_dev_fd, _IOW('D', mode, int));
|
||||
ON_ERROR_RET(res, "", "", -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
/**
|
||||
* @file encoder_dev.h
|
||||
* @brief Manage the hardware encoder unit
|
||||
* @author miaow (3703781@qq.com)
|
||||
* @version 1.0
|
||||
* @date 2022/06/11
|
||||
* @author miaow, lzy (3703781@qq.com)
|
||||
* @version 0.11
|
||||
* @date 2022/04/26
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
*
|
||||
* @copyright Copyright (c) 2022 miaow
|
||||
* @copyright Copyright (c) 2023 miaow, lyz
|
||||
*
|
||||
* @par Changelog:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2022/06/11 <td>0.9 <td>Miaow <td>Write this module
|
||||
* <tr><td>2022/04/11 <td>0.10 <td>lyz <td>Add seprate dividers up to 4 cameras
|
||||
* <tr><td>2023/04/26 <td>0.11 <td>Miaow <td>Add Clear mode
|
||||
* </table>
|
||||
*/
|
||||
#ifndef __ENCODER_DEV_H
|
||||
@ -22,12 +25,25 @@
|
||||
|
||||
#define ENCODER_DEV_DIVIDE_NOT_TO_SET 0
|
||||
|
||||
#define ENCODER_TRIG_MODE_EXTERNEL 100
|
||||
#define ENCODER_TRIG_MODE_INTERNEL 101
|
||||
typedef enum
|
||||
{
|
||||
ENCODER_TRIG_MODE_EXTERNEL = 100,
|
||||
ENCODER_TRIG_MODE_INTERNEL = 101
|
||||
} encoder_dev_trig_mode_enum;
|
||||
|
||||
int encoder_dev_set_divide(int valve_divide, int camera_divide);
|
||||
typedef enum
|
||||
{
|
||||
ENCODER_CLEAR_MODE_BOTH = 200,
|
||||
ENCODER_CLEAR_MODE_INTERNAL = 201
|
||||
} encoder_dev_clear_mode_enum;
|
||||
|
||||
int encoder_dev_set_divide(int camera_a_divide,
|
||||
int camera_b_divide,
|
||||
int camera_c_divide,
|
||||
int camera_d_divide);
|
||||
int encoder_dev_flush(void);
|
||||
int encoder_dev_set_trigmod(int mode);
|
||||
int encoder_dev_set_trigmod(encoder_dev_trig_mode_enum mode);
|
||||
int encoder_dev_set_clrmod(encoder_dev_clear_mode_enum mode);
|
||||
int encoder_dev_virtual_trig(int count);
|
||||
int encoder_dev_init(void);
|
||||
int encoder_dev_deinit(void);
|
||||
|
||||
@ -1,149 +0,0 @@
|
||||
/**
|
||||
* @file fifo_dev.c
|
||||
* @brief Operate the hardware fifo with Linux application
|
||||
* @details Call fifo_dev_init() paired with fifo_dev_deinit() as their names imply, fifo_dev_write_xxx() can be executed several times to operate the hardware fifo between fifo_dev_init() and fifo_dev_deinit()
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
* @author miaow (3703781@qq.com)
|
||||
* @version 1.1
|
||||
* @date 2022/08/07
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
*
|
||||
* @copyright Copyright (c) 2022 miaow
|
||||
*
|
||||
* @par Changelog:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2022/06/09 <td>1.0 <td>miaow <td>Write this file
|
||||
* <tr><td>2022/08/07 <td>1.1 <td>miaow <td>Add ignore_row_num to fifo_dev_write_frame
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include <fifo_dev.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <common.h>
|
||||
#include <fcntl.h>
|
||||
#include <host_computer.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <data_filter.h>
|
||||
|
||||
#define FIFO_CMD_FUNCTION_CLEAR 1
|
||||
#define FIFO_CMD_FUNCTION_PADDING 2
|
||||
#define FIFO_CMD_GET_EMPTYCOUNT 3
|
||||
|
||||
static int fifo_dev_fd = -1;
|
||||
static char perror_buffer[128];
|
||||
|
||||
/**
|
||||
* @brief Initialize the hardware fifo
|
||||
* @note This function just open the file descriptor of the hardware fifo
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int fifo_dev_init()
|
||||
{
|
||||
fifo_dev_fd = open(FIFO_DEV_PATH, O_RDWR);
|
||||
ON_ERROR_RET(fifo_dev_fd, "", "", -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the count of read operation when the fifo is empty.
|
||||
* @note The empty read count will be set to zero at fifo_dev_clear() only.
|
||||
* @return >=0 - success, other - error
|
||||
*/
|
||||
int fifo_dev_get_emptycount()
|
||||
{
|
||||
int count;
|
||||
int res = ioctl(fifo_dev_fd, _IOR('D', FIFO_CMD_GET_EMPTYCOUNT, 0), &count);
|
||||
|
||||
ON_ERROR_RET(res, "", "", -1);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set value to put of a frame.
|
||||
* @param valve_data An array HOST_COMPUTER_PICTURE_COLUMN_BYTES bytes * HOST_COMPUTER_PICTURE_ROW_NUM rows.
|
||||
* @param ignore_row_num Remove the ignore_row_num rows at the beginning of the frame. range: [0, HOST_COMPUTER_PICTURE_BYTES)
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int fifo_dev_write_frame(void *valve_data, int ignore_row_num)
|
||||
{
|
||||
ssize_t size;
|
||||
char *valve_to_write = (char *)valve_data + ignore_row_num * HOST_COMPUTER_PICTURE_COLUMN_BYTES;
|
||||
int size_to_write = HOST_COMPUTER_PICTURE_COLUMN_BYTES * (HOST_COMPUTER_PICTURE_ROW_NUM - ignore_row_num);
|
||||
|
||||
size = write(fifo_dev_fd, valve_to_write, size_to_write);
|
||||
int res = -(size < size_to_write);
|
||||
ON_ERROR_RET(res, "size=", "", -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set value to put of a row.
|
||||
* @param valve_data An array 32bytes.
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int fifo_dev_write_row(void *valve_data)
|
||||
{
|
||||
ssize_t size = write(fifo_dev_fd, valve_data, 32);
|
||||
int res = -(size < 32);
|
||||
ON_ERROR_RET(res, "size=", "", -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Flush and clear the hardware fifo.
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int fifo_dev_clear()
|
||||
{
|
||||
int res = ioctl(fifo_dev_fd, _IOW('D', FIFO_CMD_FUNCTION_CLEAR, 0));
|
||||
ON_ERROR_RET(res, "", "", -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write `count` zero-items to the haredware fifo, which acts as delay time.
|
||||
* @param count Count of zero-items to write.
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int fifo_dev_write_delay(uint32_t count)
|
||||
{
|
||||
int res = ioctl(fifo_dev_fd, _IOW('D', FIFO_CMD_FUNCTION_PADDING, 0), count);
|
||||
|
||||
ON_ERROR_RET(res, "", "", -1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the count of items in the hardware fifo.
|
||||
* @note An item from hardware fifo is of 256 bits in size, aka. 32 bytes, 8 integers
|
||||
* @return >=0 - success, other - error
|
||||
*/
|
||||
int fifo_dev_get_count()
|
||||
{
|
||||
uint32_t fifo_item_count;
|
||||
ssize_t size = read(fifo_dev_fd, &fifo_item_count, sizeof(fifo_item_count));
|
||||
|
||||
if (size != sizeof(fifo_item_count))
|
||||
ON_ERROR(-1, "size=", "");
|
||||
|
||||
return fifo_item_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the hardware fifo.
|
||||
* @note This function just close the file descriptor of the hardware fifo.
|
||||
* @return 0 - success, -1 - error
|
||||
*/
|
||||
int fifo_dev_deinit()
|
||||
{
|
||||
int res = close(fifo_dev_fd);
|
||||
|
||||
ON_ERROR_RET(res, "", "", -1);
|
||||
return 0;
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
/**
|
||||
* @file fifo_dev.h
|
||||
* @brief Operate the hardware fifo with Linux application
|
||||
* @details Call fifo_dev_init() paired with fifo_dev_deinit() as their names imply, fifo_dev_write_xxx() can be executed several times to operate the hardware fifo between fifo_dev_init() and fifo_dev_deinit()
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
* @author miaow (3703781@qq.com)
|
||||
* @version 1.1
|
||||
* @date 2022/08/07
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
*
|
||||
* @copyright Copyright (c) 2022 miaow
|
||||
*
|
||||
* @par Changelog:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2022/06/09 <td>1.0 <td>miaow <td>Write this file
|
||||
* <tr><td>2022/08/07 <td>1.1 <td>miaow <td>Add ignore_row_num to fifo_dev_write_frame
|
||||
* </table>
|
||||
*/
|
||||
#ifndef __FIFO_DEV_H
|
||||
#define __FIFO_DEV_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FIFO_DEV_PATH "/dev/fifo"
|
||||
|
||||
int fifo_dev_init(void);
|
||||
int fifo_dev_get_emptycount(void);
|
||||
int fifo_dev_write_frame(void *valve_data, int ignore_row_num);
|
||||
int fifo_dev_clear(void);
|
||||
int fifo_dev_write_delay(uint32_t count);
|
||||
int fifo_dev_write_row(void *valve_data);
|
||||
int fifo_dev_get_count(void);
|
||||
|
||||
int fifo_dev_deinit(void);
|
||||
|
||||
#endif
|
||||
@ -1,18 +1,19 @@
|
||||
/**
|
||||
* @file host_computer.c
|
||||
* @brief Commnunicate with host computer. Protocal is described in hostcomputer通信协议.md
|
||||
* @brief Commnunicate with host computer. Protocal is described in 下位机和上位机通信协议 V1.4
|
||||
* @author miaow (3703781@qq.com)
|
||||
* @version 1.1
|
||||
* @date 2022/08/06
|
||||
* @version 1.2
|
||||
* @date 2023/05/07
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
*
|
||||
* @copyright Copyright (c) 2022 miaow
|
||||
* @copyright Copyright (c) 2023 miaow
|
||||
*
|
||||
* @par Changelog:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2022/01/16 <td>1.0 <td>miaow <td>Write this file
|
||||
* <tr><td>2022/08/06 <td>1.1 <td>miaow <td>Add fifob
|
||||
* <tr><td>2023/05/07 <td>1.2 <td>miaow <td>Port to b03 branch
|
||||
* </table>
|
||||
*/
|
||||
#include <host_computer.h>
|
||||
@ -24,11 +25,14 @@
|
||||
#include <pthread.h>
|
||||
#include <common.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <fifo_dev.h>
|
||||
#include <encoder_dev.h>
|
||||
#include <data_filter.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
|
||||
static char perror_buffer[128];
|
||||
/**
|
||||
@ -41,33 +45,42 @@ typedef struct
|
||||
int need_exit; // The flag variable to indicate whether to exit the loop_thread in this file
|
||||
pthread_t loop_thread; // The main routine of this module, which parses commands and data from host, puts them into the queue
|
||||
pthread_mutex_t loop_thread_mutex; // The mutex for loop_thread
|
||||
pthread_mutex_t is_connected_mutex;
|
||||
timer_t heartbeat_timer;
|
||||
} hostcomputer_t;
|
||||
|
||||
static hostcomputer_t _global_structure;
|
||||
void *loop_thread_func(void *param);
|
||||
void heartbeat_timer_func(__sigval_t param);
|
||||
|
||||
/**
|
||||
* @brief Pre initialize host computer module
|
||||
* @param data_q A pointer to the queue storing the valve data from host computer
|
||||
* @param cmd_q A pointer to the queue storing the cmd from host computer
|
||||
* @param cmd_q A pointer#include <sys/time.h> to the queue storing the cmd from host computer
|
||||
* @return 0 - success
|
||||
*/
|
||||
int hostcomputer_init(queue_uint64_msg_t *cmd_q)
|
||||
{
|
||||
struct sigevent evp;
|
||||
struct itimerspec ts;
|
||||
_global_structure.cmd_q = cmd_q;
|
||||
|
||||
pthread_mutex_init(&_global_structure.loop_thread_mutex, NULL);
|
||||
pthread_mutex_init(&_global_structure.is_connected_mutex, NULL);
|
||||
pthread_create(&_global_structure.loop_thread, NULL, loop_thread_func, NULL);
|
||||
|
||||
memset(&evp, 0, sizeof(evp));
|
||||
evp.sigev_value.sival_ptr = &_global_structure.heartbeat_timer;
|
||||
evp.sigev_notify = SIGEV_THREAD;
|
||||
evp.sigev_notify_function = heartbeat_timer_func;
|
||||
timer_create(CLOCK_REALTIME, &evp, &_global_structure.heartbeat_timer);
|
||||
ts.it_interval.tv_sec = 3;
|
||||
ts.it_interval.tv_nsec = 0;
|
||||
ts.it_value.tv_sec = 3;
|
||||
ts.it_value.tv_nsec = 0;
|
||||
timer_settime(_global_structure.heartbeat_timer, TIMER_ABSTIME, &ts, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_error(int fd)
|
||||
{
|
||||
write(fd, "error", 5);
|
||||
printf("\r\nerror sent\r\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive `size` bytes from a socket. If no more bytes are available at the socket, this function return -1 when timeout reaches.
|
||||
* @param fd The socket fd
|
||||
@ -105,7 +118,9 @@ static int is_connected(int sock_fd)
|
||||
{
|
||||
struct tcp_info info;
|
||||
int len = sizeof(info);
|
||||
pthread_mutex_lock(&_global_structure.is_connected_mutex);
|
||||
getsockopt(sock_fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
|
||||
pthread_mutex_unlock(&_global_structure.is_connected_mutex);
|
||||
return info.tcpi_state == TCP_ESTABLISHED;
|
||||
}
|
||||
|
||||
@ -117,16 +132,12 @@ static int is_connected(int sock_fd)
|
||||
void *loop_thread_func(void *param)
|
||||
{
|
||||
// printf("loop thread in %s start\r\n", __FILE__);
|
||||
int need_exit = 0, frame_count = 0, error_sent = 0;
|
||||
int std_count, empty_packets_num = 0;
|
||||
int empty_count_initial = 0;
|
||||
int empty_count_processed = 0;
|
||||
int need_exit = 0;
|
||||
char pre;
|
||||
uint16_t n_bytes;
|
||||
uint32_t n_bytes;
|
||||
char type[2];
|
||||
char data[HOST_COMPUTER_PICTURE_BYTES + 1];
|
||||
char data[20];
|
||||
char check[2];
|
||||
datafilter_typedef datafilter;
|
||||
|
||||
while (!need_exit)
|
||||
{
|
||||
@ -136,6 +147,7 @@ void *loop_thread_func(void *param)
|
||||
// reconnect if not connected
|
||||
if (!is_connected(_global_structure.socket_fd))
|
||||
{
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_STOP);
|
||||
_global_structure.socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct timeval timeout = {.tv_sec = 10, .tv_usec = 0};
|
||||
setsockopt(_global_structure.socket_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
@ -158,7 +170,6 @@ void *loop_thread_func(void *param)
|
||||
}
|
||||
|
||||
// =======================parse the protocol=========================================
|
||||
|
||||
if (recvn(_global_structure.socket_fd, (char *)&pre, 1) > 1)
|
||||
{
|
||||
// close(_global_structure.socket_fd);
|
||||
@ -172,17 +183,17 @@ void *loop_thread_func(void *param)
|
||||
// fflush(stdout);
|
||||
continue;
|
||||
}
|
||||
if (recvn(_global_structure.socket_fd, (char *)&n_bytes, 2) != 2)
|
||||
if (recvn(_global_structure.socket_fd, (char *)&n_bytes, 4) != 4)
|
||||
{
|
||||
// close(_global_structure.socket_fd);
|
||||
printf("n_bytes_len!=2\r\n");
|
||||
printf("n_bytes_len!=4\r\n");
|
||||
continue;
|
||||
}
|
||||
n_bytes = ntohs(n_bytes);
|
||||
if (n_bytes != HOST_COMPUTER_PICTURE_BYTES + 2 && n_bytes > 10)
|
||||
n_bytes = ntohl(n_bytes);
|
||||
if (n_bytes != 10 && n_bytes != 3)
|
||||
{
|
||||
// close(_global_structure.socket_fd);
|
||||
printf("n_bytes> 10 and n_bytes!=HOST_COMPUTER_PICTURE_BYTES + 2\r\n");
|
||||
printf("n_bytes is not 10 or 3\r\n");
|
||||
continue;
|
||||
}
|
||||
if (recvn(_global_structure.socket_fd, (char *)type, 2) != 2)
|
||||
@ -220,96 +231,9 @@ void *loop_thread_func(void *param)
|
||||
|
||||
// =======================parse the commands=========================================
|
||||
// commands are reformed as an uint64_t, 0x--------xxxxxxxx, where `-` refers its paramter and `x` is HOSTCOMPUTER_CMD
|
||||
if (type[0] == 'd' && type[1] == 'a')
|
||||
{
|
||||
/*
|
||||
int current_count = fifo_dev_get_count();
|
||||
int current_count_filtered = datafilter_calculate(&datafilter_a, current_count);
|
||||
|
||||
if (++frame_count_a > HOST_COMPUTER_BEGINNING_PICTURES_IGNORE_NUM)
|
||||
{
|
||||
fifo_dev_write_frame(data, 0);
|
||||
}
|
||||
int added_count = fifo_dev_get_count();
|
||||
printf("before %d->after %d, diff %d, filter %d\r\n", current_count, added_count, added_count - current_count, current_count_filtered);
|
||||
*/
|
||||
//=================================================
|
||||
|
||||
int current_count, current_count_filtered, diff_count, empty_count_to_process;
|
||||
if (n_bytes - 2 != HOST_COMPUTER_PICTURE_BYTES)
|
||||
{
|
||||
printf("n_bytes-2!=%d\r\n", HOST_COMPUTER_PICTURE_BYTES);
|
||||
continue;
|
||||
}
|
||||
// get the item counts and its slide average value
|
||||
current_count = fifo_dev_get_count();
|
||||
current_count_filtered = datafilter_calculate(&datafilter, current_count);
|
||||
frame_count++;
|
||||
if (frame_count == HOST_COMPUTER_PICTURES_BEGINNING_IGNORE_NUM + 1)
|
||||
{
|
||||
empty_count_initial = fifo_dev_get_emptycount();
|
||||
}
|
||||
else if (frame_count == 100) // record the normal item counts in fifo
|
||||
{
|
||||
std_count = current_count_filtered;
|
||||
}
|
||||
if (frame_count > HOST_COMPUTER_PICTURES_BEGINNING_IGNORE_NUM)
|
||||
{
|
||||
// do nothing at first two frames, because that the first frame is set to zero and was concatenated to the delay frame before
|
||||
// in case of late arrival of the first two frames.
|
||||
empty_count_to_process = fifo_dev_get_emptycount() - empty_count_initial - empty_count_processed;
|
||||
if (empty_count_to_process >= HOST_COMPUTER_PICTURE_ROW_NUM)
|
||||
{
|
||||
empty_count_processed += HOST_COMPUTER_PICTURE_ROW_NUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
fifo_dev_write_frame(data, empty_count_to_process);
|
||||
empty_count_processed += empty_count_to_process;
|
||||
}
|
||||
}
|
||||
if (current_count == 0)
|
||||
empty_packets_num++;
|
||||
else
|
||||
empty_packets_num = 0;
|
||||
|
||||
|
||||
// print fifo status
|
||||
printf("a ||| %d | cnt %d | avgcnt %d | stdcnt %d",
|
||||
frame_count, current_count, current_count_filtered, std_count);
|
||||
fflush(stdout);
|
||||
// if (empty_count_to_process)
|
||||
printf(" ||| initemp %d | toprc %d | prcd %d\r\n", empty_count_initial,
|
||||
empty_count_to_process, empty_count_processed);
|
||||
// else
|
||||
// printf("\r\n");
|
||||
// if the item counts changes a lot compared with normal counts,
|
||||
// meaning something goes wrong, a message will send to the hostcomputer
|
||||
diff_count = current_count_filtered - std_count;
|
||||
int diff_cond = diff_count > 250 || diff_count < -250;
|
||||
int frame_count_cond = frame_count > 100;
|
||||
int empty_packets_cond = empty_packets_num >= 5;
|
||||
|
||||
if (((frame_count_cond && diff_cond) || empty_packets_cond) && !error_sent)
|
||||
{
|
||||
error_sent = 1;
|
||||
printf("\r\na ||| avgcnt %d | %d larger", current_count_filtered, diff_count);
|
||||
fflush(stdout);
|
||||
send_error(_global_structure.socket_fd);
|
||||
}
|
||||
}
|
||||
else if (type[0] == 's' && type[1] == 't')
|
||||
if (type[0] == 's' && type[1] == 't')
|
||||
{
|
||||
// printf("Start put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
frame_count = 0;
|
||||
error_sent = 0;
|
||||
empty_packets_num = 0;
|
||||
std_count = 0;
|
||||
datafilter_deinit(&datafilter);
|
||||
datafilter_init(&datafilter, 20);
|
||||
empty_count_processed = 0;
|
||||
empty_count_initial = 0;
|
||||
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_START);
|
||||
}
|
||||
else if (type[0] == 's' && type[1] == 'p')
|
||||
@ -317,47 +241,46 @@ void *loop_thread_func(void *param)
|
||||
// printf("Stop put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_STOP);
|
||||
}
|
||||
else if (type[0] == 't' && type[1] == 'e')
|
||||
{
|
||||
// printf("Test put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_TEST);
|
||||
}
|
||||
else if (type[0] == 't' && type[1] == 't')
|
||||
{
|
||||
// printf("Test put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_STOP_TEST);
|
||||
}
|
||||
else if (type[0] == 'p' && type[1] == 'o')
|
||||
{
|
||||
// printf("Power on put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_POWERON);
|
||||
}
|
||||
else if (type[0] == 's' && type[1] == 'c')
|
||||
else if (type[0] == 'p' && type[1] == 'a')
|
||||
{
|
||||
// printf("Set camera triggle pulse count put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT);
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_A);
|
||||
}
|
||||
else if (type[0] == 's' && type[1] == 'v')
|
||||
else if (type[0] == 'p' && type[1] == 'b')
|
||||
{
|
||||
// printf("Set valve pulse count put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_SETVALVETRIGPULSECOUNT);
|
||||
// printf("Set camera triggle pulse count put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_B);
|
||||
}
|
||||
else if ((type[0] == 's' && type[1] == 'd'))
|
||||
else if (type[0] == 'p' && type[1] == 'c')
|
||||
{
|
||||
// printf("Set camera to valve pulse count put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_SETCAMERATOVALVEPULSECOUNT);
|
||||
// printf("Set camera triggle pulse count put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_C);
|
||||
}
|
||||
else if (type[0] == 'p' && type[1] == 'd')
|
||||
{
|
||||
// printf("Set camera triggle pulse count put to cmd queue, param:%d\r\n", (int)atoll(data));
|
||||
queue_uint64_put(_global_structure.cmd_q, (atoll(data) << 32) | HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_D);
|
||||
}
|
||||
}
|
||||
printf("loop thread in %s exit\r\n", __FILE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void heartbeat_timer_func(__sigval_t param)
|
||||
{
|
||||
static uint8_t heartbeat_packet[] = {0xaa, 0x00, 0x00, 0x00, 0x03, 'h', 'b', 0xff, 0xff, 0xff, 0xbb};
|
||||
if (is_connected(_global_structure.socket_fd))
|
||||
write(_global_structure.socket_fd, heartbeat_packet, sizeof(heartbeat_packet));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize and release resources used by host computer module
|
||||
* @return int
|
||||
*/
|
||||
int hostcomputer_deinit()
|
||||
{
|
||||
timer_delete(_global_structure.heartbeat_timer);
|
||||
|
||||
pthread_mutex_lock(&_global_structure.loop_thread_mutex);
|
||||
_global_structure.need_exit = 1;
|
||||
pthread_mutex_unlock(&_global_structure.loop_thread_mutex);
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
/**
|
||||
* @file host_computer.h
|
||||
* @brief Commnunicate with host computer. Protocal is described in hostcomputer通信协议.md
|
||||
* @brief Commnunicate with host computer. Protocal is described in 下位机和上位机通信协议 V1.4
|
||||
* @author miaow (3703781@qq.com)
|
||||
* @version 1.1
|
||||
* @date 2022/08/6
|
||||
* @version 1.2
|
||||
* @date 2023/05/07
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
*
|
||||
* @copyright Copyright (c) 2022 miaow
|
||||
* @copyright Copyright (c) 2023 miaow
|
||||
*
|
||||
* @par Changelog:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2022/01/16 <td>1.0 <td>miaow <td>Write this file
|
||||
* <tr><td>2022/08/06 <td>1.1 <td>miaow <td>Add fifob
|
||||
* <tr><td>2023/05/07 <td>1.2 <td>miaow <td>Port to b03 branch
|
||||
* </table>
|
||||
*/
|
||||
#ifndef __HOST_COMPUTER_H
|
||||
@ -21,27 +23,20 @@
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define HOST_COMPUTER_IP "192.168.10.8"
|
||||
#define HOST_COMPUTER_IP "192.168.2.125"
|
||||
#define HOST_COMPUTER_PORT 13452
|
||||
#define HOST_COMPUTER_PICTURE_ROW_NUM 1024
|
||||
#define HOST_COMPUTER_PICTURE_COLUMN_NUM 256
|
||||
#define HOST_COMPUTER_PICTURE_COLUMN_BYTES (HOST_COMPUTER_PICTURE_COLUMN_NUM / 8)
|
||||
#define HOST_COMPUTER_PICTURE_BYTES (HOST_COMPUTER_PICTURE_COLUMN_BYTES * HOST_COMPUTER_PICTURE_ROW_NUM)
|
||||
#define HOST_COMPUTER_PICTURES_BEGINNING_IGNORE_NUM 1
|
||||
|
||||
/**
|
||||
* @brief The commonds, ref 通信协议
|
||||
* @brief The commonds, ref 下位机和上位机通信协议V1.4
|
||||
*/
|
||||
enum HOSTCOMPUTER_CMD
|
||||
{
|
||||
HOSTCOMPUTER_CMD_START = 2,
|
||||
HOSTCOMPUTER_CMD_STOP = 3,
|
||||
HOSTCOMPUTER_CMD_TEST = 4,
|
||||
HOSTCOMPUTER_CMD_POWERON = 5,
|
||||
HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT = 6,
|
||||
HOSTCOMPUTER_CMD_SETVALVETRIGPULSECOUNT = 7,
|
||||
HOSTCOMPUTER_CMD_SETCAMERATOVALVEPULSECOUNT = 8,
|
||||
HOSTCOMPUTER_CMD_STOP_TEST = 9
|
||||
HOSTCOMPUTER_CMD_START = 1,
|
||||
HOSTCOMPUTER_CMD_STOP = 2,
|
||||
HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_A = 3,
|
||||
HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_B = 4,
|
||||
HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_C = 5,
|
||||
HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_D = 6,
|
||||
};
|
||||
|
||||
int hostcomputer_init(queue_uint64_msg_t *cmd_q);
|
||||
|
||||
@ -2,19 +2,20 @@
|
||||
* @file main.c
|
||||
* @brief Excute the commands from host_computer
|
||||
* @author miaow (3703781@qq.com)
|
||||
* @version 1.0
|
||||
* @date 2022/06/12
|
||||
* @version 1.2
|
||||
* @date 2023/05/27
|
||||
* @mainpage github.com/NanjingForestryUniversity
|
||||
*
|
||||
* @copyright Copyright (c) 2022 miaow
|
||||
* @copyright Copyright (c) 2023 miaow
|
||||
*
|
||||
* @par Changelog:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2022/06/12 <td>1.0 <td>miaow <td>Write this file
|
||||
* <tr><td>2023/05/07 <td>1.1 <td>miaow <td>Port to b03
|
||||
* <tr><td>2023/05/27 <td>1.2 <td>miaow <td>Fix bug caused by the missing encoder_dev_set_clrmod()
|
||||
* </table>
|
||||
*/
|
||||
#include <fifo_dev.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <math.h>
|
||||
@ -25,12 +26,6 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SET_VALVE_ONLY_N_ON(u32_buf, n) \
|
||||
bzero(u32_buf, sizeof(u32_buf)); \
|
||||
SET_VALVE_N_ON(u32_buf, n)
|
||||
#define SET_VALVE_N_ON(u32_buf, n) u32_buf[n / 32] = 1 << (n % 32)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Value of state machine
|
||||
*/
|
||||
@ -43,9 +38,19 @@ typedef enum
|
||||
queue_uint64_msg_t cmd_queue = {0};
|
||||
|
||||
static status_enum_t status = SLEEPING;
|
||||
static int camera_trigger_pulse_count = 1200;
|
||||
static int valve_trigger_pulse_count = 120;
|
||||
static int camera_to_valve_pulse_count = 500;
|
||||
typedef struct
|
||||
{
|
||||
uint32_t a;
|
||||
uint32_t b;
|
||||
uint32_t c;
|
||||
uint32_t d;
|
||||
} camera_trigger_pulse_count_typedef;
|
||||
|
||||
camera_trigger_pulse_count_typedef camera_trigger_pulse_count = {
|
||||
.a = 100,
|
||||
.b = 100,
|
||||
.c = 100,
|
||||
.d = 100};
|
||||
|
||||
void process_cmd(uint64_t *cmd);
|
||||
|
||||
@ -57,51 +62,19 @@ void process_cmd(uint64_t *cmd);
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint64_t cmd;
|
||||
queue_uint64_init(&cmd_queue, 9999);
|
||||
|
||||
// Initialize drivers and clear all caches
|
||||
encoder_dev_init();
|
||||
encoder_dev_set_trigmod(ENCODER_TRIG_MODE_INTERNEL);
|
||||
encoder_dev_set_divide(2, 8);
|
||||
fifo_dev_init();
|
||||
encoder_dev_set_divide(8, 8, 8, 8);
|
||||
|
||||
//==test encoder================================================================
|
||||
// fifo_dev_init();
|
||||
// encoder_dev_set_trigmod(ENCODER_TRIG_MODE_EXTERNEL);
|
||||
// encoder_dev_set_divide(4, 8);
|
||||
// int a = 1;
|
||||
// while (a)
|
||||
// {
|
||||
// printf("input a\r\n");
|
||||
// scanf("%d", &a);
|
||||
// printf("a=%d\r\n\r\n\r\n", a);
|
||||
// }
|
||||
// encoder_dev_set_trigmod(ENCODER_TRIG_MODE_INTERNEL);
|
||||
// encoder_dev_deinit();
|
||||
// queue_uint64_deinit(&cmd_queue);
|
||||
// return 0;
|
||||
|
||||
//==test fifo================================================================
|
||||
// char data[HOST_COMPUTER_PICTURE_COLUMN_BYTES * HOST_COMPUTER_PICTURE_ROW_NUM + 1];
|
||||
// fifo_dev_init();
|
||||
// fifo_dev_write_frame(data);
|
||||
// printf("%d\r\n", fifo_dev_get_count());
|
||||
// fifo_dev_write_frame(data);
|
||||
// printf("%d\r\n", fifo_dev_get_count());
|
||||
// fifo_dev_clear();
|
||||
// printf("%d\r\n", fifo_dev_get_count());
|
||||
// fifo_dev_deinit();
|
||||
// encoder_dev_deinit();
|
||||
// return 0;
|
||||
//==================================================================
|
||||
|
||||
fifo_dev_clear();
|
||||
hostcomputer_init(&cmd_queue);
|
||||
printf("\r\n>>>>>\r\nstatus==SLEEPING\r\n<<<<<\r\n\r\n");
|
||||
uint64_t cmd;
|
||||
int TRUE = 1;
|
||||
|
||||
// Read from the cmd_queue and excute the command every 100ms
|
||||
while (TRUE)
|
||||
while (1)
|
||||
{
|
||||
if (queue_uint64_get(&cmd_queue, &cmd) == 0)
|
||||
process_cmd(&cmd);
|
||||
@ -110,11 +83,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Never run here
|
||||
hostcomputer_deinit();
|
||||
fifo_dev_clear();
|
||||
encoder_dev_set_divide(2, 8);
|
||||
encoder_dev_set_divide(100,100,100,100);
|
||||
encoder_dev_virtual_trig(20);
|
||||
|
||||
fifo_dev_deinit();
|
||||
encoder_dev_set_trigmod(ENCODER_TRIG_MODE_INTERNEL);
|
||||
encoder_dev_deinit();
|
||||
queue_uint64_deinit(&cmd_queue);
|
||||
@ -138,70 +109,37 @@ void process_cmd(uint64_t *cmd)
|
||||
{
|
||||
// Before running, clear the hardware fifo and hardware encoder. Then, the two dividers and delay value should be set.
|
||||
// Also, the hareware encoder is expected to receiving pluse of encoder: the EXTERNAL mode
|
||||
fifo_dev_clear();
|
||||
encoder_dev_flush();
|
||||
|
||||
encoder_dev_set_divide(valve_trigger_pulse_count, camera_trigger_pulse_count);
|
||||
fifo_dev_write_delay(camera_to_valve_pulse_count + HOST_COMPUTER_PICTURE_ROW_NUM * HOST_COMPUTER_PICTURES_BEGINNING_IGNORE_NUM);
|
||||
encoder_dev_set_divide(camera_trigger_pulse_count.a,
|
||||
camera_trigger_pulse_count.b,
|
||||
camera_trigger_pulse_count.c,
|
||||
camera_trigger_pulse_count.d);
|
||||
|
||||
encoder_dev_set_trigmod(ENCODER_TRIG_MODE_EXTERNEL);
|
||||
printf("\r\n>>>>>\r\nstatus==RUNNING\r\ncamera_trigger_pulse_count=%d\r\nvalve_trigger_pulse_count=%d\r\n"
|
||||
"camera_to_valve_pulse_count=%d\r\n<<<<<\r\n\r\n", camera_trigger_pulse_count,
|
||||
valve_trigger_pulse_count, camera_to_valve_pulse_count + HOST_COMPUTER_PICTURE_ROW_NUM * HOST_COMPUTER_PICTURES_BEGINNING_IGNORE_NUM);
|
||||
encoder_dev_set_clrmod(ENCODER_CLEAR_MODE_BOTH);
|
||||
printf("\r\n>>>>>\r\nstatus==RUNNING\r\ncamera_a=%d\r\ncamera_b=%d\r\ncamera_c=%d\r\ncamera_d=%d\r\n<<<<<\r\n\r\n",
|
||||
camera_trigger_pulse_count.a,
|
||||
camera_trigger_pulse_count.b,
|
||||
camera_trigger_pulse_count.c,
|
||||
camera_trigger_pulse_count.d);
|
||||
status = RUNNING;
|
||||
}
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_TEST)
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_A)
|
||||
{
|
||||
uint32_t row_data[8] = {0};
|
||||
// When to excute TEST cmd (aka testing the valve), hardware fifo and hardware encoder should be cleared.
|
||||
// A new combination of divider is set: 2 for both valve and camera, for less virtual pluse is needed to triggle valve in INTERNAL mode.
|
||||
// Note that camera can be triggled during testing.
|
||||
fifo_dev_clear();
|
||||
encoder_dev_flush();
|
||||
encoder_dev_set_trigmod(ENCODER_TRIG_MODE_INTERNEL);
|
||||
encoder_dev_set_divide(2, 8); // fifo out every 8/4=2 cycle, valveboard operate every 2 cycle
|
||||
|
||||
// A parameter below 256 represents a single shot, the value of parameter indicates the valve to triggle.
|
||||
if (tmp_data < 256)
|
||||
{
|
||||
SET_VALVE_ONLY_N_ON(row_data, tmp_data);
|
||||
fifo_dev_write_row(row_data);
|
||||
// delay for 15000 us and turn off the valve
|
||||
encoder_dev_virtual_trig(2);
|
||||
usleep(15000);
|
||||
encoder_dev_virtual_trig(2);
|
||||
camera_trigger_pulse_count.a = tmp_data;
|
||||
}
|
||||
// 257 represents triggle valve from NO.1 to 256 sequenctially. This loop blocks for 25.7s.
|
||||
else if (tmp_data == 257)
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_B)
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
camera_trigger_pulse_count.b = tmp_data;
|
||||
}
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_C)
|
||||
{
|
||||
SET_VALVE_ONLY_N_ON(row_data, i);
|
||||
fifo_dev_write_row(row_data);
|
||||
bzero(&row_data, sizeof(row_data));
|
||||
fifo_dev_write_row(row_data);
|
||||
// printf("%d,%d\r\n", fifo_dev_get_count(), fifob_dev_get_count());
|
||||
camera_trigger_pulse_count.c = tmp_data;
|
||||
}
|
||||
for (int i = 0; i < 257; i++)
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT_D)
|
||||
{
|
||||
encoder_dev_virtual_trig(2);
|
||||
usleep(15000);
|
||||
encoder_dev_virtual_trig(2);
|
||||
usleep(100000 - 15000);
|
||||
// printf("%d,%d\r\n", fifo_dev_get_count(), fifob_dev_get_count());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_SETCAMERATRIGPULSECOUNT)
|
||||
{
|
||||
camera_trigger_pulse_count = tmp_data;
|
||||
}
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_SETVALVETRIGPULSECOUNT)
|
||||
{
|
||||
valve_trigger_pulse_count = tmp_data;
|
||||
}
|
||||
else if (tmp_cmd == HOSTCOMPUTER_CMD_SETCAMERATOVALVEPULSECOUNT)
|
||||
{
|
||||
camera_to_valve_pulse_count = tmp_data;
|
||||
camera_trigger_pulse_count.d = tmp_data;
|
||||
}
|
||||
}
|
||||
// Only in RUNNING state, the lower machine responds to STOP command.
|
||||
@ -209,12 +147,9 @@ void process_cmd(uint64_t *cmd)
|
||||
{
|
||||
if (tmp_cmd == HOSTCOMPUTER_CMD_STOP)
|
||||
{
|
||||
// Clear hardware fifo.
|
||||
// 10 virtual triggles in internal mode ensure valve is turned off.
|
||||
// Hardware encoder is flushed for a fresh start.
|
||||
fifo_dev_clear();
|
||||
encoder_dev_set_trigmod(ENCODER_TRIG_MODE_INTERNEL);
|
||||
encoder_dev_set_divide(4, 4);
|
||||
encoder_dev_set_divide(4, 4, 4, 4);
|
||||
encoder_dev_virtual_trig(20);
|
||||
encoder_dev_flush();
|
||||
status = SLEEPING;
|
||||
|
||||
@ -1 +1 @@
|
||||
1.2
|
||||
1.3
|
||||
@ -188,12 +188,12 @@ static long encoder_ioctl(struct file *fp, unsigned int cmd, unsigned long tmp)
|
||||
// 3. 恢复为原来的状态和模式
|
||||
writel(data, encoder_cr_addr);
|
||||
}
|
||||
else if (cmd_parsed == ENCODER_CMD_CLEAR_MODE_INTERNAL)
|
||||
else if (cmd_parsed == ENCODER_CMD_CLEAR_MODE_BOTH)
|
||||
{
|
||||
// 设为允许内部和外部信号清除缓存
|
||||
writel(data & ~ENCODER_CR_ICO_MASK, encoder_cr_addr);
|
||||
}
|
||||
else if (cmd_parsed == ENCODER_CMD_CLEAR_MODE_BOTH)
|
||||
else if (cmd_parsed == ENCODER_CMD_CLEAR_MODE_INTERNAL)
|
||||
{
|
||||
// 设为仅允许内部清除缓存
|
||||
writel(data | ENCODER_CR_ICO_MASK, encoder_cr_addr);
|
||||
|
||||
@ -57,8 +57,6 @@ int encoder_dev_init()
|
||||
|
||||
/**
|
||||
* @brief Set the two divider in the hareware encoder unit.
|
||||
* @param valve_divide the frequency division factor between the encoder signal and valve output
|
||||
* Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter
|
||||
* @param camera_a_divide the frequency division factor between the encoder signal and camera a triggle signal
|
||||
* Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter
|
||||
* @param camera_b_divide the frequency division factor between the encoder signal and camera b triggle signal
|
||||
@ -69,14 +67,13 @@ int encoder_dev_init()
|
||||
* Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter
|
||||
* @return 0 - success, other - error
|
||||
*/
|
||||
int encoder_dev_set_divide(int valve_divide,
|
||||
int camera_a_divide,
|
||||
int encoder_dev_set_divide(int camera_a_divide,
|
||||
int camera_b_divide,
|
||||
int camera_c_divide,
|
||||
int camera_d_divide)
|
||||
{
|
||||
if (valve_divide != ENCODER_DEV_DIVIDE_NOT_TO_SET)
|
||||
encoder_dev_divide_value_structure.valve_divide_value = valve_divide;
|
||||
encoder_dev_divide_value_structure.valve_divide_value = 100;
|
||||
if (camera_a_divide != ENCODER_DEV_DIVIDE_NOT_TO_SET)
|
||||
encoder_dev_divide_value_structure.camera_a_divide_value = camera_a_divide;
|
||||
if (camera_b_divide != ENCODER_DEV_DIVIDE_NOT_TO_SET)
|
||||
|
||||
@ -37,8 +37,7 @@ typedef enum
|
||||
ENCODER_CLEAR_MODE_INTERNAL = 201
|
||||
} encoder_dev_clear_mode_enum;
|
||||
|
||||
int encoder_dev_set_divide(int valve_divide,
|
||||
int camera_a_divide,
|
||||
int encoder_dev_set_divide(int camera_a_divide,
|
||||
int camera_b_divide,
|
||||
int camera_c_divide,
|
||||
int camera_d_divide);
|
||||
|
||||
@ -1 +1 @@
|
||||
1.5
|
||||
1.6
|
||||
Loading…
Reference in New Issue
Block a user