diff -r d1ccff139c17 -r ab83333fee78 drivers/can_peak_win32/can_peak_win32.c --- a/drivers/can_peak_win32/can_peak_win32.c Sat Feb 04 01:38:15 2012 +0100 +++ b/drivers/can_peak_win32/can_peak_win32.c Sat Feb 04 17:08:48 2012 +0100 @@ -33,6 +33,21 @@ #include "cancfg.h" #include "can_driver.h" #include "def.h" + + +#define VERSION_2 + +/* dummy implementation for older version. */ +#ifndef VERSION_2 +void CAN_SetRcvEvent(HANDLE hEventx) +{ + SetEvent(hEventx); +} +#endif + + + + #ifndef extra_PCAN_init_params #define extra_PCAN_init_params /**/ #else @@ -56,22 +71,25 @@ ,print_getenv("PCANInterupt") #endif + static s_BOARD *first_board = NULL; - //Create the Event for the first board HANDLE hEvent1 = NULL; +CRITICAL_SECTION InitLock1; +CRITICAL_SECTION InitLock2; #ifdef PCAN2_HEADER_ - static s_BOARD *second_board = NULL; - HANDLE hEvent2 = NULL; + static s_BOARD *second_board = NULL; + HANDLE hEvent2 = NULL; #endif // Define for rtr CAN message #define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR /***************************************************************************/ -int TranslateBaudeRate(char* optarg){ +static int TranslateBaudeRate(char* optarg) +{ if(!strcmp( optarg, "1M")) return CAN_BAUD_1M; if(!strcmp( optarg, "500K")) return CAN_BAUD_500K; if(!strcmp( optarg, "250K")) return CAN_BAUD_250K; @@ -85,7 +103,7 @@ return 0x0000; } -UNS8 canInit (s_BOARD *board) +static UNS8 canInit (s_BOARD *board) { int baudrate; int ret = 0; @@ -93,52 +111,69 @@ #ifdef PCAN2_HEADER_ // if not the first handler if(second_board == (s_BOARD *)board) { + if(hEvent2==NULL) + { /* Create the Event for the first board */ + hEvent2 = CreateEvent(NULL, // lpEventAttributes + FALSE, // bManualReset + FALSE, // bInitialState + ""); // lpName + InitializeCriticalSection(&InitLock2); + } + + EnterCriticalSection(&InitLock2); if(baudrate = TranslateBaudeRate(board->baudrate)) { - ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); - if(ret != CAN_ERR_OK) - return 0; - } - - //Create the Event for the first board - if(hEvent2 != NULL){ - hEvent2 = CreateEvent(NULL, // lpEventAttributes - FALSE, // bManualReset - FALSE, // bInitialState - ""); // lpName + ret = CAN2_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); + if(ret != CAN_ERR_OK) + { + LeaveCriticalSection(&InitLock2); + return 0; + } } //Set Event Handle for CANReadExt CAN2_SetRcvEvent(hEvent2); + LeaveCriticalSection(&InitLock2); } else #endif if(first_board == (s_BOARD *)board) { + //Create the Event for the first board + if(hEvent1==NULL) + { + hEvent1 = CreateEvent(NULL, // lpEventAttributes + FALSE, // bManualReset + FALSE, // bInitialState + ""); // lpName + InitializeCriticalSection(&InitLock1); + } + + EnterCriticalSection(&InitLock1); if(baudrate = TranslateBaudeRate(board->baudrate)) { - ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); - if(ret != CAN_ERR_OK) - return 0; - } - //Create the Event for the first board - if(hEvent1 != NULL){ - hEvent1 = CreateEvent(NULL, // lpEventAttributes - FALSE, // bManualReset - FALSE, // bInitialState - ""); // lpName + ret = CAN_Init(baudrate, CAN_INIT_TYPE_ST extra_PCAN_init_params); + if(ret != CAN_ERR_OK) + { + LeaveCriticalSection(&InitLock1); + return 0; + } } //Set Event Handle for CANReadExt CAN_SetRcvEvent(hEvent1); + LeaveCriticalSection(&InitLock1); } return 1; } /********* functions which permit to communicate with the board ****************/ -UNS8 __stdcall canReceive_driver (CAN_HANDLE fd0, Message * m) -{ +UNS8 LIBAPI canReceive_driver(CAN_HANDLE fd0, Message * m) +{ +static int HeavyCounter = 0; int ret=0; UNS8 data; TPCANMsg peakMsg; +#ifdef CAN_READ_EX TPCANTimestamp peakRcvTime; +#endif DWORD Res; DWORD result; // loop until valid message or fatal error @@ -151,52 +186,82 @@ if (result == WAIT_OBJECT_0) Res = CAN2_ReadEx(&peakMsg, &peakRcvTime); // Exit receive thread when handle is no more valid - if(Res & CAN_ERR_ILLHANDLE) + if(Res & CAN_ERRMASK_ILLHANDLE) return 1; } else #endif // We read the queue looking for messages. - if(first_board == (s_BOARD *)fd0) { + if(first_board == (s_BOARD *)fd0) + { +#ifdef VERSION_2 result = WaitForSingleObject(hEvent1, INFINITE); if (result == WAIT_OBJECT_0) +#endif { +#ifdef CAN_READ_EX Res = CAN_ReadEx(&peakMsg, &peakRcvTime); +#else + Res = CAN_Read(&peakMsg); +#endif // Exit receive thread when handle is no more valid - if(Res & CAN_ERR_ILLHANDLE) - return 1; +#ifdef CAN_ERRMASK_ILLHANDLE + if(Res & CAN_ERRMASK_ILLHANDLE) return 1; +#else + if(Res & CAN_ERR_ILLHANDLE) return 1; +#endif + +#ifndef VERSION_2 + if(Res != CAN_ERR_OK) + result = WaitForSingleObject(hEvent1, 1); //pooling +#endif } } +#ifdef VERSION_2 else Res = CAN_ERR_BUSOFF; - +#endif + // A message was received : we process the message(s) - if (Res == CAN_ERR_OK) - { - // if something different that 11bit or rtr... problem - if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR)) - { - if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF) - { - printf ("!!! Peak board read : re-init\n"); - canInit((s_BOARD*) fd0); - usleep (10000); - } - - // If status, return status if 29bit, return overrun - return peakMsg.MSGTYPE == - MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN; - } - m->cob_id = peakMsg.ID; - - if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_ */ - m->rtr = 0; - else - m->rtr = 1; - m->len = peakMsg.LEN; /* count of data bytes (0..8) */ - for (data = 0; data < peakMsg.LEN; data++) - m->data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */ + if(Res == CAN_ERR_OK) + { + switch(peakMsg.MSGTYPE) + { + case MSGTYPE_STATUS: + switch(peakMsg.DATA[3]) + { + case CAN_ERR_BUSHEAVY: + break; + case CAN_ERR_BUSOFF: + printf ("Peak board read BUSOFF: re-init!!!\n"); + canInit((s_BOARD*)fd0); + usleep(33); + break; + } + return peakMsg.DATA[3]; /* if something different that 11bit or rtr... problem */ + + case MSGTYPE_STANDARD: /* bits of MSGTYPE_ */ + case MSGTYPE_EXTENDED: + m->rtr = 0; + break; + + case MSGTYPE_RTR: /* bits of MSGTYPE_ */ + m->rtr = 1; + break; + + default: return CAN_ERR_OVERRUN; /* If status, return status if 29bit, return overrun. */ + + } + + m->cob_id = peakMsg.ID; + if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_ */ + m->rtr = 0; + else + m->rtr = 1; + m->len = peakMsg.LEN; /* count of data bytes (0..8) */ + for (data = 0; data < peakMsg.LEN; data++) + m->Data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */ #if defined DEBUG_MSG_CONSOLE_ON MSG("in : "); print_message(m); @@ -213,27 +278,30 @@ return 1; } } - }while(Res != CAN_ERR_OK); + } while(Res != CAN_ERR_OK); return 0; } /***************************************************************************/ -UNS8 __stdcall canSend_driver (CAN_HANDLE fd0, Message const * m) +UNS8 LIBAPI canSend_driver(CAN_HANDLE fd0, Message const *m) { UNS8 data; - DWORD localerrno; TPCANMsg peakMsg; peakMsg.ID = m->cob_id; /* 11/29 bit code */ if (m->rtr == 0) - peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_ */ - else { - peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_ */ - } + if(peakMsg.ID > 0x7FF) + peakMsg.MSGTYPE = MSGTYPE_EXTENDED; /* bits of MSGTYPE_ */ + else + peakMsg.MSGTYPE = MSGTYPE_STANDARD; /* bits of MSGTYPE_ */ + } + else + peakMsg.MSGTYPE = MSGTYPE_RTR; /* bits of MSGTYPE_ */ + peakMsg.LEN = m->len; /* count of data bytes (0..8) */ for (data = 0; data < m->len; data++) - peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */ + peakMsg.DATA[data] = m->Data[data]; /* data bytes, up to 8 */ do { @@ -241,19 +309,19 @@ // if not the first handler if(second_board == (s_BOARD *)fd0) { - errno = localerrno = CAN2_Write (&peakMsg); + errno = CAN2_Write (&peakMsg); } else #endif if(first_board == (s_BOARD *)fd0) { - errno = localerrno = CAN_Write (&peakMsg); + errno = CAN_Write (&peakMsg); } else goto fail; - if (localerrno) - { - if (localerrno == CAN_ERR_BUSOFF) + if (errno) + { + if (errno == CAN_ERR_BUSOFF) { printf ("!!! Peak board write : re-init\n"); canInit((s_BOARD*)fd0); @@ -262,7 +330,7 @@ usleep (1000); } } - while (localerrno != CAN_ERR_OK); + while (errno != CAN_ERR_OK); #if defined DEBUG_MSG_CONSOLE_ON MSG("out : "); print_message(m); @@ -273,16 +341,15 @@ } /***************************************************************************/ -UNS8 __stdcall canChangeBaudRate_driver( CAN_HANDLE fd, char* baud) +UNS8 LIBAPI canChangeBaudRate_driver(CAN_HANDLE fd, char* baud) { printf("canChangeBaudRate not yet supported by this driver\n"); return 0; } /***************************************************************************/ -CAN_HANDLE __stdcall canOpen_driver (s_BOARD * board) -{ - char busname[64]; +LIBPUBLIC CAN_HANDLE LIBAPI canOpen_driver(s_BOARD * board) +{ char* pEnd; int ret; @@ -308,35 +375,36 @@ return NULL; } + /***************************************************************************/ -int __stdcall canClose_driver (CAN_HANDLE fd0) +int LIBAPI canClose_driver(CAN_HANDLE fd0) { #ifdef PCAN2_HEADER_ - // if not the first handler - if(second_board == (s_BOARD *)fd0) - { - CAN2_SetRcvEvent(NULL); - CAN2_Close (); - if(hEvent2) - { - SetEvent(hEvent2); - CloseHandle(hEvent2); - hEvent2 = NULL; - } - second_board = (s_BOARD *)NULL; - }else -#endif - if(first_board == (s_BOARD *)fd0) - { - CAN_SetRcvEvent(NULL); - CAN_Close (); - if(hEvent1) - { - SetEvent(hEvent1); - CloseHandle(hEvent1); - hEvent1 = NULL; - } - first_board = (s_BOARD *)NULL; - } - return 0; -} + // if not the first handler + if(second_board == (s_BOARD *)fd0) + { + CAN2_SetRcvEvent(NULL); + CAN2_Close (); + if(hEvent2) + { + SetEvent(hEvent2); + CloseHandle(hEvent2); + hEvent2 = NULL; + } + second_board = (s_BOARD *)NULL; + }else +#endif + if(first_board == (s_BOARD *)fd0) + { + CAN_SetRcvEvent(NULL); + CAN_Close (); + if(hEvent1) + { + SetEvent(hEvent1); + CloseHandle(hEvent1); + hEvent1 = NULL; + } + first_board = (s_BOARD *)NULL; + } + return 0; +}