git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1370 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2009-12-02 16:24:32 +00:00
parent 3d182788ee
commit c2ad391323
5 changed files with 92 additions and 29 deletions

View File

@ -56,8 +56,9 @@
typedef enum {
CAN_UNINIT = 0, /**< @brief Not initialized. */
CAN_STOP = 1, /**< @brief Stopped. */
CAN_READY = 2, /**< @brief Ready. */
CAN_SLEEP = 3 /**< @brief Sleep state. */
CAN_STARTING = 2, /**< @brief Starting. */
CAN_READY = 3, /**< @brief Ready. */
CAN_SLEEP = 4 /**< @brief Sleep state. */
} canstate_t;
#include "can_lld.h"

View File

@ -163,21 +163,25 @@ void can_lld_init(void) {
*/
void can_lld_start(CANDriver *canp) {
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
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;
}
/* Configuration.*/
canp->cd_can->MCR = canp->cd_config->cc_mcr;
#endif
/* Entering initialization mode. */
canp->cd_state = CAN_STARTING;
canp->cd_can->MCR = CAN_MCR_INRQ;
while ((canp->cd_can->MSR & CAN_MSR_INAK) == 0)
chThdSleepS(1);
/* Initialization.*/
canp->cd_can->BTR = canp->cd_config->cc_btr;
canp->cd_can->MCR = canp->cd_config->cc_mcr;
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 |
@ -196,7 +200,6 @@ void can_lld_stop(CANDriver *canp) {
#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);

View File

@ -29,11 +29,15 @@
#if CH_HAL_USE_CAN || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief This switch defines whether the driver implementation supports
* a low power switch mode with automatic an wakeup feature.
*/
#define CAN_SUPPORTS_SLEEP TRUE
#define CAN_SUPPORTS_SLEEP TRUE
/*===========================================================================*/
/* Driver pre-compile time settings. */
@ -69,10 +73,6 @@
#define CAN_USE_SLEEP_MODE FALSE
#endif /* !CAN_SUPPORTS_SLEEP */
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@ -99,6 +99,39 @@ typedef struct {
};
} CANFrame;
/**
* @brief CAN filter.
* @note Refer to the STM32 reference manual for info about filters.
*/
typedef struct {
/**
* @brief Filter mode.
* @note This bit represent the CAN_FM1R register bit associated to this
* filter (0=mask mode, 1=list mode).
*/
uint32_t cf_mode:1;
/**
* @brief Filter sclae.
* @note This bit represent the CAN_FS1R register bit associated to this
* filter (0=16 bits mode, 1=32 bits mode).
*/
uint32_t cf_scale:1;
/**
* @brief Filter mode.
* @note This bit represent the CAN_FFA1R register bit associated to this
* filter, must be set to zero in this version of the driver.
*/
uint32_t cf_assignment:1;
/**
* @brief Filter register 1 (identifier).
*/
uint32_t cf_register1;
/**
* @brief Filter register 2 (mask/identifier depending on cf_mode=0/1).
*/
uint32_t cf_register2;
} CANFilter;
/**
* @brief Driver configuration structure.
*/
@ -115,6 +148,18 @@ typedef struct {
* their status in this field.
*/
uint32_t cc_btr;
/**
* @brief Number of elements into the filters array.
* @note By setting this field to zero a default filter is enabled that
* allows all frames, this should be adequate for simple applications.
*/
uint32_t cc_num;
/**
* @brief Pointer to an array of @p CANFilter structures.
* @note This field can be set to @p NULL if the field @p cc_num is set to
* zero.
*/
const CANFilter *cc_filters;
} CANConfig;
/**
@ -138,7 +183,12 @@ typedef struct {
*/
Semaphore cd_rxsem;
/**
* @brief One or more frames become available.
* @brief One or more frames become available.
* @note After broadcasting this event it will not be broadcasted again
* until the received frames queue has been completely emptied. It
* is <b>not</b> broadcasted for each received frame. It is
* responsibility of the application to empty the queue by repeatedly
* invoking @p chReceive() when listening to this event.
*/
EventSource cd_rxfull_event;
/**

View File

@ -69,12 +69,18 @@ void canStart(CANDriver *canp, const CANConfig *config) {
chDbgCheck((canp != NULL) && (config != NULL), "canStart");
chSysLock();
chDbgAssert((canp->cd_state == CAN_STOP) || (canp->cd_state == CAN_READY),
chDbgAssert((canp->cd_state == CAN_STOP) ||
(canp->cd_state == CAN_STARTING) ||
(canp->cd_state == CAN_READY),
"canStart(), #1",
"invalid state");
canp->cd_config = config;
can_lld_start(canp);
canp->cd_state = CAN_READY;
while (canp->cd_state == CAN_STARTING)
chThdSleepS(1);
if (canp->cd_state == CAN_STOP) {
canp->cd_config = config;
can_lld_start(canp);
canp->cd_state = CAN_READY;
}
chSysUnlock();
}
@ -145,12 +151,15 @@ msg_t canTransmit(CANDriver *canp, const CANFrame *cfp, systime_t timeout) {
* @param[out] cfp pointer to the buffer where the CAN frame is copied
* @param[in] timeout the number of ticks before the operation timeouts,
* the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout.
* - @a TIME_IMMEDIATE immediate timeout (useful in an
* event driven scenario where a thread never blocks
* for I/O).
* - @a TIME_INFINITE no timeout.
* .
* @return The operation result.
* @retval RDY_OK a frame has been received and placed in the buffer.
* @retval RDY_TIMEOUT operation not finished within the specified time.
* @retval RDY_TIMEOUT operation not finished within the specified time or
* frame not immediately available if invoked using @p TIME_IMMEDIATE.
* @retval RDY_RESET driver stopped while waiting.
*/
msg_t canReceive(CANDriver *canp, CANFrame *cfp, systime_t timeout) {

View File

@ -28,11 +28,11 @@
#define _XXX_LLD_H_
/*===========================================================================*/
/* Driver pre-compile time settings. */
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver constants. */
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/