greg@455: /* greg@455: This file is part of CanFestival, a library implementing CanOpen Stack. greg@455: greg@455: Copyright (C): VScom greg@455: greg@455: See COPYING file for copyrights details. greg@455: greg@455: This library is free software; you can redistribute it and/or greg@455: modify it under the terms of the GNU Lesser General Public greg@455: License as published by the Free Software Foundation; either greg@455: version 2.1 of the License, or (at your option) any later version. greg@455: greg@455: This library is distributed in the hope that it will be useful, greg@455: but WITHOUT ANY WARRANTY; without even the implied warranty of greg@455: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU greg@455: Lesser General Public License for more details. greg@455: greg@455: You should have received a copy of the GNU Lesser General Public greg@455: License along with this library; if not, write to the Free Software greg@455: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA greg@455: */ greg@455: greg@455: /** greg@455: * @file can_vscom.c greg@455: * @author VScom (http://www.vscom.de) greg@455: * @date 17/04/08 greg@455: * greg@455: * This file implements interface between CanFestival and the VSCAN API greg@455: * (supported VScom products SER-CAN, USB-CAN, NET-CAN). greg@455: * greg@455: * To build this interface following files will needed: greg@455: * vs_can_api.h greg@455: * va_can_api.lib (for Windows builds) greg@455: */ greg@455: greg@455: #include greg@455: #include greg@455: #include greg@455: #include greg@455: greg@455: // VSCAN API header greg@455: #include "vs_can_api.h" // for CAN_HANDLE greg@455: greg@455: #include "can_driver.h" greg@455: greg@455: /*********functions which permit to communicate with the board****************/ greg@455: UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m) greg@455: { greg@455: VSCAN_MSG Msg[1]; greg@455: UNS8 i; greg@455: DWORD dwRead; /* number of read frames */ greg@455: greg@455: greg@455: if (VSCAN_Read((VSCAN_HANDLE)fd0, Msg, 1, &dwRead) != VSCAN_ERR_OK) greg@455: { greg@455: printf("canReceive_driver (VScom): error receiving frame)\n"); greg@455: return 1; greg@455: } greg@455: greg@455: /* identifier of the CAN frame */ greg@455: m->cob_id = Msg[0].Id; greg@455: greg@455: /* CAN frame type */ greg@455: if (Msg[0].Flags == VSCAN_FLAGS_STANDARD) greg@455: m->rtr = 0; greg@455: else greg@455: m->rtr = 1; greg@455: greg@455: /* width of the data bytes */ greg@455: m->len = Msg[0].Size; greg@455: greg@455: /* copy data bytes from the CAN frame, up to 8 */ greg@455: for(i = 0 ; i < Msg[0].Size ; i++) greg@455: { greg@455: m->data[i] = Msg[0].Data[i]; greg@455: } greg@455: greg@455: return 0; greg@455: } greg@455: greg@455: /***************************************************************************/ greg@455: UNS8 canSend_driver(CAN_HANDLE fd0, Message *m) greg@455: { greg@455: VSCAN_MSG Msg[1]; greg@455: UNS8 i; greg@455: DWORD dwWritten; /* number of written frames */ greg@455: greg@455: /* identifier of the CAN frame */ greg@455: Msg[0].Id = m->cob_id; greg@455: greg@455: /* CAN frame type */ greg@455: if(m->rtr == 0) greg@455: Msg[0].Flags = VSCAN_FLAGS_STANDARD; greg@455: else greg@455: Msg[0].Flags = VSCAN_FLAGS_REMOTE; greg@455: greg@455: /* width of the data bytes */ greg@455: Msg[0].Size = m->len; greg@455: greg@455: /* copy data bytes to the CAN frame, up to 8 */ greg@455: for(i = 0 ; i < m->len; i++) greg@455: Msg[0].Data[i] = m->data[i]; greg@455: greg@455: /* copy CAN frame to the output buffer */ greg@455: if (!(VSCAN_Write((VSCAN_HANDLE)fd0, Msg, (DWORD)1, &dwWritten) == VSCAN_ERR_OK && dwWritten)) greg@455: { greg@455: perror("canSend_driver (VScom): error writing to output buffer.\n"); greg@455: return 1; greg@455: } greg@455: greg@455: /* really send CAN frame */ greg@455: if(VSCAN_Flush((VSCAN_HANDLE)fd0) != VSCAN_ERR_OK) greg@455: { greg@455: perror("canSend_driver (VScom): error flushing.\n"); greg@455: return 1; greg@455: } greg@455: greg@455: return 0; greg@455: } greg@455: greg@455: greg@455: /***************************************************************************/ greg@455: int TranslateBaudeRate(char* optarg){ greg@455: if(!strcmp( optarg, "1M")) return (int)VSCAN_SPEED_1M; greg@455: if(!strcmp( optarg, "500K")) return (int)VSCAN_SPEED_500K; greg@455: if(!strcmp( optarg, "250K")) return (int)VSCAN_SPEED_250K; greg@455: if(!strcmp( optarg, "125K")) return (int)VSCAN_SPEED_125K; greg@455: if(!strcmp( optarg, "100K")) return (int)VSCAN_SPEED_100K; greg@455: if(!strcmp( optarg, "50K")) return (int)VSCAN_SPEED_50K; greg@455: if(!strcmp( optarg, "20K")) return (int)VSCAN_SPEED_20K; greg@455: if(!strcmp( optarg, "none")) return 0; greg@455: return 0x0000; greg@455: } greg@455: greg@455: UNS8 canChangeBaudRate_driver( CAN_HANDLE fd, char* baud) greg@455: { greg@455: int baudrate; greg@455: greg@455: baudrate = TranslateBaudeRate(baud); greg@455: if(baudrate == 0) greg@455: return 0; greg@455: greg@455: if (VSCAN_Ioctl((VSCAN_HANDLE)fd, VSCAN_IOCTL_SET_SPEED, (void *)baudrate) != VSCAN_ERR_OK) greg@455: { greg@455: fprintf(stderr, "canOpen_driver (VScom): IOCTL set speed failed\n"); greg@455: return 0; greg@455: } greg@455: greg@455: return 1; greg@455: } greg@455: greg@455: /***************************************************************************/ greg@455: CAN_HANDLE canOpen_driver(s_BOARD *board) greg@455: { greg@455: VSCAN_HANDLE fd0 = 0; greg@455: char busname[64]; greg@455: char* pEnd; greg@455: int i; greg@455: int baudrate; greg@455: greg@455: printf("bus %s ", board->busname); greg@455: fd0 = VSCAN_Open(board->busname, VSCAN_MODE_NORMAL); greg@455: if(fd0 <= 0) greg@455: { greg@455: fprintf(stderr, "canOpen_driver (VScom): error opening %s\n", board->busname); greg@455: return (CAN_HANDLE)fd0; greg@455: } greg@455: printf("(fd = %d)\n", fd0); greg@455: baudrate = TranslateBaudeRate(board->baudrate); greg@455: if(baudrate == 0) greg@455: return 0; greg@455: greg@455: if (VSCAN_Ioctl((VSCAN_HANDLE)fd0, VSCAN_IOCTL_SET_SPEED, (void *)baudrate) != VSCAN_ERR_OK) greg@455: { greg@455: fprintf(stderr, "canOpen_driver (VScom): IOCTL set speed failed\n"); greg@455: return 0; greg@455: } greg@455: greg@455: return (CAN_HANDLE)fd0; greg@455: } greg@455: greg@455: /***************************************************************************/ greg@455: int canClose_driver(CAN_HANDLE fd0) greg@455: { greg@455: VSCAN_Close((VSCAN_HANDLE)fd0); greg@455: return 0; greg@455: }