123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149 |
- /**
- **************************************************************************
- * @file at32f413_can.c
- * @version v2.0.5
- * @date 2022-05-20
- * @brief contains all the functions for the can firmware library
- **************************************************************************
- * Copyright notice & Disclaimer
- *
- * The software Board Support Package (BSP) that is made available to
- * download from Artery official website is the copyrighted work of Artery.
- * Artery authorizes customers to use, copy, and distribute the BSP
- * software and its related documentation for the purpose of design and
- * development in conjunction with Artery microcontrollers. Use of the
- * software is governed by this copyright notice and the following disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
- * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
- * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
- * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
- * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
- *
- **************************************************************************
- */
- #include "at32f413_conf.h"
- /** @addtogroup AT32F413_periph_driver
- * @{
- */
- /** @defgroup CAN
- * @brief CAN driver modules
- * @{
- */
- #ifdef CAN_MODULE_ENABLED
- /** @defgroup CAN_private_functions
- * @{
- */
- /**
- * @brief deinitialize the can peripheral registers to their default reset values.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @retval none.
- */
- void can_reset(can_type* can_x)
- {
- if(can_x == CAN1)
- {
- crm_periph_reset(CRM_CAN1_PERIPH_RESET, TRUE);
- crm_periph_reset(CRM_CAN1_PERIPH_RESET, FALSE);
- }
- else if(can_x == CAN2)
- {
- crm_periph_reset(CRM_CAN2_PERIPH_RESET, TRUE);
- crm_periph_reset(CRM_CAN2_PERIPH_RESET, FALSE);
- }
- }
- /**
- * @brief fill each can_baudrate_struct member with its default value.
- * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be initialized.
- * @retval none.
- */
- void can_baudrate_default_para_init(can_baudrate_type* can_baudrate_struct)
- {
- /* reset can baudrate structure parameters values */
- /* baud rate division */
- can_baudrate_struct->baudrate_div = 1;
- /* resynchronization adjust width */
- can_baudrate_struct->rsaw_size = CAN_RSAW_2TQ;
- /* bit time segment 1 */
- can_baudrate_struct->bts1_size = CAN_BTS1_4TQ;
- /* bit time segment 2 */
- can_baudrate_struct->bts2_size = CAN_BTS2_3TQ;
- }
- /**
- * @brief set the baudrate of the can peripheral
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be set.
- * @note baudrate calculate method is:
- * baudrate = fpclk/(baudrate_div *(3 + bts1_size + bts2_size))
- * @retval the result of baudrate set
- * this parameter can be one of the following values:
- * SUCCESS or ERROR
- */
- error_status can_baudrate_set(can_type* can_x, can_baudrate_type* can_baudrate_struct)
- {
- error_status status_index = ERROR;
- uint32_t wait_ack_index = 0x00000000;
- /* exit from doze mode */
- can_x->mctrl_bit.dzen = FALSE;
- /* request freeze mode */
- can_x->mctrl_bit.fzen = TRUE;
- /* wait the acknowledge */
- while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
- {
- wait_ack_index++;
- }
- /* check acknowledge */
- if(can_x->msts_bit.fzc)
- {
- can_x->btmg_bit.brdiv = can_baudrate_struct->baudrate_div - 1;
- can_x->btmg_bit.rsaw = can_baudrate_struct->rsaw_size;
- can_x->btmg_bit.bts1 = can_baudrate_struct->bts1_size;
- can_x->btmg_bit.bts2 = can_baudrate_struct->bts2_size;
- /* request leave freeze mode */
- can_x->mctrl_bit.fzen = FALSE;
- /* wait the acknowledge */
- wait_ack_index = 0;
- while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
- {
- wait_ack_index++;
- }
- /* check acknowledged */
- if(can_x->msts_bit.fzc)
- {
- status_index = ERROR;
- }
- else
- {
- status_index = SUCCESS ;
- }
- }
- else
- {
- status_index = ERROR;
- }
- /* return the status of baudrate set */
- return status_index;
- }
- /**
- * @brief fill each can_init_struct member with its default value.
- * @param can_base_struct: pointer to a can_base_type structure which will be initialized.
- * @retval none.
- */
- void can_default_para_init(can_base_type* can_base_struct)
- {
- /* reset can init structure parameters values */
- /* initialize the time triggered communication mode */
- can_base_struct->ttc_enable = FALSE;
- /* initialize the automatic exit bus-off management */
- can_base_struct->aebo_enable = FALSE;
- /* initialize the automatic exit doze mode */
- can_base_struct->aed_enable = FALSE;
- /* initialize the prohibit retransmission when sending fails */
- can_base_struct->prsf_enable = FALSE;
- /* initialize the message discarding rule select when overflow */
- can_base_struct->mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;
- /* initialize the multiple message sending sequence rule */
- can_base_struct->mmssr_selection = CAN_SENDING_BY_ID;
- /* initialize the can_mode */
- can_base_struct->mode_selection = CAN_MODE_COMMUNICATE;
- }
- /**
- * @brief initialize the can peripheral according to the specified
- * parameters in the can_init_struct.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param can_base_struct: pointer to a can_base_struct structure that contains the configuration information for the can peripheral.
- * @retval the status of initialization
- * this parameter can be one of the following values:
- * SUCCESS or ERROR
- */
- error_status can_base_init(can_type* can_x, can_base_type* can_base_struct)
- {
- error_status init_status_index = ERROR;
- uint32_t wait_ack_index = 0x00000000;
- /* exit from doze mode */
- can_x->mctrl_bit.dzen = FALSE;
- /* request freeze mode */
- can_x->mctrl_bit.fzen = TRUE;
- /* wait the acknowledge */
- while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
- {
- wait_ack_index++;
- }
- /* check acknowledge */
- if(can_x->msts_bit.fzc)
- {
- /* set the time triggered communication mode */
- can_x->mctrl_bit.ttcen = can_base_struct->ttc_enable;
- /* set the automatic exit bus-off management */
- can_x->mctrl_bit.aeboen = can_base_struct->aebo_enable;
- /* set the automatic automatic exit doze mode */
- can_x->mctrl_bit.aeden = can_base_struct->aed_enable;
- /* set the prohibit retransmission when sending fails */
- can_x->mctrl_bit.prsfen = can_base_struct->prsf_enable;
- /* set the message discarding rule select when overflow */
- can_x->mctrl_bit.mdrsel = can_base_struct->mdrsel_selection;
- /* set the multiple message sending sequence rule */
- can_x->mctrl_bit.mmssr = can_base_struct->mmssr_selection;
- /* set the test mode */
- can_x->btmg_bit.lben = can_base_struct->mode_selection & 0x01;
- can_x->btmg_bit.loen = (can_base_struct->mode_selection >> 1) & 0x01;
- /* request leave freeze mode */
- can_x->mctrl_bit.fzen = FALSE;
- /* wait the acknowledge */
- wait_ack_index = 0;
- while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT))
- {
- wait_ack_index++;
- }
- /* check acknowledged */
- if(can_x->msts_bit.fzc)
- {
- init_status_index = ERROR;
- }
- else
- {
- init_status_index = SUCCESS ;
- }
- }
- else
- {
- init_status_index = ERROR;
- }
- /* return the status of initialization */
- return init_status_index;
- }
- /**
- * @brief fill each can_filter_init_struct member with its default value.
- * @param can_filter_init_struct: pointer to a can_filter_init_type structure which will be initialized.
- * @retval none.
- */
- void can_filter_default_para_init(can_filter_init_type* can_filter_init_struct)
- {
- /* reset can filter init structure parameters values */
- /* initialize the filter activate state */
- can_filter_init_struct->filter_activate_enable = FALSE;
- /* filter mode */
- can_filter_init_struct->filter_mode = CAN_FILTER_MODE_ID_MASK;
- /* filter relation fifo select */
- can_filter_init_struct->filter_fifo = CAN_FILTER_FIFO0;
- /* filter number select */
- can_filter_init_struct->filter_number = 0;
- /* initialize the filter bit width */
- can_filter_init_struct->filter_bit = CAN_FILTER_16BIT;
- /* initialize the filters filter data bit */
- can_filter_init_struct->filter_id_high = 0;
- can_filter_init_struct->filter_id_low = 0;
- can_filter_init_struct->filter_mask_high = 0;
- can_filter_init_struct->filter_mask_low = 0;
- }
- /**
- * @brief initialize the can peripheral according to the specified
- * parameters in the can_filter_init_struct.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param can_filter_init_struct: pointer to a can_filter_init_type structure that contains the configuration information.
- * @retval none.
- */
- void can_filter_init(can_type* can_x, can_filter_init_type* can_filter_init_struct)
- {
- uint32_t filter_number_bit_pos = 0;
- filter_number_bit_pos = ((uint32_t)1) << can_filter_init_struct->filter_number;
- /* set the filter turn into configuration condition */
- can_x->fctrl_bit.fcs = TRUE;
- /* filter activate disable */
- can_x->facfg &= ~(uint32_t)filter_number_bit_pos;
- /* filter bit width */
- switch(can_filter_init_struct->filter_bit)
- {
- case CAN_FILTER_16BIT:
- can_x->fbwcfg &= ~(uint32_t)filter_number_bit_pos;
- /* first 16-bit identifier and first 16-bit mask or first 16-bit identifier and second 16-bit identifier */
- can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low) << 16);
- can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low);
- /* second 16-bit identifier and second 16-bit mask or third 16-bit identifier and fourth 16-bit identifier */
- can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16);
- can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high);
- break;
- case CAN_FILTER_32BIT:
- can_x->fbwcfg |= filter_number_bit_pos;
- /* 32-bit identifier or first 32-bit identifier */
- can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high) << 16);
- can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low);
- /* 32-bit mask or second 32-bit identifier */
- can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16);
- can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low);
- break;
- default:
- break;
- }
- /* filter mode */
- switch(can_filter_init_struct->filter_mode)
- {
- case CAN_FILTER_MODE_ID_MASK:
- can_x->fmcfg &= ~(uint32_t)filter_number_bit_pos;
- break;
- case CAN_FILTER_MODE_ID_LIST:
- can_x->fmcfg |= (uint32_t)filter_number_bit_pos;
- break;
- default:
- break;
- }
- /* filter relation fifo select */
- switch(can_filter_init_struct->filter_fifo)
- {
- case CAN_FILTER_FIFO0:
- can_x->frf &= ~(uint32_t)filter_number_bit_pos;
- break;
- case CAN_FILTER_FIFO1:
- can_x->frf |= (uint32_t)filter_number_bit_pos;
- break;
- default:
- break;
- }
- /* filter activate enable */
- switch(can_filter_init_struct->filter_activate_enable)
- {
- case TRUE:
- can_x->facfg |= (uint32_t)filter_number_bit_pos;
- break;
- case FALSE:
- can_x->facfg &= ~(uint32_t)filter_number_bit_pos;
- break;
- default:
- break;
- }
- /* set the filter turn into working condition */
- can_x->fctrl_bit.fcs = FALSE;
- }
- /**
- * @brief enable or disable the debug transmission prohibit of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param new_state: new state of debug transmission prohibit.
- * this parameter can be: TRUE or FALSE.
- * @retval none.
- */
- void can_debug_transmission_prohibit(can_type* can_x, confirm_state new_state)
- {
- can_x->mctrl_bit.ptd = new_state;
- }
- /**
- * @brief enable or disable time trigger operation communication mode of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1 or CAN2.
- * @param new_state : new state of time trigger operation communication mode.
- * this parameter can be: TRUE or FALSE.
- * @note
- * note1:
- * when enabled, transmit mailbox time stamp(tmts[15:0]) value is sent in the last two data bytes of
- * the 8-byte message: tmts[7:0] in data byte 6 and tmts[15:8] in data byte 7
- * @note
- * note2:
- * tmdtbl must be programmed as 8 in order time stamp (2 bytes) to be sent over the can bus.
- * @retval none
- */
- void can_ttc_mode_enable(can_type* can_x, confirm_state new_state)
- {
- /* config the ttc mode new_state */
- can_x->mctrl_bit.ttcen = new_state;
- /* config tmtsten bits new_state */
- can_x->tx_mailbox[0].tmc_bit.tmtsten = new_state;
- can_x->tx_mailbox[1].tmc_bit.tmtsten = new_state;
- can_x->tx_mailbox[2].tmc_bit.tmtsten = new_state;
- }
- /**
- * @brief fill the transmission message and transmit of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param tx_message_struct: pointer to a structure which contains the message to be trans.
- * @retval the number of the mailbox that is used for transmission:
- * this parameter can be one of the following values:
- * - CAN_TX_MAILBOX0
- * - CAN_TX_MAILBOX1
- * - CAN_TX_MAILBOX2
- * - CAN_TX_STATUS_NO_EMPTY <meanings there is no empty mailbox, message cannot be filled>
- */
- uint8_t can_message_transmit(can_type* can_x, can_tx_message_type* tx_message_struct)
- {
- uint8_t transmit_mailbox = CAN_TX_STATUS_NO_EMPTY;
- /* select one empty transmit mailbox */
- if(can_x->tsts_bit.tm0ef)
- {
- transmit_mailbox = CAN_TX_MAILBOX0;
- }
- else if(can_x->tsts_bit.tm1ef)
- {
- transmit_mailbox = CAN_TX_MAILBOX1;
- }
- else if(can_x->tsts_bit.tm2ef)
- {
- transmit_mailbox = CAN_TX_MAILBOX2;
- }
- else
- {
- transmit_mailbox = CAN_TX_STATUS_NO_EMPTY;
- }
- if(transmit_mailbox != CAN_TX_STATUS_NO_EMPTY)
- {
- /* set up the id */
- can_x->tx_mailbox[transmit_mailbox].tmi &= 0x00000001;
- can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmidsel = tx_message_struct->id_type;
- switch(tx_message_struct->id_type)
- {
- case CAN_ID_STANDARD:
- can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsid = tx_message_struct->standard_id;
- break;
- case CAN_ID_EXTENDED:
- can_x->tx_mailbox[transmit_mailbox].tmi |= (tx_message_struct->extended_id << 3);
- break;
- default:
- break;
- }
- can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmfrsel = tx_message_struct->frame_type;
- /* set up the dlc */
- can_x->tx_mailbox[transmit_mailbox].tmc_bit.tmdtbl = (tx_message_struct->dlc & ((uint8_t)0x0F));
- /* set up the data field */
- can_x->tx_mailbox[transmit_mailbox].tmdtl = (((uint32_t)tx_message_struct->data[3] << 24) |
- ((uint32_t)tx_message_struct->data[2] << 16) |
- ((uint32_t)tx_message_struct->data[1] << 8) |
- ((uint32_t)tx_message_struct->data[0]));
- can_x->tx_mailbox[transmit_mailbox].tmdth = (((uint32_t)tx_message_struct->data[7] << 24) |
- ((uint32_t)tx_message_struct->data[6] << 16) |
- ((uint32_t)tx_message_struct->data[5] << 8) |
- ((uint32_t)tx_message_struct->data[4]));
- /* request transmission */
- can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsr = TRUE;
- }
- return transmit_mailbox;
- }
- /**
- * @brief check the transmission state of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1 or CAN2.
- * @param transmit_mailbox: the number of the mailbox that is used for transmission.
- * this parameter can be one of the following values:
- * - CAN_TX_MAILBOX0
- * - CAN_TX_MAILBOX1
- * - CAN_TX_MAILBOX2
- * @retval can transmit status
- * this parameter can be one of the following values:
- * - CAN_TX_STATUS_SUCCESSFUL
- * - CAN_TX_STATUS_FAILED
- * - CAN_TX_STATUS_PENDING
- */
- can_transmit_status_type can_transmit_status_get(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox)
- {
- can_transmit_status_type state_index = CAN_TX_STATUS_FAILED;
- switch(transmit_mailbox)
- {
- case CAN_TX_MAILBOX0:
- if(can_x->tsts_bit.tm0tcf != RESET)
- {
- if(can_x->tsts_bit.tm0tsf != RESET)
- {
- state_index = CAN_TX_STATUS_SUCCESSFUL;
- }
- else
- {
- state_index = CAN_TX_STATUS_FAILED;
- }
- }
- else
- {
- state_index = CAN_TX_STATUS_PENDING;
- }
- break;
- case CAN_TX_MAILBOX1:
- if(can_x->tsts_bit.tm1tcf != RESET)
- {
- if(can_x->tsts_bit.tm1tsf != RESET)
- {
- state_index = CAN_TX_STATUS_SUCCESSFUL;
- }
- else
- {
- state_index = CAN_TX_STATUS_FAILED;
- }
- }
- else
- {
- state_index = CAN_TX_STATUS_PENDING;
- }
- break;
- case CAN_TX_MAILBOX2:
- if(can_x->tsts_bit.tm2tcf != RESET)
- {
- if(can_x->tsts_bit.tm2tsf != RESET)
- {
- state_index = CAN_TX_STATUS_SUCCESSFUL;
- }
- else
- {
- state_index = CAN_TX_STATUS_FAILED;
- }
- }
- else
- {
- state_index = CAN_TX_STATUS_PENDING;
- }
- break;
- default:
- state_index = CAN_TX_STATUS_FAILED;
- break;
- }
- return state_index;
- }
- /**
- * @brief cancel a transmit request of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1 or CAN2.
- * @param mailbox: mailbox number.
- * this parameter can be one of the following values:
- * - CAN_TX_MAILBOX0
- * - CAN_TX_MAILBOX1
- * - CAN_TX_MAILBOX2
- * @retval none.
- */
- void can_transmit_cancel(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox)
- {
- switch (transmit_mailbox)
- {
- case CAN_TX_MAILBOX0:
- can_x->tsts = CAN_TSTS_TM0CT_VAL;
- break;
- case CAN_TX_MAILBOX1:
- can_x->tsts = CAN_TSTS_TM1CT_VAL;
- break;
- case CAN_TX_MAILBOX2:
- can_x->tsts = CAN_TSTS_TM2CT_VAL;
- break;
- default:
- break;
- }
- }
- /**
- * @brief receive message of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param fifo_number: receive fifo number.
- * this parameter can be one of the following values:
- * - CAN_RX_FIFO0
- * - CAN_RX_FIFO1
- * @param rx_message_struct: pointer to a structure which store the receive message.
- * @retval none.
- */
- void can_message_receive(can_type* can_x, can_rx_fifo_num_type fifo_number, can_rx_message_type* rx_message_struct)
- {
- /* get the id type */
- rx_message_struct->id_type = (can_identifier_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rfidi;
- switch (rx_message_struct->id_type)
- {
- case CAN_ID_STANDARD:
- rx_message_struct->standard_id = can_x->fifo_mailbox[fifo_number].rfi_bit.rfsid;
- break;
- case CAN_ID_EXTENDED:
- rx_message_struct->extended_id = 0x1FFFFFFF & (can_x->fifo_mailbox[fifo_number].rfi >> 3);
- break;
- default:
- break;
- }
- rx_message_struct->frame_type = (can_trans_frame_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rffri;
- /* get the dlc */
- rx_message_struct->dlc = can_x->fifo_mailbox[fifo_number].rfc_bit.rfdtl;
- /* get the filter match number */
- rx_message_struct->filter_index = can_x->fifo_mailbox[fifo_number].rfc_bit.rffmn;
- /* get the data field */
- rx_message_struct->data[0] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt0;
- rx_message_struct->data[1] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt1;
- rx_message_struct->data[2] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt2;
- rx_message_struct->data[3] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt3;
- rx_message_struct->data[4] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt4;
- rx_message_struct->data[5] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt5;
- rx_message_struct->data[6] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt6;
- rx_message_struct->data[7] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt7;
- /* release the fifo */
- can_receive_fifo_release(can_x, fifo_number);
- }
- /**
- * @brief release the specified fifo of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param fifo_number: fifo to be release.
- * this parameter can be one of the following values:
- * - CAN_RX_FIFO0
- * - CAN_RX_FIFO1
- * @retval none.
- */
- void can_receive_fifo_release(can_type* can_x, can_rx_fifo_num_type fifo_number)
- {
- switch (fifo_number)
- {
- case CAN_RX_FIFO0:
- can_x->rf0 = CAN_RF0_RF0R_VAL;
- break;
- case CAN_RX_FIFO1:
- can_x->rf1 = CAN_RF1_RF1R_VAL;
- break;
- default:
- break;
- }
- }
- /**
- * @brief return the number of pending messages of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param fifo_number: receive fifo number.
- * this parameter can be one of the following values:
- * - CAN_RX_FIFO0
- * - CAN_RX_FIFO1
- * @retval the number of message pending in the receive fifo.
- */
- uint8_t can_receive_message_pending_get(can_type* can_x, can_rx_fifo_num_type fifo_number)
- {
- uint8_t message_pending = 0;
- switch (fifo_number)
- {
- case CAN_RX_FIFO0:
- message_pending = can_x->rf0_bit.rf0mn;
- break;
- case CAN_RX_FIFO1:
- message_pending = can_x->rf1_bit.rf1mn;
- break;
- default:
- break;
- }
- return message_pending;
- }
- /**
- * @brief set the operation mode of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param can_operating_mode: can operating mode.
- * this parameter can be one of the following values:
- * - CAN_OPERATINGMODE_FREEZE
- * - CAN_OPERATINGMODE_DOZE
- * - CAN_OPERATINGMODE_COMMUNICATE
- * @retval status of operation mode set
- * this parameter can be one of the following values:
- * SUCCESS or ERROR
- */
- error_status can_operating_mode_set(can_type* can_x, can_operating_mode_type can_operating_mode)
- {
- error_status status = ERROR;
- uint32_t time_out_index = FZC_TIMEOUT;
- if (can_operating_mode == CAN_OPERATINGMODE_FREEZE)
- {
- /* request enter freeze mode */
- can_x->mctrl_bit.dzen = FALSE;
- can_x->mctrl_bit.fzen = TRUE;
- while(((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc)) && (time_out_index != 0))
- {
- time_out_index--;
- }
- if((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc))
- {
- status = ERROR;
- }
- else
- {
- status = SUCCESS;
- }
- }
- else if(can_operating_mode == CAN_OPERATINGMODE_DOZE)
- {
- /* request enter doze mode */
- can_x->mctrl_bit.dzen = TRUE;
- can_x->mctrl_bit.fzen = FALSE;
- while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0))
- {
- time_out_index--;
- }
- if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc))
- {
- status = ERROR;
- }
- else
- {
- status = SUCCESS;
- }
- }
- else if(can_operating_mode == CAN_OPERATINGMODE_COMMUNICATE)
- {
- /* request enter normal mode */
- can_x->mctrl_bit.dzen = FALSE;
- can_x->mctrl_bit.fzen = FALSE;
- while(((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0))
- {
- time_out_index--;
- }
- if((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc))
- {
- status = ERROR;
- }
- else
- {
- status = SUCCESS;
- }
- }
- else
- {
- status = ERROR;
- }
- return status;
- }
- /**
- * @brief enter the low power mode of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @retval status of doze mode enter, the returned value can be:
- * - CAN_ENTER_DOZE_SUCCESSFUL <it meaning enter the doze mode succeed>
- * - CAN_ENTER_DOZE_FAILED <it meaning enter the doze mode failed>
- */
- can_enter_doze_status_type can_doze_mode_enter(can_type* can_x)
- {
- can_enter_doze_status_type status = CAN_ENTER_DOZE_FAILED;
- uint32_t time_out_index = FZC_TIMEOUT;
- can_x->mctrl_bit.fzen = FALSE;
- can_x->mctrl_bit.dzen = TRUE;
- while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0))
- {
- time_out_index--;
- }
- if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc))
- {
- status = CAN_ENTER_DOZE_FAILED;
- }
- else
- {
- status = CAN_ENTER_DOZE_SUCCESSFUL;
- }
- return status;
- }
- /**
- * @brief exit the doze mode of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @retval status of doze mode enter, the returned value can be:
- * - CAN_QUIT_DOZE_SUCCESSFUL <it meaning exit the doze mode succeed>
- * - CAN_QUIT_DOZE_FAILED <it meaning exit the doze mode failed>
- */
- can_quit_doze_status_type can_doze_mode_exit(can_type* can_x)
- {
- can_quit_doze_status_type status = CAN_QUIT_DOZE_FAILED;
- uint32_t time_out_index = DZC_TIMEOUT;
- can_x->mctrl_bit.dzen = FALSE;
- while((can_x->msts_bit.dzc) && (time_out_index != 0))
- {
- time_out_index--;
- }
- if(!can_x->msts_bit.dzc)
- {
- status = CAN_QUIT_DOZE_SUCCESSFUL;
- }
- return status;
- }
- /**
- * @brief return the error type record (etr) of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @retval the value of the error code
- * the return can be one of the follow values:
- * - CAN_ERRORRECORD_NOERR
- * - CAN_ERRORRECORD_STUFFERR,
- * - CAN_ERRORRECORD_FORMERR,
- * - CAN_ERRORRECORD_ACKERR,
- * - CAN_ERRORRECORD_BITRECESSIVEERR,
- * - CAN_ERRORRECORD_BITDOMINANTERR,
- * - CAN_ERRORRECORD_CRCERR,
- * - CAN_ERRORRECORD_SOFTWARESETERR
- */
- can_error_record_type can_error_type_record_get(can_type* can_x)
- {
- can_error_record_type error_code = CAN_ERRORRECORD_NOERR;
- error_code = (can_error_record_type)can_x->ests_bit.etr;
- return error_code;
- }
- /**
- * @brief return the receive error counter (rec) of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @retval the value of receive error counter.
- */
- uint8_t can_receive_error_counter_get(can_type* can_x)
- {
- uint8_t counter = 0;
- counter = can_x->ests_bit.rec;
- return counter;
- }
- /**
- * @brief return the transmit error counter of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @retval the value of transmit error counter.
- */
- uint8_t can_transmit_error_counter_get(can_type* can_x)
- {
- uint8_t counter = 0;
- counter = can_x->ests_bit.tec;
- return counter;
- }
- /**
- * @brief enable or disable the interrupt of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param can_int: specifies the can interrupt sources to be enabled or disabled.
- * this parameter can be one of the following values:
- * - CAN_TCIEN_INT
- * - CAN_RF0MIEN_INT
- * - CAN_RF0FIEN_INT
- * - CAN_RF0OIEN_INT
- * - CAN_RF1MIEN_INT
- * - CAN_RF1FIEN_INT
- * - CAN_RF1OIEN_INT
- * - CAN_EAIEN_INT
- * - CAN_EPIEN_INT
- * - CAN_BOIEN_INT
- * - CAN_ETRIEN_INT
- * - CAN_EOIEN_INT
- * - CAN_QDZIEN_INT
- * - CAN_EDZIEN_INT
- * @param new_state: new state of the can interrupts.
- * this parameter can be: TRUE or FALSE.
- * @retval none.
- */
- void can_interrupt_enable(can_type* can_x, uint32_t can_int, confirm_state new_state)
- {
- if (new_state != FALSE)
- {
- can_x->inten |= can_int;
- }
- else
- {
- can_x->inten &= ~can_int;
- }
- }
- /**
- * @brief get flag of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param can_flag: select the flag.
- * this parameter can be one of the following flags:
- * - CAN_EAF_FLAG
- * - CAN_EPF_FLAG
- * - CAN_BOF_FLAG
- * - CAN_ETR_FLAG
- * - CAN_EOIF_FLAG
- * - CAN_TM0TCF_FLAG
- * - CAN_TM1TCF_FLAG
- * - CAN_TM2TCF_FLAG
- * - CAN_RF0MN_FLAG
- * - CAN_RF0FF_FLAG
- * - CAN_RF0OF_FLAG
- * - CAN_RF1MN_FLAG
- * - CAN_RF1FF_FLAG
- * - CAN_RF1OF_FLAG
- * - CAN_QDZIF_FLAG
- * - CAN_EDZC_FLAG
- * - CAN_TMEF_FLAG
- * note:the state of CAN_EDZC_FLAG need to check dzc and edzif bit
- * note:the state of CAN_TMEF_FLAG need to check rqc0,rqc1 and rqc2 bit
- * @retval status of can_flag, the returned value can be:SET or RESET.
- */
- flag_status can_flag_get(can_type* can_x, uint32_t can_flag)
- {
- flag_status bit_status = RESET;
- switch(can_flag)
- {
- case CAN_EAF_FLAG:
- bit_status = (flag_status)can_x->ests_bit.eaf;
- break;
- case CAN_EPF_FLAG:
- bit_status = (flag_status)can_x->ests_bit.epf;
- break;
- case CAN_BOF_FLAG:
- bit_status = (flag_status)can_x->ests_bit.bof;
- break;
- case CAN_ETR_FLAG:
- if(can_x->ests_bit.etr != 0)
- {
- bit_status = SET;
- }
- else
- {
- bit_status = RESET;
- }
- break;
- case CAN_EOIF_FLAG:
- bit_status = (flag_status)can_x->msts_bit.eoif;
- break;
- case CAN_TM0TCF_FLAG:
- bit_status = (flag_status)can_x->tsts_bit.tm0tcf;
- break;
- case CAN_TM1TCF_FLAG:
- bit_status = (flag_status)can_x->tsts_bit.tm1tcf;
- break;
- case CAN_TM2TCF_FLAG:
- bit_status = (flag_status)can_x->tsts_bit.tm2tcf;
- break;
- case CAN_RF0MN_FLAG:
- if(can_x->rf0_bit.rf0mn != 0)
- {
- bit_status = SET;
- }
- else
- {
- bit_status = RESET;
- }
- break;
- case CAN_RF0FF_FLAG:
- bit_status = (flag_status)can_x->rf0_bit.rf0ff;
- break;
- case CAN_RF0OF_FLAG:
- bit_status = (flag_status)can_x->rf0_bit.rf0of;
- break;
- case CAN_RF1MN_FLAG:
- if(can_x->rf1_bit.rf1mn != 0)
- {
- bit_status = SET;
- }
- else
- {
- bit_status = RESET;
- }
- break;
- case CAN_RF1FF_FLAG:
- bit_status = (flag_status)can_x->rf1_bit.rf1ff;
- break;
- case CAN_RF1OF_FLAG:
- bit_status = (flag_status)can_x->rf1_bit.rf1of;
- break;
- case CAN_QDZIF_FLAG:
- bit_status = (flag_status)can_x->msts_bit.qdzif;
- break;
- case CAN_EDZC_FLAG:
- if((can_x->msts_bit.dzc != RESET) ||(can_x->msts_bit.edzif != RESET))
- {
- bit_status = SET;
- }
- else
- {
- bit_status = RESET;
- }
- break;
- case CAN_TMEF_FLAG:
- if((can_x->tsts_bit.tm0ef != RESET) || (can_x->tsts_bit.tm1ef != RESET) || (can_x->tsts_bit.tm2ef != RESET))
- {
- bit_status = SET;
- }
- else
- {
- bit_status = RESET;
- }
- break;
- default:
- bit_status = RESET;
- break;
- }
- return bit_status;
- }
- /**
- * @brief clear flag of the specified can peripheral.
- * @param can_x: select the can peripheral.
- * this parameter can be one of the following values:
- * CAN1,CAN2.
- * @param can_flag: select the flag.
- * this parameter can be one of the following flags:
- * - CAN_EAF_FLAG
- * - CAN_EPF_FLAG
- * - CAN_BOF_FLAG
- * - CAN_ETR_FLAG
- * - CAN_EOIF_FLAG
- * - CAN_TM0TCF_FLAG
- * - CAN_TM1TCF_FLAG
- * - CAN_TM2TCF_FLAG
- * - CAN_RF0FF_FLAG
- * - CAN_RF0OF_FLAG
- * - CAN_RF1FF_FLAG
- * - CAN_RF1OF_FLAG
- * - CAN_QDZIF_FLAG
- * - CAN_EDZC_FLAG
- * - CAN_TMEF_FLAG
- * - CAN_ETR_SOFTWARE_FLAG
- * note:CAN_RF0MN_FLAG and CAN_RF1MN_FLAG can not clear by this function
- * @retval none.
- */
- void can_flag_clear(can_type* can_x, uint32_t can_flag)
- {
- switch(can_flag)
- {
- case CAN_EAF_FLAG:
- case CAN_EPF_FLAG:
- case CAN_BOF_FLAG:
- case CAN_EOIF_FLAG:
- can_x->msts = CAN_MSTS_EOIF_VAL;
- break;
- case CAN_ETR_FLAG:
- can_x->msts = CAN_MSTS_EOIF_VAL;
- can_x->ests = 0;
- break;
- case CAN_TM0TCF_FLAG:
- can_x->tsts = CAN_TSTS_TM0TCF_VAL;
- break;
- case CAN_TM1TCF_FLAG:
- can_x->tsts = CAN_TSTS_TM1TCF_VAL;
- break;
- case CAN_TM2TCF_FLAG:
- can_x->tsts = CAN_TSTS_TM2TCF_VAL;
- break;
- case CAN_RF0FF_FLAG:
- can_x->rf0 = CAN_RF0_RF0FF_VAL;
- break;
- case CAN_RF0OF_FLAG:
- can_x->rf0 = CAN_RF0_RF0OF_VAL;
- break;
- case CAN_RF1FF_FLAG:
- can_x->rf1 = CAN_RF1_RF1FF_VAL;
- break;
- case CAN_RF1OF_FLAG:
- can_x->rf1 = CAN_RF1_RF1OF_VAL;
- break;
- case CAN_QDZIF_FLAG:
- can_x->msts = CAN_MSTS_QDZIF_VAL;
- break;
- case CAN_EDZC_FLAG:
- can_x->msts = CAN_MSTS_EDZIF_VAL;
- break;
- case CAN_TMEF_FLAG:
- can_x->tsts = CAN_TSTS_TM0TCF_VAL | CAN_TSTS_TM1TCF_VAL | CAN_TSTS_TM2TCF_VAL;
- break;
- default:
- break;
- }
- }
- /**
- * @}
- */
- #endif
- /**
- * @}
- */
- /**
- * @}
- */
|