git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1368 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
770c4873d2
commit
8a433087af
|
@ -41,6 +41,14 @@ typedef enum {
|
|||
|
||||
#include "can_lld.h"
|
||||
|
||||
/**
|
||||
* @brief Adds some flags to the CAN status mask.
|
||||
*
|
||||
* @param[in] canp pointer to the @p CANDriver object
|
||||
* @param[in] mask flags to be added to the status mask
|
||||
*/
|
||||
#define canAddFlagsI(canp, mask) ((canp)->cd_status |= (mask))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -50,6 +58,7 @@ extern "C" {
|
|||
void canStop(CANDriver *canp);
|
||||
msg_t canTransmit(CANDriver *canp, const CANFrame *cfp, systime_t timeout);
|
||||
msg_t canReceive(CANDriver *canp, CANFrame *cfp, systime_t timeout);
|
||||
canstatus_t canGetAndClearFlags(CANDriver *canp);
|
||||
#if CAN_USE_SLEEP_MODE
|
||||
void canSleep(CANDriver *canp);
|
||||
void canWakeup(CANDriver *canp);
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
/* Low Level Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_STM32_ADC1 || defined(__DOXYGEN__)
|
||||
/** @brief ADC1 driver identifier.*/
|
||||
#if USE_STM32_ADC1 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ typedef struct {
|
|||
|
||||
/** @cond never*/
|
||||
#if USE_STM32_ADC1
|
||||
ADCDriver ADCD1;
|
||||
extern ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
/* Low Level Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief ADC1 driver identifier.*/
|
||||
#if USE_STM32_CAN1 || defined(__DOXYGEN__)
|
||||
CANDriver CAND1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -45,6 +50,62 @@
|
|||
/* Low Level Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* CAN1 TX interrupt handler.
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector8C) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
/* No more events until a message is transmitted.*/
|
||||
CAN1->IER &= ~CAN_IER_TMEIE;
|
||||
chEvtBroadcastI(&CAND1.cd_txempty_event);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*
|
||||
* CAN1 RX0 interrupt handler.
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector90) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
/* No more events until the incoming messages queues are emptied.*/
|
||||
CAN1->IER &= ~(CAN_IER_FMPIE0 | CAN_IER_FMPIE1);
|
||||
chEvtBroadcastI(&CAND1.cd_rxfull_event);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*
|
||||
* CAN1 RX1 interrupt handler.
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector94) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
/* No more events until the incoming messages queues are emptied.*/
|
||||
CAN1->IER &= ~(CAN_IER_FMPIE0 | CAN_IER_FMPIE1);
|
||||
chEvtBroadcastI(&CAND1.cd_rxfull_event);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*
|
||||
* CAN1 SCE interrupt handler.
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector98) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
canAddFlagsI(&CAND1, 1);
|
||||
chEvtBroadcastI(&CAND1.cd_error_event);
|
||||
CAN1->MSR = CAN_MSR_ERRI;
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Low Level Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -63,7 +124,7 @@ void can_lld_init(void) {
|
|||
*/
|
||||
void can_lld_start(CANDriver *canp) {
|
||||
|
||||
if (canp->can_state == CAN_STOP) {
|
||||
if (canp->cd_state == CAN_STOP) {
|
||||
/* Clock activation.*/
|
||||
}
|
||||
/* Configuration.*/
|
||||
|
|
|
@ -39,6 +39,15 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief ADC1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(USE_STM32_CAN1) || defined(__DOXYGEN__)
|
||||
#define USE_STM32_CAN1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Sleep mode related APIs inclusion switch.
|
||||
* @note This switch is enforced to @p FALSE if the driver implementation
|
||||
|
@ -60,6 +69,11 @@
|
|||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief CAN status flags.
|
||||
*/
|
||||
typedef uint32_t canstatus_t;
|
||||
|
||||
/**
|
||||
* @brief CAN frame.
|
||||
* @note Accessing the frame data as word16 or word32 is not portable because
|
||||
|
@ -79,9 +93,20 @@ typedef struct {
|
|||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief CAN MCR register initialization data.
|
||||
* @note Some bits in this register are enforced by the driver regardless
|
||||
* their status in this field.
|
||||
*/
|
||||
uint32_t cc_mcr;
|
||||
/**
|
||||
* @brief CAN BTR register initialization data.
|
||||
* @note Some bits in this register are enforced by the driver regardless
|
||||
* their status in this field.
|
||||
*/
|
||||
uint32_t cc_btr;
|
||||
} CANConfig;
|
||||
|
||||
/**
|
||||
|
@ -91,44 +116,61 @@ typedef struct {
|
|||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
canstate_t can_state;
|
||||
canstate_t cd_state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const CANConfig *can_config;
|
||||
const CANConfig *cd_config;
|
||||
/**
|
||||
* @brief Transmission queue semaphore.
|
||||
*/
|
||||
Semaphore can_txsem;
|
||||
Semaphore cd_txsem;
|
||||
/**
|
||||
* @brief Receive queue semaphore.
|
||||
*/
|
||||
Semaphore can_rxsem;
|
||||
Semaphore cd_rxsem;
|
||||
/**
|
||||
* @brief One or more frames become available.
|
||||
*/
|
||||
EventSource can_rxfull_event;
|
||||
EventSource cd_rxfull_event;
|
||||
/**
|
||||
* @brief One or more transmission slots become available.
|
||||
* @brief One or more transmission slots become available.
|
||||
*/
|
||||
EventSource can_txempty_event;
|
||||
EventSource cd_txempty_event;
|
||||
/**
|
||||
* @brief A CAN bus error happened.
|
||||
*/
|
||||
EventSource cd_error_event;
|
||||
/**
|
||||
* @brief Error flags set when an error event is broadcasted.
|
||||
*/
|
||||
canstatus_t cd_status;
|
||||
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
|
||||
/**
|
||||
* @brief Entering sleep state event.
|
||||
*/
|
||||
EventSource can_sleep_event;
|
||||
EventSource cd_sleep_event;
|
||||
/**
|
||||
* @brief Exiting sleep state event.
|
||||
*/
|
||||
EventSource can_wakeup_event;
|
||||
EventSource cd_wakeup_event;
|
||||
#endif /* CAN_USE_SLEEP_MODE */
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the CAN registers.
|
||||
*/
|
||||
CAN_TypeDef *cd_canp;
|
||||
} CANDriver;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @cond never*/
|
||||
#if USE_STM32_CAN1
|
||||
extern CANDriver CAND1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -146,6 +188,7 @@ extern "C" {
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/** @endcond*/
|
||||
|
||||
#endif /* CH_HAL_USE_CAN */
|
||||
|
||||
|
|
|
@ -44,15 +44,15 @@ void canInit(void) {
|
|||
*/
|
||||
void canObjectInit(CANDriver *canp) {
|
||||
|
||||
canp->can_state = CAN_STOP;
|
||||
canp->can_config = NULL;
|
||||
chSemInit(&canp->can_txsem, 0);
|
||||
chSemInit(&canp->can_rxsem, 0);
|
||||
chEvtInit(&canp->can_rxfull_event);
|
||||
chEvtInit(&canp->can_txempty_event);
|
||||
canp->cd_state = CAN_STOP;
|
||||
canp->cd_config = NULL;
|
||||
chSemInit(&canp->cd_txsem, 0);
|
||||
chSemInit(&canp->cd_rxsem, 0);
|
||||
chEvtInit(&canp->cd_rxfull_event);
|
||||
chEvtInit(&canp->cd_txempty_event);
|
||||
#if CAN_USE_SLEEP_MODE
|
||||
chEvtInit(&canp->can_sleep_event);
|
||||
chEvtInit(&canp->can_wakeup_event);
|
||||
chEvtInit(&canp->cd_sleep_event);
|
||||
chEvtInit(&canp->cd_wakeup_event);
|
||||
#endif /* CAN_USE_SLEEP_MODE */
|
||||
}
|
||||
|
||||
|
@ -67,12 +67,12 @@ void canStart(CANDriver *canp, const CANConfig *config) {
|
|||
chDbgCheck((canp != NULL) && (config != NULL), "canStart");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((canp->can_state == CAN_STOP) || (canp->can_state == CAN_READY),
|
||||
chDbgAssert((canp->cd_state == CAN_STOP) || (canp->cd_state == CAN_READY),
|
||||
"canStart(), #1",
|
||||
"invalid state");
|
||||
canp->can_config = config;
|
||||
canp->cd_config = config;
|
||||
can_lld_start(canp);
|
||||
canp->can_state = CAN_READY;
|
||||
canp->cd_state = CAN_READY;
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
|
@ -86,11 +86,11 @@ void canStop(CANDriver *canp) {
|
|||
chDbgCheck(canp != NULL, "canStop");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((canp->can_state == CAN_STOP) || (canp->can_state == CAN_READY),
|
||||
chDbgAssert((canp->cd_state == CAN_STOP) || (canp->cd_state == CAN_READY),
|
||||
"canStop(), #1",
|
||||
"invalid state");
|
||||
can_lld_stop(canp);
|
||||
canp->can_state = CAN_STOP;
|
||||
canp->cd_state = CAN_STOP;
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
|
@ -118,11 +118,11 @@ msg_t canTransmit(CANDriver *canp, const CANFrame *cfp, systime_t timeout) {
|
|||
chDbgCheck((canp != NULL) && (cfp != NULL), "canTransmit");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((canp->can_state == CAN_READY) || (canp->can_state == CAN_SLEEP),
|
||||
chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
|
||||
"canTransmit(), #1",
|
||||
"invalid state");
|
||||
if ((canp->can_state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
|
||||
msg = chSemWaitTimeoutS(&canp->can_txsem, timeout);
|
||||
if ((canp->cd_state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
|
||||
msg = chSemWaitTimeoutS(&canp->cd_txsem, timeout);
|
||||
if (msg != RDY_OK) {
|
||||
chSysUnlock();
|
||||
return msg;
|
||||
|
@ -156,11 +156,11 @@ msg_t canReceive(CANDriver *canp, CANFrame *cfp, systime_t timeout) {
|
|||
chDbgCheck((canp != NULL) && (cfp != NULL), "canReceive");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((canp->can_state == CAN_READY) || (canp->can_state == CAN_SLEEP),
|
||||
chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
|
||||
"canReceive(), #1",
|
||||
"invalid state");
|
||||
if ((canp->can_state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
|
||||
msg = chSemWaitTimeoutS(&canp->can_rxsem, timeout);
|
||||
if ((canp->cd_state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
|
||||
msg = chSemWaitTimeoutS(&canp->cd_rxsem, timeout);
|
||||
if (msg != RDY_OK) {
|
||||
chSysUnlock();
|
||||
return msg;
|
||||
|
@ -171,6 +171,23 @@ msg_t canReceive(CANDriver *canp, CANFrame *cfp, systime_t timeout) {
|
|||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the current status mask and clears it.
|
||||
*
|
||||
* @param[in] canp pointer to the @p CANDriver object
|
||||
*
|
||||
* @return The status flags mask.
|
||||
*/
|
||||
canstatus_t canGetAndClearFlags(CANDriver *canp) {
|
||||
canstatus_t status;
|
||||
|
||||
chSysLock();
|
||||
status = canp->cd_status;
|
||||
canp->cd_status = 0;
|
||||
chSysUnlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Enters the sleep mode.
|
||||
|
@ -182,13 +199,13 @@ void canSleep(CANDriver *canp) {
|
|||
chDbgCheck(canp != NULL, "canSleep");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((canp->can_state == CAN_READY) || (canp->can_state == CAN_SLEEP),
|
||||
chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
|
||||
"canSleep(), #1",
|
||||
"invalid state");
|
||||
if (canp->can_state == CAN_READY) {
|
||||
if (canp->cd_state == CAN_READY) {
|
||||
can_lld_sleep(canp);
|
||||
canp->can_state = CAN_SLEEP;
|
||||
chEvtBroadcastI(&canp->can_sleep_event);
|
||||
canp->cd_state = CAN_SLEEP;
|
||||
chEvtBroadcastI(&canp->cd_sleep_event);
|
||||
chSchRescheduleS();
|
||||
}
|
||||
chSysUnlock();
|
||||
|
@ -206,13 +223,13 @@ void canWakeup(CANDriver *canp) {
|
|||
chDbgCheck(canp != NULL, "canWakeup");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((canp->can_state == CAN_READY) || (canp->can_state == CAN_SLEEP),
|
||||
chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
|
||||
"canWakeup(), #1",
|
||||
"invalid state");
|
||||
if (canp->can_state == CAN_SLEEP) {
|
||||
if (canp->cd_state == CAN_SLEEP) {
|
||||
can_lld_wakeup(canp);
|
||||
canp->can_state = CAN_READY;
|
||||
chEvtBroadcastI(&canp->can_wakeup_event);
|
||||
canp->cd_state = CAN_READY;
|
||||
chEvtBroadcastI(&canp->cd_wakeup_event);
|
||||
chSchRescheduleS();
|
||||
}
|
||||
chSysUnlock();
|
||||
|
|
|
@ -60,6 +60,11 @@
|
|||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief CAN status flags.
|
||||
*/
|
||||
typedef uint32_t canstatus_t;
|
||||
|
||||
/**
|
||||
* @brief CAN frame.
|
||||
* @note Accessing the frame data as word16 or word32 is not portable because
|
||||
|
@ -91,36 +96,44 @@ typedef struct {
|
|||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
canstate_t can_state;
|
||||
canstate_t cd_state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const CANConfig *can_config;
|
||||
const CANConfig *cd_config;
|
||||
/**
|
||||
* @brief Transmission queue semaphore.
|
||||
* @brief Transmission queue semaphore.
|
||||
*/
|
||||
Semaphore can_txsem;
|
||||
Semaphore cd_txsem;
|
||||
/**
|
||||
* @brief Receive queue semaphore.
|
||||
*/
|
||||
Semaphore can_rxsem;
|
||||
Semaphore cd_rxsem;
|
||||
/**
|
||||
* @brief One or more frames become available.
|
||||
* @brief One or more frames become available.
|
||||
*/
|
||||
EventSource can_rxfull_event;
|
||||
EventSource cd_rxfull_event;
|
||||
/**
|
||||
* @brief One or more transmission slots become available.
|
||||
* @brief One or more transmission slots become available.
|
||||
*/
|
||||
EventSource can_txempty_event;
|
||||
EventSource cd_txempty_event;
|
||||
/**
|
||||
* @brief A CAN bus error happened.
|
||||
*/
|
||||
EventSource cd_error_event;
|
||||
/**
|
||||
* @brief Error flags set when an error event is broadcasted.
|
||||
*/
|
||||
canstatus_t cd_status;
|
||||
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
|
||||
/**
|
||||
* @brief Entering sleep state event.
|
||||
* @brief Entering sleep state event.
|
||||
*/
|
||||
EventSource can_sleep_event;
|
||||
EventSource cd_sleep_event;
|
||||
/**
|
||||
* @brief Exiting sleep state event.
|
||||
* @brief Exiting sleep state event.
|
||||
*/
|
||||
EventSource can_wakeup_event;
|
||||
EventSource cd_wakeup_event;
|
||||
#endif /* CAN_USE_SLEEP_MODE */
|
||||
/* End of the mandatory fields.*/
|
||||
} CANDriver;
|
||||
|
|
Loading…
Reference in New Issue