1
0
Fork 0
CANopenNode/stack/LPC177x_8x/CANOpenTask.c
2015-07-25 14:03:15 +02:00

211 lines
7.6 KiB
C

/*--------------------------------------------------------------*/
/* GENESYS ELECTRONICS DESIGN PTY LTD */
/*--------------------------------------------------------------*/
/* */
/* FILE NAME : CANOpenTask.h */
/* */
/* REVISION NUMBER: 1.0 */
/* */
/* PURPOSE : This is the implementation of the CANOpen main task*/
/* */
/* */
/*--------------------------------------------------------------*/
/* */
/* AUTHOR: */
/* Harshah Sagar */
/* GENESYS ELECTRONICS DESIGN Pty Ltd */
/* Unit 5/33 Ryde Road */
/* Pymble NSW 2073 */
/* Australia. */
/* Telephone # 61-02-9496 8900 */
/*--------------------------------------------------------------*/
/* Revision Number : */
/* Revision By : Amit Hergass */
/* Date : 30-Jun-2014 */
/* Description : Original Issue */
/* */
/* !--------------------------------------------------------! */
/* ! Revisions to be entered in reverse chronological order ! */
/* !--------------------------------------------------------! */
/* */
/*--------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "board.h"
#include "Watchdog.h"
#include "CANopen.h"
#include "application.h"
#include "CANOpenTask.h"
/* Global variables and objects */
volatile uint16_t CO_timer1ms = 0U; /* variable increments each millisecond */
static bool canStackEnabled = true;
void CO_TimerProcess(void);
#ifdef TASK_WATCHDOG_ENABLED
static hWatchdog CanOpenWdHandler;
#endif
/* main ***********************************************************************/
void CANOpenTask ( void *pvParameters )
{
CO_NMT_reset_cmd_t reset = CO_RESET_NOT;
/* Configure microcontroller. */
#ifdef TASK_WATCHDOG_ENABLED
/* wait number of the task iteration delay time (#seconds until WD expires * (1000ms/WD task frequency))
Give the task 20 seconds to recover*/
CanOpenWdHandler = watchogTaskRegister( "CANOpen", (20 * (1000 / WATCHDOG_TASK_FREQUENCY_MS)));
#endif
while(true)
{
reset = CO_RESET_NOT;
/* TODO: initialize EEPROM */
/* Todo: Loading COD */
DEBUGOUT("CANOpenTask() Loading COD\n\r");
/* Verify, if OD structures have proper alignment of initial values */
DEBUGOUT("Checking COD in RAM (size=%d)\n\r", &CO_OD_RAM.LastWord - &CO_OD_RAM.FirstWord);
if (CO_OD_RAM.FirstWord != CO_OD_RAM.LastWord)
DEBUGOUT("Err COD in RAM\n\r");
DEBUGOUT("Checking COD in EEPROM (size=%d)\n\r", &CO_OD_EEPROM.LastWord - &CO_OD_EEPROM.FirstWord);
if (CO_OD_EEPROM.FirstWord != CO_OD_EEPROM.LastWord)
DEBUGOUT("Err COD in EEPROM\n\r");
DEBUGOUT("Checking COD in ROM (size=%d)\n\r", &CO_OD_ROM.LastWord - &CO_OD_ROM.FirstWord);
if (CO_OD_ROM.FirstWord != CO_OD_ROM.LastWord)
DEBUGOUT("Err COD in ROM\n\r");
/* Application interface */
programStart();
/* increase variable each startup. Variable is stored in EEPROM. */
OD_powerOnCounter++;
DEBUGOUT("CO power-on (BTR=%dk Node=0x%x)\n\r", CO_OD_ROM.CANBitRate, CO_OD_ROM.CANNodeID);
while((reset != CO_RESET_APP)&& (true == canStackEnabled)){
/* CANopen communication reset - initialize CANopen objects *******************/
CO_ReturnError_t err;
uint16_t timer1msPrevious=0;
/* disable timer and CAN interrupts */
NVIC_DisableIRQ(CAN_IRQn);
/* initialize CANopen */
err = CO_init();
if(err != CO_ERROR_NO){
DEBUGOUT("CANOpenTask CO_init() Failed!!!\n\r");
CO_errorReport(CO->em, CO_EM_MEMORY_ALLOCATION_ERROR, CO_EMC_SOFTWARE_INTERNAL, err);
while(1)
{
vTaskDelay(1);
};
}
/* initialize variables */
timer1msPrevious = CO_timer1ms;
reset = CO_RESET_NOT;
/* Application interface */
communicationReset();
/* start CAN and enable interrupts */
CO_CANsetNormalMode(ADDR_CAN1);
while((reset == CO_RESET_NOT) && (true == canStackEnabled)){
/* loop for normal program execution ******************************************/
uint16_t timer1msDiff;
CO_DISABLE_INTERRUPTS();
/*execution every 1 millisecond */
timer1msDiff = CO_timer1ms - timer1msPrevious;
if(0 < timer1msDiff)
{
CO_TimerProcess();
}
else
{
vTaskDelay(1);
}
timer1msPrevious = CO_timer1ms;
CO_ENABLE_INTERRUPTS();
/* Application interface */
programAsync(timer1msDiff);
/* CANopen process */
reset = CO_process(CO, timer1msDiff);
/* Process EEPROM */
#ifdef TASK_WATCHDOG_ENABLED
watchogTaskFeed(CanOpenWdHandler);
#endif
}
}
DEBUGOUT("CANOpenTask Terminated reset= %d ,canStackEnabled= %d !!!\n\r", reset,canStackEnabled);
/* program exit ***************************************************************/
/* Application interface */
programEnd();
/* delete objects from memory */
CO_delete();
}
//Exit the task
vTaskDelete( NULL );
}
/* timer interrupt every millisecond ************************/
/*void vApplicationTickHook(void) since the tick is 1ms we can use the FreeRTOS tick hook*/
void /* interrupt */ CO_TimerInterruptHandler(void){
/* clear interrupt flag */
CO_timer1ms++;
}
/* function executes every millisecond ************************/
void CO_TimerProcess(void){
CO_process_RPDO(CO);
/* Application interface */
program1ms();
CO_process_TPDO(CO);
/* verify timer overflow (is flag set again?) */
if(0){
CO_errorReport(CO->em, CO_EM_ISR_TIMER_OVERFLOW, CO_EMC_SOFTWARE_INTERNAL, 0U);
}
}
/* CAN interrupt function *****************************************************/
void /* interrupt */ CAN_IRQHandler(void){ /* CO_CAN1InterruptHandler(void){*/
CO_CANinterrupt(CO->CANmodule[0]);
/* clear interrupt flag */
}
/* CAN_StackEnable() CAN Task Enable/Disable *****************************************************/
/*enableSwitch: true- Task enables, false- Task disabled */
void CAN_StackEnable(bool enableSwitch){
/* CAN Task can only be terminated, not restarted at this stage*/
if(canStackEnabled)
{
canStackEnabled = enableSwitch;
}
}
/* CAN_GetStackEnable *****************************************************/
/*Return: true- Task enables, false- Task disabled */
bool CAN_GetStackEnable(void){
return canStackEnabled;
}