git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1369 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
8a433087af
commit
3d182788ee
|
@ -45,7 +45,7 @@
|
||||||
* @brief Enables the CAN subsystem.
|
* @brief Enables the CAN subsystem.
|
||||||
*/
|
*/
|
||||||
#if !defined(CH_HAL_USE_CAN) || defined(__DOXYGEN__)
|
#if !defined(CH_HAL_USE_CAN) || defined(__DOXYGEN__)
|
||||||
#define CH_HAL_USE_CAN FALSE
|
#define CH_HAL_USE_CAN TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,27 @@
|
||||||
|
|
||||||
#if CH_HAL_USE_CAN || defined(__DOXYGEN__)
|
#if CH_HAL_USE_CAN || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Errors rate warning.
|
||||||
|
*/
|
||||||
|
#define CAN_LIMIT_WARNING 1
|
||||||
|
/**
|
||||||
|
* @brief Errors rate error.
|
||||||
|
*/
|
||||||
|
#define CAN_LIMIT_ERROR 2
|
||||||
|
/**
|
||||||
|
* @brief Bus off condition reached.
|
||||||
|
*/
|
||||||
|
#define CAN_BUS_OFF_ERROR 4
|
||||||
|
/**
|
||||||
|
* @brief Framing error of some kind on the CAN bus.
|
||||||
|
*/
|
||||||
|
#define CAN_FRAMING_ERROR 8
|
||||||
|
/**
|
||||||
|
* @brief Overflow in receive queue.
|
||||||
|
*/
|
||||||
|
#define CAN_OVERFLOW_ERROR 16
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Driver state machine possible states.
|
* @brief Driver state machine possible states.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -112,7 +112,7 @@ CH_IRQ_HANDLER(Vector6C) {
|
||||||
void adc_lld_init(void) {
|
void adc_lld_init(void) {
|
||||||
|
|
||||||
#if USE_STM32_ADC1
|
#if USE_STM32_ADC1
|
||||||
/* ADC reset, ensures reset state in order to avoid truouble with JTAGs.*/
|
/* ADC reset, ensures reset state in order to avoid trouble with JTAGs.*/
|
||||||
RCC->APB2RSTR = RCC_APB2RSTR_ADC1RST;
|
RCC->APB2RSTR = RCC_APB2RSTR_ADC1RST;
|
||||||
RCC->APB2RSTR = 0;
|
RCC->APB2RSTR = 0;
|
||||||
|
|
||||||
|
|
|
@ -68,12 +68,24 @@ CH_IRQ_HANDLER(Vector8C) {
|
||||||
* CAN1 RX0 interrupt handler.
|
* CAN1 RX0 interrupt handler.
|
||||||
*/
|
*/
|
||||||
CH_IRQ_HANDLER(Vector90) {
|
CH_IRQ_HANDLER(Vector90) {
|
||||||
|
uint32_t rf0r;
|
||||||
|
|
||||||
CH_IRQ_PROLOGUE();
|
CH_IRQ_PROLOGUE();
|
||||||
|
|
||||||
/* No more events until the incoming messages queues are emptied.*/
|
rf0r = CAN1->RF0R;
|
||||||
CAN1->IER &= ~(CAN_IER_FMPIE0 | CAN_IER_FMPIE1);
|
chSysLockFromIsr();
|
||||||
|
if ((rf0r & CAN_RF0R_FMP0) > 0) {
|
||||||
|
/* No more receive events until the queue 0 has been emptied.*/
|
||||||
|
CAN1->IER &= ~CAN_IER_FMPIE0;
|
||||||
chEvtBroadcastI(&CAND1.cd_rxfull_event);
|
chEvtBroadcastI(&CAND1.cd_rxfull_event);
|
||||||
|
}
|
||||||
|
if ((rf0r & CAN_RF0R_FOVR0) > 0) {
|
||||||
|
/* Overflow events handling.*/
|
||||||
|
CAN1->RF0R = CAN_RF0R_FOVR0;
|
||||||
|
canAddFlagsI(&CAND1, CAN_OVERFLOW_ERROR);
|
||||||
|
chEvtBroadcastI(&CAND1.cd_error_event);
|
||||||
|
}
|
||||||
|
chSysUnlockFromIsr();
|
||||||
|
|
||||||
CH_IRQ_EPILOGUE();
|
CH_IRQ_EPILOGUE();
|
||||||
}
|
}
|
||||||
|
@ -85,9 +97,7 @@ CH_IRQ_HANDLER(Vector94) {
|
||||||
|
|
||||||
CH_IRQ_PROLOGUE();
|
CH_IRQ_PROLOGUE();
|
||||||
|
|
||||||
/* No more events until the incoming messages queues are emptied.*/
|
chSysHalt(); /* Not supported (yet).*/
|
||||||
CAN1->IER &= ~(CAN_IER_FMPIE0 | CAN_IER_FMPIE1);
|
|
||||||
chEvtBroadcastI(&CAND1.cd_rxfull_event);
|
|
||||||
|
|
||||||
CH_IRQ_EPILOGUE();
|
CH_IRQ_EPILOGUE();
|
||||||
}
|
}
|
||||||
|
@ -96,12 +106,32 @@ CH_IRQ_HANDLER(Vector94) {
|
||||||
* CAN1 SCE interrupt handler.
|
* CAN1 SCE interrupt handler.
|
||||||
*/
|
*/
|
||||||
CH_IRQ_HANDLER(Vector98) {
|
CH_IRQ_HANDLER(Vector98) {
|
||||||
|
uint32_t msr;
|
||||||
|
|
||||||
CH_IRQ_PROLOGUE();
|
CH_IRQ_PROLOGUE();
|
||||||
|
|
||||||
canAddFlagsI(&CAND1, 1);
|
msr = CAN1->MSR;
|
||||||
|
CAN1->MSR = CAN_MSR_ERRI | CAN_MSR_WKUI | CAN_MSR_SLAKI;
|
||||||
|
/* Wakeup event.*/
|
||||||
|
if (msr & CAN_MSR_WKUI) {
|
||||||
|
chSysLockFromIsr();
|
||||||
|
chEvtBroadcastI(&CAND1.cd_wakeup_event);
|
||||||
|
chSysUnlockFromIsr();
|
||||||
|
}
|
||||||
|
/* Error event.*/
|
||||||
|
if (msr & CAN_MSR_ERRI) {
|
||||||
|
canstatus_t flags;
|
||||||
|
uint32_t esr = CAN1->ESR;
|
||||||
|
|
||||||
|
CAN1->ESR &= ~CAN_ESR_LEC;
|
||||||
|
flags = (canstatus_t)(esr & 7);
|
||||||
|
if ((esr & CAN_ESR_LEC) > 0)
|
||||||
|
flags |= CAN_FRAMING_ERROR;
|
||||||
|
chSysLockFromIsr();
|
||||||
|
canAddFlagsI(&CAND1, flags);
|
||||||
chEvtBroadcastI(&CAND1.cd_error_event);
|
chEvtBroadcastI(&CAND1.cd_error_event);
|
||||||
CAN1->MSR = CAN_MSR_ERRI;
|
chSysUnlockFromIsr();
|
||||||
|
}
|
||||||
|
|
||||||
CH_IRQ_EPILOGUE();
|
CH_IRQ_EPILOGUE();
|
||||||
}
|
}
|
||||||
|
@ -115,6 +145,15 @@ CH_IRQ_HANDLER(Vector98) {
|
||||||
*/
|
*/
|
||||||
void can_lld_init(void) {
|
void can_lld_init(void) {
|
||||||
|
|
||||||
|
#if USE_STM32_CAN1
|
||||||
|
/* CAN reset, ensures reset state in order to avoid trouble with JTAGs.*/
|
||||||
|
RCC->APB1RSTR = RCC_APB1RSTR_CAN1RST;
|
||||||
|
RCC->APB1RSTR = 0;
|
||||||
|
|
||||||
|
/* Driver initialization.*/
|
||||||
|
canObjectInit(&CAND1);
|
||||||
|
CAND1.cd_can = CAN1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,8 +165,23 @@ void can_lld_start(CANDriver *canp) {
|
||||||
|
|
||||||
if (canp->cd_state == CAN_STOP) {
|
if (canp->cd_state == CAN_STOP) {
|
||||||
/* Clock activation.*/
|
/* Clock activation.*/
|
||||||
|
#if USE_STM32_CAN1
|
||||||
|
if (&CAND1 == canp) {
|
||||||
|
NVICEnableVector(USB_HP_CAN1_TX_IRQn, STM32_CAN1_IRQ_PRIORITY);
|
||||||
|
NVICEnableVector(USB_LP_CAN1_RX0_IRQn, STM32_CAN1_IRQ_PRIORITY);
|
||||||
|
NVICEnableVector(CAN1_RX1_IRQn, STM32_CAN1_IRQ_PRIORITY);
|
||||||
|
NVICEnableVector(CAN1_SCE_IRQn, STM32_CAN1_IRQ_PRIORITY);
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* Configuration.*/
|
/* Configuration.*/
|
||||||
|
canp->cd_can->MCR = canp->cd_config->cc_mcr;
|
||||||
|
canp->cd_can->BTR = canp->cd_config->cc_btr;
|
||||||
|
canp->cd_can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
|
||||||
|
CAN_IER_WKUIE | CAN_IER_ERRIE | CAN_IER_LECIE |
|
||||||
|
CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE |
|
||||||
|
CAN_IER_FOVIE0 | CAN_IER_FOVIE1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,6 +191,21 @@ void can_lld_start(CANDriver *canp) {
|
||||||
*/
|
*/
|
||||||
void can_lld_stop(CANDriver *canp) {
|
void can_lld_stop(CANDriver *canp) {
|
||||||
|
|
||||||
|
/* If in ready state then disables the CAN clock.*/
|
||||||
|
if (canp->cd_state == CAN_READY) {
|
||||||
|
#if USE_STM32_CAN1
|
||||||
|
if (&CAND1 == canp) {
|
||||||
|
CAN1->MCR = 0x00010002; /* Register reset value. */
|
||||||
|
CAN1->BTR = 0x01230000; /* Register reset value. */
|
||||||
|
CAN1->IER = 0x00000000; /* All sources disabled. */
|
||||||
|
NVICDisableVector(USB_HP_CAN1_TX_IRQn);
|
||||||
|
NVICDisableVector(USB_LP_CAN1_RX0_IRQn);
|
||||||
|
NVICDisableVector(CAN1_RX1_IRQn);
|
||||||
|
NVICDisableVector(CAN1_SCE_IRQn);
|
||||||
|
RCC->APB1ENR &= ~RCC_APB1ENR_CAN1EN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ADC1 driver enable switch.
|
* @brief CAN1 driver enable switch.
|
||||||
* @details If set to @p TRUE the support for ADC1 is included.
|
* @details If set to @p TRUE the support for ADC1 is included.
|
||||||
* @note The default is @p TRUE.
|
* @note The default is @p TRUE.
|
||||||
*/
|
*/
|
||||||
|
@ -48,6 +48,14 @@
|
||||||
#define USE_STM32_CAN1 TRUE
|
#define USE_STM32_CAN1 TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CAN1 interrupt priority level setting.
|
||||||
|
* @note @p BASEPRI_KERNEL >= @p STM32_SPI1_IRQ_PRIORITY > @p PRIORITY_PENDSV.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_CAN1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_CAN1_IRQ_PRIORITY 0xB0
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sleep mode related APIs inclusion switch.
|
* @brief Sleep mode related APIs inclusion switch.
|
||||||
* @note This switch is enforced to @p FALSE if the driver implementation
|
* @note This switch is enforced to @p FALSE if the driver implementation
|
||||||
|
@ -159,7 +167,7 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Pointer to the CAN registers.
|
* @brief Pointer to the CAN registers.
|
||||||
*/
|
*/
|
||||||
CAN_TypeDef *cd_canp;
|
CAN_TypeDef *cd_can;
|
||||||
} CANDriver;
|
} CANDriver;
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -50,6 +50,8 @@ void canObjectInit(CANDriver *canp) {
|
||||||
chSemInit(&canp->cd_rxsem, 0);
|
chSemInit(&canp->cd_rxsem, 0);
|
||||||
chEvtInit(&canp->cd_rxfull_event);
|
chEvtInit(&canp->cd_rxfull_event);
|
||||||
chEvtInit(&canp->cd_txempty_event);
|
chEvtInit(&canp->cd_txempty_event);
|
||||||
|
chEvtInit(&canp->cd_error_event);
|
||||||
|
canp->cd_status = 0;
|
||||||
#if CAN_USE_SLEEP_MODE
|
#if CAN_USE_SLEEP_MODE
|
||||||
chEvtInit(&canp->cd_sleep_event);
|
chEvtInit(&canp->cd_sleep_event);
|
||||||
chEvtInit(&canp->cd_wakeup_event);
|
chEvtInit(&canp->cd_wakeup_event);
|
||||||
|
@ -91,6 +93,7 @@ void canStop(CANDriver *canp) {
|
||||||
"invalid state");
|
"invalid state");
|
||||||
can_lld_stop(canp);
|
can_lld_stop(canp);
|
||||||
canp->cd_state = CAN_STOP;
|
canp->cd_state = CAN_STOP;
|
||||||
|
canp->cd_status = 0;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue