int main(void) { uint32_t timer1msDiff; uint32_t t; static uint32_t timer1msPrevious; CO_NMT_reset_cmd_t reset = CO_RESET_NOT; HAL_Init(); /* Configure the system clock to 48 MHz */ SystemClock_Config(); /* Enable GPIOA Clock */ LED_GPIOA_CLK_ENABLE(); /* Enable CAN peripherals */ CAN_CLK_ENABLE(); CAN_GPIO_CLK_ENABLE(); // debug_printf("This is a pass test"); /* Initialize LEDs */ InitCanLeds(); /* -3- Toggle IOs in an infinite loop */ CanLedsSet(CoLed_Green); // CanLedsSet(CoLed_Red); // CanLedsSet(CoLed_Blue); // CanLedsSet(CoLed_Yellow); /* Configure Timer interrupt function for execution every 1 ms*/ TIMER_InitRCC(); TIMER_InitGeneral(); /* Program start - Application Call */ programStart(); while (reset != CO_RESET_APP) { /* disable timer interrupts */ NVIC_DisableIRQ(TIM2_IRQn); /* CANopen communication reset - initialize CANopen objects; CanOpen is initialized from within communication reset function */ communicationReset(); /* start Timer interupts*/ NVIC_EnableIRQ(TIM2_IRQn); reset = CO_RESET_NOT; timer1msPrevious = timer1ms; while (reset == CO_RESET_NOT) { /* loop for normal program execution */ timer1msDiff = timer1ms - timer1msPrevious; timer1msPrevious = timer1ms; /* Program Async for SDO and NMT messages */ reset = programAsync(timer1msDiff); // t = getTime_us(&tprof); // t = 100; OD_performance[ODA_performance_mainCycleTime] = t; if (t > OD_performance[ODA_performance_mainCycleMaxTime]) OD_performance[ODA_performance_mainCycleMaxTime] = t; } /* while (reset != 0) */ } /* while (reset != 2) */ /* program exit */ CO_DISABLE_INTERRUPTS(); CanLedsSet(CoLed_None); CanLedsSet(CoLed_Red); /* delete CANopen object from memory */ CO_delete(); }
//=========================================================================== // CANopen stack main entry point //=========================================================================== void CO_main(void) { CO_FlashInit(); while (1) { reset = CO_RESET_NOT; // Application interface programStart(); // increase variable each startup. Variable is stored in EEPROM. OD_powerOnCounter++; while (reset < CO_RESET_APP) { // CANopen communication reset - initialize CANopen objects int16_t err; cyg_uint64 timer1msPrevious = CO_TmrGetMilliSec(); // initialize CANopen err = CO_init(); if(err) { CO_eCos_errorReport(CO->em, CO_EM_MEMORY_ALLOCATION_ERROR, CO_EMC_SOFTWARE_INTERNAL, err); while(1); } // register object dictionary functions to support store and restore // of parameters via objects 0x1010 and 0x1011 CO_FlashRegisterODFunctions(CO); // initialize variables reset = CO_RESET_NOT; // Application interface communicationReset(); // start CAN and enable interrupts CO_CANsetNormalMode(ADDR_CAN1); while (CO_RESET_NOT == reset) { //diag_print_reg("CAN GSR", CAN_CTRL_1_REG_BASE + CANREG_GSR); // loop for normal program execution cyg_uint64 timer1ms = CO_TmrGetMilliSec(); uint16_t timer1msDiff = timer1ms - timer1msPrevious; timer1msPrevious = timer1ms; // Application interface programAsync(timer1msDiff); // CANopen process reset = CO_process(CO, timer1msDiff); if (CO_TmrIsExpired(CANopenPollingTimer)) { CANopenPollingTimer = CO_TmrStartFrom(CANopenPollingTimer, 1); CO_process_RPDO(CO); program1ms(); CO_process_TPDO(CO); } } } } }
/* main ***********************************************************************/ int main (void){ unsigned int temp_ui; CO_NMT_reset_cmd_t reset = CO_RESET_NOT; /* Configure system for maximum performance. plib is necessary for that.*/ /* SYSTEMConfig(CO_FSYS*1000, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE); */ /* Enable system multi vectored interrupts */ INTCONbits.MVEC = 1; __builtin_enable_interrupts(); /* Disable JTAG and trace port */ DDPCONbits.JTAGEN = 0; DDPCONbits.TROEN = 0; /* Verify, if OD structures have proper alignment of initial values */ if(CO_OD_RAM.FirstWord != CO_OD_RAM.LastWord) while(1) CO_clearWDT(); if(CO_OD_EEPROM.FirstWord != CO_OD_EEPROM.LastWord) while(1) CO_clearWDT(); if(CO_OD_ROM.FirstWord != CO_OD_ROM.LastWord) while(1) CO_clearWDT(); /* initialize EEPROM - part 1 */ #ifdef USE_EEPROM CO_ReturnError_t eeStatus = CO_EE_init_1(&CO_EEO, (uint8_t*) &CO_OD_EEPROM, sizeof(CO_OD_EEPROM), (uint8_t*) &CO_OD_ROM, sizeof(CO_OD_ROM)); #endif programStart(); /* increase variable each startup. Variable is stored in eeprom. */ OD_powerOnCounter++; while(reset != CO_RESET_APP){ /* CANopen communication reset - initialize CANopen objects *******************/ CO_ReturnError_t err; uint16_t timer1msPrevious; uint16_t TMR_TMR_PREV = 0; uint8_t nodeId; uint16_t CANBitRate; /* disable timer and CAN interrupts */ CO_TMR_ISR_ENABLE = 0; CO_CAN_ISR_ENABLE = 0; CO_CAN_ISR2_ENABLE = 0; /* Read CANopen Node-ID and CAN bit-rate from object dictionary */ nodeId = OD_CANNodeID; if(nodeId<1 || nodeId>127) nodeId = 0x10; CANBitRate = OD_CANBitRate;/* in kbps */ /* initialize CANopen */ err = CO_init(ADDR_CAN1, nodeId, CANBitRate); if(err != CO_ERROR_NO){ while(1) CO_clearWDT(); /* CO_errorReport(CO->em, CO_EM_MEMORY_ALLOCATION_ERROR, CO_EMC_SOFTWARE_INTERNAL, err); */ } /* initialize eeprom - part 2 */ #ifdef USE_EEPROM CO_EE_init_2(&CO_EEO, eeStatus, CO->SDO, CO->em); #endif /* initialize variables */ timer1msPrevious = CO_timer1ms; OD_performance[ODA_performance_mainCycleMaxTime] = 0; OD_performance[ODA_performance_timerCycleMaxTime] = 0; reset = CO_RESET_NOT; /* Configure Timer interrupt function for execution every 1 millisecond */ CO_TMR_CON = 0; CO_TMR_TMR = 0; #if CO_PBCLK > 65000 #error wrong timer configuration #endif CO_TMR_PR = CO_PBCLK - 1; /* Period register */ CO_TMR_CON = 0x8000; /* start timer (TON=1) */ CO_TMR_ISR_FLAG = 0; /* clear interrupt flag */ CO_TMR_ISR_PRIORITY = 3; /* interrupt - set lower priority than CAN (set the same value in interrupt) */ /* Configure CAN1 Interrupt (Combined) */ CO_CAN_ISR_FLAG = 0; /* CAN1 Interrupt - Clear flag */ CO_CAN_ISR_PRIORITY = 5; /* CAN1 Interrupt - Set higher priority than timer (set the same value in '#define CO_CAN_ISR_PRIORITY') */ CO_CAN_ISR2_FLAG = 0; /* CAN2 Interrupt - Clear flag */ CO_CAN_ISR2_PRIORITY = 5; /* CAN Interrupt - Set higher priority than timer (set the same value in '#define CO_CAN_ISR_PRIORITY') */ communicationReset(); /* start CAN and enable interrupts */ CO_CANsetNormalMode(ADDR_CAN1); CO_TMR_ISR_ENABLE = 1; CO_CAN_ISR_ENABLE = 1; #if CO_NO_CAN_MODULES >= 2 CO_CANsetNormalMode(ADDR_CAN2); CO_CAN_ISR2_ENABLE = 1; #endif while(reset == CO_RESET_NOT){ /* loop for normal program execution ******************************************/ uint16_t timer1msCopy, timer1msDiff; CO_clearWDT(); /* calculate cycle time for performance measurement */ timer1msCopy = CO_timer1ms; timer1msDiff = timer1msCopy - timer1msPrevious; timer1msPrevious = timer1msCopy; uint16_t t0 = CO_TMR_TMR; uint16_t t = t0; if(t >= TMR_TMR_PREV){ t = t - TMR_TMR_PREV; t = (timer1msDiff * 100) + (t / (CO_PBCLK / 100)); } else if(timer1msDiff){ t = TMR_TMR_PREV - t; t = (timer1msDiff * 100) - (t / (CO_PBCLK / 100)); } else t = 0; OD_performance[ODA_performance_mainCycleTime] = t; if(t > OD_performance[ODA_performance_mainCycleMaxTime]) OD_performance[ODA_performance_mainCycleMaxTime] = t; TMR_TMR_PREV = t0; /* Application asynchronous program */ programAsync(timer1msDiff); CO_clearWDT(); /* CANopen process */ reset = CO_process(CO, timer1msDiff, NULL); CO_clearWDT(); #ifdef USE_EEPROM CO_EE_process(&CO_EEO); #endif } } /* program exit ***************************************************************/ // CO_DISABLE_INTERRUPTS(); /* delete objects from memory */ programEnd(); CO_delete(ADDR_CAN1); /* reset */ SYSKEY = 0x00000000; SYSKEY = 0xAA996655; SYSKEY = 0x556699AA; RSWRSTSET = 1; temp_ui = RSWRST; while(1); }
DWORD WINAPI CanOpen_run(LPVOID lpParam) { /* initialize EEPROM - part 1 */ #ifdef USE_EEPROM CO_ReturnError_t eeStatus = CO_EE_init_1(&CO_EEO, (uint8_t*)&CO_OD_EEPROM, sizeof(CO_OD_EEPROM), (uint8_t*)&CO_OD_ROM, sizeof(CO_OD_ROM)); #endif programStart(); /* increase variable each startup. Variable is stored in eeprom. */ OD_powerOnCounter++; while (reset != CO_RESET_APP) { /* CANopen communication reset - initialize CANopen objects *******************/ CO_ReturnError_t err; uint16_t timer1msPrevious; uint16_t TMR_TMR_PREV = 0; uint8_t nodeId; uint16_t CANBitRate; /* disable CAN and CAN interrupts */ CO_CAN_ISR_ENABLE = 0; CO_CAN_ISR2_ENABLE = 0; /* Read CANopen Node-ID and CAN bit-rate from object dictionary */ nodeId = OD_CANNodeID; if (nodeId<1 || nodeId>127) nodeId = 0x10; CANBitRate = OD_CANBitRate;/* in kbps */ /* initialize CANopen */ err = CO_init(ADDR_CAN1, nodeId, CANBitRate); if (err != CO_ERROR_NO) { //FIXME do something here? /* CO_errorReport(CO->em, CO_EM_MEMORY_ALLOCATION_ERROR, CO_EMC_SOFTWARE_INTERNAL, err); */ } /* initialize eeprom - part 2 */ #ifdef USE_EEPROM CO_EE_init_2(&CO_EEO, eeStatus, CO->SDO[0], CO->em); #endif /* Configure callback functions */ CO_SYNC_initCallback(CO->SYNC, CANrx_lockCbSync); /* initialize variables */ timer1msPrevious = CO_timer1ms; OD_performance[ODA_performance_mainCycleMaxTime] = 0; OD_performance[ODA_performance_timerCycleMaxTime] = 0; reset = CO_RESET_NOT; /* Configure Timer interrupt function for execution every 1 millisecond */ /* Not sure if this is the best type of timer to use */ /* The jitter on the timing is not great */ BOOL success = CreateTimerQueueTimer( &m_timerHandle, NULL, TimerProc, NULL, 0, 1, //Period in ms WT_EXECUTEINTIMERTHREAD); #if CO_PBCLK > 65000 #error wrong timer configuration #endif communicationReset(); /* start CAN and enable interrupts */ CO_CANsetNormalMode(CO->CANmodule[0]); #if CO_NO_CAN_MODULES >= 2 CO_CANsetNormalMode(CO->CANmodule[1]); CO_CAN_ISR2_ENABLE = 1; #endif while (reset == CO_RESET_NOT) { /* loop for normal program execution ******************************************/ uint16_t timer1msCopy, timer1msDiff; /* calculate cycle time for performance measurement */ timer1msCopy = CO_timer1ms; timer1msDiff = timer1msCopy - timer1msPrevious; timer1msPrevious = timer1msCopy; LARGE_INTEGER Frequency; LARGE_INTEGER StartingTime; LARGE_INTEGER ElapsedMicroseconds; QueryPerformanceFrequency(&Frequency); QueryPerformanceCounter(&StartingTime); ElapsedMicroseconds.QuadPart = StartingTime.QuadPart - li_main.QuadPart; ElapsedMicroseconds.QuadPart *= 1000000; ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; double t = ElapsedMicroseconds.QuadPart / 1000.0; t = 1000.0 / t; OD_performance[ODA_performance_mainCycleTime] = t; if (t > OD_performance[ODA_performance_mainCycleMaxTime]) OD_performance[ODA_performance_mainCycleMaxTime] = t; li_main = StartingTime; /* Application asynchronous program */ programAsync(timer1msDiff); /* Pump the SDO master */ /* TODO In theory we should support as many masters as is defined in OD*/ canprocessSDOmaster(timer1msDiff); /* CANopen process */ reset = CO_process(CO, timer1msDiff, NULL); Sleep(1); //add some grace time to the thread as we do not want to hammer the async thread at 100% } #ifdef USE_EEPROM CO_EE_process(&CO_EEO); #endif } /* program exit ***************************************************************/ /* delete objects from memory */ programEnd(); CO_delete(ADDR_CAN1); // fix me graceful shutdown on win32 return 0; }