git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1374 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
980f0b6751
commit
03a0255b04
|
@ -213,6 +213,10 @@ void can_lld_start(CANDriver *canp) {
|
||||||
}
|
}
|
||||||
cfp++;
|
cfp++;
|
||||||
fmask <<= 1;
|
fmask <<= 1;
|
||||||
|
/* Gives a chance for preemption since this is a rather long loop.*/
|
||||||
|
chSysUnlock();
|
||||||
|
chThdYield();
|
||||||
|
chSysLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -239,7 +243,7 @@ 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 in ready state then disables the CAN peripheral.*/
|
||||||
if (canp->cd_state == CAN_READY) {
|
if (canp->cd_state == CAN_READY) {
|
||||||
#if USE_STM32_CAN1
|
#if USE_STM32_CAN1
|
||||||
if (&CAND1 == canp) {
|
if (&CAND1 == canp) {
|
||||||
|
@ -273,9 +277,31 @@ bool_t can_lld_can_transmit(CANDriver *canp) {
|
||||||
* @brief Inserts a frame into the transmit queue.
|
* @brief Inserts a frame into the transmit queue.
|
||||||
*
|
*
|
||||||
* @param[in] canp pointer to the @p CANDriver object
|
* @param[in] canp pointer to the @p CANDriver object
|
||||||
* @param[in] cfp pointer to the CAN frame to be transmitted
|
* @param[in] ctfp pointer to the CAN frame to be transmitted
|
||||||
*/
|
*/
|
||||||
void can_lld_transmit(CANDriver *canp, const CANTxFrame *ctfp) {
|
void can_lld_transmit(CANDriver *canp, const CANTxFrame *ctfp) {
|
||||||
|
uint32_t tir;
|
||||||
|
CAN_TxMailBox_TypeDef *tmbp;
|
||||||
|
|
||||||
|
/* Pointer to a free transmission mailbox.*/
|
||||||
|
tmbp = &canp->cd_can->sTxMailBox[(canp->cd_can->TSR & CAN_TSR_CODE) >> 24];
|
||||||
|
|
||||||
|
/* Preparing the message.*/
|
||||||
|
if (ctfp->cf_IDE)
|
||||||
|
tir = ((uint32_t)ctfp->cf_EID << 3) |
|
||||||
|
((uint32_t)ctfp->cf_IDE << 2) |
|
||||||
|
((uint32_t)ctfp->cf_RTR << 1);
|
||||||
|
else
|
||||||
|
tir = ((uint32_t)ctfp->cf_SID << 24) |
|
||||||
|
((uint32_t)ctfp->cf_IDE << 2) |
|
||||||
|
((uint32_t)ctfp->cf_RTR << 1);
|
||||||
|
tmbp->TDTR = ctfp->cf_DLC;
|
||||||
|
tmbp->TDLR = ctfp->cf_data32[0];
|
||||||
|
tmbp->TDHR = ctfp->cf_data32[1];
|
||||||
|
tmbp->TIR = tir | CAN_TI0R_TXRQ;
|
||||||
|
|
||||||
|
/* Re-enables the interrupt in order to generate events again.*/
|
||||||
|
canp->cd_can->IER |= CAN_IER_TMEIE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -296,7 +322,7 @@ bool_t can_lld_can_receive(CANDriver *canp) {
|
||||||
* @brief Receives a frame from the input queue.
|
* @brief Receives a frame from the input queue.
|
||||||
*
|
*
|
||||||
* @param[in] canp pointer to the @p CANDriver object
|
* @param[in] canp pointer to the @p CANDriver object
|
||||||
* @param[out] cfp pointer to the buffer where the CAN frame is copied
|
* @param[out] crfp pointer to the buffer where the CAN frame is copied
|
||||||
*/
|
*/
|
||||||
void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
|
void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
|
||||||
uint32_t r;
|
uint32_t r;
|
||||||
|
@ -310,13 +336,19 @@ void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
|
||||||
crfp->cf_RTR = r & CAN_RI0R_RTR;
|
crfp->cf_RTR = r & CAN_RI0R_RTR;
|
||||||
crfp->cf_IDE = r & CAN_RI0R_IDE;
|
crfp->cf_IDE = r & CAN_RI0R_IDE;
|
||||||
if (crfp->cf_IDE)
|
if (crfp->cf_IDE)
|
||||||
crfp->cf_ID = r >> 3;
|
crfp->cf_EID = r >> 3;
|
||||||
else
|
else
|
||||||
crfp->cf_ID = r >> 24;
|
crfp->cf_SID = r >> 24;
|
||||||
crfp->cf_data32[0] = canp->cd_can->sFIFOMailBox[0].RDLR;
|
crfp->cf_data32[0] = canp->cd_can->sFIFOMailBox[0].RDLR;
|
||||||
crfp->cf_data32[1] = canp->cd_can->sFIFOMailBox[0].RDHR;
|
crfp->cf_data32[1] = canp->cd_can->sFIFOMailBox[0].RDHR;
|
||||||
|
|
||||||
/* Releases the mailbox.*/
|
/* Releases the mailbox.*/
|
||||||
canp->cd_can->RF0R |= CAN_RF0R_RFOM0;
|
canp->cd_can->RF0R |= CAN_RF0R_RFOM0;
|
||||||
|
|
||||||
|
/* If the queue is empty re-enables the interrupt in order to generate
|
||||||
|
events again.*/
|
||||||
|
if ((canp->cd_can->RF0R & CAN_RF0R_FMP0) == 0)
|
||||||
|
canp->cd_can->IER |= CAN_IER_FMPIE0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
|
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
|
||||||
|
@ -327,7 +359,7 @@ void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
|
||||||
*/
|
*/
|
||||||
void can_lld_sleep(CANDriver *canp) {
|
void can_lld_sleep(CANDriver *canp) {
|
||||||
|
|
||||||
(void)canp;
|
canp->cd_can->MCR |= CAN_MCR_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -337,7 +369,7 @@ void can_lld_sleep(CANDriver *canp) {
|
||||||
*/
|
*/
|
||||||
void can_lld_wakeup(CANDriver *canp) {
|
void can_lld_wakeup(CANDriver *canp) {
|
||||||
|
|
||||||
(void)canp;
|
canp->cd_can->MCR &= ~CAN_MCR_SLEEP;
|
||||||
}
|
}
|
||||||
#endif /* CAN_USE_SLEEP_MODE */
|
#endif /* CAN_USE_SLEEP_MODE */
|
||||||
|
|
||||||
|
|
|
@ -97,10 +97,19 @@ typedef uint32_t canstatus_t;
|
||||||
* machine data endianness, it can be still useful for a quick filling.
|
* machine data endianness, it can be still useful for a quick filling.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cf_DLC:4; /**< @brief Data length. */
|
struct {
|
||||||
uint8_t cf_RTR:1; /**< @brief Frame type. */
|
uint8_t cf_DLC:4; /**< @brief Data length. */
|
||||||
uint8_t cf_IDE:1; /**< @brief Identifier type. */
|
uint8_t cf_RTR:1; /**< @brief Frame type. */
|
||||||
uint32_t cf_ID; /**< @brief Frame identifier. */
|
uint8_t cf_IDE:1; /**< @brief Identifier type. */
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t cf_SID:11; /**< @brief Standard identifier.*/
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint32_t cf_EID:29; /**< @brief Extended identifier.*/
|
||||||
|
};
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
uint8_t cf_data8[8]; /**< @brief Frame data. */
|
uint8_t cf_data8[8]; /**< @brief Frame data. */
|
||||||
uint16_t cf_data16[4]; /**< @brief Frame data. */
|
uint16_t cf_data16[4]; /**< @brief Frame data. */
|
||||||
|
@ -114,12 +123,23 @@ typedef struct {
|
||||||
* machine data endianness, it can be still useful for a quick filling.
|
* machine data endianness, it can be still useful for a quick filling.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t cf_TIME; /**< @brief Time stamp. */
|
struct {
|
||||||
uint8_t cf_FMI; /**< @brief Filter id. */
|
uint8_t cf_FMI; /**< @brief Filter id. */
|
||||||
uint8_t cf_DLC:4; /**< @brief Data length. */
|
uint16_t cf_TIME; /**< @brief Time stamp. */
|
||||||
uint8_t cf_RTR:1; /**< @brief Frame type. */
|
};
|
||||||
uint8_t cf_IDE:1; /**< @brief Identifier type. */
|
struct {
|
||||||
uint32_t cf_ID; /**< @brief Frame identifier. */
|
uint8_t cf_DLC:4; /**< @brief Data length. */
|
||||||
|
uint8_t cf_RTR:1; /**< @brief Frame type. */
|
||||||
|
uint8_t cf_IDE:1; /**< @brief Identifier type. */
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t cf_SID:11; /**< @brief Standard identifier.*/
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint32_t cf_EID:29; /**< @brief Extended identifier.*/
|
||||||
|
};
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
uint8_t cf_data8[8]; /**< @brief Frame data. */
|
uint8_t cf_data8[8]; /**< @brief Frame data. */
|
||||||
uint16_t cf_data16[4]; /**< @brief Frame data. */
|
uint16_t cf_data16[4]; /**< @brief Frame data. */
|
||||||
|
@ -216,7 +236,8 @@ typedef struct {
|
||||||
* until the received frames queue has been completely emptied. It
|
* until the received frames queue has been completely emptied. It
|
||||||
* is <b>not</b> broadcasted for each received frame. It is
|
* is <b>not</b> broadcasted for each received frame. It is
|
||||||
* responsibility of the application to empty the queue by repeatedly
|
* responsibility of the application to empty the queue by repeatedly
|
||||||
* invoking @p chReceive() when listening to this event.
|
* invoking @p chReceive() when listening to this event. This behavior
|
||||||
|
* minimizes the interrupt served by the system because CAN traffic.
|
||||||
*/
|
*/
|
||||||
EventSource cd_rxfull_event;
|
EventSource cd_rxfull_event;
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -63,10 +63,6 @@ void can_lld_init(void) {
|
||||||
*/
|
*/
|
||||||
void can_lld_start(CANDriver *canp) {
|
void can_lld_start(CANDriver *canp) {
|
||||||
|
|
||||||
if (canp->can_state == CAN_STOP) {
|
|
||||||
/* Clock activation.*/
|
|
||||||
}
|
|
||||||
/* Configuration.*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,8 +72,13 @@ 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 peripheral.*/
|
||||||
|
if (canp->cd_state == CAN_READY) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Determines whether a frame can be transmitted.
|
* @brief Determines whether a frame can be transmitted.
|
||||||
*
|
*
|
||||||
|
@ -94,16 +95,12 @@ bool_t can_lld_can_transmit(CANDriver *canp) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Inserts a frame into the transmit queue.
|
* @brief Inserts a frame into the transmit queue.
|
||||||
*
|
|
||||||
* @param[in] canp pointer to the @p CANDriver object
|
|
||||||
* @param[in] cfp pointer to the CAN frame to be transmitted
|
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @param[in] canp pointer to the @p CANDriver object
|
||||||
* @retval RDY_OK frame transmitted.
|
* @param[in] ctfp pointer to the CAN frame to be transmitted
|
||||||
*/
|
*/
|
||||||
msg_t can_lld_transmit(CANDriver *canp, const CANFrame *cfp) {
|
void can_lld_transmit(CANDriver *canp, const CANTxFrame *ctfp) {
|
||||||
|
|
||||||
return RDY_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,16 +119,12 @@ bool_t can_lld_can_receive(CANDriver *canp) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Receives a frame from the input queue.
|
* @brief Receives a frame from the input queue.
|
||||||
*
|
|
||||||
* @param[in] canp pointer to the @p CANDriver object
|
|
||||||
* @param[out] cfp pointer to the buffer where the CAN frame is copied
|
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @param[in] canp pointer to the @p CANDriver object
|
||||||
* @retval RDY_OK frame received.
|
* @param[out] crfp pointer to the buffer where the CAN frame is copied
|
||||||
*/
|
*/
|
||||||
msg_t can_lld_receive(CANDriver *canp, CANFrame *cfp) {
|
void can_lld_receive(CANDriver *canp, CANRxFrame *crfp) {
|
||||||
|
|
||||||
return RDY_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
|
#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
|
|
||||||
#if CH_HAL_USE_CAN || defined(__DOXYGEN__)
|
#if CH_HAL_USE_CAN || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This switch defines whether the driver implementation supports
|
* @brief This switch defines whether the driver implementation supports
|
||||||
* a low power switch mode with automatic an wakeup feature.
|
* a low power switch mode with automatic an wakeup feature.
|
||||||
|
@ -52,10 +56,6 @@
|
||||||
#define CAN_USE_SLEEP_MODE FALSE
|
#define CAN_USE_SLEEP_MODE FALSE
|
||||||
#endif /* !CAN_SUPPORTS_SLEEP */
|
#endif /* !CAN_SUPPORTS_SLEEP */
|
||||||
|
|
||||||
/*===========================================================================*/
|
|
||||||
/* Driver constants. */
|
|
||||||
/*===========================================================================*/
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver data structures and types. */
|
/* Driver data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -66,21 +66,63 @@
|
||||||
typedef uint32_t canstatus_t;
|
typedef uint32_t canstatus_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CAN frame.
|
* @brief CAN transmission frame.
|
||||||
* @note Accessing the frame data as word16 or word32 is not portable because
|
* @note Accessing the frame data as word16 or word32 is not portable because
|
||||||
* machine data endianness, it can be still useful for a quick filling.
|
* machine data endianness, it can be still useful for a quick filling.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t cf_DLC:4; /**< @brief Data length. */
|
struct {
|
||||||
uint8_t cf_IDE:1; /**< @brief Identifier type. */
|
uint8_t cf_DLC:4; /**< @brief Data length. */
|
||||||
uint8_t cf_RTR:1; /**< @brief Frame type. */
|
uint8_t cf_RTR:1; /**< @brief Frame type. */
|
||||||
uint32_t cf_id; /**< @brief Frame identifier. */
|
uint8_t cf_IDE:1; /**< @brief Identifier type. */
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t cf_SID:11; /**< @brief Standard identifier.*/
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint32_t cf_EID:29; /**< @brief Extended identifier.*/
|
||||||
|
};
|
||||||
|
};
|
||||||
union {
|
union {
|
||||||
uint8_t cf_data8[8]; /**< @brief Frame data. */
|
uint8_t cf_data8[8]; /**< @brief Frame data. */
|
||||||
uint16_t cf_data16[4]; /**< @brief Frame data. */
|
uint16_t cf_data16[4]; /**< @brief Frame data. */
|
||||||
uint32_t cf_data32[2]; /**< @brief Frame data. */
|
uint32_t cf_data32[2]; /**< @brief Frame data. */
|
||||||
};
|
};
|
||||||
} CANFrame;
|
} CANTxFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CAN received frame.
|
||||||
|
* @note Accessing the frame data as word16 or word32 is not portable because
|
||||||
|
* machine data endianness, it can be still useful for a quick filling.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
uint8_t cf_DLC:4; /**< @brief Data length. */
|
||||||
|
uint8_t cf_RTR:1; /**< @brief Frame type. */
|
||||||
|
uint8_t cf_IDE:1; /**< @brief Identifier type. */
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint32_t cf_SID:11; /**< @brief Standard identifier.*/
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint32_t cf_EID:29; /**< @brief Extended identifier.*/
|
||||||
|
};
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
uint8_t cf_data8[8]; /**< @brief Frame data. */
|
||||||
|
uint16_t cf_data16[4]; /**< @brief Frame data. */
|
||||||
|
uint32_t cf_data32[2]; /**< @brief Frame data. */
|
||||||
|
};
|
||||||
|
} CANRxFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CAN filter.
|
||||||
|
* @note It could not be present on some architectures.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
} CANFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Driver configuration structure.
|
* @brief Driver configuration structure.
|
||||||
|
@ -111,6 +153,12 @@ typedef struct {
|
||||||
Semaphore cd_rxsem;
|
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. This behavior
|
||||||
|
* minimizes the interrupt served by the system because CAN traffic.
|
||||||
*/
|
*/
|
||||||
EventSource cd_rxfull_event;
|
EventSource cd_rxfull_event;
|
||||||
/**
|
/**
|
||||||
|
@ -149,9 +197,9 @@ extern "C" {
|
||||||
void can_lld_start(CANDriver *canp);
|
void can_lld_start(CANDriver *canp);
|
||||||
void can_lld_stop(CANDriver *canp);
|
void can_lld_stop(CANDriver *canp);
|
||||||
bool_t can_lld_can_transmit(CANDriver *canp);
|
bool_t can_lld_can_transmit(CANDriver *canp);
|
||||||
msg_t can_lld_transmit(CANDriver *canp, const CANFrame *cfp);
|
void can_lld_transmit(CANDriver *canp, const CANTxFrame *crfp);
|
||||||
bool_t can_lld_can_receive(CANDriver *canp);
|
bool_t can_lld_can_receive(CANDriver *canp);
|
||||||
msg_t can_lld_receive(CANDriver *canp, CANFrame *cfp);
|
void can_lld_receive(CANDriver *canp, CANRxFrame *ctfp);
|
||||||
#if CAN_USE_SLEEP_MODE
|
#if CAN_USE_SLEEP_MODE
|
||||||
void can_lld_sleep(CANDriver *canp);
|
void can_lld_sleep(CANDriver *canp);
|
||||||
void can_lld_wakeup(CANDriver *canp);
|
void can_lld_wakeup(CANDriver *canp);
|
||||||
|
|
Loading…
Reference in New Issue