#include "global.h" void nodelink_timer_init(void); //扩展信息 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[IO_EXTERN_NUMBER]; //IO扩展信息结构体 //IO扩展缓存 byte_bits_t io_extern_inputs[(EXTEND_IO_INPUT_NUMBER + 7)>> 3]; byte_bits_t io_extern_outputs[(EXTEND_IO_OUTPUT_NUMBER + 7)>> 3]; unsigned char ResetFlg; unsigned char BeginRecvFlg; unsigned short sendtime=2000; //==================================================扩展应用程序=========================================// /** * 发送数据生成 * * @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 = 2; io_extern_data_t *extern_dat = device->user_data; data[0] = device->id; data[1] = 0xA3; if (extern_dat->output_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->output_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; dst_index = extern_dat->input_shift; while (src_index < extern_dat->input_number) { if (data[(src_index >> 3) + 2] & (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++; } device->txcount=0; } /** * 收发超时 * * @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==============================================// nodelink_master_t master; static int nl_recv_step = 0; //接收步骤 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 = 8; io_extern_datas[io_extern_count].inputs = (char *)&io_extern_inputs[(((IO_PIN_INPUT_NUMBER%8)+io_extern_input_count + 7) >> 3)-1]; io_extern_datas[io_extern_count].output_number = 6; io_extern_datas[io_extern_count].outputs = (char *)&io_extern_outputs[(((IO_PIN_OUTPUT_NUMBER%8)+io_extern_output_count + 7) >> 3) - 1]; io_extern_datas[io_extern_count].input_shift = (io_extern_input_count + IO_PIN_INPUT_NUMBER) % 8; io_extern_datas[io_extern_count].output_shift = (io_extern_output_count + IO_PIN_OUTPUT_NUMBER) % 8; 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; } nodelink_timer_init(); ResetFlg=0; BeginRecvFlg=0; //#endif } /** * 主站应用执行 * * @author LXZ (070620) * * @param void */ void nodelink_master_app_run(void) { //#if USE_EXTEND_INOUTPUT static unsigned long connect_time; int length = 0; //接收数据 switch (nl_recv_step) { case 0: hw_dma_uart_begin_read(2, recv_buffer, sizeof(recv_buffer)); nl_recv_step++; connect_time = dwTickCount + 1000; if((GetAlarmCode(QDCT_ALARM_ADDR) == QDCT_EX_ALARM) && USE_EXTEND_ALARM)SetAlarmCode(QDCT_ALARM_ADDR,QDCT_NO_ALARM); break; case 1: length = hw_dma_uart_read_finish(2); if (length > 0) { bus_timeout = dwTickCount + 1000; nodelink_master_recv(&master, recv_buffer, length); hw_dma_uart_begin_read(2, recv_buffer, sizeof(recv_buffer)); if((GetAlarmCode(QDCT_ALARM_ADDR) == QDCT_EX_ALARM) && USE_EXTEND_ALARM)SetAlarmCode(QDCT_ALARM_ADDR,QDCT_NO_ALARM); //nl_recv_step = 0; connect_time = dwTickCount + 1000; } if(master.bus_status == 0xFF) connect_time = dwTickCount + 1000; if((dwTickCount >= connect_time || ResetFlg==1) && master.bus_status != 0xFF) { if (USE_EXTEND_ALARM) SetAlarmCode(QDCT_ALARM_ADDR,QDCT_EX_ALARM); //复位一下总线 nodelink_master_reset(&master); io_extern_count =0; io_extern_input_count = 0; io_extern_output_count = 0; nl_recv_step = 0; connect_time = dwTickCount + 1000; } if(master.bus_status == 0xF1 && master.data_in[1]==0xA1) { //复位一下总线 nodelink_master_reset(&master); io_extern_count =0; io_extern_input_count = 0; io_extern_output_count = 0; nl_recv_step = 0; sendtime=1000; } break; } //每隔2毫秒送一次总线信号 switch (nl_send_step) { case 0: sw_timer_start(&send_timer, 0, sendtime); bus_timeout = dwTickCount + 5000; nl_send_step++; break; case 1: if (sw_timer_expire(&send_timer)) { if (bus_timeout < dwTickCount) { bus_timeout = dwTickCount + 5000; { //复位一下总线 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(2, (const char *)send_buffer, length); nl_send_step++; } //sw_timer_start(&send_timer, 0, 2000); } break; case 2: if (hw_dma_uart_write_finish(2)) { nl_send_step = 0; } break; } user_datas[529]=master.bus_status; user_datas[530]=master.step; user_datas[531]=master.dev_count; //#endif } void nodelink_timer_init(void) { RCC->APB1ENR |= (1<< 4); Sys_NVIC_Init(1, 1, TIM6_IRQn, 1); TIM6->CR1 = 0; TIM6->CR1 |= (0 << 8) | (1 << 7) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 2) | (0 << 1); // 禁止自动重载 TIM6->CR2 = 0; TIM6->PSC = 0; TIM6->ARR = 120000000 / 10000 + 1;//50k //TIM6->CCER = 0; //TIM6->CCMR1 = 0; TIM6->DIER = 0; TIM6->DIER |= 1; // 允许更新中断 TIM6->CNT = 0; TIM6->CR1 |= 1 << 0; TIM6->SR = 0; } void TIM6_IRQHandler(void) { if (TIM6->SR & TIM_SR_UIF) { nodelink_master_app_run(); TIM6->SR &= ~TIM_SR_UIF; } } void nodelink_read_input(void) { unsigned char input_shift = IO_PIN_INPUT_NUMBER % 8; int index = 0; if(input_shift==0) { memcpy(&io_inputs[((IO_PIN_INPUT_NUMBER + 7) >> 3)], &io_extern_inputs[0], (EXTEND_IO_INPUT_NUMBER + 7)>> 3); } else { index=input_shift; while (index < 8) { if (io_extern_inputs[0].value & (1 << index)) { io_inputs[((IO_PIN_INPUT_NUMBER + 7) >> 3)-1].value |= 1 << index; } else { io_inputs[((IO_PIN_INPUT_NUMBER + 7) >> 3)-1].value &= ~(1 << index); } index++; } memcpy(&io_inputs[((IO_PIN_INPUT_NUMBER + 7) >> 3)], &io_extern_inputs[1], ((EXTEND_IO_INPUT_NUMBER + 7)>> 3)-1); //memcpy(&io_inputs[((IO_PIN_INPUT_NUMBER + 7) >> 3)], //&io_extern_inputs[1], 5); } } void nodelink_write_output(void) { unsigned char output_shift = IO_PIN_OUTPUT_NUMBER % 8; int index = 0; if(output_shift==0) { memcpy(&io_extern_outputs[0], &io_outputs[((IO_PIN_OUTPUT_NUMBER + 7) >> 3)-1], (EXTEND_IO_OUTPUT_NUMBER + 7)>> 3); } else { index=output_shift; while (index < 8) { if (io_outputs[((IO_PIN_OUTPUT_NUMBER + 7) >> 3)-1].value & (1 << index)) { io_extern_outputs[0].value |= 1 << index; } else { io_extern_outputs[0].value &= ~(1 << index); } index++; } memcpy(&io_extern_outputs[1], &io_outputs[((IO_PIN_OUTPUT_NUMBER + 7) >> 3)], (EXTEND_IO_OUTPUT_NUMBER - (8 - output_shift) + 7)>> 3); } } void nodelink_reset(void) { nodelink_master_reset(&master); io_extern_count =0; io_extern_input_count = 0; io_extern_output_count = 0; nl_recv_step = 0; }