diff --git a/include/libopencm3/stm32/can.h b/include/libopencm3/stm32/can.h index cdb5df19..c5313949 100644 --- a/include/libopencm3/stm32/can.h +++ b/include/libopencm3/stm32/can.h @@ -1,3 +1,17 @@ +/** @defgroup can_defines CAN defines + +@ingroup STM32F_defines + +@brief libopencm3 Defined Constants and Types for STM32 CAN + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski + +@date 12 November 2012 + +LGPL License Terms @ref lgpl_license +*/ /* * This file is part of the libopencm3 project. * @@ -23,11 +37,19 @@ #include #include +/**@{*/ + /* --- Convenience macros -------------------------------------------------- */ /* CAN register base adresses (for convenience) */ +/*****************************************************************************/ +/** @defgroup can_reg_base CAN register base address +@ingroup can_defines + +@{*/ #define CAN1 BX_CAN1_BASE #define CAN2 BX_CAN2_BASE +/**@}*/ /* --- CAN registers ------------------------------------------------------- */ diff --git a/lib/stm32/can.c b/lib/stm32/can.c index 73036f4c..9b2f22af 100644 --- a/lib/stm32/can.c +++ b/lib/stm32/can.c @@ -1,3 +1,21 @@ +/** @defgroup can_file CAN + +@ingroup STM32F_files + +@brief libopencm3 STM32Fxxx CAN + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 Piotr Esden-Tempski + +@date 12 November 2012 + +Devices can have up to two CAN peripherals. The peripherals support up to 1MBit +transmission rate. The peripheral has several filters for incoming messages that +can be distributed between two FIFOs and three transmit mailboxes. + +LGPL License Terms @ref lgpl_license +*/ /* * This file is part of the libopencm3 project. * @@ -29,6 +47,14 @@ # error "stm32 family not defined." #endif +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Reset + +The CAN peripheral and all its associated configuration registers are placed in the +reset condition. The reset is effective via the RCC peripheral reset system. + +@param[in] canport Unsigned int32. CAN block register address base @ref can_reg_base. + */ void can_reset(u32 canport) { if (canport == CAN1) { @@ -40,6 +66,24 @@ void can_reset(u32 canport) } } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Init + +Initialize the selected CAN peripheral block. + +@param[in] canport Unsigend int32. CAN register base address @ref can_reg_base. +@param[in] ttcm bool. Time triggered communication mode. +@param[in] abom bool. Automatic bus-off management. +@param[in] awum bool. Automatic wakeup mode. +@param[in] nart bool. No automatic retransmission. +@param[in] rflm bool. Receive FIFO locked mode. +@param[in] txfp bool. Transmit FIFO priority. +@param[in] sjw Unsigned int32. Resynchronization time quanta jump width. +@param[in] ts1 Unsigned int32. Time segment 1 time quanta width. +@param[in] ts2 Unsigned int32. Time segment 2 time quanta width. +@param[in] brp Unsigned int32. Baud rate prescaler. +@returns int 0 on success, 1 on initialization failure. +*/ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart, bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp) { @@ -114,6 +158,20 @@ int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart, return ret; } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Filter Init + +Initialize incoming message filter and assign to FIFO. + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] scale_32bit bool. 32-bit scale for the filter? +@param[in] id_list_mode bool. ID list filter mode? +@param[in] fr1 Unsigned int32. First filter register content. +@param[in] fr2 Unsigned int32. Second filter register content. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode, u32 fr1, u32 fr2, u32 fifo, bool enable) { @@ -160,6 +218,18 @@ void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode, CAN_FMR(canport) &= ~CAN_FMR_FINIT; } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 16bit Message ID Mask Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id1 Unsigned int16. First message ID to filter. +@param[in] mask1 Unsigned int16. First message ID bit mask. +@param[in] id2 Unsigned int16. Second message ID to filter. +@param[in] mask2 Unsigned int16. Second message ID bit mask. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1, u16 id2, u16 mask2, u32 fifo, bool enable) { @@ -168,12 +238,34 @@ void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1, ((u32)id2 << 16) | (u32)mask2, fifo, enable); } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 32bit Message ID Mask Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id Unsigned int32. Message ID to filter. +@param[in] mask Unsigned int32. Message ID bit mask. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ void can_filter_id_mask_32bit_init(u32 canport, u32 nr, u32 id, u32 mask, u32 fifo, bool enable) { can_filter_init(canport, nr, true, false, id, mask, fifo, enable); } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 16bit Message ID List Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id1 Unsigned int16. First message ID to match. +@param[in] id2 Unsigned int16. Second message ID to match. +@param[in] id3 Unsigned int16. Third message ID to match. +@param[in] id4 Unsigned int16. Fourth message ID to match. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2, u16 id3, u16 id4, u32 fifo, bool enable) { @@ -182,27 +274,62 @@ void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2, ((u32)id3 << 16) | (u32)id4, fifo, enable); } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Initialize a 32bit Message ID List Filter + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] nr Unsigned int32. ID number of the filter. +@param[in] id1 Unsigned int32. First message ID to match. +@param[in] id2 Unsigned int32. Second message ID to match. +@param[in] fifo Unsigned int32. FIFO id. +@param[in] enable bool. Enable filter? + */ void can_filter_id_list_32bit_init(u32 canport, u32 nr, u32 id1, u32 id2, u32 fifo, bool enable) { can_filter_init(canport, nr, true, true, id1, id2, fifo, enable); } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Enable IRQ + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] irq Unsigned int32. IRQ bit(s). + */ void can_enable_irq(u32 canport, u32 irq) { CAN_IER(canport) |= irq; } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Disable IRQ + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] irq Unsigned int32. IRQ bit(s). + */ void can_disable_irq(u32 canport, u32 irq) { CAN_IER(canport) &= ~irq; } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Transmit Message + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] id Unsigned int32. Message ID. +@param[in] ext bool. Extended message ID? +@param[in] rtr bool. Request transmit? +@param[in] length Unsigned int8. Message payload length. +@param[in] data Unsigned int8[]. Message payload data. +@returns int 0, 1 or 2 on success and depending on which outgoing mailbox got +selected. -1 if no mailbox was available and no transmission got queued. + */ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data) { int ret = 0, i; u32 mailbox = 0; + /* Check which transmit mailbox is empty if any. */ if ((CAN_TSR(canport) & CAN_TSR_TME0) == CAN_TSR_TME0) { ret = 0; mailbox = CAN_MBOX0; @@ -216,7 +343,7 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data) ret = -1; } - /* Check if we have an empty mailbox. */ + /* If we have no empty mailbox return with an error. */ if (ret == -1) return ret; @@ -254,6 +381,12 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data) return ret; } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Release FIFO + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] fifo Unsigned int8. FIFO id. + */ void can_fifo_release(u32 canport, u8 fifo) { if (fifo == 0) @@ -262,6 +395,19 @@ void can_fifo_release(u32 canport, u8 fifo) CAN_RF1R(canport) |= CAN_RF1R_RFOM1; } +/*-----------------------------------------------------------------------------*/ +/** @brief CAN Receive Message + +@param[in] canport Unsigned int32. CAN block register base @ref can_reg_base. +@param[in] fifo Unsigned int8. FIFO id. +@param[in] release bool. Release the FIFO automatically after coping data out. +@param[out] id Unsigned int32 pointer. Message ID. +@param[out] ext bool pointer. The message ID is extended? +@param[out] rtr bool pointer. Request of transmission? +@param[out] fmi Unsigned int32 pointer. ID of the matched filter. +@param[out] length Unsigned int8 pointer. Length of message payload. +@param[out] data Unsigned int8[]. Message payload data. + */ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext, bool *rtr, u32 *fmi, u8 *length, u8 *data) {