From ecaa660b9dc5d9b0a9484856a4789d71908f8e2f Mon Sep 17 00:00:00 2001 From: Olivier Desenfans Date: Wed, 13 Nov 2019 13:28:21 +0100 Subject: [PATCH] Revert "Single project-wide header for driver functions" This reverts commit 07c61316b3b89f4885a6fddae6daad5cf5c41e39. Will start from beginning. Try to keep git history. --- CO_driver.h | 281 ------------------ CO_types.h | 86 ------ .../{CO_driver_target.h => CO_driver.h} | 118 ++++++-- .../{CO_driver_target.h => CO_driver.h} | 150 +++++++--- .../{CO_driver_target.h => CO_driver.h} | 130 ++++++-- .../{CO_driver_target.h => CO_driver.h} | 214 +++++++++---- .../PIC32/{CO_driver_target.h => CO_driver.h} | 145 +++++++-- .../SAM3X/{CO_driver_target.h => CO_driver.h} | 135 +++++++-- .../STM32/{CO_driver_target.h => CO_driver.h} | 115 +++++-- .../{CO_driver_target.h => CO_driver.h} | 85 +++++- .../{CO_driver_target.h => CO_driver.h} | 237 +++++++++++++-- .../{CO_driver_target.h => CO_driver.h} | 125 ++++++-- .../eCos/{CO_driver_target.h => CO_driver.h} | 140 +++++++-- stack/neuberger-socketCAN/CO_driver.c | 12 +- .../{CO_driver_target.h => CO_driver.h} | 115 ++++++- stack/neuberger-socketCAN/CO_driver_base.h | 77 +++-- .../{CO_driver_target.h => CO_driver.h} | 120 ++++++-- 17 files changed, 1547 insertions(+), 738 deletions(-) delete mode 100644 CO_driver.h delete mode 100644 CO_types.h rename stack/LPC1768/{CO_driver_target.h => CO_driver.h} (55%) rename stack/LPC177x_8x/{CO_driver_target.h => CO_driver.h} (53%) rename stack/MCF5282/{CO_driver_target.h => CO_driver.h} (79%) rename stack/PIC24_dsPIC33/{CO_driver_target.h => CO_driver.h} (74%) rename stack/PIC32/{CO_driver_target.h => CO_driver.h} (75%) rename stack/SAM3X/{CO_driver_target.h => CO_driver.h} (53%) rename stack/STM32/{CO_driver_target.h => CO_driver.h} (67%) rename stack/STM32F3/{CO_driver_target.h => CO_driver.h} (70%) rename stack/drvTemplate/{CO_driver_target.h => CO_driver.h} (58%) rename stack/dsPIC30F/{CO_driver_target.h => CO_driver.h} (81%) rename stack/eCos/{CO_driver_target.h => CO_driver.h} (59%) rename stack/neuberger-socketCAN/{CO_driver_target.h => CO_driver.h} (80%) rename stack/socketCAN/{CO_driver_target.h => CO_driver.h} (60%) diff --git a/CO_driver.h b/CO_driver.h deleted file mode 100644 index 90c88f7..0000000 --- a/CO_driver.h +++ /dev/null @@ -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 . - * For more information on CANopen see . - * - * 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 /* 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 */ diff --git a/CO_types.h b/CO_types.h deleted file mode 100644 index 67a371c..0000000 --- a/CO_types.h +++ /dev/null @@ -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 . - * For more information on CANopen see . - * - * 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 */ diff --git a/stack/LPC1768/CO_driver_target.h b/stack/LPC1768/CO_driver.h similarity index 55% rename from stack/LPC1768/CO_driver_target.h rename to stack/LPC1768/CO_driver.h index 19b87ea..9f4aac9 100644 --- a/stack/LPC1768/CO_driver_target.h +++ b/stack/LPC1768/CO_driver.h @@ -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 /* 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 diff --git a/stack/LPC177x_8x/CO_driver_target.h b/stack/LPC177x_8x/CO_driver.h similarity index 53% rename from stack/LPC177x_8x/CO_driver_target.h rename to stack/LPC177x_8x/CO_driver.h index fbd628d..23d8ced 100644 --- a/stack/LPC177x_8x/CO_driver_target.h +++ b/stack/LPC177x_8x/CO_driver.h @@ -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 /* 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 diff --git a/stack/MCF5282/CO_driver_target.h b/stack/MCF5282/CO_driver.h similarity index 79% rename from stack/MCF5282/CO_driver_target.h rename to stack/MCF5282/CO_driver.h index 8a4aedf..ed29678 100644 --- a/stack/MCF5282/CO_driver_target.h +++ b/stack/MCF5282/CO_driver.h @@ -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 /* 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 diff --git a/stack/PIC24_dsPIC33/CO_driver_target.h b/stack/PIC24_dsPIC33/CO_driver.h similarity index 74% rename from stack/PIC24_dsPIC33/CO_driver_target.h rename to stack/PIC24_dsPIC33/CO_driver.h index fc02b73..9a58a03 100644 --- a/stack/PIC24_dsPIC33/CO_driver_target.h +++ b/stack/PIC24_dsPIC33/CO_driver.h @@ -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 /* for 'int8_t' to 'uint64_t' */ #include /* 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 == */ -#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 diff --git a/stack/PIC32/CO_driver_target.h b/stack/PIC32/CO_driver.h similarity index 75% rename from stack/PIC32/CO_driver_target.h rename to stack/PIC32/CO_driver.h index e0e9c7f..8dd8a68 100644 --- a/stack/PIC32/CO_driver_target.h +++ b/stack/PIC32/CO_driver.h @@ -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 /* processor header file */ @@ -32,43 +35,41 @@ #include /* for 'int8_t' to 'uint64_t' */ #include /* 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 diff --git a/stack/SAM3X/CO_driver_target.h b/stack/SAM3X/CO_driver.h similarity index 53% rename from stack/SAM3X/CO_driver_target.h rename to stack/SAM3X/CO_driver.h index 4776d85..c337fcc 100644 --- a/stack/SAM3X/CO_driver_target.h +++ b/stack/SAM3X/CO_driver.h @@ -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 /* for 'NULL' */ @@ -56,40 +59,57 @@ #include -/** 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); diff --git a/stack/STM32/CO_driver_target.h b/stack/STM32/CO_driver.h similarity index 67% rename from stack/STM32/CO_driver_target.h rename to stack/STM32/CO_driver.h index bae49e4..a9f17df 100644 --- a/stack/STM32/CO_driver_target.h +++ b/stack/STM32/CO_driver.h @@ -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 diff --git a/stack/STM32F3/CO_driver_target.h b/stack/STM32F3/CO_driver.h similarity index 70% rename from stack/STM32F3/CO_driver_target.h rename to stack/STM32F3/CO_driver.h index c168041..71db38b 100644 --- a/stack/STM32F3/CO_driver_target.h +++ b/stack/STM32F3/CO_driver.h @@ -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 diff --git a/stack/drvTemplate/CO_driver_target.h b/stack/drvTemplate/CO_driver.h similarity index 58% rename from stack/drvTemplate/CO_driver_target.h rename to stack/drvTemplate/CO_driver.h index 9d40a74..9d3b941 100644 --- a/stack/drvTemplate/CO_driver_target.h +++ b/stack/drvTemplate/CO_driver.h @@ -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 /* 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 diff --git a/stack/dsPIC30F/CO_driver_target.h b/stack/dsPIC30F/CO_driver.h similarity index 81% rename from stack/dsPIC30F/CO_driver_target.h rename to stack/dsPIC30F/CO_driver.h index af8c8ae..3677fed 100644 --- a/stack/dsPIC30F/CO_driver_target.h +++ b/stack/dsPIC30F/CO_driver.h @@ -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 /* processor header file */ @@ -32,34 +35,31 @@ #include /* for 'int8_t' to 'uint64_t' */ #include /* 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 diff --git a/stack/eCos/CO_driver_target.h b/stack/eCos/CO_driver.h similarity index 59% rename from stack/eCos/CO_driver_target.h rename to stack/eCos/CO_driver.h index 0d19932..0553e33 100644 --- a/stack/eCos/CO_driver_target.h +++ b/stack/eCos/CO_driver.h @@ -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 #include -#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 diff --git a/stack/neuberger-socketCAN/CO_driver.c b/stack/neuberger-socketCAN/CO_driver.c index 8cd13fd..46dee7a 100644 --- a/stack/neuberger-socketCAN/CO_driver.c +++ b/stack/neuberger-socketCAN/CO_driver.c @@ -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) diff --git a/stack/neuberger-socketCAN/CO_driver_target.h b/stack/neuberger-socketCAN/CO_driver.h similarity index 80% rename from stack/neuberger-socketCAN/CO_driver_target.h rename to stack/neuberger-socketCAN/CO_driver.h index 7a5ffcc..97aaeb5 100644 --- a/stack/neuberger-socketCAN/CO_driver_target.h +++ b/stack/neuberger-socketCAN/CO_driver.h @@ -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 . + */ +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 diff --git a/stack/neuberger-socketCAN/CO_driver_base.h b/stack/neuberger-socketCAN/CO_driver_base.h index 29d1973..89bf53a 100644 --- a/stack/neuberger-socketCAN/CO_driver_base.h +++ b/stack/neuberger-socketCAN/CO_driver_base.h @@ -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 #include -#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 diff --git a/stack/socketCAN/CO_driver_target.h b/stack/socketCAN/CO_driver.h similarity index 60% rename from stack/socketCAN/CO_driver_target.h rename to stack/socketCAN/CO_driver.h index bb81696..f6b6fe3 100644 --- a/stack/socketCAN/CO_driver_target.h +++ b/stack/socketCAN/CO_driver.h @@ -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 -/* 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