#include "CAN_Setup.h" // DSP281x Headerfile Include File #include "modbus_table_v2.h" #include "DSP281x_Examples.h" // DSP281x Examples Include File #include "DSP281x_Device.h" #include "global_time.h" #include "TuneUpPlane.h" #include "profile_interrupt.h" unsigned int CanTimeOutErrorTR = 0; unsigned int CanBusOffError = 0; int enable_can_recive_after_units_box = 0; int flag_enable_can_from_mpu=0; int flag_enable_can_from_terminal=0; long time_pause_enable_can_from_mpu=0; long time_pause_enable_can_from_terminal=0; int flag_disable_update_modbus_in_can_from_mpu=0; //unsigned long can_base_adr_terminal, can_base_adr_units, can_base_adr_mpu1, can_base_adr_alarm_log; //unsigned int enable_profile_led1_can = 1; //unsigned int enable_profile_led2_can = 0; #pragma DATA_SECTION(cycle,".slow_vars") CYCLE cycle[UNIT_QUA]; #pragma DATA_SECTION(new_cycle_fifo,".slow_vars") NEW_CYCLE_FIFO new_cycle_fifo; #pragma DATA_SECTION(fifo,".slow_vars") #pragma DATA_SECTION(refo,".slow_vars") FIFO fifo, refo; #pragma DATA_SECTION(BUSY,".slow_vars") int BUSY = 0; #pragma DATA_SECTION(Unites, ".slow_vars") int Unites[UNIT_QUA_UNITS][UNIT_LEN]; #pragma DATA_SECTION(TerminalUnites, ".slow_vars") int TerminalUnites[TERMINAL_UNIT_QUA_UNITS][TERMINAL_UNIT_LEN]; #pragma DATA_SECTION(CanOpenUnites, ".slow_vars") int CanOpenUnites[CANOPENUNIT_LEN]; /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// //#pragma DATA_SECTION(CAN_timeout,".slow_vars") #pragma DATA_SECTION(CAN_timeout,".fast_vars") // массив отсутсвия обмена с устройством int CAN_timeout[UNIT_QUA]; // #pragma DATA_SECTION(CAN_request_sent,".slow_vars") int CAN_request_sent[UNIT_QUA]; // #pragma DATA_SECTION(CAN_answer_wait,".slow_vars") int CAN_answer_wait[UNIT_QUA]; // #pragma DATA_SECTION(CAN_no_answer,".slow_vars") int CAN_no_answer[UNIT_QUA]; // как долго не обновлялись, по приходу любой посылки #pragma DATA_SECTION(CAN_refresh_cicle,".slow_vars") int CAN_refresh_cicle[UNIT_QUA]; // время обновления всего массива #pragma DATA_SECTION(CAN_count_cycle_input_units,".slow_vars") int CAN_count_cycle_input_units[UNIT_QUA_UNITS]; #pragma DATA_SECTION(CAN_timeout_cicle,".fast_vars") //#pragma DATA_SECTION(CAN_timeout_cicle, ".slow_vars") // счетчик unsigned int CAN_timeout_cicle[UNIT_QUA]; /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// #pragma DATA_SECTION(unites_can_setup, ".slow_vars") UNITES_CAN_SETUP unites_can_setup = UNITES_CAN_SETUP_DEFAULT; #pragma DATA_SECTION(mpu_can_setup, ".slow_vars") MPU_CAN_SETUP mpu_can_setup = MPU_CAN_SETUP_DEFAULT; #pragma DATA_SECTION(terminal_can_setup, ".slow_vars") TERMINAL_CAN_SETUP terminal_can_setup = TERMINAL_CAN_SETUP_DEFAULT; #pragma DATA_SECTION(alarm_log_can_setup, ".slow_vars") ALARM_LOG_CAN_SETUP alarm_log_can_setup = ALARM_LOG_CAN_SETUP_DEFAULT; #pragma DATA_SECTION(mailboxs_can_setup, ".slow_vars") MAILBOXS_CAN_SETUP mailboxs_can_setup = MAILBOXS_CAN_SETUP_DEFAULT; #pragma DATA_SECTION(canopen_can_setup, ".slow_vars") CANOPEN_CAN_SETUP canopen_can_setup = CANOPEN_CAN_SETUP_DEFAULT; ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// int init_units_can_boxs(UNITES_CAN_SETUP *p) { int c,e; e=0; for (c=0;cactive_box[c]) { p->adr_box[c+UNITS_NUMERATION_FROM_0_OR_1] = e; if (p->revers_box[c]) // Реверс бокс, меняем адреса для имитации Unites между разными TMS { p->can_in_mbox_adr[e] = p->can_base_adr + c; p->can_out_mbox_adr[e] = p->can_base_adr + OFFSET_CAN_ADR_UNITS + c; } else { p->can_out_mbox_adr[e] = p->can_base_adr + c; p->can_in_mbox_adr[e] = p->can_base_adr + OFFSET_CAN_ADR_UNITS + c; } // p->can_in_mbox_adr[e] = START_CAN_ADR_UNITS + c*2; // p->can_out_mbox_adr[e] = START_CAN_ADR_UNITS + OFFSET_CAN_ADR_UNITS + c*2; e++; } } p->max_number = e; return e; } ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// int init_canopen_can_boxs(CANOPEN_CAN_SETUP *p) { int i; // p->max_number = 8; for(i = 0; i < CANOPENUNIT_LEN; i++) CanOpenUnites[i] = 0; return 1; } ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// int init_mpu_can_boxs(MPU_CAN_SETUP *p ) { int c,e; e = 0; for (c=0;cactive_box[c]) { p->adr_box[c] = e; p->can_out_mbox_adr[e] = p->can_base_adr + c; p->can_in_mbox_adr[e] = p->can_base_adr + 0x10 + c; //OFFSET_CAN_ADR_MPU e++; } } p->max_number = e; return e; } ///////////////////////////////////////////////////////// int init_terminal_can_boxs(TERMINAL_CAN_SETUP *p ) { int c,e; e = 0; for (c=0;cactive_box[c]) { p->adr_box[c] = e; p->can_out_mbox_adr[e] = p->can_base_adr + c; p->can_in_mbox_adr[e] = p->can_base_adr + 0x10 + c; //OFFSET_CAN_ADR_MPU e++; } } p->max_number = e; return e; } ///////////////////////////////////////////////////////// int init_alarm_log_can_boxs(ALARM_LOG_CAN_SETUP *p ) { int c,e; e = 0; for (c=0;cactive_box[c]) { p->adr_box[c] = e; p->can_out_mbox_adr[e] = p->can_base_adr + c; p->can_in_mbox_adr[e] = p->can_base_adr + 0x10 + c; //OFFSET_CAN_ADR_MPU e++; } } p->max_number = e; return e; } ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// void init_mailboxs_can( UNITES_CAN_SETUP *p_units, MPU_CAN_SETUP *p_mpu, TERMINAL_CAN_SETUP *p_terminal, ALARM_LOG_CAN_SETUP *p_alarm_log, CANOPEN_CAN_SETUP *p_canopen, MAILBOXS_CAN_SETUP *p_mailboxs ) { volatile int c,e,max_number_in,max_number_out; e = 0; max_number_in = 0; max_number_out = 0; if (p_units->max_number>0) { for (c=0;cmax_number;c++) { p_mailboxs->can_mbox_adr[e] = p_units->can_in_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = UNITS_TYPE_BOX; p_units->adr_in_mbox[c] = e; max_number_in++; e++; p_mailboxs->can_mbox_adr[e] = p_units->can_out_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = UNITS_TYPE_BOX; p_units->adr_out_mbox[c] = e; max_number_out++; e++; } } if (p_mpu->max_number>0) { for (c=0;cmax_number;c++) { p_mailboxs->can_mbox_adr[e] = p_mpu->can_in_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = MPU_TYPE_BOX; p_mpu->adr_in_mbox[c] = e; max_number_in++; e++; p_mailboxs->can_mbox_adr[e] = p_mpu->can_out_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = MPU_TYPE_BOX; p_mpu->adr_out_mbox[c] = e; max_number_out++; e++; } } if (p_terminal->max_number>0) { for (c=0;cmax_number;c++) { p_mailboxs->can_mbox_adr[e] = p_terminal->can_in_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = TERMINAL_TYPE_BOX; p_terminal->adr_in_mbox[c] = e; max_number_in++; e++; p_mailboxs->can_mbox_adr[e] = p_terminal->can_out_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = TERMINAL_TYPE_BOX; p_terminal->adr_out_mbox[c] = e; max_number_out++; e++; } } if (p_alarm_log->max_number>0) { for (c=0;cmax_number;c++) { p_mailboxs->can_mbox_adr[e] = p_alarm_log->can_in_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = ALARM_LOG_TYPE_BOX; p_alarm_log->adr_in_mbox[c] = e; max_number_in++; e++; p_mailboxs->can_mbox_adr[e] = p_alarm_log->can_out_mbox_adr[c] | 0x80000000; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = ALARM_LOG_TYPE_BOX; p_alarm_log->adr_out_mbox[c] = e; max_number_out++; e++; } } if (p_canopen->max_number>0) { for (c=0;cmax_number;c++) { p_mailboxs->can_mbox_adr[e] = p_canopen->can_in_mbox_adr[c]; p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN; p_mailboxs->local_number_box[e] = c; p_mailboxs->type_box[e] = CANOPEN_TYPE_BOX; p_canopen->adr_in_mbox[c] = e; max_number_in++; e++; } } p_mailboxs->max_number_in = max_number_in; p_mailboxs->max_number_out = max_number_out; } ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// void init_all_mailboxs(unsigned long can_base_adr_units, unsigned long can_base_adr_mpu, unsigned long can_base_adr_alarm_log, unsigned long can_base_adr_terminal) { // unites_can_setup.can_base_adr = can_base_adr_units; init_units_can_boxs(&unites_can_setup); // mpu_can_setup.can_base_adr = can_base_adr_mpu; init_mpu_can_boxs(&mpu_can_setup); // terminal_can_setup.can_base_adr = can_base_adr_terminal; init_terminal_can_boxs(&terminal_can_setup); // alarm_log_can_setup.can_base_adr = can_base_adr_alarm_log; init_alarm_log_can_boxs(&alarm_log_can_setup); // init_canopen_can_boxs(&canopen_can_setup); // init_mailboxs_can(&unites_can_setup, &mpu_can_setup, &terminal_can_setup, &alarm_log_can_setup, &canopen_can_setup, &mailboxs_can_setup); } ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// void reset_CAN_timeout_cicle(int box) { CAN_timeout_cicle[box]=0; } #pragma CODE_SECTION(inc_CAN_timeout_cicle, ".fast_run2"); void inc_CAN_timeout_cicle() { unsigned int i, t_refresh; static unsigned int old_time = 0; t_refresh = get_delta_milisec(&old_time, 1); if (t_refresh>1000) t_refresh = 1000; for(i = 0; i < UNIT_QUA; i++) { if (CAN_timeout_cicle[i] < MAX_CAN_WAIT_TIMEOUT) { CAN_timeout_cicle[i] += t_refresh; } else { CAN_timeout[i] = 1; CAN_refresh_cicle[i] = -1; } } } void InitCan(unsigned long can_base_adr_units, unsigned long can_base_adr_mpu, unsigned long can_base_adr_alarm_log, unsigned long can_base_adr_terminal) { struct ECAN_REGS ECanaShadow; int i, c; volatile struct MBOX *tmbox; volatile Uint32 *tmoto; unsigned long canme_bits = 0; unsigned long canmd_bits = 0; unsigned long canmim_bits = 0; init_all_mailboxs(can_base_adr_units, can_base_adr_mpu, can_base_adr_alarm_log, can_base_adr_terminal); // Configure CAN pins using GPIO regs here EALLOW; GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1; GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1; // Configure the eCAN RX and TX pins for eCAN transmissions ECanaRegs.CANTIOC.all = 8; // only 3rd bit, TXFUNC, is significant ECanaRegs.CANRIOC.all = 8; // only 3rd bit, RXFUNC, is significant // Specify that 8 bits will be sent/received for (c=0;c<32;c++) { tmbox = &ECanaMboxes.MBOX0 + c; tmbox->MSGCTRL.all = 0x00000008; } // Disable all Mailboxes // Required before writing the MSGIDs ECanaRegs.CANME.all = 0; canme_bits = 0; canmd_bits = 0; canmim_bits = 0; // receive+transive //Ura for (c=0;c<32;c++) { if (mailboxs_can_setup.can_mbox_adr[c]) { tmbox = &ECanaMboxes.MBOX0 + c; if(mailboxs_can_setup.type_box[c] == UNITS_TYPE_BOX) { // tmbox->MSGID.bit.IDE = 0; // tmbox->MSGID.bit.STDMSGID = mailboxs_can_setup.can_mbox_adr[c]; tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c]; } else { if(mailboxs_can_setup.type_box[c] == CANOPEN_TYPE_BOX) { tmbox->MSGID.bit.IDE = 0; tmbox->MSGID.bit.STDMSGID = mailboxs_can_setup.can_mbox_adr[c]; //tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c]; } else tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c]; } canme_bits |= ((unsigned long)1<> 4) ) return 3; if (load_level_byte < (NEW_CYCLE_FIFO_LEN >> 2) ) return 2; if (load_level_byte < (NEW_CYCLE_FIFO_LEN >> 1) ) return 1; return 0; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// int new_cycle_fifo_load(int box, unsigned long adr, int * adr_from, unsigned long addr_to, unsigned long quant, int extended, int priority, int cmd_wait) { unsigned int ind; if (((new_cycle_fifo.index_data - new_cycle_fifo.index_send)&NEW_CYCLE_FIFO_LEN_MASK)>=(NEW_CYCLE_FIFO_LEN_MASK-3)) { new_cycle_fifo.count_lost++; // may_be_send_cycle_fifo(); // на всякий случай дернем передачу, вдруг мы не передаем почему-то, а массив забит! return -1; // переполнили! } if (new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].box==0) // тут чисто можно загружать { new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].box = box; new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].adr = adr; new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].adr_to = addr_to; new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].adr_from = adr_from; new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].quant = quant; new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].extended = extended; new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].priority = priority; new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].busy = 1; // увеличиваем длину очереди для этого ящика new_cycle_fifo.cycle_box[box]++; if (new_cycle_fifo.index_data == new_cycle_fifo.index_send) { // мы похоже ничего не передаем, индексы совпадают // } // сдвигаем индекс new_cycle_fifo.index_data++; new_cycle_fifo.index_data &= NEW_CYCLE_FIFO_LEN_MASK; // if (new_cycle_fifo.index_data>=NEW_CYCLE_FIFO_LEN) // перешли в ноль индекс // new_cycle_fifo.index_data = 0; // перешли в ноль индекс // may_be_send_fifo(); // if (cmd_wait==0) // may_be_send_cycle_fifo(); return 1; // все ок! } else { new_cycle_fifo.count_lost++; // may_be_send_cycle_fifo(); // на всякий случай дернем передачу, вдруг мы не передаем почему-то, а массив забит! return -1; // переполнили! } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// int CAN_FLY_free(int box) { return !cycle[box].FLY; } int CAN_cycle_free(int box) { int i; #if (CAN_PROTOCOL_VERSION==2) if (new_cycle_fifo.cycle_box[box] >= 200) { new_cycle_fifo.lost_box[box]++; return 0; } else return 1; #endif #if (CAN_PROTOCOL_VERSION==1) return !cycle[box].busy; #endif } int CAN_cycle_full_free(int box, int statistics_flag) { int i; #if (CAN_PROTOCOL_VERSION==2) if (new_cycle_fifo.cycle_box[box] != 0) { if (statistics_flag==CAN_BOX_STAT_ON) new_cycle_fifo.lost_box[box]++; return 0; } else return 1; #endif #if (CAN_PROTOCOL_VERSION==1) return !cycle[box].busy; #endif } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// int CAN_FIFO_free(unsigned int quant) { #if (CAN_PROTOCOL_VERSION==2) return 0; #endif #if (CAN_PROTOCOL_VERSION==1) return ((FIFO_LEN-(unsigned int)fifo.adr)>quant); #endif } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// void CAN_cycle_stop(int box) { cycle[box].busy=0; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// #pragma CODE_SECTION(CAN_send2,".fast_run2"); void CAN_send2(int box,unsigned long hiword, unsigned long loword) { volatile struct MBOX *Mailbox; unsigned long mask; // cycle[box].FLY = 1; new_cycle_fifo.flag_inter = 1; mask = ((unsigned long)1<MDH.all = hiword; Mailbox->MDL.all = loword; ECanaRegs.CANTRS.all = mask; } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// /////////////////////////////////////////////// int get_real_out_mbox(int type_box, int box) { if (type_box==FREE_TYPE_BOX) return -1; if (type_box==UNITS_TYPE_BOX) { if (box new_cycle_fifo.cycle_data[cur_send_index].priority) && new_cycle_fifo.cycle_data[next_send_index].box) { // выделили данные с большим приоритетом new_data = new_cycle_fifo.cycle_data[next_send_index]; new_cycle_fifo.index_send--; new_cycle_fifo.index_send &= NEW_CYCLE_FIFO_LEN_MASK; // и записали их на самый верх и -1 new_cycle_fifo.cycle_data[new_cycle_fifo.index_send] = new_data; new_cycle_fifo.cycle_data[next_send_index].box = 0; new_cycle_fifo.cycle_data[next_send_index].busy = 0; return; } } while (next_send_index!=new_cycle_fifo.index_data); return; } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //#pragma CODE_SECTION(CAN_cycle_fifo_step,".fast_run1"); int CAN_cycle_fifo_one_box(void) { unsigned long hiword,loword,mask; unsigned int * point; unsigned int box=0, index; index = new_cycle_fifo.index_send; // уже все передали? выходим... if (index == new_cycle_fifo.index_data) return 0; // текущий слот передачи уже пуст... выходим. // if (new_cycle_fifo.cycle_data[index].box==0) // return; // проверка на завершение передачи данных, уже все передано, весь массив данных quant штук. if(new_cycle_fifo.cycle_data[index].adr>=new_cycle_fifo.cycle_data[index].quant || new_cycle_fifo.cycle_data[index].box==0) { //уменьшаем длину очереди для этого ящика if (new_cycle_fifo.cycle_data[index].box) new_cycle_fifo.cycle_box[new_cycle_fifo.cycle_data[index].box]--; // затираем переданные в new_fifo в слоте данных new_cycle_fifo.cycle_data[index].busy = 0; // очищаем данный слот передачи, нужно переходить к следующему new_cycle_fifo.cycle_data[index].box = 0; // сдвигаем индекс new_cycle_fifo.index_send++; new_cycle_fifo.index_send &= NEW_CYCLE_FIFO_LEN_MASK; return 0; } // данные есть, передаем их mask = 0xE000; if(new_cycle_fifo.cycle_data[index].adr==new_cycle_fifo.cycle_data[index].quant-1) mask = 0x8000; if(new_cycle_fifo.cycle_data[index].adr==new_cycle_fifo.cycle_data[index].quant-2) mask = 0xC000; point = (unsigned int *)&hiword; // адрес данных if (new_cycle_fifo.cycle_data[index].extended == 0) point[1] = mask | (new_cycle_fifo.cycle_data[index].adr_to + new_cycle_fifo.cycle_data[index].adr); else { // расширение, для передачи большого массива, удаляем mask чтоб влез больший адрес. point[1] = (new_cycle_fifo.cycle_data[index].adr_to + new_cycle_fifo.cycle_data[index].adr)/3L; // делим на 3 чтоб влез больший адрес в слово, получается 65535*3 = 196605 слов, максимальный размер передаваемого буфера при extended=1 } // первое слово данный point[0] = new_cycle_fifo.cycle_data[index].adr_from[new_cycle_fifo.cycle_data[index].adr]; point = (unsigned int *)&loword; // второе слово данный point[1] = new_cycle_fifo.cycle_data[index].adr_from[new_cycle_fifo.cycle_data[index].adr+1]; // третье слово данных point[0] = new_cycle_fifo.cycle_data[index].adr_from[new_cycle_fifo.cycle_data[index].adr+2]; new_cycle_fifo.cycle_data[index].adr+=3; box = new_cycle_fifo.cycle_data[index].box; #if (CAN_PROTOCOL_VERSION==2) CAN_send2(box,hiword,loword); //new_fifo_load(box,hiword,loword); #endif return 1; } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //#pragma CODE_SECTION(CAN_cycle_fifo_step,".fast_run1"); int CAN_cycle_fifo_step(void) { unsigned long hiword,loword,mask; unsigned int * point; unsigned int box=0, index; index = new_cycle_fifo.index_send; // уже все передали? выходим... if (index==new_cycle_fifo.index_data) return 0; // текущий слот передачи уже пуст... выходим. // if (new_cycle_fifo.cycle_data[index].box==0) // return; if (new_cycle_fifo.flag_inter==0) { realign_new_cycle_fifo_on_priority(); CAN_cycle_fifo_one_box(); } return 1; } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// #define CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK 333L //99 // кратное 3 надо делать //#pragma CODE_SECTION(CAN_cycle_send,".fast_run2"); void CAN_cycle_send(int type_box, int box, unsigned long Addr, int * Data, unsigned long quant, int extended, int priority) { int real_mbox; unsigned int old_time; real_mbox = get_real_out_mbox (type_box, box); if (real_mbox<0) return; #if (CAN_PROTOCOL_VERSION==1) cycle[real_mbox].adr = 0; cycle[real_mbox].adr_from = Data; cycle[real_mbox].adr_to = Addr; cycle[real_mbox].quant = quant; cycle[real_mbox].busy = 1; cycle[real_mbox].extended = extended; CAN_cycle_step(real_mbox); #endif #if (CAN_PROTOCOL_VERSION==2) if (priority==CAN_BOX_PRIORITY_LOW) { do { // if (get_new_cycle_fifo_load_level()<=2) if (quant>CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK) { if (new_cycle_fifo_load (real_mbox, 0, Data, Addr, CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK, extended, priority, 1) == 1) { quant -= CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK; Data += CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK; Addr += CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK; } } else { new_cycle_fifo_load (real_mbox, 0, Data, Addr, quant, extended, priority, 0); quant = 0; } } while (quant>0); // } else new_cycle_fifo_load (real_mbox, 0, Data, Addr, quant, extended, priority, 0); #endif } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// // инкремен счетчика полных посылок для УКСС //////////////////////////////////////////////////////////////// void detect_time_refresh_units(int box, int adr) { if (box>=UNIT_QUA_UNITS) return; if (adr==unites_can_setup.adr_detect_refresh[box]) { //CAN_count_cycle_input_units[box]++; if (box=MPU_UNIT_QUA_UNITS) return; if (adr==mpu_can_setup.adr_detect_refresh[box]) { //CAN_count_cycle_input_units[box]++; if (box> 16 ) & 0xffff; CanOpenUnites[adr+1] = (h_word ) & 0xffff; CanOpenUnites[adr+2] = (l_word >> 16 ) & 0xffff; CanOpenUnites[adr+3] = (l_word ) & 0xffff; } } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// void parse_data_from_mbox(unsigned int box, unsigned long hiword, unsigned long loword) { unsigned int bit[3], real_mbox; int local_number_box; int adr; static int reply_box = 0; static volatile int err=0; //////////////////////////////////////////////////////////////////// // CAN OPEN //////////////////////////////////////////////////////////////////// if (mailboxs_can_setup.type_box[box] == CANOPEN_TYPE_BOX) { #ifdef BWC_CAN_FATEC messageParserToUnites(box, hiword, loword); #endif #ifdef BWC_CAN_SIEMENS messageParserToUnitesSiemens(box, hiword, loword); #endif #ifdef INGITIM_CAN_OPEN messagePaserToUnitesIngitim(box, hiword, loword); #endif // messageParser(box, hiword, loword); return; } adr = hiword >> 16; bit[0] = adr & 0x8000; bit[1] = adr & 0x4000; bit[2] = adr & 0x2000; adr &= 0x1fff; // ------------------------------------------------------------------------- // Используетси стандартное CAN-сообщение, а 8 байт данных имеют следующий формат: // | 3 бита маска данных | регистр (13 бит) | data1 | data2 | data3 | // маска данных: [0|1] - обрабатывать ли соответствующее dataX // регистр: начальный регистр с которым ведётсЯ работа // при "записи" соотвественно: регистр=data1, регистр+1=data2, регистр+2=data3 // при "чтении" соотвественно: читаетсЯ регистр, регистр+2, регистр+3 // Всё это при условии, что все три бита маски = "1". // ------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////// //SMPU_CAN_DEVICE - специальный Ящик длЯ удаленной прошивки контроллера через МПУ ID = 0x80CEB0E1; //////////////////////////////////////////////////////////////////// /* if (mailboxs_can_setup.type_box[box] == SMPU_TYPE_BOX) { if (adr==5 || adr==1) { run_cmd_super_can_5(adr,(unsigned int)((hiword ) & 0xffff),(unsigned int)((loword>>16) & 0xffff),(unsigned int)((loword) & 0xffff)); } else ready_run_cmd_super_can(adr,(unsigned int)((hiword ) & 0xffff),(unsigned int)((loword>>16) & 0xffff),(unsigned int)((loword) & 0xffff)); return; } */ /////////////////////////////////////////////////////////////////// //MPU /////////////////////////////////////////////////////////////////// if (mailboxs_can_setup.type_box[box] == MPU_TYPE_BOX) { local_number_box = mailboxs_can_setup.local_number_box[box]; if (local_number_box>=MPU_UNIT_QUA_UNITS) return; if(bit[0]) { timer_pause_enable_can_from_mpu(); if (adr0) { if (flag_enable_can_from_mpu && flag_disable_update_modbus_in_can_from_mpu==0) modbus_table_can_in[adr-1].all = /*(unsigned int)*/((hiword ) & 0xffff); detect_time_refresh_mpu(local_number_box,adr-1); } adr++; } else { err++; } } if(bit[1]) { timer_pause_enable_can_from_mpu(); if (adr0) { if (flag_enable_can_from_mpu && flag_disable_update_modbus_in_can_from_mpu==0) modbus_table_can_in[adr-1].all = /*(unsigned int)*/((loword>>16) & 0xffff); detect_time_refresh_mpu(local_number_box,adr-1); } adr++; } else { err++; } } if(bit[2]) { timer_pause_enable_can_from_mpu(); if (adr0) { if (flag_enable_can_from_mpu && flag_disable_update_modbus_in_can_from_mpu==0) modbus_table_can_in[adr-1].all = /*(unsigned int)*/((loword) & 0xffff); detect_time_refresh_mpu(local_number_box,adr-1); } adr++; } else { err++; } } real_mbox = get_real_in_mbox (MPU_TYPE_BOX, 0); return; } /////////////////////////////////////////////////////////////////// //TERMINAL //////////////////////////////////////////////////////////////////// if (mailboxs_can_setup.type_box[box] == TERMINAL_TYPE_BOX) { local_number_box = mailboxs_can_setup.local_number_box[box]; if (local_number_box>=TERMINAL_UNIT_QUA_UNITS) return; if(bit[0]) { timer_pause_enable_can_from_terminal(); if (adr=0) && flag_enable_can_from_terminal) { TerminalUnites[local_number_box][adr] = /*(unsigned int)*/((hiword ) & 0xffff); } adr++; } } if(bit[1]) { timer_pause_enable_can_from_terminal(); if (adr=0) && flag_enable_can_from_terminal) { TerminalUnites[local_number_box][adr] = /*(unsigned int)*/((loword>>16) & 0xffff); } adr++; } } if(bit[2]) { timer_pause_enable_can_from_terminal(); if (adr=0) && flag_enable_can_from_terminal) { TerminalUnites[local_number_box][adr] = /*(unsigned int)*/((loword) & 0xffff); } adr++; } } return; } //////////////////////////////////////////////////////////////////// //UKSS //////////////////////////////////////////////////////////////////// if (mailboxs_can_setup.type_box[box] == UNITS_TYPE_BOX) { local_number_box = mailboxs_can_setup.local_number_box[box]; if (local_number_box>=UNIT_QUA_UNITS) return; if(bit[0]) { if ( (adr=0) ) { Unites[local_number_box][adr] = (hiword ) & 0xffff; detect_time_refresh_units(local_number_box,adr); } adr++; } if(bit[1]) { if ( (adr=0) ) { Unites[local_number_box][adr] = ((loword>>16) & 0xffff); detect_time_refresh_units(local_number_box,adr); } adr++; } if(bit[2]) { if ( (adr=0) ) { Unites[local_number_box][adr] = (loword ) & 0xffff; detect_time_refresh_units(local_number_box,adr); } adr++; } return; } } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //#pragma CODE_SECTION(CAN_handler,".fast_run"); interrupt void CAN_handler(void) { volatile struct MBOX *Mailbox; unsigned long hiword, loword, mask = 1; int box,type_in_out_box, box_i; // Set interrupt priority: volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all; IER |= M_INT9; IER &= MINT9; // Set "global" priority PieCtrlRegs.PIEIER9.all &= MG95; // Set "group" priority PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable PIE interrupts #if (_ENABLE_INTERRUPT_PROFILE_LED1) if (profile_interrupt.for_led1.bits.can) i_led1_on_off_special(1); #endif #if (_ENABLE_INTERRUPT_PROFILE_LED2) if (profile_interrupt.for_led2.bits.can) i_led2_on_off_special(1); #endif EINT; box = ECanaRegs.CANGIF0.bit.MIV0; mask <<= box; type_in_out_box = mailboxs_can_setup.type_in_out_box[box]; if(type_in_out_box == CAN_BOX_TYPE_OUT) { cycle[box].FLY=0; // new_cycle_fifo.flag_inter = 0; ECanaRegs.CANTA.all = mask; ECanaRegs.CANAA.all = mask; #ifdef SUPER_CAN if(box == SMPU_CAN_DEVICE_TRANSMIT) // SMPU_CAN_DEVICE_TRANSMIT - ID = 0x80CEB0F1; { loword = Mailbox->MDL.all; hiword = Mailbox->MDH.all; adr = (hiword >> 16) & 0x1FFF; if(adr == 5) // { flag_send_mess_super_can = 1; } } #endif #if (CAN_PROTOCOL_VERSION==1) if(!BUSY && fifo.adr && !cycle[fifo.pak[fifo.adr-1].box].FLY) { BUSY=1; fifo.adr--; CAN_send( fifo.pak[fifo.adr].box, fifo.pak[fifo.adr].hiword, fifo.pak[fifo.adr].loword); BUSY=0; } else if(refo.adr && !cycle[refo.pak[refo.adr-1].box].FLY) { refo.adr--; CAN_send( refo.pak[refo.adr].box, refo.pak[refo.adr].hiword, refo.pak[refo.adr].loword); } if(cycle[box].busy) // 26.01.2011 Dimas CAN_cycle_step(box); // 26.01.2011 Dimas #endif #if (CAN_PROTOCOL_VERSION==2) new_cycle_fifo.flag_inter = CAN_cycle_fifo_one_box();//CAN_cycle_fifo_step(new_cycle_fifo.index_send); // // передаем что накопилось в буфере // new_fifo_unload(); // // // смотрим есть ли данные в цепочке ящика передачи для этого ящика что закончил передачу // if(cycle[box].busy) // // CAN_cycle_step(box); // // // // if(cycle[box].busy==0) // // { // // а тут смотрим есть ли данные в цепочке других ящиков // for (box_i=0;box_iMDL.all; hiword = Mailbox->MDH.all; if (enable_can_recive_after_units_box) { parse_data_from_mbox(box, hiword, loword); } CAN_timeout[box]=0; // сбросили ошибку таймаута по приему CAN_refresh_cicle[box]=CAN_timeout_cicle[box]; CAN_timeout_cicle[box]=0; // led2_toggle(); } //#if (CAN_PROTOCOL_VERSION==2) //// // передаем что накопилось в буфере //// new_fifo_unload(); //// // // а тут смотрим есть ли данные в цепочке других ящиков // for (box_i=0;box_i=TIME_PAUSE_CAN_FROM_TERMINAL) { time_pause_enable_can_from_terminal=TIME_PAUSE_CAN_FROM_TERMINAL; flag_enable_can_from_terminal = 1; } } void timer_pause_enable_can_from_mpu(void) { time_pause_enable_can_from_mpu++; if (time_pause_enable_can_from_mpu>=TIME_PAUSE_CAN_FROM_MPU) { time_pause_enable_can_from_mpu=TIME_PAUSE_CAN_FROM_MPU; flag_enable_can_from_mpu = 1; } } unsigned int test_can_live_mpu(void) { if (CAN_timeout[get_real_out_mbox(MPU_TYPE_BOX,0)]==0) return 1; else return 0; } unsigned int test_can_live_terminal(int n) { if (CAN_timeout[get_real_out_mbox(TERMINAL_TYPE_BOX,n)]==0) return 1; else return 0; } void InitCanSoft(void) { struct ECAN_REGS ECanaShadow; int i, c; volatile struct MBOX *tmbox; volatile Uint32 *tmoto; unsigned long canme_bits = 0; unsigned long canmd_bits = 0; unsigned long canmim_bits = 0; // Configure CAN pins using GPIO regs here EALLOW; // GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1; // GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1; // Configure the eCAN RX and TX pins for eCAN transmissions // ECanaRegs.CANTIOC.all = 8; // only 3rd bit, TXFUNC, is significant // ECanaRegs.CANRIOC.all = 8; // only 3rd bit, RXFUNC, is significant // Specify that 8 bits will be sent/received // for (c=0;c<32;c++) // { // tmbox = &ECanaMboxes.MBOX0 + c; // tmbox->MSGCTRL.all = 0x00000008; // } // Disable all Mailboxes // Required before writing the MSGIDs // ECanaRegs.CANME.all = 0; canme_bits = 0; canmd_bits = 0; canmim_bits = 0; // receive+transive //Ura for (c=0;c<32;c++) { if (mailboxs_can_setup.can_mbox_adr[c]) { // tmbox = &ECanaMboxes.MBOX0 + c; // if(mailboxs_can_setup.type_box[c] == UNITS_TYPE_BOX) // { //// tmbox->MSGID.bit.IDE = 0; //// tmbox->MSGID.bit.STDMSGID = mailboxs_can_setup.can_mbox_adr[c]; // tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c]; // } // else // { // if(mailboxs_can_setup.type_box[c] == CANOPEN_TYPE_BOX) // { // tmbox->MSGID.bit.IDE = 0; // tmbox->MSGID.bit.STDMSGID = mailboxs_can_setup.can_mbox_adr[c]; // //tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c]; // } // else // tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c]; // } canme_bits |= ((unsigned long)1<