#include "global.h" #define IO_EXTERN_NUMBER 4 //支持的IO扩展个数 //扩展信息 typedef struct { char *inputs; //输入指针 char *outputs; //输出指针 char input_number; //输入IO个数 char output_number; //输出IO个数 char input_shift; //输入偏移位 char output_shift; //输出偏移位 int missing; //丢包计数 } io_extern_data_t; //#if USE_EXTEND_INOUTPUT static char io_extern_count = 0; //IO扩展个数统计 static char io_extern_input_count = 0; static char io_extern_output_count = 0; static io_extern_data_t io_extern_datas[4]; //IO扩展信息结构体 //==================================================扩展应用程序=========================================// /** * 发送数据生成 * * @author LXZ (070720) * * @param device * @param data * * @return int */ static int slave_on_send(nodelink_device_t *device, unsigned char *data) { int index = 0; int len = 0; io_extern_data_t *extern_dat = device->user_data; data[len++] = 0x01; if (extern_dat->input_shift == 0) { memcpy(&data[len], extern_dat->outputs, (extern_dat->output_number + 7) >> 3); len += (extern_dat->output_number + 7) >> 3; } else { unsigned char dat = 0; int number = (extern_dat->input_number + 7) >> 3; while (index < number) { dat = extern_dat->outputs[index] >> extern_dat->output_shift; dat |= extern_dat->outputs[index + 1] << (8 - extern_dat->output_shift); data[len++] = dat; index++; } } return len; } /** * 接收数据生成 * * @author LXZ (070720) * * @param device * @param data */ static void slave_on_recv(nodelink_device_t *device, unsigned char *data) { int dst_index = 0; int src_index = 0; io_extern_data_t *extern_dat = device->user_data; if (data[0] == 0x01) { dst_index = extern_dat->input_shift; while (src_index < extern_dat->input_number) { if (data[(src_index >> 3) + 1] & (1 << (src_index & 0x07))) { extern_dat->inputs[dst_index >> 3] |= 1 << (dst_index & 0x07); } else { extern_dat->inputs[dst_index >> 3] &= ~(1 << (dst_index & 0x07)); } src_index++; dst_index++; } } } /** * 收发超时 * * @author LXZ (070720) * * @param device */ static void slave_on_timeout(nodelink_device_t *device) { io_extern_data_t *dat = device->user_data; dat->missing++; } static nodelink_device_ops io_extern_ops = { slave_on_recv, slave_on_send, slave_on_timeout }; //=================================================扩展主站APP==============================================// static nodelink_master_t master; static int nl_recv_step = 0; //接收步骤 static int nl_send_step = 0; //发送步骤 static sw_timer_t send_timer; static unsigned char recv_buffer[256]; static unsigned char send_buffer[256]; static int bus_timeout = 0; /** * 主站的回调函数 * * @author LXZ (070720) * * @param master * @param cmd * @param argv */ static void master_callback(nodelink_master_t *master, char cmd, void *argv) { switch (cmd) { case NL_MASTER_EVENT_FOUND_DEVICE: //发现一个扩展模块 { nodelink_device_t *device = (nodelink_device_t *)argv; if (device->model == 1) { //根据型号注册信息 device->user_data = &io_extern_datas[io_extern_count]; device->ops = &io_extern_ops; io_extern_datas[io_extern_count].input_number = 6; io_extern_datas[io_extern_count].inputs = (char *)&io_inputs[((IO_PIN_INPUT_NUMBER + 7) >> 3) + (io_extern_input_count >> 3)]; io_extern_datas[io_extern_count].output_number = 7; io_extern_datas[io_extern_count].outputs = (char *)&io_outputs[((IO_PIN_OUTPUT_NUMBER + 7) >> 3) + (io_extern_output_count >> 3)]; io_extern_datas[io_extern_count].input_shift = io_extern_input_count & 0x07; io_extern_datas[io_extern_count].output_shift = io_extern_output_count & 0x07; io_extern_datas[io_extern_count].missing = 0; io_extern_input_count += io_extern_datas[io_extern_count].input_number; io_extern_output_count += io_extern_datas[io_extern_count].output_number; io_extern_count++; } } break; } } //#endif /** * 扩展主站初始化 * * @author LXZ (070620) * * @param void */ void nodelink_master_app_init(void) { if (USE_EXTEND_INOUTPUT) { nodelink_master_init(&master); { int value = 1000; //需要发送几次总线复位的命令 hw_dma_uart_control(0, UART_CTRL_SET_RDFIN_TIME, &value); } //设置回调函数 nodelink_master_set_callback(&master, master_callback); { //复位一下总线 nodelink_master_reset(&master); io_extern_count =0; io_extern_input_count = 0; io_extern_output_count = 0; bus_timeout = dwTickCount + 4000; } } } /** * 主站应用执行 * * @author LXZ (070620) * * @param void */ void nodelink_master_app_run(void) { if (USE_EXTEND_INOUTPUT) { static unsigned long connect_time; int length = 0; io_inputs_old[3] = io_inputs[3]; //接收数据 switch (nl_recv_step) { case 0: hw_dma_uart_begin_read(0, recv_buffer, sizeof(recv_buffer)); nl_recv_step++; connect_time = dwTickCount + 500; break; case 1: length = hw_dma_uart_read_finish(0); if (length > 0) { bus_timeout = dwTickCount + 1000; nodelink_master_recv(&master, recv_buffer, length); nl_recv_step = 0; } break; } //每隔10毫秒送一次总线信号 switch (nl_send_step) { case 0: sw_timer_start(&send_timer, 0, 10000); nl_send_step++; break; case 1: if (sw_timer_expire(&send_timer)) { if (bus_timeout < dwTickCount) { bus_timeout = dwTickCount + 1000; { //复位一下总线 nodelink_master_reset(&master); io_extern_count =0; io_extern_input_count = 0; io_extern_output_count = 0; } } length = nodelink_master_send(&master, send_buffer); if (length == 1) { nl_send_step = 0; } else if (length > 0) { hw_dma_uart_begin_write(0, (const char *)send_buffer, length); nl_send_step++; } } break; case 2: if (hw_dma_uart_write_finish(0)) { nl_send_step = 0; } break; } } }