mirror of
				https://github.com/digistump/DigistumpArduino.git
				synced 2025-11-03 13:04:48 -08:00 
			
		
		
		
	switch to setup for Arduino Boards Manager
This commit is contained in:
		
							
								
								
									
										492
									
								
								digistump-sam/system/libsam/include/can.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										492
									
								
								digistump-sam/system/libsam/include/can.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,492 @@
 | 
			
		||||
/**
 | 
			
		||||
 * \file
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Controller Area Network (CAN) driver module for SAM.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_start
 | 
			
		||||
 *
 | 
			
		||||
 * \page License
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
			
		||||
 *    this list of conditions and the following disclaimer in the documentation
 | 
			
		||||
 *    and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
			
		||||
 *    from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * 4. This software may only be redistributed and used in connection with an
 | 
			
		||||
 *    Atmel microcontroller product.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
			
		||||
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
			
		||||
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
			
		||||
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
			
		||||
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
			
		||||
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
			
		||||
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * \asf_license_stop
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CAN_H_INCLUDED
 | 
			
		||||
#define CAN_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include "../chip.h"
 | 
			
		||||
 | 
			
		||||
/** @cond 0 */
 | 
			
		||||
/**INDENT-OFF**/
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/**INDENT-ON**/
 | 
			
		||||
/** @endcond */
 | 
			
		||||
 | 
			
		||||
/** Define the Mailbox mask for eight mailboxes. */
 | 
			
		||||
#define GLOBAL_MAILBOX_MASK           0x000000ff
 | 
			
		||||
 | 
			
		||||
/** Disable all interrupt mask */
 | 
			
		||||
#define CAN_DISABLE_ALL_INTERRUPT_MASK 0xffffffff
 | 
			
		||||
 | 
			
		||||
/** Define the typical baudrate for CAN communication in KHz. */
 | 
			
		||||
#define CAN_BPS_1000K                 1000
 | 
			
		||||
#define CAN_BPS_800K                  800
 | 
			
		||||
#define CAN_BPS_500K                  500
 | 
			
		||||
#define CAN_BPS_250K                  250
 | 
			
		||||
#define CAN_BPS_125K                  125
 | 
			
		||||
#define CAN_BPS_50K                   50
 | 
			
		||||
#define CAN_BPS_25K                   25
 | 
			
		||||
#define CAN_BPS_10K                   10
 | 
			
		||||
#define CAN_BPS_5K                    5
 | 
			
		||||
 | 
			
		||||
/** Define the mailbox mode. */
 | 
			
		||||
#define CAN_MB_DISABLE_MODE           0
 | 
			
		||||
#define CAN_MB_RX_MODE                1
 | 
			
		||||
#define CAN_MB_RX_OVER_WR_MODE        2
 | 
			
		||||
#define CAN_MB_TX_MODE                3
 | 
			
		||||
#define CAN_MB_CONSUMER_MODE          4
 | 
			
		||||
#define CAN_MB_PRODUCER_MODE          5
 | 
			
		||||
 | 
			
		||||
/** Define CAN mailbox transfer status code. */
 | 
			
		||||
#define CAN_MAILBOX_TRANSFER_OK       0     //! Read from or write into mailbox successfully.
 | 
			
		||||
#define CAN_MAILBOX_NOT_READY         0x01  //! Receiver is empty or transmitter is busy.
 | 
			
		||||
#define CAN_MAILBOX_RX_OVER           0x02  //! Message overwriting happens or there're messages lost in different receive modes.
 | 
			
		||||
#define CAN_MAILBOX_RX_NEED_RD_AGAIN  0x04  //! Application needs to re-read the data register in Receive with Overwrite mode.
 | 
			
		||||
 | 
			
		||||
/** Define the struct for CAN message mailbox. */
 | 
			
		||||
typedef struct {
 | 
			
		||||
	uint32_t ul_mb_idx;
 | 
			
		||||
	uint8_t uc_obj_type;  //! Mailbox object type, one of the six different objects.
 | 
			
		||||
	uint8_t uc_id_ver;    //! 0 stands for standard frame, 1 stands for extended frame.
 | 
			
		||||
	uint8_t uc_length;    //! Received data length or transmitted data length.
 | 
			
		||||
	uint8_t uc_tx_prio;   //! Mailbox priority, no effect in receive mode.
 | 
			
		||||
	uint32_t ul_status;   //! Mailbox status register value.
 | 
			
		||||
	uint32_t ul_id_msk;   //! No effect in transmit mode.
 | 
			
		||||
	uint32_t ul_id;       //! Received frame ID or the frame ID to be transmitted.
 | 
			
		||||
	uint32_t ul_fid;      //! Family ID.
 | 
			
		||||
	uint32_t ul_datal;
 | 
			
		||||
	uint32_t ul_datah;
 | 
			
		||||
} can_mb_conf_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \defgroup sam_driver_can_group Controller Area Network (CAN) Driver
 | 
			
		||||
 *
 | 
			
		||||
 * See \ref sam_can_quickstart.
 | 
			
		||||
 *
 | 
			
		||||
 * \par Purpose
 | 
			
		||||
 *
 | 
			
		||||
 * The CAN controller provides all the features required to implement
 | 
			
		||||
 * the serial communication protocol CAN defined by Robert Bosch GmbH,
 | 
			
		||||
 * the CAN specification. This is a driver for configuration, enabling,
 | 
			
		||||
 * disabling and use of the CAN peripheral.
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
uint32_t can_init(Can *p_can, uint32_t ul_mck, uint32_t ul_baudrate);
 | 
			
		||||
 | 
			
		||||
void can_enable(Can *p_can);
 | 
			
		||||
void can_disable(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_disable_low_power_mode(Can *p_can);
 | 
			
		||||
void can_enable_low_power_mode(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_disable_autobaud_listen_mode(Can *p_can);
 | 
			
		||||
void can_enable_autobaud_listen_mode(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_disable_overload_frame(Can *p_can);
 | 
			
		||||
void can_enable_overload_frame(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_set_timestamp_capture_point(Can *p_can, uint32_t ul_flag);
 | 
			
		||||
 | 
			
		||||
void can_disable_time_triggered_mode(Can *p_can);
 | 
			
		||||
void can_enable_time_triggered_mode(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_disable_timer_freeze(Can *p_can);
 | 
			
		||||
void can_enable_timer_freeze(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_disable_tx_repeat(Can *p_can);
 | 
			
		||||
void can_enable_tx_repeat(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_set_rx_sync_stage(Can *p_can, uint32_t ul_stage);
 | 
			
		||||
 | 
			
		||||
void can_enable_interrupt(Can *p_can, uint32_t dw_mask);
 | 
			
		||||
void can_disable_interrupt(Can *p_can, uint32_t dw_mask);
 | 
			
		||||
 | 
			
		||||
uint32_t can_get_interrupt_mask(Can *p_can);
 | 
			
		||||
 | 
			
		||||
uint32_t can_get_status(Can *p_can);
 | 
			
		||||
 | 
			
		||||
uint32_t can_get_internal_timer_value(Can *p_can);
 | 
			
		||||
 | 
			
		||||
uint32_t can_get_timestamp_value(Can *p_can);
 | 
			
		||||
 | 
			
		||||
uint8_t can_get_tx_error_cnt(Can *p_can);
 | 
			
		||||
uint8_t can_get_rx_error_cnt(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_reset_internal_timer(Can *p_can);
 | 
			
		||||
 | 
			
		||||
void can_global_send_transfer_cmd(Can *p_can, uint8_t uc_mask);
 | 
			
		||||
void can_global_send_abort_cmd(Can *p_can, uint8_t uc_mask);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Mailbox functions
 | 
			
		||||
 */
 | 
			
		||||
void can_mailbox_set_timemark(Can *p_can, uint8_t uc_index, uint16_t us_cnt);
 | 
			
		||||
uint32_t can_mailbox_get_status(Can *p_can, uint8_t uc_index);
 | 
			
		||||
void can_mailbox_send_transfer_cmd(Can *p_can, uint8_t uc_index);
 | 
			
		||||
void can_mailbox_send_abort_cmd(Can *p_can, uint8_t uc_index);
 | 
			
		||||
void can_mailbox_init(Can *p_can, can_mb_conf_t *p_mailbox);
 | 
			
		||||
uint32_t can_mailbox_read(Can *p_can, can_mb_conf_t *p_mailbox);
 | 
			
		||||
uint32_t can_mailbox_write(Can *p_can, can_mb_conf_t *p_mailbox);
 | 
			
		||||
uint32_t can_mailbox_tx_remote_frame(Can *p_can, can_mb_conf_t *p_mailbox);
 | 
			
		||||
void can_reset_all_mailbox(Can *p_can);
 | 
			
		||||
 | 
			
		||||
// from wilfredo
 | 
			
		||||
uint32_t can_reset_mailbox_data(can_mb_conf_t *p_mailbox);
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/** @cond 0 */
 | 
			
		||||
/**INDENT-OFF**/
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
/**INDENT-ON**/
 | 
			
		||||
/** @endcond */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \page sam_can_quickstart Quickstart guide for SAM CAN module.
 | 
			
		||||
 *
 | 
			
		||||
 * This is the quickstart guide for the \ref sam_drivers_can_group "SAM CAN module",
 | 
			
		||||
 * with step-by-step instructions on how to configure and use the drivers in a
 | 
			
		||||
 * selection of use cases.
 | 
			
		||||
 *
 | 
			
		||||
 * The use cases contain several code fragments. The code fragments in the
 | 
			
		||||
 * steps for setup can be copied into a custom initialization function, while
 | 
			
		||||
 * the steps for usage can be copied into, e.g., the main application function.
 | 
			
		||||
 *
 | 
			
		||||
 * \section can_basic_use_case Basic use case
 | 
			
		||||
 * In this basic use case, as CAN module needs to work in network, two CAN modules
 | 
			
		||||
 * need to be configured. CAN0 mailbox 0 is configured as transmitter, and CAN1 mailbox 0
 | 
			
		||||
 * is configured as receiver. The communication baudrate is 1Mbit/s.
 | 
			
		||||
 *
 | 
			
		||||
 * \section can_basic_use_case_setup Setup steps
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_basic_use_case_setup_prereq Prerequisites
 | 
			
		||||
 *  - \ref group_pmc "Power Management Controller driver"
 | 
			
		||||
 *  - \ref group_sn65hvd234_transceiver "CAN transceiver driver"
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_basic_use_case_setup_code Example code
 | 
			
		||||
 * Add to application initialization:
 | 
			
		||||
 * \code
 | 
			
		||||
 *    can_mb_conf_t can0_mailbox;
 | 
			
		||||
 *    can_mb_conf_t can1_mailbox;
 | 
			
		||||
 *
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN0);
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN1);
 | 
			
		||||
 *
 | 
			
		||||
 *    can_init(CAN0, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *    can_init(CAN1, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *
 | 
			
		||||
 *    can_reset_all_mailbox(CAN0);
 | 
			
		||||
 *    can_reset_all_mailbox(CAN1);
 | 
			
		||||
 *
 | 
			
		||||
 *    can1_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can1_mailbox.uc_obj_type = CAN_MB_RX_MODE;
 | 
			
		||||
 *    can1_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk;
 | 
			
		||||
 *    can1_mailbox.ul_id = CAN_MID_MIDvA(0x07);
 | 
			
		||||
 *    can_mailbox_init(CAN1, &can1_mailbox);
 | 
			
		||||
 *
 | 
			
		||||
 *    can0_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can0_mailbox.uc_obj_type = CAN_MB_TX_MODE;
 | 
			
		||||
 *    can0_mailbox.uc_tx_prio = 15;
 | 
			
		||||
 *    can0_mailbox.uc_id_ver = 0;
 | 
			
		||||
 *    can0_mailbox.ul_id_msk = 0;
 | 
			
		||||
 *    can_mailbox_init(CAN0, &can0_mailbox);
 | 
			
		||||
 *
 | 
			
		||||
 *    can0_mailbox.ul_id = CAN_MID_MIDvA(0x07);
 | 
			
		||||
 *    can0_mailbox.ul_datal = 0x12345678;
 | 
			
		||||
 *    can0_mailbox.ul_datah = 0x87654321;
 | 
			
		||||
 *    can0_mailbox.uc_length = 8;
 | 
			
		||||
 *    can_mailbox_write(CAN0, &can0_mailbox);
 | 
			
		||||
 * \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_basic_use_case_setup_flow Workflow
 | 
			
		||||
 * -# Define the CAN0 and CAN1 Transfer mailbox structure:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can_mb_conf_t can0_mailbox;
 | 
			
		||||
 *    can_mb_conf_t can1_mailbox;
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Enable the module clock for CAN0 and CAN1:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN0);
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN1);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Initialize CAN0 and CAN1, baudrate is 1Mb/s:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can_init(CAN0, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *    can_init(CAN1, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 *   - \note The CAN transceiver should be configured before initializing the CAN module.
 | 
			
		||||
 * -# Reset all CAN0 and CAN1 mailboxes:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can_reset_all_mailbox(CAN0);
 | 
			
		||||
 *    can_reset_all_mailbox(CAN1);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Initialize CAN1 mailbox 0 as receiver, frame ID is 0x07:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can1_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can1_mailbox.uc_obj_type = CAN_MB_RX_MODE;
 | 
			
		||||
 *    can1_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk;
 | 
			
		||||
 *    can1_mailbox.ul_id = CAN_MID_MIDvA(0x07);
 | 
			
		||||
 *    can_mailbox_init(CAN1, &can1_mailbox);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Initialize CAN0 mailbox 0 as transmitter, transmit priority is 15:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can0_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can0_mailbox.uc_obj_type = CAN_MB_TX_MODE;
 | 
			
		||||
 *    can0_mailbox.uc_tx_prio = 15;
 | 
			
		||||
 *    can0_mailbox.uc_id_ver = 0;
 | 
			
		||||
 *    can0_mailbox.ul_id_msk = 0;
 | 
			
		||||
 *    can_mailbox_init(CAN0, &can0_mailbox);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Prepare transmit ID, data and data length in CAN0 mailbox 0:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can0_mailbox.ul_id = CAN_MID_MIDvA(0x07);
 | 
			
		||||
 *    can0_mailbox.ul_datal = 0x12345678;
 | 
			
		||||
 *    can0_mailbox.ul_datah = 0x87654321;
 | 
			
		||||
 *    can0_mailbox.uc_length = 8;
 | 
			
		||||
 *    can_mailbox_write(CAN0, &can0_mailbox);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \section can_basic_use_case_usage Usage steps
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_basic_use_case_usage_code Example code
 | 
			
		||||
 * Add to, e.g., main loop in application C-file:
 | 
			
		||||
 * \code
 | 
			
		||||
 *    can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0);
 | 
			
		||||
 *
 | 
			
		||||
 *    while (!(can_mailbox_get_status(CAN1, 0) & CAN_MSR_MRDY)) {
 | 
			
		||||
 *    }
 | 
			
		||||
 *
 | 
			
		||||
 *    can_mailbox_read(CAN1, &can1_mailbox);
 | 
			
		||||
 * \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_basic_use_case_usage_flow Workflow
 | 
			
		||||
 * -# Send out data in CAN0 mailbox 0:
 | 
			
		||||
 *   - \code can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0); \endcode
 | 
			
		||||
 * -# Wait for CAN1 mailbox 0 to receive the data:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    while (!(can_mailbox_get_status(CAN1, 0) & CAN_MSR_MRDY)) {
 | 
			
		||||
 *    }
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Read the received data from CAN1 mailbox 0:
 | 
			
		||||
 *   - \code can_mailbox_read(CAN1, &can1_mailbox); \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \section can_use_cases Advanced use cases
 | 
			
		||||
 * For more advanced use of the CAN driver, see the following use cases:
 | 
			
		||||
 * - \subpage can_use_case_1 : Two CAN modules work in PRODUCER and CONSUMER mode
 | 
			
		||||
 * respectively, use CAN interrupt handler to check whether the communication has been
 | 
			
		||||
 * completed.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \page can_use_case_1 Use case #1
 | 
			
		||||
 *
 | 
			
		||||
 * In this use case, CAN0 mailbox 0 works in PRODUCER mode, and CAN1 mailbox 0
 | 
			
		||||
 * works in CONSUMER mode. While CAN1 mailbox 0 receives a data frame from the bus,
 | 
			
		||||
 * an interrupt is triggered.
 | 
			
		||||
 *
 | 
			
		||||
 * \section can_use_case_1_setup Setup steps
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_basic_use_case_setup_prereq Prerequisites
 | 
			
		||||
 *  - \ref group_pmc "Power Management Controller driver"
 | 
			
		||||
 *  - \ref group_sn65hvd234_transceiver "CAN transceiver driver"
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_use_case_1_setup_code Example code
 | 
			
		||||
 * Add to application C-file:
 | 
			
		||||
 * \code
 | 
			
		||||
 *    can_mb_conf_t can0_mailbox;
 | 
			
		||||
 *    can_mb_conf_t can1_mailbox;
 | 
			
		||||
 *    volatile uint32_t g_ul_recv_status = 0;
 | 
			
		||||
 * \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \code
 | 
			
		||||
 *    void CAN1_Handler(void)
 | 
			
		||||
 *    {
 | 
			
		||||
 *        uint32_t ul_status;
 | 
			
		||||
 *
 | 
			
		||||
 *        ul_status = can_mailbox_get_status(CAN1, 0);
 | 
			
		||||
 *        if ((ul_status & CAN_MSR_MRDY) == CAN_MSR_MRDY) {
 | 
			
		||||
 *            can1_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *            can1_mailbox.ul_status = ul_status;
 | 
			
		||||
 *            can_mailbox_read(CAN1, &can1_mailbox);
 | 
			
		||||
 *            g_ul_recv_status = 1;
 | 
			
		||||
 *        }
 | 
			
		||||
 *    }
 | 
			
		||||
 * \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \code
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN0);
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN1);
 | 
			
		||||
 *
 | 
			
		||||
 *    can_init(CAN0, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *    can_init(CAN1, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *
 | 
			
		||||
 *    can_reset_all_mailbox(CAN0);
 | 
			
		||||
 *    can_reset_all_mailbox(CAN1);
 | 
			
		||||
 *
 | 
			
		||||
 *    can0_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can0_mailbox.uc_obj_type = CAN_MB_PRODUCER_MODE;
 | 
			
		||||
 *    can0_mailbox.ul_id_msk = 0;
 | 
			
		||||
 *    can0_mailbox.ul_id = CAN_MID_MIDvA(0x0b);
 | 
			
		||||
 *    can_mailbox_init(CAN0, &can0_mailbox);
 | 
			
		||||
 *
 | 
			
		||||
 *    can0_mailbox.ul_datal = 0x11223344;
 | 
			
		||||
 *    can0_mailbox.ul_datah = 0x44332211;
 | 
			
		||||
 *    can0_mailbox.uc_length = 8;
 | 
			
		||||
 *    can_mailbox_write(CAN0, &can0_mailbox);
 | 
			
		||||
 *
 | 
			
		||||
 *    can1_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can1_mailbox.uc_obj_type = CAN_MB_CONSUMER_MODE;
 | 
			
		||||
 *    can1_mailbox.uc_tx_prio = 15;
 | 
			
		||||
 *    can1_mailbox.ul_id_msk = CAN_MID_MIDvA_Msk | CAN_MID_MIDvB_Msk;
 | 
			
		||||
 *    can1_mailbox.ul_id = CAN_MID_MIDvA(0x0b);
 | 
			
		||||
 *    can_mailbox_init(CAN1, &can1_mailbox);
 | 
			
		||||
 *
 | 
			
		||||
 *    can_enable_interrupt(CAN1, CAN_IER_MB0);
 | 
			
		||||
 *    NVIC_EnableIRQ(CAN1_IRQn);
 | 
			
		||||
 * \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_use_case_1_setup_flow Workflow
 | 
			
		||||
 * -# Define the CAN0 and CAN1 Transfer mailbox structure:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can_mb_conf_t can0_mailbox;
 | 
			
		||||
 *    can_mb_conf_t can1_mailbox;
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Define the receive flag that is changed in CAN1 ISR handler:
 | 
			
		||||
 *   - \code volatile uint32_t g_ul_recv_status = 0; \endcode
 | 
			
		||||
 * -# Define the CAN1 ISR handler in the application:
 | 
			
		||||
 *   - \code void CAN1_Handler(void); \endcode
 | 
			
		||||
 * -# In CAN1_Handler(), get CAN1 mailbox 0 status:
 | 
			
		||||
 *   - \code ul_status = can_mailbox_get_status(CAN1, 0); \endcode
 | 
			
		||||
 * -# In CAN1_Handler(), check whether the mailbox 0 has received a data frame:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    if ((ul_status & CAN_MSR_MRDY) == CAN_MSR_MRDY) {
 | 
			
		||||
 *        can1_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *        can1_mailbox.ul_status = ul_status;
 | 
			
		||||
 *        can_mailbox_read(CAN1, &can1_mailbox);
 | 
			
		||||
 *        g_ul_recv_status = 1;
 | 
			
		||||
 *    }
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# In CAN1_Handler(), if mailbox 0 is ready, read the received data from CAN1 mailbox 0:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can1_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can1_mailbox.ul_status = ul_status;
 | 
			
		||||
 *    can_mailbox_read(CAN1, &can1_mailbox);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# In CAN1_Handler(), if mailbox 0 is ready, set up the receive flag:
 | 
			
		||||
 *   - \code g_ul_recv_status = 1; \endcode
 | 
			
		||||
 * -# Enable the module clock for CAN0 and CAN1:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN0);
 | 
			
		||||
 *    pmc_enable_periph_clk(ID_CAN1);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Initialize CAN0 and CAN1, baudrate is 1Mb/s:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can_init(CAN0, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *    can_init(CAN1, ul_sysclk, CAN_BPS_1000K);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 *   - \note The CAN transceiver should be configured before initializing the CAN module.
 | 
			
		||||
 * -# Reset all CAN0 and CAN1 mailboxes:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can_reset_all_mailbox(CAN0);
 | 
			
		||||
 *    can_reset_all_mailbox(CAN1);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Initialize CAN0 mailbox 0 as PRODUCER:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can0_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can0_mailbox.uc_obj_type = CAN_MB_PRODUCER_MODE;
 | 
			
		||||
 *    can0_mailbox.ul_id_msk = 0;
 | 
			
		||||
 *    can0_mailbox.ul_id = CAN_MID_MIDvA(0x0b);
 | 
			
		||||
 *    can_mailbox_init(CAN0, &can0_mailbox);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Prepare the response information when it receives a remote frame:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can0_mailbox.ul_datal = 0x11223344;
 | 
			
		||||
 *    can0_mailbox.ul_datah = 0x44332211;
 | 
			
		||||
 *    can0_mailbox.uc_length = 8;
 | 
			
		||||
 *    can_mailbox_write(CAN0, &can0_mailbox);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Initialize CAN1 mailbox 0 as CONSUMER:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can1_mailbox.ul_mb_idx = 0;
 | 
			
		||||
 *    can1_mailbox.uc_obj_type = CAN_MB_CONSUMER_MODE;
 | 
			
		||||
 *    can1_mailbox.uc_tx_prio = 15;
 | 
			
		||||
 *    can1_mailbox.ul_id_msk = CAN_MID_MIDvA_Msk | CAN_MID_MIDvB_Msk;
 | 
			
		||||
 *    can1_mailbox.ul_id = CAN_MID_MIDvA(0x0b);
 | 
			
		||||
 *    can_mailbox_init(CAN1, &can1_mailbox);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 * -# Enable the CAN1 mailbox 0 interrupt:
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    can_enable_interrupt(CAN1, CAN_IER_MB0);
 | 
			
		||||
 *    NVIC_EnableIRQ(CAN1_IRQn);
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \section can_use_case_1_usage Usage steps
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_use_case_1_usage_code Example code
 | 
			
		||||
 * \code
 | 
			
		||||
 *    can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0);
 | 
			
		||||
 *    can_global_send_transfer_cmd(CAN1, CAN_TCR_MB0);
 | 
			
		||||
 *
 | 
			
		||||
 *    while (!g_ul_recv_status) {
 | 
			
		||||
 *    }
 | 
			
		||||
 * \endcode
 | 
			
		||||
 *
 | 
			
		||||
 * \subsection can_use_case_1_usage_flow Workflow
 | 
			
		||||
 * -# Enable CAN0 mailbox 0 to receive remote frame and respond it:
 | 
			
		||||
 *   - \code can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0); \endcode
 | 
			
		||||
 * -# Enable CAN1 mailbox 0 to send out a remote frame and then receive data frame from bus:
 | 
			
		||||
 *   - \code can_global_send_transfer_cmd(CAN1, CAN_TCR_MB0); \endcode
 | 
			
		||||
 * -# Wait for the communication to be completed.
 | 
			
		||||
 *   - \code
 | 
			
		||||
 *    while (!g_ul_recv_status) {
 | 
			
		||||
 *    }
 | 
			
		||||
 *   \endcode
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#endif /* CAN_H_INCLUDED */
 | 
			
		||||
		Reference in New Issue
	
	Block a user