Commit acae2cc4 authored by Matthias Wenzl's avatar Matthias Wenzl
Browse files

initial commit

parents
/*
* EK_TM4C1294XL_CAN.c
*
* Created on: Feb 2, 2018
* Author: wenzl
*/
/*
* =============================== CAN ===============================
*/
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(CAN_config, ".const:CAN_config")
#pragma DATA_SECTION(canTivaHWAttrs, ".const:canTivaHWAttrs")
#endif
#include "include/EK_TM4C1294XL_CAN.h"
#include "include/can_driver.h"
#include "include/canTiva.h"
CANTiva_Object canTivaObjects[EK_TM4C1294XL_CANCOUNT];
/* PWM configuration structure */
const CANTiva_HWAttrs canTivaHWAttrs[EK_TM4C1294XL_CANCOUNT] = {
{
/*TODO:implement_me*/.base_addr = 0,
/*TODO:implement_me*/.clock = 0,
/*TODO:implement_me*/.irq = 0,
/*TODO:implement_me*/.brp = 0,
/*TODO:implement_me*/.prop = 0,
/*TODO:implement_me*/.ph1 = 0,
/*TODO:implement_me*/.ph2 = 0,
/*TODO:implement_me*/.sjw = 0,
}
};
const CAN_Config CAN_config[] = {
{&CANTiva_FxnTable, &canTivaObjects[0], &canTivaHWAttrs[0]},
{NULL, NULL, NULL}
};
void EK_TM4C1294XL_initCAN(void)
{
/*TODO:implement_me*/
/*hint: pin configuration goes here*/
CAN_Init();
}
TIRTOS integrated CAN driver template with EK_TM4C1294XL target specific implementation.
This repos provides an implementation template only.
Use this repo as a git submodule for your TIRTOS project.
Issue `git submodule add https://es.technikum-wien.at/ti-connected-launchpad/tirtos_CAN_driver_template.git tirtos_can_driver` to clone this repos as a submodule into an existing git repository at loaction ./tirtos_can_driver.
It is recommended to add the submodule from commandline since CCS' git client seems to use the remote URI as submodule path.
In case you want to update the your repo to the latest commit of the referenced submodule call `git submodule update --remote references`
/*
*
* canTiva.c
*
* Created on: Aug 14, 2017
* Author: wenzl
*/
#include "include/canTiva.h"
/* \brief CAN function table for CANCTiva implementation
*
* Fill up with function names in the order of their definition appearance in CAN_FxnTable
*
*/
const CAN_FxnTable CANTiva_FxnTable = {
/*TODO:implement_me*/
};
Swi_Handle gCanBusOffSwi;
void CANBusOffSwiHandler(UArg arg0, UArg arg1) {
/*TODO:implement_me*/
}
int canTivaInit(CAN_Handle handle) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int canTivaOpen(CAN_Handle handle) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int canTivaClose(CAN_Handle handle) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int canTivaRegisterMsgObject(CAN_Handle handle,uint32_t objId, CAN_Msg *msg, uint32_t msgType) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int canTivaAlterRxCallback(CAN_Handle handle, CAN_RxCallback callback) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int canTivaGetStats(CAN_Handle handle, CAN_Stats *stats) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
void CANIntHandler(UArg uarg) {
/*TODO:implement_me*/
}
/*
* can_wrapper.c
*
* Created on: Aug 14, 2017
* Author: wenzl
*/
#include "include/EK_TM4C1294XL_CAN.h"
#include <stddef.h>
#include <stdint.h>
#include "include/can_driver.h"
/* Reference to external defined CAN_config structure */
extern const CAN_Config CAN_config[];
/*initialization marker*/
static int CAN_count = -1;
void CAN_Init(void) {
if (CAN_count == -1) {
/*Call each driver's init function */
for (CAN_count = 0; CAN_config[CAN_count].fxnTablePtr != NULL; CAN_count++) {
CAN_config[CAN_count].fxnTablePtr->canInit((CAN_Handle)&(CAN_config[CAN_count]));
}
}
}
int CAN_Open(int index) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int CAN_Close(int index) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int CAN_RegisterMsgObj(int index, int objId, CAN_Msg *txmsg, uint32_t msgType) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int CAN_AlterRxCallback(int index, CAN_RxCallback callback) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
int CAN_GetStats(int index, CAN_Stats *stats) {
/*TODO:implement_me*/
return CAN_SUCCESS;
}
/*
* EK_TM4C1294XL_CAN.h
*
* Created on: Feb 2, 2018
* Author: wenzl
*/
#ifndef LOCAL_INC_EK_TM4C1294XL_CAN_H_
#define LOCAL_INC_EK_TM4C1294XL_CAN_H_
/*
* --- CAN_0 wiring configuration ---
* Set JP4 and JP5 on the baseboard to CAN instead of UART for the CAN module to work properly.
* However, this causes UART0 to be unavailable for ICDI communication, but UART2 steps in.
* CAN_0 TX and RX are available via PA0 and PA1 through Booster Pack 2 X-9 and X-11 respectively.
*/
/*!
* @def EK_TM4C1294XL_CANName
* @brief Enumeration of CAN devices on the EK_TM4C1294XL development board
*/
typedef enum EK_TM4C1294XL_CANName {
EK_TM4C1294XL_CAN0,
EK_TM4C1294XL_CANCOUNT //!< Upper bound of devices available/enabled
} EK_TM4C1294XL_CANName;
/*!
* @brief Initialize board specific CAN settings
*
* This function initializes the board specific CAN settings and then calls
* the CAN_init function to initialize the CAN modules.
*
* The CAN peripherals controlled by the CAN module are determined by the
* CAN_config variable.
*/
extern void EK_TM4C1294XL_initCAN(void);
#endif /* LOCAL_INC_EK_TM4C1294XL_CAN_H_ */
/*!
*
* Hardware module specific CAN driver implementation for the TM4C1294NCPDT MCU
*
* canTiva.h
*
* Created on: Aug 14, 2017
* Author: wenzl
*/
#ifndef CANTIVA_H_
#define CANTIVA_H_
#include "EK_TM4C1294XL.h"
#include <stdbool.h>
#include <ti/sysbios/family/arm/m3/Hwi.h>
#include <ti/sysbios/knl/Swi.h>
#include <xdc/cfg/global.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <string.h>
#include <driverlib/can.h>
#include "can_driver.h"
/*originally defined in inc/tm4c1294ncpdt.h*/
#define CAN_INT_INTID_STATUS 0x00008000 // Status Interrupt
extern const CAN_FxnTable CANTiva_FxnTable;
/*! \brief Hardware specific CAN attributes block
*/
typedef struct CANTiva_HWAttrs{
uint32_t base_addr;//!< Base address of device
uint32_t clock;//!< System clock rate
uint32_t irq;//!< IRQ number
uint32_t brp;
uint8_t prop;
uint8_t ph1;
uint8_t ph2;
uint8_t sjw;
}CANTiva_HWAttrs;
/*! \brief Administrative CAN object
*
*/
typedef struct CANTiva_Object{
bool isOpen;//!< Check if device has been opened
CAN_Stats stats;//!< Statistics block of this device
volatile CAN_RxCallback rxCb; //!< Pointer to message received complete callback
}CANTiva_Object;
/*! \brief Initialize, but do not start, or enable the interrupts of all available CAN devices (register isr, set bitrate,..)
*
* \param handle Pointer to CAN_Config structure
* \return CAN_SUCCESS on success, negative value otherwise
*
*/
int canTivaInit(CAN_Handle handle);
/*! \brief Enable interrupts and start transmission and reception of frames
*
* \param handle Pointer to CAN_Config structure
* \return CAN_SUCCESS on success, negative value otherwise
*
*/
int canTivaOpen(CAN_Handle handle);
/*! \brief Stop CAN interrupts and cease transmission and reception of frames
*
* \param handle Pointer to CAN_Config structure
* \return CAN_SUCCESS on success, negative value otherwise
*
*/
int canTivaClose(CAN_Handle handle);
/*! \brief Initialize, but do not start all available CAN devices
*
* \param handle Pointer to CAN_Config structure
* \param objId Index of transfer block in CAN module memory
* \param *msg Pointer to CAN message block
* \param msgType Be it a transfer, receive, or remote message block
* \return CAN_SUCCESS on success, negative value otherwise
*
*/
int canTivaRegisterMsgObject(CAN_Handle handle,uint32_t objId, CAN_Msg *msg, uint32_t msgType);
/*! \brief Initialize, but do not start all available CAN devices
*
* \param handle Pointer to CAN_Config structure
* \param callback pointer to user supplied function that must be called upon reception of a frame has been completed
* \return CAN_SUCCESS on success, negative value otherwise
*
*/
int canTivaAlterRxCallback(CAN_Handle handle, CAN_RxCallback callback);
/*! \brief Get pointer to statistics block
*
* \param handle Pointer to CAN_Config structure
* \param *stats Pointer to statistics block
* \return CAN_SUCCESS on success, negative value otherwise
*
*/
int canTivaGetStats(CAN_Handle handle, CAN_Stats *stats);
/*! \brief CAN module interrupt handler
*
* \param uarg pointer to entry of CAN_Config structure
*
*/
void CANIntHandler(UArg uarg);
/*! \brief Software interrupt called upon interrupt detect as bus off condition
*
* \param arg0 Pointer to correct entry in the CAN_config structure
* \param arg1 unused
*
*/
void CANBusOffSwiHandler(UArg arg0, UArg arg1);
#endif /*ENABLE_CAN*/
/*!
* CAN HAL layer - Must be called by user applications
* can_wrapper.h
*
* Created on: Aug 14, 2017
* Author: wenzl
*/
#ifndef CAN_DRIVER_H_
#define CAN_DRIVER_H_
#include <stddef.h>
#include <stdint.h>
/* HAL function return messages*/
/*! CAN HAL function returns successfully */
#define CAN_SUCCESS (0)
/*! CAN generic error */
#define CAN_ERROR (-1)
/*! CAN_Handle is null */
#define CAN_HANDLE_IS_NULL (-2)
/*! CAN HAL device already opened*/
#define CAN_IS_OPEN (-3)
/*! CAN HAL device is already closed */
#define CAN_IS_CLOSED (-4)
/*! Specified CAN HAL device is invalid */
#define CAN_INVALID_DEVICE (-5)
/*! \brief Statistic block for a CAN module; Stores transmission, reception and error counters of a CAN module
*/
typedef struct CAN_Stats{
volatile uint32_t bus_off;//!< How often the node had to be taken off the bus counter
volatile uint32_t lec_stuff;//!< Bit stuffing error counter
volatile uint32_t lec_form;//!< Frame format error counter
volatile uint32_t lec_ack;//!< Acknowledgement error counter
volatile uint32_t lec_bit1;//!< Line level error counter - expected 1, read 0
volatile uint32_t lec_bit0;//!< Line level error counter - expected 0, read 1
volatile uint32_t lec_crc;//!< CRC checksum error counter
volatile uint32_t txok;//!< Transmission OK counter
volatile uint32_t rxok;//!< Reception OK counter
} CAN_Stats;
/*! \brief Structure of a CAN message object in memory
*/
typedef struct CAN_Msg {
uint32_t ui32MsgID; //!< CAN header message ID
uint32_t ui32MsgIDMask; //!< Mask for message id filter, see driver lib manual for details
uint32_t ui32Flags; //!< Configure this message object as sender, receiver or remote frame
uint32_t ui32MsgLen; //!< Length of message
uint8_t *pui8MsgData; //!< pointer to message
}CAN_Msg;
/* Function pointer type definitions for HAL function table*/
typedef struct CAN_Config *CAN_Handle;
typedef void (*CAN_RxCallback) (CAN_Msg *msgObj);
typedef int (*FxnCANInit) (CAN_Handle handle);
typedef int (*FxnCANOpen) (CAN_Handle handle);
typedef int (*FxnCANClose) (CAN_Handle handle);
typedef int (*FxnCANGetStats) (CAN_Handle handle, CAN_Stats *stats);
typedef int (*FxnCANRegisterMsgObject) (CAN_Handle handle, uint32_t objId, CAN_Msg *msg, uint32_t msgType);
typedef int (*FxnCANAlterRxCallback) (CAN_Handle handle, CAN_RxCallback callback);
/*! \brief Function pointer table connecting HAL functions with CAN device object
*/
typedef struct CAN_FxnTable{
FxnCANInit canInit;
FxnCANOpen canOpen;
FxnCANClose canClose;
FxnCANGetStats canGetStats;
FxnCANRegisterMsgObject canRegMsgObject;
FxnCANAlterRxCallback canAlterCb;
}CAN_FxnTable;
/*! \brief Representation of an abstract CAN device in memory
*/
typedef struct CAN_Config{
CAN_FxnTable const *fxnTablePtr; //!< Pointer to function pointer table; This connects the HAL functions to the device specific driver functions
void *object; //!< Generic pointer to a device object handle; It represents a hardware agnostic structure to store administrative properties; See the CAN_Config initialization in EK_TM4C*.c for example
void const *hwAttrs; //!< Pointer to a structure holding the device specific hardware parameters, such as base address, interrupt number,...
}CAN_Config;
/*! \brief Initialize, but do not start all available CAN devices
*
* Iterates through all available can devices and calls hw specific init functions
*
*/
void CAN_Init(void);
/*! \brief Start a specific CAN device
*
* Call hw specific open function through CAN_config structure
*
* \param index Specified CAN module
* \return negative value in case something went wrong, otherwise CAN_SUCCESS
*/
int CAN_Open(int index);
/*! \brief Stop specific CAN device
*
* Call hw specific close function through CAN_config structure
*
* \param index Specified CAN module
* \return negative value in case something went wrong, otherwise CAN_SUCCESS
*
*/
int CAN_Close(int index);
/*! \brief Register new message object for transmission or reception at specific CAN device
*
* Call hw specific function to register transmission and reception objects through CAN_config structure
*
* \param index Specified CAN module
* \param objId Transfer slot of can driver
* \param *msg Pointer to message structure
* \param msgType Transmit, Receive, Remote frame type
* \return negative value in case something went wrong, otherwise CAN_SUCCESS
*
*/
int CAN_RegisterMsgObj(int index, int objId, CAN_Msg *msg, uint32_t msgType);
/*! \brief Add receiver callback CAN device
*
* Call hw specific function to receiver callback through CAN_config structure
*
* \param index Specified CAN module
* \param callback Callback function triggered upon reception completion
* \return negative value in case something went wrong, otherwise CAN_SUCCESS
*
*/
int CAN_AlterRxCallback(int index, CAN_RxCallback callback);
/*! \brief Get reference to statistics object of CAN device
*
* Call hw specific function to obtain statistics object CAN_config structure
*
* \param index Specified CAN module
* \param *stats pointer to statistics block
* \return negative value in case something went wrong, otherwise CAN_SUCCESS
*/
int CAN_GetStats(int index, CAN_Stats *stats);
#endif /* CAN_DRIVER_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment