1
0
Fork 0

Revert "Single project-wide header for driver functions"

This reverts commit 07c61316b3.

Will start from beginning. Try to keep git history.
This commit is contained in:
Olivier Desenfans 2019-11-13 13:28:21 +01:00 committed by Janez
parent 57f264c2c4
commit ecaa660b9d
17 changed files with 1547 additions and 738 deletions

View file

@ -1,281 +0,0 @@
/**
* CAN driver functions.
*
* Defines functions that must be implemented for each target.
*
* @file CO_driver.h
* @ingroup CO_driver
* @author Janez Paternoster
* @copyright 2004 - 2020 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "CO_driver_target.h"
#include "CO_types.h"
/* Include processor header file */
#include <stdint.h> /* for 'int8_t' to 'uint64_t' */
/**
* @defgroup CO_driver Driver
* @ingroup CO_CANopen
* @{
*
* Microcontroller specific code for CANopenNode.
*
* This file contains type definitions, functions and macros for:
* - Basic data types.
* - Receive and transmit buffers for CANopen messages.
* - Interaction with CAN module on the microcontroller.
* - CAN receive and transmit interrupts.
*
* This file is not only a CAN driver. There are no classic CAN queues for CAN
* messages. This file provides direct connection with other CANopen
* objects. It tries to provide fast responses and tries to avoid unnecessary
* calculations and memory consumptions.
*
* CO_CANmodule_t contains an array of _Received message objects_ (of type
* CO_CANrx_t) and an array of _Transmit message objects_ (of type CO_CANtx_t).
* Each CANopen communication object owns one member in one of the arrays.
* For example Heartbeat producer generates one CANopen transmitting object,
* so it has reserved one member in CO_CANtx_t array.
* SYNC module may produce sync or consume sync, so it has reserved one member
* in CO_CANtx_t and one member in CO_CANrx_t array.
*
* ###Reception of CAN messages.
* Before CAN messages can be received, each member in CO_CANrx_t must be
* initialized. CO_CANrxBufferInit() is called by CANopen module, which
* uses specific member. For example @ref CO_HBconsumer uses multiple members
* in CO_CANrx_t array. (It monitors multiple heartbeat messages from remote
* nodes.) It must call CO_CANrxBufferInit() multiple times.
*
* Main arguments to the CO_CANrxBufferInit() function are CAN identifier
* and a pointer to callback function. Those two arguments (and some others)
* are copied to the member of the CO_CANrx_t array.
*
* Callback function is a function, specified by specific CANopen module
* (for example by @ref CO_HBconsumer). Each CANopen module defines own
* callback function. Callback function will process the received CAN message.
* It will copy the necessary data from CAN message to proper place. It may
* also trigger additional task, which will further process the received message.
* Callback function must be fast and must only make the necessary calculations
* and copying.
*
* Received CAN messages are processed by CAN receive interrupt function.
* After CAN message is received, function first tries to find matching CAN
* identifier from CO_CANrx_t array. If found, then a corresponding callback
* function is called.
*
* Callback function accepts two parameters:
* - object is pointer to object registered by CO_CANrxBufferInit().
* - msg is pointer to CAN message of type CO_CANrxMsg_t.
*
* Callback function must return #CO_ReturnError_t: CO_ERROR_NO,
* CO_ERROR_RX_OVERFLOW, CO_ERROR_RX_PDO_OVERFLOW, CO_ERROR_RX_MSG_LENGTH or
* CO_ERROR_RX_PDO_LENGTH.
*
*
* ###Transmission of CAN messages.
* Before CAN messages can be transmitted, each member in CO_CANtx_t must be
* initialized. CO_CANtxBufferInit() is called by CANopen module, which
* uses specific member. For example Heartbeat producer must initialize it's
* member in CO_CANtx_t array.
*
* CO_CANtxBufferInit() returns a pointer of type CO_CANtx_t, which contains buffer
* where CAN message data can be written. CAN message is send with calling
* CO_CANsend() function. If at that moment CAN transmit buffer inside
* microcontroller's CAN module is free, message is copied directly to CAN module.
* Otherwise CO_CANsend() function sets _bufferFull_ flag to true. Message will be
* then sent by CAN TX interrupt as soon as CAN module is freed. Until message is
* not copied to CAN module, its contents must not change. There may be multiple
* _bufferFull_ flags in CO_CANtx_t array set to true. In that case messages with
* lower index inside array will be sent first.
*/
/**
* Request CAN configuration (stopped) mode and *wait* untill it is set.
*
* @param CANdriverState User-provided CAN module structure.
*/
void CO_CANsetConfigurationMode(void *CANdriverState);
/**
* Request CAN normal (opearational) mode and *wait* untill it is set.
*
* @param CANmodule This object.
*/
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/**
* Initialize CAN module object.
*
* Function must be called in the communication reset section. CAN module must
* be in Configuration Mode before.
*
* @param CANmodule This object will be initialized.
* @param CANdriverState User-provided CAN module structure..
* @param rxArray Array for handling received CAN messages
* @param rxSize Size of the above array. Must be equal to number of receiving CAN objects.
* @param txArray Array for handling transmitting CAN messages
* @param txSize Size of the above array. Must be equal to number of transmitting CAN objects.
* @param CANbitRate Valid values are (in kbps): 10, 20, 50, 125, 250, 500, 800, 1000.
* If value is illegal, bitrate defaults to 125.
*
* Return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/**
* Switch off CANmodule. Call at program exit.
*
* @param CANmodule CAN module object.
*/
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/**
* Read CAN identifier from received message
*
* @param rxMsg Pointer to received message
* @return 11-bit CAN standard identifier.
*/
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/**
* Configure CAN message receive buffer.
*
* Function configures specific CAN receive buffer. It sets CAN identifier
* and connects buffer with specific object. Function must be called for each
* member in _rxArray_ from CO_CANmodule_t.
*
* @param CANmodule This object.
* @param index Index of the specific buffer in _rxArray_.
* @param ident 11-bit standard CAN Identifier.
* @param mask 11-bit mask for identifier. Most usually set to 0x7FF.
* Received message (rcvMsg) will be accepted if the following
* condition is true: (((rcvMsgId ^ ident) & mask) == 0).
* @param rtr If true, 'Remote Transmit Request' messages will be accepted.
* @param object CANopen object, to which buffer is connected. It will be used as
* an argument to pFunct. Its type is (void), pFunct will change its
* type back to the correct object type.
* @param pFunct Pointer to function, which will be called, if received CAN
* message matches the identifier. It must be fast function.
*
* Return #CO_ReturnError_t: CO_ERROR_NO CO_ERROR_ILLEGAL_ARGUMENT or
* CO_ERROR_OUT_OF_MEMORY (not enough masks for configuration).
*/
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/**
* Configure CAN message transmit buffer.
*
* Function configures specific CAN transmit buffer. Function must be called for
* each member in _txArray_ from CO_CANmodule_t.
*
* @param CANmodule This object.
* @param index Index of the specific buffer in _txArray_.
* @param ident 11-bit standard CAN Identifier.
* @param rtr If true, 'Remote Transmit Request' messages will be transmitted.
* @param noOfBytes Length of CAN message in bytes (0 to 8 bytes).
* @param syncFlag This flag bit is used for synchronous TPDO messages. If it is set,
* message will not be sent, if curent time is outside synchronous window.
*
* @return Pointer to CAN transmit message buffer. 8 bytes data array inside
* buffer should be written, before CO_CANsend() function is called.
* Zero is returned in case of wrong arguments.
*/
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/**
* Send CAN message.
*
* @param CANmodule This object.
* @param buffer Pointer to transmit buffer, returned by CO_CANtxBufferInit().
* Data bytes must be written in buffer before function call.
*
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_TX_OVERFLOW or
* CO_ERROR_TX_PDO_WINDOW (Synchronous TPDO is outside window).
*/
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/**
* Clear all synchronous TPDOs from CAN module transmit buffers.
*
* CANopen allows synchronous PDO communication only inside time between SYNC
* message and SYNC Window. If time is outside this window, new synchronous PDOs
* must not be sent and all pending sync TPDOs, which may be on CAN TX buffers,
* must be cleared.
*
* This function checks (and aborts transmission if necessary) CAN TX buffers
* when it is called. Function should be called by the stack in the moment,
* when SYNC time was just passed out of synchronous window.
*
* @param CANmodule This object.
*/
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/**
* Verify all errors of CAN module.
*
* Function is called directly from CO_EM_process() function.
*
* @param CANmodule This object.
*/
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
#ifdef __cplusplus
}
#endif /* __cplusplus */
/** @} */
#endif /* CO_DRIVER_H */

View file

@ -1,86 +0,0 @@
/**
* CANopenNode types.
*
* Defines common types for CANopenNode.
*
* @file CO_types.h
* @ingroup CO_CANopen
* @author Olivier Desenfans
* @copyright 2004 - 2020 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CO_TYPES_H
#define CO_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Return values of some CANopen functions.
*
* A function should return 0 on success and a negative value on error.
*/
typedef enum {
/** Operation completed successfully */
CO_ERROR_NO = 0,
/** Error in function arguments */
CO_ERROR_ILLEGAL_ARGUMENT = -1,
/** Memory allocation failed */
CO_ERROR_OUT_OF_MEMORY = -2,
/** Function timeout */
CO_ERROR_TIMEOUT = -3,
/** Illegal baudrate passed to function CO_CANmodule_init() */
CO_ERROR_ILLEGAL_BAUDRATE = -4,
/** Previous message was not processed yet */
CO_ERROR_RX_OVERFLOW = -5,
/** previous PDO was not processed yet */
CO_ERROR_RX_PDO_OVERFLOW = -6,
/** Wrong receive message length */
CO_ERROR_RX_MSG_LENGTH = -7,
/** Wrong receive PDO length */
CO_ERROR_RX_PDO_LENGTH = -8,
/** Previous message is still waiting, buffer full */
CO_ERROR_TX_OVERFLOW = -9,
/** Synchronous TPDO is outside window */
CO_ERROR_TX_PDO_WINDOW = -10,
/** Transmit buffer was not confugured properly */
CO_ERROR_TX_UNCONFIGURED = -11,
/** Error in function function parameters */
CO_ERROR_PARAMETERS = -12,
/** Stored data are corrupt */
CO_ERROR_DATA_CORRUPT = -13,
/** CRC does not match */
CO_ERROR_CRC = -14,
/** Sending rejected because driver is busy. Try again */
CO_ERROR_TX_BUSY = -15,
/** Command can't be processed in current state */
CO_ERROR_WRONG_NMT_STATE = -16,
/** Syscall failed */
CO_ERROR_SYSCALL = -17,
/** Driver not ready */
CO_ERROR_INVALID_STATE = -18,
} CO_ReturnError_t;
#ifdef __cplusplus
}
#endif /* __cplusplus */
/** @} */
#endif /* CO_TYPES_H */

View file

@ -1,7 +1,7 @@
/*
* CAN module object for LPC1768 microcontroller using Mbed SDK.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @ingroup CO_driver
* @author Benoit Rapidel
* @copyright 2016 Benoit Rapidel
@ -44,8 +44,8 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
@ -56,32 +56,49 @@
#include <stdbool.h> /* for 'true', 'false' */
/* Endianness */
#define CO_LITTLE_ENDIAN
/* CAN module base address */
#define MBED_CAN 1
/* Critical sections */
#define CO_LOCK_CAN_SEND()
#define CO_UNLOCK_CAN_SEND()
#define CO_LOCK_CAN_SEND()
#define CO_UNLOCK_CAN_SEND()
#define CO_LOCK_EMCY()
#define CO_UNLOCK_EMCY()
#define CO_LOCK_EMCY()
#define CO_UNLOCK_EMCY()
#define CO_LOCK_OD()
#define CO_UNLOCK_OD()
#define CO_LOCK_OD()
#define CO_UNLOCK_OD()
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
@ -128,8 +145,69 @@ typedef struct{
}CO_CANmodule_t;
/* Endianes */
#define CO_LITTLE_ENDIAN
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* Receives and transmits CAN messages. */
void CO_CANinterrupt(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -3,7 +3,7 @@
*
* This file is a template for other microcontrollers.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @author Amit H
* @copyright 2004 - 2014 Janez Paternoster
@ -46,8 +46,11 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
#include "FreeRTOS.h"
@ -57,48 +60,65 @@
#include <stdint.h> /* for 'int8_t' to 'uint64_t' */
/* Endianness */
#define CO_LITTLE_ENDIAN
/* CAN module base address */
#define ADDR_CAN1 0
#define ADDR_CAN2 1
#define ADDR_CAN1 0
#define ADDR_CAN2 1
#define CAN_NODE_ID_0_PORT 1
#define CAN_NODE_ID_0_PIN 23
#define CAN_NODE_ID_1_PORT 1
#define CAN_NODE_ID_1_PIN 24
#define CAN_NODE_ID_2_PORT 1
#define CAN_NODE_ID_2_PIN 25
#define CAN_NODE_ID_3_PORT 1
#define CAN_NODE_ID_3_PIN 26
#define CAN_NODE_ID_4_PORT 1
#define CAN_NODE_ID_4_PIN 28
#define CAN_NODE_ID_0_PORT 1
#define CAN_NODE_ID_0_PIN 23
#define CAN_NODE_ID_1_PORT 1
#define CAN_NODE_ID_1_PIN 24
#define CAN_NODE_ID_2_PORT 1
#define CAN_NODE_ID_2_PIN 25
#define CAN_NODE_ID_3_PORT 1
#define CAN_NODE_ID_3_PIN 26
#define CAN_NODE_ID_4_PORT 1
#define CAN_NODE_ID_4_PIN 28
#define CAN_RUN_LED_PORT 1
#define CAN_RUN_LED_PIN 20
#define CAN_RUN_LED_PORT 1
#define CAN_RUN_LED_PIN 20
/* Critical sections */
#define CO_LOCK_CAN_SEND() taskENTER_CRITICAL()
#define CO_UNLOCK_CAN_SEND() taskEXIT_CRITICAL()
#define CO_LOCK_CAN_SEND() taskENTER_CRITICAL()
#define CO_UNLOCK_CAN_SEND() taskEXIT_CRITICAL()
#define CO_LOCK_EMCY() taskENTER_CRITICAL()
#define CO_UNLOCK_EMCY() taskEXIT_CRITICAL()
#define CO_LOCK_EMCY() taskENTER_CRITICAL()
#define CO_UNLOCK_EMCY() taskEXIT_CRITICAL()
#define CO_LOCK_OD() taskENTER_CRITICAL()
#define CO_UNLOCK_OD() taskEXIT_CRITICAL()
#define CO_LOCK_OD() taskENTER_CRITICAL()
#define CO_UNLOCK_OD() taskEXIT_CRITICAL()
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
@ -147,8 +167,70 @@ typedef struct{
void *em;
}CO_CANmodule_t;
/* Endianes */
#define CO_LITTLE_ENDIAN
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupt receives and transmits CAN messages. */
void CO_CANinterrupt(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -1,7 +1,7 @@
/*
* CAN module object for Freescale MCF5282 ColdFire V2 microcontroller.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @author Laurent Grosbois
* @copyright 2004 - 2014 Janez Paternoster
@ -44,8 +44,11 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
#include "mcf5282.h" /* processor header file */
@ -53,23 +56,20 @@
#include <stdint.h> /* for 'int8_t' to 'uint64_t' */
/* Endianness */
#define CO_LITTLE_ENDIAN
/* CAN module base address */
#define ADDR_CAN1 0
#define ADDR_CAN2 (_CAN2_BASE_ADDRESS - _CAN1_BASE_ADDRESS)
#define ADDR_CAN1 0
#define ADDR_CAN2 (_CAN2_BASE_ADDRESS - _CAN1_BASE_ADDRESS)
/* Critical sections */
#define CO_LOCK_CAN_SEND() asm{ move.w #0x2700,sr};
#define CO_UNLOCK_CAN_SEND() asm{ move.w #0x2000,sr};
#define CO_LOCK_CAN_SEND() asm{ move.w #0x2700,sr};
#define CO_UNLOCK_CAN_SEND() asm{ move.w #0x2000,sr};
#define CO_LOCK_EMCY() asm{ move.w #0x2700,sr};
#define CO_UNLOCK_EMCY() asm{ move.w #0x2000,sr};
#define CO_LOCK_EMCY() asm{ move.w #0x2700,sr};
#define CO_UNLOCK_EMCY() asm{ move.w #0x2000,sr};
#define CO_LOCK_OD() asm{ move.w #0x2700,sr};
#define CO_UNLOCK_OD() asm{ move.w #0x2000,sr};
#define CO_LOCK_OD() asm{ move.w #0x2700,sr};
#define CO_UNLOCK_OD() asm{ move.w #0x2000,sr};
/* MACRO : get information from Rx buffer */
@ -77,13 +77,13 @@
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* CAN bit rates
@ -305,6 +305,26 @@ typedef struct{
}CO_CANbitRateData_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
typedef struct{
unsigned timestamp :8; /* 8 bits timestamp, see MCF5282 documentation */
@ -356,8 +376,74 @@ typedef struct{
}CO_CANmodule_t;
/* Endianes */
#define CO_LITTLE_ENDIAN
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object.
*
* MCF5282 FlexCAN configuration: 16 buffers are available.
* Buffers [0..13] are used for reception
* Buffers [14..15] are used for reception
*/
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate); /* Valid values are (in kbps): 125, 1000. If value is illegal, bitrate defaults to 125. */
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupt receives and transmits CAN messages. */
void CO_CANinterrupt(CO_CANmodule_t *CANmodule, uint16_t ICODE);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -1,7 +1,7 @@
/*
* CAN module object for Microchip dsPIC33 or PIC24 microcontroller.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @author Peter Rozsahegyi (EDS)
* @author Jens Nielsen (CAN receive)
@ -25,8 +25,11 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
#if defined(__dsPIC33F__) || defined(__PIC24H__)
@ -38,93 +41,91 @@
#include <stdint.h> /* for 'int8_t' to 'uint64_t' */
#include <stdbool.h> /* for 'true' and 'false' */
/* Endianness */
#define CO_LITTLE_ENDIAN
/* CAN message buffer sizes for CAN module 1 and 2. Valid values
* are 0, 4, 6, 8, 12, 16. Default is one TX and seven RX messages (FIFO). */
#ifndef CO_CAN1msgBuffSize
#define CO_CAN1msgBuffSize 8
#endif /* CO_CAN1msgBuffSize */
#ifndef CO_CAN2msgBuffSize
#define CO_CAN2msgBuffSize 0 //CAN module 2 not used by default
#endif /* CO_CAN2msgBuffSize */
#ifndef CO_CAN1msgBuffSize
#define CO_CAN1msgBuffSize 8
#endif
#ifndef CO_CAN2msgBuffSize
#define CO_CAN2msgBuffSize 0 //CAN module 2 not used by default
#endif
/* Default DMA addresses for CAN modules. */
#ifndef CO_CAN1_DMA0
#define CO_CAN1_DMA0 ADDR_DMA0
#endif /* CO_CAN1_DMA0 */
#ifndef CO_CAN1_DMA1
#define CO_CAN1_DMA1 ADDR_DMA1
#endif /* CO_CAN1_DMA1 */
#ifndef CO_CAN2_DMA0
#define CO_CAN2_DMA0 ADDR_DMA2
#endif /* CO_CAN2_DMA0 */
#ifndef CO_CAN2_DMA1
#define CO_CAN2_DMA1 ADDR_DMA3
#endif /* CO_CAN2_DMA1 */
#ifndef CO_CAN1_DMA0
#define CO_CAN1_DMA0 ADDR_DMA0
#endif
#ifndef CO_CAN1_DMA1
#define CO_CAN1_DMA1 ADDR_DMA1
#endif
#ifndef CO_CAN2_DMA0
#define CO_CAN2_DMA0 ADDR_DMA2
#endif
#ifndef CO_CAN2_DMA1
#define CO_CAN2_DMA1 ADDR_DMA3
#endif
/* Define DMA attribute on supported platforms */
#if defined(__dsPIC33F__) || defined(__PIC24H__) || defined(__DMA_BASE)
#define __dma __attribute__((space(dma)))
#else
#define __dma
#if defined(__C30_VERSION__) && !defined(__XC16_VERSION__)
#define __builtin_dmaoffset(V) (uint16_t)V
#if defined(__dsPIC33F__) || defined(__PIC24H__) || defined(__DMA_BASE)
#define __dma __attribute__((space(dma)))
#else
#define __dma
#if defined(__C30_VERSION__) && !defined(__XC16_VERSION__)
#define __builtin_dmaoffset(V) (uint16_t)V
#endif
#endif
#endif
/* Define EDS attribute on supported platforms */
#if defined(__HAS_EDS__)
#define __eds __attribute__((eds))
#if defined(__C30_VERSION__) && !defined(__XC16_VERSION__)
#define __builtin_dmapage(V) (uint16_t)0
#if defined(__HAS_EDS__)
#define __eds __attribute__((eds))
#if defined(__C30_VERSION__) && !defined(__XC16_VERSION__)
#define __builtin_dmapage(V) (uint16_t)0
#endif
#else
#define __eds
#define __eds__
#endif
#else
#define __eds
#define __eds__
#endif
/* CAN module base addresses */
#define ADDR_CAN1 ((uint16_t)&C1CTRL1)
#define ADDR_CAN2 ((uint16_t)&C2CTRL1)
#define ADDR_CAN1 ((uint16_t)&C1CTRL1)
#define ADDR_CAN2 ((uint16_t)&C2CTRL1)
/* DMA addresses */
#define ADDR_DMA0 ((uint16_t)&DMA0CON)
#define ADDR_DMA1 ((uint16_t)&DMA1CON)
#define ADDR_DMA2 ((uint16_t)&DMA2CON)
#define ADDR_DMA3 ((uint16_t)&DMA3CON)
#define ADDR_DMA4 ((uint16_t)&DMA4CON)
#define ADDR_DMA5 ((uint16_t)&DMA5CON)
#define ADDR_DMA6 ((uint16_t)&DMA6CON)
#define ADDR_DMA7 ((uint16_t)&DMA7CON)
#define ADDR_DMA0 ((uint16_t)&DMA0CON)
#define ADDR_DMA1 ((uint16_t)&DMA1CON)
#define ADDR_DMA2 ((uint16_t)&DMA2CON)
#define ADDR_DMA3 ((uint16_t)&DMA3CON)
#define ADDR_DMA4 ((uint16_t)&DMA4CON)
#define ADDR_DMA5 ((uint16_t)&DMA5CON)
#define ADDR_DMA6 ((uint16_t)&DMA6CON)
#define ADDR_DMA7 ((uint16_t)&DMA7CON)
/* Critical sections */
#define CO_LOCK_CAN_SEND() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_CAN_SEND() asm volatile ("disi #0x0000")
#define CO_LOCK_CAN_SEND() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_CAN_SEND() asm volatile ("disi #0x0000")
#define CO_LOCK_EMCY() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_EMCY() asm volatile ("disi #0x0000")
#define CO_LOCK_EMCY() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_EMCY() asm volatile ("disi #0x0000")
#define CO_LOCK_OD() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_OD() asm volatile ("disi #0x0000")
#define CO_LOCK_OD() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_OD() asm volatile ("disi #0x0000")
#define CO_DISABLE_INTERRUPTS() asm volatile ("disi #0x3FFF")
#define CO_ENABLE_INTERRUPTS() asm volatile ("disi #0x0000")
#define CO_DISABLE_INTERRUPTS() asm volatile ("disi #0x3FFF")
#define CO_ENABLE_INTERRUPTS() asm volatile ("disi #0x0000")
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* CAN bit rates
@ -343,8 +344,8 @@ typedef unsigned char domain_t;
{1, 2, TQ_x_17} /*Not working*/
#else
#error define_CO_FCY CO_FCY not supported
#endif /* CO_FCY == <value> */
#endif /* CO_FCY */
#endif
#endif
/* Structure contains timing coefficients for CAN module.
@ -365,6 +366,26 @@ typedef struct{
}CO_CANbitRateData_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module.
* In dsPIC33F and PIC24H this structure is used for both: transmitting and
* receiving to and from CAN module. (Object is ownded by CAN module).
@ -420,6 +441,67 @@ typedef struct{
}CO_CANmodule_t;
/* Endianes */
#define CO_LITTLE_ENDIAN
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupt receives and transmits CAN messages.
*
* Function must be called directly from _C1Interrupt or _C2Interrupt with
@ -428,4 +510,4 @@ typedef struct{
void CO_CANinterrupt(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -1,7 +1,7 @@
/*
* CAN module object for Microchip PIC32MX microcontroller.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @copyright 2004 - 2020 Janez Paternoster
*
@ -23,8 +23,11 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
#include <p32xxxx.h> /* processor header file */
@ -32,43 +35,41 @@
#include <stdint.h> /* for 'int8_t' to 'uint64_t' */
#include <stdbool.h> /* for 'true', 'false' */
/* Endianness */
#define CO_LITTLE_ENDIAN
/* CAN module base address */
#define ADDR_CAN1 0
#define ADDR_CAN2 (_CAN2_BASE_ADDRESS - _CAN1_BASE_ADDRESS)
#define ADDR_CAN1 0
#define ADDR_CAN2 (_CAN2_BASE_ADDRESS - _CAN1_BASE_ADDRESS)
/* Translate a kernel virtual address in KSEG0 or KSEG1 to a real
* physical address and back. */
typedef unsigned long CO_paddr_t; /* a physical address */
typedef unsigned long CO_vaddr_t; /* a virtual address */
#define CO_KVA_TO_PA(v) ((CO_paddr_t)(v) & 0x1fffffff)
#define CO_PA_TO_KVA0(pa) ((void *) ((pa) | 0x80000000))
#define CO_PA_TO_KVA1(pa) ((void *) ((pa) | 0xa0000000))
* physical address and back. */
typedef unsigned long CO_paddr_t; /* a physical address */
typedef unsigned long CO_vaddr_t; /* a virtual address */
#define CO_KVA_TO_PA(v) ((CO_paddr_t)(v) & 0x1fffffff)
#define CO_PA_TO_KVA0(pa) ((void *) ((pa) | 0x80000000))
#define CO_PA_TO_KVA1(pa) ((void *) ((pa) | 0xa0000000))
/* Critical sections */
extern unsigned int CO_interruptStatus;
#define CO_LOCK_CAN_SEND() CO_interruptStatus = __builtin_disable_interrupts()
#define CO_UNLOCK_CAN_SEND() if(CO_interruptStatus & 0x00000001) {__builtin_enable_interrupts();}
extern unsigned int CO_interruptStatus;
#define CO_LOCK_CAN_SEND() CO_interruptStatus = __builtin_disable_interrupts()
#define CO_UNLOCK_CAN_SEND() if(CO_interruptStatus & 0x00000001) {__builtin_enable_interrupts();}
#define CO_LOCK_EMCY() CO_interruptStatus = __builtin_disable_interrupts()
#define CO_UNLOCK_EMCY() if(CO_interruptStatus & 0x00000001) {__builtin_enable_interrupts();}
#define CO_LOCK_EMCY() CO_interruptStatus = __builtin_disable_interrupts()
#define CO_UNLOCK_EMCY() if(CO_interruptStatus & 0x00000001) {__builtin_enable_interrupts();}
#define CO_LOCK_OD() CO_interruptStatus = __builtin_disable_interrupts()
#define CO_UNLOCK_OD() if(CO_interruptStatus & 0x00000001) {__builtin_enable_interrupts();}
#define CO_LOCK_OD() CO_interruptStatus = __builtin_disable_interrupts()
#define CO_UNLOCK_OD() if(CO_interruptStatus & 0x00000001) {__builtin_enable_interrupts();}
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* CAN bit rates
@ -290,6 +291,26 @@ typedef struct{
}CO_CANbitRateData_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
typedef struct{
unsigned ident :11; /* Standard Identifier */
@ -341,6 +362,74 @@ typedef struct{
}CO_CANmodule_t;
/* Endianes */
#define CO_LITTLE_ENDIAN
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object.
*
* PIC32MX CAN FIFO configuration: Two FIFOs are used. First FIFO is 32 messages
* long and is used for reception. Second is used for transmission and is 1
* message long. Format of message in fifo is described by CO_CANrxMsg_t for
* both: receiving and transmitting messages. However transmitting messages does
* not use all structure members.
*/
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupt receives and transmits CAN messages.
*
* Function must be called directly from _C1Interrupt or _C2Interrupt with
@ -349,4 +438,4 @@ typedef struct{
void CO_CANinterrupt(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -1,7 +1,7 @@
/*
* CAN module object for the Atmel SAM3X microcontroller.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @author Olof Larsson
* @copyright 2014 Janez Paternoster
@ -44,8 +44,11 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
#include <stddef.h> /* for 'NULL' */
@ -56,40 +59,57 @@
#include <can.h>
/** Endianness */
#define CO_LITTLE_ENDIAN
/* CAN module base address */
#define ADDR_CAN1 CAN0
#define ADDR_CAN2 CAN1
/*
Remember to set:
#define CONF_BOARD_CAN0
#define CONF_BOARD_CAN1
in conf_board.h
*/
#define ADDR_CAN1 CAN0
#define ADDR_CAN2 CAN1
/*
Remember to set:
#define CONF_BOARD_CAN0
#define CONF_BOARD_CAN1
in conf_board.h
*/
/* Critical sections */
#define CO_LOCK_CAN_SEND() //taskENTER_CRITICAL()
#define CO_UNLOCK_CAN_SEND() //taskEXIT_CRITICAL()
#define CO_LOCK_CAN_SEND() //taskENTER_CRITICAL()
#define CO_UNLOCK_CAN_SEND() //taskEXIT_CRITICAL()
#define CO_LOCK_EMCY() //taskENTER_CRITICAL()
#define CO_UNLOCK_EMCY() //taskEXIT_CRITICAL()
#define CO_LOCK_EMCY() //taskENTER_CRITICAL()
#define CO_UNLOCK_EMCY() //taskEXIT_CRITICAL()
#define CO_LOCK_OD() //taskENTER_CRITICAL()
#define CO_UNLOCK_OD() //taskEXIT_CRITICAL()
#define CO_LOCK_OD() //taskENTER_CRITICAL()
#define CO_UNLOCK_OD() //taskEXIT_CRITICAL()
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
@ -141,6 +161,67 @@ typedef struct{
}CO_CANmodule_t;
/* Endianes */
#define CO_LITTLE_ENDIAN
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupt receives and transmits CAN messages. */
void CO_CANinterrupt(CO_CANmodule_t *CANmodule);

View file

@ -1,7 +1,7 @@
/*
* CAN module object for ST STM32F103 microcontroller.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @author Ondrej Netik
* @author Vijayendra
@ -46,31 +46,34 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
/* Includes ------------------------------------------------------------------*/
// #include "common.h"
// #include "stm32f10x_conf.h"
#include "common.h"
#include "stm32f10x_conf.h"
/* Exported define -----------------------------------------------------------*/
#define PACKED_STRUCT __attribute__((packed))
#define ALIGN_STRUCT_DWORD __attribute__((aligned(4)))
/* Peripheral addresses */
#define ADDR_CAN1 CAN1
#define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */
#define ADDR_CAN1 CAN1
#define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */
/* Critical sections */
#define CO_LOCK_CAN_SEND() __set_PRIMASK(1);
#define CO_UNLOCK_CAN_SEND() __set_PRIMASK(0);
#define CO_LOCK_CAN_SEND() __set_PRIMASK(1);
#define CO_UNLOCK_CAN_SEND() __set_PRIMASK(0);
#define CO_LOCK_EMCY() __set_PRIMASK(1);
#define CO_UNLOCK_EMCY() __set_PRIMASK(0);
#define CO_LOCK_EMCY() __set_PRIMASK(1);
#define CO_UNLOCK_EMCY() __set_PRIMASK(0);
#define CO_LOCK_OD() __set_PRIMASK(1);
#define CO_UNLOCK_OD() __set_PRIMASK(0);
#define CO_LOCK_OD() __set_PRIMASK(1);
#define CO_UNLOCK_OD() __set_PRIMASK(0);
#define CLOCK_CAN RCC_APB1Periph_CAN1
@ -117,11 +120,30 @@
#define INAK_TIMEOUT ((uint32_t)0x0000FFFF)
/* Data types */
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module.
* prevzato z stm32f10_can.h - velikostne polozky a poradi odpovidaji. */
@ -192,10 +214,65 @@ void CanLedsSet(eCoLeds led);
#endif /* CO_USE_LEDS */
/* Request CAN configuration or normal mode */
//void CO_CANsetConfigurationMode(CAN_TypeDef *CANdriverState);
//void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
//uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
int8_t rtr,
void *object,
void (*pFunct)(void *object, CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
int8_t rtr,
uint8_t noOfBytes,
int8_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupts receives and transmits CAN messages. */
void CO_CANinterrupt_Rx(CO_CANmodule_t *CANmodule);
void CO_CANinterrupt_Tx(CO_CANmodule_t *CANmodule);
void CO_CANinterrupt_Status(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -1,7 +1,7 @@
/*
* CAN module object for ST STM32F334 microcontroller.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @author Ondrej Netik
* @author Vijayendra
@ -113,12 +113,30 @@
#define INAK_TIMEOUT ((uint32_t)0x0000FFFF)
/* Data types */
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module.
* prevzato z stm32f10_can.h - velikostne polozky a poradi odpovidaji. */
@ -171,9 +189,62 @@ typedef struct{
void *em;
}CO_CANmodule_t;
/* Exported variables -----------------------------------------------------------*/
/* Exported functions -----------------------------------------------------------*/
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
int8_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
int8_t rtr,
uint8_t noOfBytes,
int8_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupts receives and transmits CAN messages. */
void CO_CANinterrupt_Rx(CO_CANmodule_t *CANmodule);
void CO_CANinterrupt_Tx(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -3,7 +3,7 @@
*
* This file is a template for other microcontrollers.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @ingroup CO_driver
* @author Janez Paternoster
* @copyright 2004 - 2020 Janez Paternoster
@ -26,8 +26,8 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
#ifdef __cplusplus
extern "C" {
@ -39,15 +39,6 @@ extern "C" {
#include <stdbool.h> /* for 'true', 'false' */
/**
* Endianness.
*
* Depending on processor or compiler architecture, one of the two macros must
* be defined: CO_LITTLE_ENDIAN or CO_BIG_ENDIAN. CANopen itself is little endian.
*/
#define CO_LITTLE_ENDIAN
/**
* @defgroup CO_driver Driver
* @ingroup CO_CANopen
@ -159,14 +150,14 @@ extern "C" {
* CO_SYNC_initCallback() function.
* @{
*/
#define CO_LOCK_CAN_SEND() /**< Lock critical section in CO_CANsend() */
#define CO_UNLOCK_CAN_SEND()/**< Unlock critical section in CO_CANsend() */
#define CO_LOCK_CAN_SEND() /**< Lock critical section in CO_CANsend() */
#define CO_UNLOCK_CAN_SEND()/**< Unlock critical section in CO_CANsend() */
#define CO_LOCK_EMCY() /**< Lock critical section in CO_errorReport() or CO_errorReset() */
#define CO_UNLOCK_EMCY() /**< Unlock critical section in CO_errorReport() or CO_errorReset() */
#define CO_LOCK_EMCY() /**< Lock critical section in CO_errorReport() or CO_errorReset() */
#define CO_UNLOCK_EMCY() /**< Unlock critical section in CO_errorReport() or CO_errorReset() */
#define CO_LOCK_OD() /**< Lock critical section when accessing Object Dictionary */
#define CO_UNLOCK_OD() /**< Unock critical section when accessing Object Dictionary */
#define CO_LOCK_OD() /**< Lock critical section when accessing Object Dictionary */
#define CO_UNLOCK_OD() /**< Unock critical section when accessing Object Dictionary */
/** @} */
/**
@ -199,16 +190,39 @@ extern "C" {
*
* According to Misra C
*/
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t; /**< bool_t */
typedef float float32_t; /**< float32_t */
typedef long double float64_t; /**< float64_t */
typedef char char_t; /**< char_t */
typedef unsigned char oChar_t; /**< oChar_t */
typedef unsigned char domain_t; /**< domain_t */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t; /**< bool_t */
typedef float float32_t; /**< float32_t */
typedef long double float64_t; /**< float64_t */
typedef char char_t; /**< char_t */
typedef unsigned char oChar_t; /**< oChar_t */
typedef unsigned char domain_t; /**< domain_t */
/** @} */
/**
* Return values of some CANopen functions. If function was executed
* successfully it returns 0 otherwise it returns <0.
*/
typedef enum{
CO_ERROR_NO = 0, /**< Operation completed successfully */
CO_ERROR_ILLEGAL_ARGUMENT = -1, /**< Error in function arguments */
CO_ERROR_OUT_OF_MEMORY = -2, /**< Memory allocation failed */
CO_ERROR_TIMEOUT = -3, /**< Function timeout */
CO_ERROR_ILLEGAL_BAUDRATE = -4, /**< Illegal baudrate passed to function CO_CANmodule_init() */
CO_ERROR_RX_OVERFLOW = -5, /**< Previous message was not processed yet */
CO_ERROR_RX_PDO_OVERFLOW = -6, /**< previous PDO was not processed yet */
CO_ERROR_RX_MSG_LENGTH = -7, /**< Wrong receive message length */
CO_ERROR_RX_PDO_LENGTH = -8, /**< Wrong receive PDO length */
CO_ERROR_TX_OVERFLOW = -9, /**< Previous message is still waiting, buffer full */
CO_ERROR_TX_PDO_WINDOW = -10, /**< Synchronous TPDO is outside window */
CO_ERROR_TX_UNCONFIGURED = -11, /**< Transmit buffer was not confugured properly */
CO_ERROR_PARAMETERS = -12, /**< Error in function function parameters */
CO_ERROR_DATA_CORRUPT = -13, /**< Stored data are corrupt */
CO_ERROR_CRC = -14 /**< CRC does not match */
}CO_ReturnError_t;
/**
* CAN receive message structure as aligned in CAN module. It is different in
* different microcontrollers. It usually contains other variables.
@ -274,6 +288,175 @@ typedef struct{
}CO_CANmodule_t;
/**
* Endianness.
*
* Depending on processor or compiler architecture, one of the two macros must
* be defined: CO_LITTLE_ENDIAN or CO_BIG_ENDIAN. CANopen itself is little endian.
*/
#define CO_LITTLE_ENDIAN
/**
* Request CAN configuration (stopped) mode and *wait* untill it is set.
*
* @param CANdriverState User-provided CAN module structure.
*/
void CO_CANsetConfigurationMode(void *CANdriverState);
/**
* Request CAN normal (opearational) mode and *wait* untill it is set.
*
* @param CANmodule This object.
*/
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/**
* Initialize CAN module object.
*
* Function must be called in the communication reset section. CAN module must
* be in Configuration Mode before.
*
* @param CANmodule This object will be initialized.
* @param CANdriverState User-provided CAN module structure..
* @param rxArray Array for handling received CAN messages
* @param rxSize Size of the above array. Must be equal to number of receiving CAN objects.
* @param txArray Array for handling transmitting CAN messages
* @param txSize Size of the above array. Must be equal to number of transmitting CAN objects.
* @param CANbitRate Valid values are (in kbps): 10, 20, 50, 125, 250, 500, 800, 1000.
* If value is illegal, bitrate defaults to 125.
*
* Return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/**
* Switch off CANmodule. Call at program exit.
*
* @param CANmodule CAN module object.
*/
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/**
* Read CAN identifier from received message
*
* @param rxMsg Pointer to received message
* @return 11-bit CAN standard identifier.
*/
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/**
* Configure CAN message receive buffer.
*
* Function configures specific CAN receive buffer. It sets CAN identifier
* and connects buffer with specific object. Function must be called for each
* member in _rxArray_ from CO_CANmodule_t.
*
* @param CANmodule This object.
* @param index Index of the specific buffer in _rxArray_.
* @param ident 11-bit standard CAN Identifier.
* @param mask 11-bit mask for identifier. Most usually set to 0x7FF.
* Received message (rcvMsg) will be accepted if the following
* condition is true: (((rcvMsgId ^ ident) & mask) == 0).
* @param rtr If true, 'Remote Transmit Request' messages will be accepted.
* @param object CANopen object, to which buffer is connected. It will be used as
* an argument to pFunct. Its type is (void), pFunct will change its
* type back to the correct object type.
* @param pFunct Pointer to function, which will be called, if received CAN
* message matches the identifier. It must be fast function.
*
* Return #CO_ReturnError_t: CO_ERROR_NO CO_ERROR_ILLEGAL_ARGUMENT or
* CO_ERROR_OUT_OF_MEMORY (not enough masks for configuration).
*/
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/**
* Configure CAN message transmit buffer.
*
* Function configures specific CAN transmit buffer. Function must be called for
* each member in _txArray_ from CO_CANmodule_t.
*
* @param CANmodule This object.
* @param index Index of the specific buffer in _txArray_.
* @param ident 11-bit standard CAN Identifier.
* @param rtr If true, 'Remote Transmit Request' messages will be transmitted.
* @param noOfBytes Length of CAN message in bytes (0 to 8 bytes).
* @param syncFlag This flag bit is used for synchronous TPDO messages. If it is set,
* message will not be sent, if curent time is outside synchronous window.
*
* @return Pointer to CAN transmit message buffer. 8 bytes data array inside
* buffer should be written, before CO_CANsend() function is called.
* Zero is returned in case of wrong arguments.
*/
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/**
* Send CAN message.
*
* @param CANmodule This object.
* @param buffer Pointer to transmit buffer, returned by CO_CANtxBufferInit().
* Data bytes must be written in buffer before function call.
*
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_TX_OVERFLOW or
* CO_ERROR_TX_PDO_WINDOW (Synchronous TPDO is outside window).
*/
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/**
* Clear all synchronous TPDOs from CAN module transmit buffers.
*
* CANopen allows synchronous PDO communication only inside time between SYNC
* message and SYNC Window. If time is outside this window, new synchronous PDOs
* must not be sent and all pending sync TPDOs, which may be on CAN TX buffers,
* must be cleared.
*
* This function checks (and aborts transmission if necessary) CAN TX buffers
* when it is called. Function should be called by the stack in the moment,
* when SYNC time was just passed out of synchronous window.
*
* @param CANmodule This object.
*/
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/**
* Verify all errors of CAN module.
*
* Function is called directly from CO_EM_process() function.
*
* @param CANmodule This object.
*/
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/**
* Receives and transmits CAN messages.
*
@ -285,7 +468,7 @@ void CO_CANinterrupt(CO_CANmodule_t *CANmodule);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*__cplusplus*/
/** @} */
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -1,7 +1,7 @@
/*
* CAN module object for Microchip dsPIC30F microcontroller.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Janez Paternoster
* @copyright 2004 - 2020 Janez Paternoster
*
@ -23,8 +23,11 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
#include <p30Fxxxx.h> /* processor header file */
@ -32,34 +35,31 @@
#include <stdint.h> /* for 'int8_t' to 'uint64_t' */
#include <stdbool.h> /* for true and false */
/* Endianness */
#define CO_LITTLE_ENDIAN
/* CAN module base address */
#define ADDR_CAN1 0x300
#define ADDR_CAN2 0x3C0
#define ADDR_CAN1 0x300
#define ADDR_CAN2 0x3C0
/* Critical sections */
#define CO_LOCK_CAN_SEND() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_CAN_SEND() asm volatile ("disi #0x0000")
#define CO_LOCK_CAN_SEND() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_CAN_SEND() asm volatile ("disi #0x0000")
#define CO_LOCK_EMCY() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_EMCY() asm volatile ("disi #0x0000")
#define CO_LOCK_EMCY() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_EMCY() asm volatile ("disi #0x0000")
#define CO_LOCK_OD() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_OD() asm volatile ("disi #0x0000")
#define CO_LOCK_OD() asm volatile ("disi #0x3FFF")
#define CO_UNLOCK_OD() asm volatile ("disi #0x0000")
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* CAN bit rates
@ -311,6 +311,26 @@ typedef struct{
}CO_CANbitRateData_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
typedef struct{
uint16_t ident; /* Standard Identifier as aligned in CAN module. 16 bits:
@ -360,6 +380,67 @@ typedef struct{
}CO_CANmodule_t;
/* Endianes */
#define CO_LITTLE_ENDIAN
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* CAN interrupt receives and transmits CAN messages.
*
* Function must be called directly from _C1Interrupt or _C2Interrupt with
@ -368,4 +449,4 @@ typedef struct{
void CO_CANinterrupt(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif

View file

@ -1,7 +1,7 @@
/*
* CAN module object for eCos RTOS CAN layer
*
* @file CO_driver_target.h
* @file CO_driver.h
* @author Uwe Kindler
* @copyright 2013 Uwe Kindler
*
@ -43,8 +43,8 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
@ -58,10 +58,6 @@
#include <cyg/io/io.h>
#include <cyg/kernel/kapi.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
//===========================================================================
// CONFIGURATION
@ -90,40 +86,60 @@ extern "C"
/* CAN module base address */
// we don't really care about the addresses here because the eCos port
// uses I/O handles for accessing its CAN devices
#define ADDR_CAN1 0
#define ADDR_CAN2 1
#define ADDR_CAN1 0
#define ADDR_CAN2 1
/* Critical sections */
// shared data is accessed only from thread level code (not from ISR or DSR)
// so we simply do a scheduler lock here to prevent access from different
// threads
#define CO_LOCK_CAN_SEND() cyg_scheduler_lock()
#define CO_UNLOCK_CAN_SEND() cyg_scheduler_unlock()
#define CO_LOCK_CAN_SEND() cyg_scheduler_lock()
#define CO_UNLOCK_CAN_SEND() cyg_scheduler_unlock()
#define CO_LOCK_EMCY() cyg_scheduler_lock()
#define CO_UNLOCK_EMCY() cyg_scheduler_unlock()
#define CO_LOCK_EMCY() cyg_scheduler_lock()
#define CO_UNLOCK_EMCY() cyg_scheduler_unlock()
#define CO_LOCK_OD() cyg_scheduler_lock()
#define CO_UNLOCK_OD() cyg_scheduler_unlock()
#define CO_LOCK_OD() cyg_scheduler_lock()
#define CO_UNLOCK_OD() cyg_scheduler_unlock()
/* Data types */
typedef unsigned char bool_t;
typedef cyg_uint8 uint8_t;
typedef cyg_uint16 uint16_t;
typedef cyg_uint32 uint32_t;
typedef cyg_uint64 uint64_t;
typedef cyg_int8 int8_t;
typedef cyg_int16 int16_t;
typedef cyg_int32 int32_t;
typedef cyg_int64 int64_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
typedef unsigned char bool_t;
typedef cyg_uint8 uint8_t;
typedef cyg_uint16 uint16_t;
typedef cyg_uint32 uint32_t;
typedef cyg_uint64 uint64_t;
typedef cyg_int8 int8_t;
typedef cyg_int16 int16_t;
typedef cyg_int32 int32_t;
typedef cyg_int64 int64_t;
typedef float float32_t;
typedef long double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
@ -173,7 +189,69 @@ typedef struct{
cyg_io_handle_t ioHandle;
}CO_CANmodule_t;
#ifdef __cplusplus
extern "C"
{
#endif
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
int16_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t *rxArray,
uint16_t rxSize,
CO_CANtx_t *txArray,
uint16_t txSize,
uint16_t CANbitRate);
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
int16_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
uint8_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint8_t rtr,
uint8_t noOfBytes,
uint8_t syncFlag);
/* Send CAN message. */
int16_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
#ifdef __cplusplus
} //extern "C"
#endif /* __cplusplus */
#endif /* CO_DRIVER_TARGET_H */
#endif
#endif

View file

@ -498,9 +498,9 @@ uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg)
/******************************************************************************/
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
uint32_t index,
uint32_t ident,
uint32_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message))
@ -508,7 +508,7 @@ CO_ReturnError_t CO_CANrxBufferInit(
CO_ReturnError_t ret = CO_ERROR_NO;
if((CANmodule!=NULL) && (index < CANmodule->rxSize)){
uint16_t i;
uint32_t i;
CO_CANrx_t *buffer;
/* check if COB ID is already used */
@ -599,8 +599,8 @@ bool_t CO_CANrxBuffer_getInterface(
/******************************************************************************/
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint32_t index,
uint32_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag)

View file

@ -3,7 +3,7 @@
*
* This file is a template for other microcontrollers.
*
* @file CO_driver_target.h
* @file CO_driver.h
* @ingroup CO_driver
* @author Janez Paternoster, Martin Wagner
* @copyright 2004 - 2015 Janez Paternoster, 2017 Neuberger Gebaeudeautomation GmbH
@ -47,12 +47,12 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif
/**
@ -87,7 +87,7 @@ extern "C" {
#ifdef CO_DRIVER_ERROR_REPORTING
#include "CO_error.h"
#endif /* CO_DRIVER_ERROR_REPORTING */
#endif
/**
* socketCAN interface object
@ -125,9 +125,24 @@ typedef struct{
*/
uint32_t rxIdentToIndex[CO_CAN_MSG_SFF_MAX_COB_ID]; /**< COB ID to index assignment */
uint32_t txIdentToIndex[CO_CAN_MSG_SFF_MAX_COB_ID]; /**< COB ID to index assignment */
#endif /* CO_DRIVER_MULTI_INTERFACE */
#endif
}CO_CANmodule_t;
/**
* Request CAN configuration (stopped) mode and *wait* until it is set.
*
* @param CANdriverState CAN module base address.
*/
void CO_CANsetConfigurationMode(void *CANdriverState);
/**
* Request CAN normal (opearational) mode and *wait* until it is set.
*
* @param CANmodule This object.
*/
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
#ifdef CO_DRIVER_MULTI_INTERFACE
/**
@ -164,7 +179,7 @@ typedef struct{
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or
* CO_ERROR_SYSCALL.
*/
#endif /* CO_DRIVER_MULTI_INTERFACE */
#endif
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
@ -190,7 +205,23 @@ CO_ReturnError_t CO_CANmodule_addInterface(
CO_CANmodule_t *CANmodule,
void *CANdriverState);
#endif /* CO_DRIVER_MULTI_INTERFACE */
#endif
/**
* Close socketCAN connection. Call at program exit.
*
* @param CANmodule CAN module object.
*/
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/**
* Read CAN identifier from received message
*
* @param rxMsg Pointer to received message
* @return 11-bit CAN standard identifier.
*/
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/**
@ -218,9 +249,9 @@ CO_ReturnError_t CO_CANmodule_addInterface(
*/
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
uint32_t index,
uint32_t ident,
uint32_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
@ -244,10 +275,39 @@ CO_ReturnError_t CO_CANrxBufferInit(
*/
bool_t CO_CANrxBuffer_getInterface(
CO_CANmodule_t *CANmodule,
uint16_t ident,
uint32_t ident,
void **CANdriverStateRx,
struct timespec *timestamp);
#endif
/**
* Configure CAN message transmit buffer.
*
* Function configures specific CAN transmit buffer. Function must be called for
* each member in _txArray_ from CO_CANmodule_t.
*
* @param CANmodule This object.
* @param index Index of the specific buffer in _txArray_.
* @param ident 11-bit standard CAN Identifier.
* @param rtr If true, 'Remote Transmit Request' messages will be transmitted.
* @param noOfBytes Length of CAN message in bytes (0 to 8 bytes).
* @param syncFlag not supported
*
* @return Pointer to CAN transmit message buffer. 8 bytes data array inside
* buffer should be written, before CO_CANsend() function is called.
* Zero is returned in case of wrong arguments.
*/
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint32_t index,
uint32_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
#ifdef CO_DRIVER_MULTI_INTERFACE
/**
* Set which interface should be used for message buffer transmission
*
@ -265,11 +325,22 @@ bool_t CO_CANrxBuffer_getInterface(
*/
CO_ReturnError_t CO_CANtxBuffer_setInterface(
CO_CANmodule_t *CANmodule,
uint16_t ident,
uint32_t ident,
void *CANdriverStateTx);
#endif /* CO_DRIVER_MULTI_INTERFACE */
#endif
/**
* Send CAN message.
*
* @param CANmodule This object.
* @param buffer Pointer to transmit buffer, returned by CO_CANtxBufferInit().
* Data bytes must be written in buffer before function call.
*
* @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_TX_OVERFLOW or
* CO_ERROR_TX_PDO_WINDOW (Synchronous TPDO is outside window).
*/
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/**
* The same as #CO_CANsend(), but ensures that there is enough space remaining
@ -288,6 +359,20 @@ CO_ReturnError_t CO_CANtxBuffer_setInterface(
*/
CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/**
* Clear all synchronous TPDOs from CAN module transmit buffers.
* This function is not supported in this driver.
*/
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/**
* Verify all errors of CAN module.
* This function is not supported in this driver. Error checking is done
* inside <CO_CANrxWait()>.
*/
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/**
* Functions receives CAN messages. It is blocking.
@ -310,7 +395,7 @@ int32_t CO_CANrxWait(CO_CANmodule_t *CANmodule, int fdTimer, CO_CANrxMsg_t *buff
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*__cplusplus*/
/** @} */
#endif

View file

@ -1,7 +1,7 @@
/**
* CAN module object for Linux socketCAN.
*
* @file CO_driver_target.h
* @file CO_driver_base.h
* @ingroup CO_driver
* @author Janez Paternoster, Martin Wagner
* @copyright 2004 - 2015 Janez Paternoster, 2018 Neuberger Gebaeudeautomation GmbH
@ -57,25 +57,9 @@
#include <linux/can.h>
#include <net/if.h>
#include "CO_types.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Endianness.
*
* Depending on processor or compiler architecture, one of the two macros must
* be defined: CO_LITTLE_ENDIAN or CO_BIG_ENDIAN. CANopen itself is little endian.
*/
#ifdef __BYTE_ORDER
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define CO_LITTLE_ENDIAN
#else
#define CO_BIG_ENDIAN
#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */
#endif /* __BYTE_ORDER */
#endif
/**
* @defgroup CO_driver Driver
@ -233,16 +217,43 @@ static inline void CO_UNLOCK_OD() { (void)pthread_mutex_unlock(&CO_OD_mutex);
*
* According to Misra C
*/
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t; /**< bool_t */
typedef float float32_t; /**< float32_t */
typedef long double float64_t; /**< float64_t */
typedef char char_t; /**< char_t */
typedef unsigned char oChar_t; /**< oChar_t */
typedef unsigned char domain_t; /**< domain_t */
/* int8_t to uint64_t are defined in stdint.h */
typedef unsigned char bool_t; /**< bool_t */
typedef float float32_t; /**< float32_t */
typedef long double float64_t; /**< float64_t */
typedef char char_t; /**< char_t */
typedef unsigned char oChar_t; /**< oChar_t */
typedef unsigned char domain_t; /**< domain_t */
/** @} */
/**
* Return values of some CANopen functions. If function was executed
* successfully it returns 0 otherwise it returns <0.
*/
typedef enum{
CO_ERROR_NO = 0, /**< Operation completed successfully */
CO_ERROR_ILLEGAL_ARGUMENT = -1, /**< Error in function arguments */
CO_ERROR_OUT_OF_MEMORY = -2, /**< Memory allocation failed */
CO_ERROR_TIMEOUT = -3, /**< Function timeout */
CO_ERROR_ILLEGAL_BAUDRATE = -4, /**< Illegal baudrate passed to function CO_CANmodule_init() */
CO_ERROR_RX_OVERFLOW = -5, /**< Previous message was not processed yet */
CO_ERROR_RX_PDO_OVERFLOW = -6, /**< previous PDO was not processed yet */
CO_ERROR_RX_MSG_LENGTH = -7, /**< Wrong receive message length */
CO_ERROR_RX_PDO_LENGTH = -8, /**< Wrong receive PDO length */
CO_ERROR_TX_OVERFLOW = -9, /**< Previous message is still waiting, buffer full */
CO_ERROR_TX_BUSY = -10, /**< Sending rejected because driver is busy. Try again */
CO_ERROR_TX_PDO_WINDOW = -11, /**< Synchronous TPDO is outside window */
CO_ERROR_TX_UNCONFIGURED = -12, /**< Transmit buffer was not confugured properly */
CO_ERROR_PARAMETERS = -13, /**< Error in function function parameters */
CO_ERROR_DATA_CORRUPT = -14, /**< Stored data are corrupt */
CO_ERROR_CRC = -15, /**< CRC does not match */
CO_ERROR_WRONG_NMT_STATE = -16, /**< Command can't be processed in current state */
CO_ERROR_SYSCALL = -17, /**< Syscall failed */
CO_ERROR_INVALID_STATE = -18 /**< Driver not ready */
}CO_ReturnError_t;
/**
* Max COB ID for standard frame format
*/
@ -293,9 +304,23 @@ typedef struct{
void *CANdriverState; /**< CAN Interface identifier to use */
} CO_CANtx_t;
/**
* Endianess.
*
* Depending on processor or compiler architecture, one of the two macros must
* be defined: CO_LITTLE_ENDIAN or CO_BIG_ENDIAN. CANopen itself is little endian.
*/
#ifdef __BYTE_ORDER
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define CO_LITTLE_ENDIAN
#else
#define CO_BIG_ENDIAN
#endif
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*__cplusplus*/
/** @} */
#endif

View file

@ -23,8 +23,8 @@
*/
#ifndef CO_DRIVER_TARGET_H
#define CO_DRIVER_TARGET_H
#ifndef CO_DRIVER_H
#define CO_DRIVER_H
/* For documentation see file drvTemplate/CO_driver.h */
@ -45,16 +45,6 @@
#include <linux/can/error.h>
/* Endianness */
#ifdef BYTE_ORDER
#if BYTE_ORDER == LITTLE_ENDIAN
#define CO_LITTLE_ENDIAN
#else
#define CO_BIG_ENDIAN
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
#endif /* BYTE_ORDER */
/* general configuration */
// #define CO_LOG_CAN_MESSAGES /* Call external function for each received or transmitted CAN message. */
#define CO_SDO_BUFFER_SIZE 889 /* Override default SDO buffer size. */
@ -85,7 +75,7 @@
#define CO_UNLOCK_OD() {if(pthread_mutex_unlock(&CO_OD_mtx) != 0) CO_errExit("Mutex unlock CO_OD_mtx failed");}
#define CANrxMemoryBarrier() {__sync_synchronize();}
#endif /* CO_SINGLE_THREAD */
#endif
/* Syncronisation functions */
#define IS_CANrxNew(rxNew) ((uintptr_t)rxNew)
@ -94,13 +84,33 @@
/* Data types */
/* int8_t to uint64_t are defined in stdint.h */
typedef _Bool bool_t;
typedef float float32_t;
typedef double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* int8_t to uint64_t are defined in stdint.h */
typedef _Bool bool_t;
typedef float float32_t;
typedef double float64_t;
typedef char char_t;
typedef unsigned char oChar_t;
typedef unsigned char domain_t;
/* Return values */
typedef enum{
CO_ERROR_NO = 0,
CO_ERROR_ILLEGAL_ARGUMENT = -1,
CO_ERROR_OUT_OF_MEMORY = -2,
CO_ERROR_TIMEOUT = -3,
CO_ERROR_ILLEGAL_BAUDRATE = -4,
CO_ERROR_RX_OVERFLOW = -5,
CO_ERROR_RX_PDO_OVERFLOW = -6,
CO_ERROR_RX_MSG_LENGTH = -7,
CO_ERROR_RX_PDO_LENGTH = -8,
CO_ERROR_TX_OVERFLOW = -9,
CO_ERROR_TX_PDO_WINDOW = -10,
CO_ERROR_TX_UNCONFIGURED = -11,
CO_ERROR_PARAMETERS = -12,
CO_ERROR_DATA_CORRUPT = -13,
CO_ERROR_CRC = -14
}CO_ReturnError_t;
/* CAN receive message structure as aligned in CAN module. */
@ -153,10 +163,78 @@ typedef struct{
void *em;
}CO_CANmodule_t;
/* Endianes */
#ifdef BYTE_ORDER
#if BYTE_ORDER == LITTLE_ENDIAN
#define CO_LITTLE_ENDIAN
#else
#define CO_BIG_ENDIAN
#endif
#endif
/* Helper function, must be defined externally. */
void CO_errExit(char* msg);
/* Request CAN configuration or normal mode */
void CO_CANsetConfigurationMode(void *CANdriverState);
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);
/* Initialize CAN module object. */
CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule,
void *CANdriverState,
CO_CANrx_t rxArray[],
uint16_t rxSize,
CO_CANtx_t txArray[],
uint16_t txSize,
uint16_t CANbitRate); /* not used */
/* Switch off CANmodule. */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);
/* Read CAN identifier */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);
/* Configure CAN message receive buffer. */
CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
uint16_t mask,
bool_t rtr,
void *object,
void (*pFunct)(void *object, const CO_CANrxMsg_t *message));
/* Configure CAN message transmit buffer. */
CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule,
uint16_t index,
uint16_t ident,
bool_t rtr,
uint8_t noOfBytes,
bool_t syncFlag);
/* Send CAN message. */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/* Clear all synchronous TPDOs from CAN module transmit buffers. */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);
/* Verify all errors of CAN module. */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);
/* Functions receives CAN messages. It is blocking.
*
* @param CANmodule This object.
@ -164,4 +242,4 @@ void CO_errExit(char* msg);
void CO_CANrxWait(CO_CANmodule_t *CANmodule);
#endif /* CO_DRIVER_TARGET_H */
#endif