]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/AtmelFiles/drivers/peripherals/mcan.h
Add SAMA5D2 Xplained IAR demo.
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D2x_Xplained_IAR / AtmelFiles / drivers / peripherals / mcan.h
diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/AtmelFiles/drivers/peripherals/mcan.h b/FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/AtmelFiles/drivers/peripherals/mcan.h
new file mode 100644 (file)
index 0000000..23dc63f
--- /dev/null
@@ -0,0 +1,439 @@
+/* ----------------------------------------------------------------------------\r
+ *         SAM Software Package License\r
+ * ----------------------------------------------------------------------------\r
+ * Copyright (c) 2015, Atmel Corporation\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the disclaimer below.\r
+ *\r
+ * Atmel's name may not be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * ----------------------------------------------------------------------------\r
+ */\r
+\r
+/**\r
+ * \file\r
+ *\r
+ * \section Purpose\r
+ *\r
+ * Controller Area Network with Flexible Data-rate.\r
+ * Interface for configuring and using the MCAN peripheral.\r
+ */\r
+\r
+#ifndef _MCAN_H_\r
+#define _MCAN_H_\r
+\r
+/*----------------------------------------------------------------------------\r
+ *         Headers\r
+ *----------------------------------------------------------------------------*/\r
+\r
+#include "chip.h"\r
+\r
+#include <assert.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*----------------------------------------------------------------------------\r
+ *         Definitions\r
+ *----------------------------------------------------------------------------*/\r
+\r
+enum mcan_can_mode\r
+{\r
+       /* ISO 11898-1 CAN mode */\r
+       MCAN_MODE_CAN,\r
+\r
+       /* Long CAN FD frame.\r
+        * - TX and RX payloads up to 64 bytes.\r
+        * - Slow transmitter: TX frames are sent at constant bit rate.\r
+        * - Fast receiver: both constant-rate (slow) and dual-rate (fast)\r
+        *   RX frames are supported and received. */\r
+       MCAN_MODE_EXT_LEN_CONST_RATE,\r
+\r
+       /* Long and fast CAN FD frame.\r
+        * - TX and RX payloads up to 64 bytes.\r
+        * - Fast transmitter: control, data and CRC fields are transmitted at a\r
+        *   higher bit rate.\r
+        * - Fast receiver. */\r
+       MCAN_MODE_EXT_LEN_DUAL_RATE,\r
+};\r
+\r
+/* Flag signalling a standard (11-bit) message identifiers */\r
+#define CAN_STD_MSG_ID (0x0u << 30)\r
+/* Flag to be bitwise or'ed to extended (29-bit) message identifiers */\r
+#define CAN_EXT_MSG_ID (0x1u << 30)\r
+\r
+struct mcan_msg_info\r
+{\r
+       uint32_t id;\r
+       uint32_t timestamp;\r
+       uint8_t *data;\r
+       uint8_t full_len;\r
+       uint8_t data_len;\r
+};\r
+\r
+struct mcan_config\r
+{\r
+       uint32_t id;                  /* peripheral ID (ID_xxx) */\r
+       Mcan *regs;                   /* set of MCAN hardware registers */\r
+       uint32_t *msg_ram;            /* base address of the Message RAM to be\r
+                                      * assigned to this MCAN instance */\r
+\r
+       uint8_t array_size_filt_std;  /* # of 11-bit Message ID Rx Filters */\r
+       uint8_t array_size_filt_ext;  /* # of 29-bit Message ID Rx Filters */\r
+       uint8_t fifo_size_rx0;        /* # of Rx Buffers in Rx FIFO 0 */\r
+       uint8_t fifo_size_rx1;        /* # of Rx Buffers in Rx FIFO 1 */\r
+       uint8_t array_size_rx;        /* # of dedicated Rx Buffers */\r
+       uint8_t fifo_size_tx_evt;     /* # of Tx Event Elements in the Tx Event\r
+                                      * FIFO */\r
+       uint8_t array_size_tx;        /* # of dedicated Tx Buffers */\r
+       uint8_t fifo_size_tx;         /* # of Tx Buffers in the Tx FIFO or Tx\r
+                                      * Queue */\r
+\r
+       uint8_t buf_size_rx_fifo0;    /* size of the data field in each Rx\r
+                                      * Buffer of Rx FIFO 0, in bytes */\r
+       uint8_t buf_size_rx_fifo1;    /* size of the data field in each Rx\r
+                                      * Buffer of Rx FIFO 1, in bytes */\r
+       uint8_t buf_size_rx;          /* size of the data field in each\r
+                                      * dedicated Rx Buffer, in bytes */\r
+       uint8_t buf_size_tx;          /* size of the data field in each Tx\r
+                                      * Buffer, in bytes. Applies to all Tx\r
+                                      * Buffers, dedicated and in Tx FIFO /\r
+                                      * Queue. */\r
+\r
+       uint32_t bit_rate;            /* requested CAN bit rate in CAN mode,\r
+                                      * in bps */\r
+       uint16_t quanta_before_sp;    /* duration of the time segment before the\r
+                                      * sample point (Sync_Seg + Prop_Seg +\r
+                                      * Phase_Seg1), while in CAN mode,\r
+                                      * expressed in CAN time quanta */\r
+       uint8_t quanta_after_sp;      /* duration of the time segment after the\r
+                                      * sample point (Phase_Seg2), while in CAN\r
+                                      * mode, expressed in CAN time quanta */\r
+\r
+       uint32_t bit_rate_fd;         /* requested CAN bit rate in fast CAN FD\r
+                                      * mode, in bps */\r
+       uint8_t quanta_before_sp_fd;  /* duration of the time segment before the\r
+                                      * sample point (Sync_Seg + Prop_Seg +\r
+                                      * Phase_Seg1), while in fast CAN FD mode,\r
+                                      * expressed in CAN time quanta */\r
+       uint8_t quanta_after_sp_fd;   /* duration of the time segment after the\r
+                                      * sample point (Phase_Seg2), while in\r
+                                      * fast CAN FD mode, expressed in CAN time\r
+                                      * quanta */\r
+\r
+       uint8_t quanta_sync_jump;     /* duration of a (re)synchronization jump,\r
+                                      * while in CAN mode, expressed in CAN\r
+                                      * time quanta */\r
+       uint8_t quanta_sync_jump_fd;  /* duration of a (re)synchronization jump,\r
+                                      * while in fast CAN FD mode, expressed in\r
+                                      * CAN time quanta */\r
+};\r
+\r
+/* This structure is private to the MCAN Driver.\r
+ * Allocate it but ignore its members. */\r
+struct mcan_set\r
+{\r
+       struct mcan_config cfg;\r
+       uint32_t *ram_filt_std;\r
+       uint32_t *ram_filt_ext;\r
+       uint32_t *ram_fifo_rx0;\r
+       uint32_t *ram_fifo_rx1;\r
+       uint32_t *ram_array_rx;\r
+       uint32_t *ram_fifo_tx_evt;\r
+       uint32_t *ram_array_tx;\r
+};\r
+\r
+/*----------------------------------------------------------------------------\r
+ *         Exported symbols\r
+ *----------------------------------------------------------------------------*/\r
+\r
+static inline bool mcan_is_enabled(const struct mcan_set *set)\r
+{\r
+       Mcan *mcan = set->cfg.regs;\r
+       return ((mcan->MCAN_CCCR & MCAN_CCCR_INIT) == MCAN_CCCR_INIT_DISABLED);\r
+}\r
+\r
+static inline bool mcan_is_extended_id(uint32_t msg_id)\r
+{\r
+       return msg_id & CAN_EXT_MSG_ID ? true : false;\r
+}\r
+\r
+static inline uint32_t mcan_get_id(uint32_t msg_id)\r
+{\r
+       return msg_id & CAN_EXT_MSG_ID ? msg_id & 0x1fffffff : msg_id & 0x7ff;\r
+}\r
+\r
+static inline bool mcan_is_tx_complete(const struct mcan_set *set)\r
+{\r
+       Mcan *mcan = set->cfg.regs;\r
+       return mcan->MCAN_IR & MCAN_IR_TC ? true : false;\r
+}\r
+\r
+static inline void mcan_clear_tx_flag(const struct mcan_set *set)\r
+{\r
+       Mcan *mcan = set->cfg.regs;\r
+       mcan->MCAN_IR = MCAN_IR_TC;\r
+}\r
+\r
+static inline bool mcan_rx_array_data(const struct mcan_set *set)\r
+{\r
+       Mcan *mcan = set->cfg.regs;\r
+       return mcan->MCAN_IR & MCAN_IR_DRX ? true : false;\r
+}\r
+\r
+static inline void mcan_clear_rx_array_flag(const struct mcan_set *set)\r
+{\r
+       Mcan *mcan = set->cfg.regs;\r
+       mcan->MCAN_IR = MCAN_IR_DRX;\r
+}\r
+\r
+static inline bool mcan_rx_fifo_data(const struct mcan_set *set, uint8_t fifo)\r
+{\r
+       assert(fifo == 0 || fifo == 1);\r
+\r
+       Mcan *mcan = set->cfg.regs;\r
+\r
+       return mcan->MCAN_IR & (fifo ? MCAN_IR_RF1N : MCAN_IR_RF0N) ? true\r
+           : false;\r
+}\r
+\r
+static inline void mcan_clear_rx_fifo_flag(const struct mcan_set *set,\r
+    uint8_t fifo)\r
+{\r
+       assert(fifo == 0 || fifo == 1);\r
+\r
+       Mcan *mcan = set->cfg.regs;\r
+\r
+       mcan->MCAN_IR = fifo ? MCAN_IR_RF1N : MCAN_IR_RF0N;\r
+}\r
+\r
+/**\r
+ * \brief Compute the size of the Message RAM to be assigned to the MCAN.\r
+ * \param cfg  MCAN configuration to be considered. Only integer size parameters\r
+ * need to be configured. The other parameters can be left blank at this stage.\r
+ * \param size  address where the required size of the Message RAM will be\r
+ * written, expressed in (32-bit) words.\r
+ * \return true if successful, false if a parameter is set to an unsupported\r
+ * value.\r
+ */\r
+bool mcan_configure_msg_ram(const struct mcan_config *cfg, uint32_t *size);\r
+\r
+/**\r
+ * \brief Initialize the MCAN hardware for the given peripheral.\r
+ * Default: Non-FD, ISO 11898-1 CAN mode; mixed mode TX Buffer + FIFO.\r
+ * \param set  Pointer to uninitialized driver instance data.\r
+ * \param cfg  MCAN configuration to be used.\r
+ * \return true if successful, false if a parameter is set to an unsupported\r
+ * value.\r
+ */\r
+bool mcan_initialize(struct mcan_set *set, const struct mcan_config *cfg);\r
+\r
+/**\r
+ * \brief Unlock the peripheral configuration so it can be altered.\r
+ * Prerequisite: the peripheral shall be disabled. In case the device has been\r
+ * enabled, call mcan_disable.\r
+ * \param set  Pointer to driver instance data.\r
+ */\r
+void mcan_reconfigure(struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Select either the legacy ISO 11898-1 CAN mode or the CAN-FD mode,\r
+ * along with the FD variant in the latter case.\r
+ * Should be called further to mcan_initialize() or mcan_reconfigure(), before\r
+ * mcan_enable().\r
+ * \param set  Pointer to driver instance data.\r
+ * \param mode  CAN mode, and FD variant in case of FD mode.\r
+ */\r
+void mcan_set_mode(struct mcan_set *set, enum mcan_can_mode mode);\r
+\r
+/**\r
+ * \brief Query the current CAN mode.\r
+ * \param set  Pointer to driver instance data.\r
+ * \return Currently selected CAN mode, and FD variant in case of CAN FD mode.\r
+ */\r
+enum mcan_can_mode mcan_get_mode(const struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Select the TX Queue mode, disable TX FIFO mode.\r
+ * INIT must be set - so this should be called between mcan_initialize() and\r
+ * mcan_enable().\r
+ * \param set  Pointer to driver instance data.\r
+ */\r
+void mcan_set_tx_queue_mode(struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Initialize the MCAN in loop back mode.\r
+ * INIT must be set - so this should be called between mcan_initialize() and\r
+ * mcan_enable().\r
+ * \param set  Pointer to driver instance data.\r
+ */\r
+void mcan_init_loopback(struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Enable the peripheral I/O stage. Synchronize with the bus.\r
+ * INIT must be set - so this should be called after mcan_initialize().\r
+ * \param set  Pointer to driver instance data.\r
+ */\r
+void mcan_enable(struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Disable the peripheral I/O stage. Go Bus_Off.\r
+ * \note Subsequent operations may include reconfiguring the peripheral\r
+ * (mcan_reconfigure) and/or re-enabling it (mcan_enable).\r
+ * \param set  Pointer to driver instance data.\r
+ */\r
+void mcan_disable(struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Turn the loop-back mode ON.\r
+ * \note TEST must be set in MCAN_CCCR. This mode should have been enabled upon\r
+ * initialization.\r
+ * \param set  Pointer to driver instance data.\r
+ */\r
+void mcan_loopback_on(struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Turn the loop-back mode OFF.\r
+ * \param set  Pointer to driver instance data.\r
+ */\r
+void mcan_loopback_off(struct mcan_set *set);\r
+\r
+/**\r
+ * \brief Select either the m_can_int0 or the m_can_int1 interrupt line.\r
+ * Also, enable the 'Message stored to Dedicated Receive Buffer' specific\r
+ * interrupt.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param int_line  The interrupt line to be enabled:\r
+ *    0   -> m_can_int0\r
+ *    1   -> m_can_int1.\r
+ */\r
+void mcan_enable_rx_array_flag(struct mcan_set *set, uint8_t int_line);\r
+\r
+/**\r
+ * \brief Configure a Dedicated TX Buffer.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param buf_idx  Index of the dedicated transmit buffer to be used.\r
+ * \param id  Message ID.\r
+ * \param len  Data length, in bytes.\r
+ * \return Address of data byte 0, part of the transmit buffer.\r
+ */\r
+uint8_t * mcan_prepare_tx_buffer(struct mcan_set *set, uint8_t buf_idx,\r
+    uint32_t id, uint8_t len);\r
+\r
+/**\r
+ * \brief Start the transmission of a Dedicated TX Buffer.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param buf_idx  Index of the dedicated transmit buffer to be used.\r
+ */\r
+void mcan_send_tx_buffer(struct mcan_set *set, uint8_t buf_idx);\r
+\r
+/**\r
+ * \brief Append the provided message to the TX FIFO, or to the TX Queue,\r
+ * depending on whether mcan_set_tx_queue_mode() has been invoked or not.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param id  Message ID.\r
+ * \param len  Data length, in bytes.\r
+ * \param data  Pointer to data.\r
+ * \return Index of the assigned transmit buffer, part of the FIFO / queue.\r
+ * Or 0xff if the TX FIFO / queue was full, or an error occurred.\r
+ */\r
+uint8_t mcan_enqueue_outgoing_msg(struct mcan_set *set, uint32_t id,\r
+     uint8_t len, const uint8_t *data);\r
+\r
+/**\r
+ * \brief Check if message transmitted from the specified TX Buffer, either\r
+ * dedicated or part of the TX FIFO or TX Queue.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param buf_idx  Index of the transmit buffer to be queried.\r
+ * \return true if the message has been successfully transmitted, false\r
+ * otherwise.\r
+ */\r
+bool mcan_is_buffer_sent(const struct mcan_set *set, uint8_t buf_idx);\r
+\r
+/**\r
+ * \brief Configure RX buffer filter.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param buf_idx  Index of the receive buffer to be used as the recipient.\r
+ * \param filter  Index of the filter to be configured.\r
+ * \param id  Single message identifier. Incoming message need to match exactly\r
+ * to be accepted.\r
+ */\r
+void mcan_filter_single_id(struct mcan_set *set, uint8_t buf_idx,\r
+    uint8_t filter, uint32_t id);\r
+\r
+/**\r
+ * \brief Configure classic RX filter.\r
+ * The classic filters direct the accepted messages to a FIFO, and include both\r
+ * an ID and an ID mask.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param fifo  Index of the RX FIFO to be used as the recipient.\r
+ * \param filter  Index of the filter to be configured.\r
+ * \param id  Message identifier.\r
+ * \param mask  Message identifier mask to be matched.\r
+ */\r
+void mcan_filter_id_mask(struct mcan_set *set, uint8_t fifo, uint8_t filter,\r
+    uint32_t id, uint32_t mask);\r
+\r
+/**\r
+ * \brief Check whether some data has been received into the specified RX\r
+ * Buffer.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param buf_idx  Index of the receive buffer to be queried.\r
+ * \return true if the receive buffer is flagged as containing an unfetched\r
+ * frame, and false otherwise.\r
+ */\r
+bool mcan_rx_buffer_data(const struct mcan_set *set, uint8_t buf_idx);\r
+\r
+/**\r
+ * \brief Get RX buffer.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param buf_idx  Index of the receive buffer to be read.\r
+ * \param msg  Address where the CAN message properties will be written.\r
+ * The msg->data and msg->data_len parameters shall be initialized prior to\r
+ * calling this function. Message contents will be copied to msg->data if\r
+ * msg->data is not null and if msg->data_len is large enough.\r
+ */\r
+void mcan_read_rx_buffer(struct mcan_set *set, uint8_t buf_idx,\r
+    struct mcan_msg_info *msg);\r
+\r
+/**\r
+ * \brief Detach one received message from the specified RX FIFO, and copy it to\r
+ * a buffer owned by the application.\r
+ * \param set  Pointer to driver instance data.\r
+ * \param fifo  Index of the RX FIFO to dequeue from.\r
+ * \param msg  Address where the CAN message properties will be written.\r
+ * The msg->data and msg->data_len parameters shall be initialized prior to\r
+ * calling this function. Message contents will be copied to msg->data if\r
+ * msg->data is not null and if msg->data_len is large enough.\r
+ * \return: # of FIFO entries at the time the function was entered:\r
+ *    0       -> The FIFO was initially empty.\r
+ *    1       -> The FIFO had 1 entry upon entry, but is empty upon exit.\r
+ *    2 to 64 -> The FIFO had several entries upon entry, and still holds one\r
+ *               or more entries upon exit.\r
+ */\r
+uint8_t mcan_dequeue_received_msg(struct mcan_set *set, uint8_t fifo,\r
+    struct mcan_msg_info *msg);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* #ifndef _MCAN_H_ */\r