/** * @file main.c * @brief Excute the commands from host_computer * @author miaow (3703781@qq.com) * @version 1.0 * @date 2022/06/12 * @mainpage github.com/NanjingForestryUniversity * * @copyright Copyright (c) 2022 miaow * * @par Changelog: * *
Date Version Author Description *
2022/06/12 1.0 miaow Write this file *
*/ #include #include #include #include #include #include #include #include #include #include #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 */ typedef enum { SLEEPING = 0, RUNNING = 1, } status_enum_t; 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; void process_cmd(uint64_t *cmd); /** * @brief Read from the cmd_queue and excute the command every 100ms. * @param argc not used * @param argv not used * @return int should not return. */ int main(int argc, char *argv[]) { 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(); //==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) { if (queue_uint64_get(&cmd_queue, &cmd) == 0) process_cmd(&cmd); usleep(1000); } // Never run here hostcomputer_deinit(); fifo_dev_clear(); encoder_dev_set_divide(2, 8); encoder_dev_virtual_trig(20); fifo_dev_deinit(); encoder_dev_set_trigmod(ENCODER_TRIG_MODE_INTERNEL); encoder_dev_deinit(); queue_uint64_deinit(&cmd_queue); return 0; } /** * @brief Excute the command and control the states * @param cmd The command to be excuted */ void process_cmd(uint64_t *cmd) { int tmp_cmd = (int)*cmd; int tmp_data = (int)(*cmd >> 32); // Only in the SLEEPING state, it resbonds to START or TEST command. if (status == SLEEPING) { if (tmp_cmd == HOSTCOMPUTER_CMD_START) { // 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_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); status = RUNNING; } else if (tmp_cmd == HOSTCOMPUTER_CMD_TEST) { 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); } // 257 represents triggle valve from NO.1 to 256 sequenctially. This loop blocks for 25.7s. else if (tmp_data == 257) { for (int i = 0; i < 256; i++) { 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()); } for (int i = 0; i < 257; i++) { 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; } } // Only in RUNNING state, the lower machine responds to STOP command. else if (status == RUNNING) { 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_virtual_trig(20); encoder_dev_flush(); status = SLEEPING; printf("\r\n>>>>>\r\nstatus==SLEEPING\r\n<<<<<\r\n\r\n"); } } }