123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110 |
- /*!
- * @file apm32f10x_can.c
- *
- * @brief This file provides all the CAN firmware functions
- *
- * @version V1.0.1
- *
- * @date 2021-03-23
- *
- */
- #include "apm32f10x_can.h"
- #include "apm32f10x_rcm.h"
- /** @addtogroup Peripherals_Library Standard Peripheral Library
- @{
- */
- /** @addtogroup CAN_Driver CAN Driver
- @{
- */
- /** @addtogroup CAN_Fuctions Fuctions
- @{
- */
- /*!
- * @brief Reset CAN registers
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_Reset(CAN_T* can)
- {
- if (can == CAN1)
- {
- RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CAN1);
- RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CAN1);
- }
- else if (can == CAN2)
- {
- RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CAN2);
- RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CAN2);
- }
- }
- /*!
- * @brief Initialization parameter configuration
- *
- * @param can: Select the CAN peripheral which can be CAN1 or CAN2.
- *
- * @param canConfig: Point to a CAN_Config_T structure.
- *
- * @retval ERROR or SUCCEESS
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_Config(CAN_T* can, CAN_Config_T* canConfig)
- {
- uint8_t initStatus = ERROR;
- uint32_t wait_ack = 0x00000000;
- /** Exit from sleep mode */
- can->MCTRL_B.SLEEPREQ = BIT_RESET;
- /** Request initialisation */
- can->MCTRL_B.INITREQ = BIT_SET;
- /** Wait the acknowledge */
- while(((can->MSTS_B.INITFLG) != BIT_SET) && (wait_ack != 0x0000FFFF))
- {
- wait_ack++;
- }
- /** Check acknowledge */
- if(((can->MSTS_B.INITFLG) != BIT_SET))
- {
- initStatus = ERROR;
- }
- else
- {
- if(canConfig->timeTrigComMode == ENABLE)
- {
- can->MCTRL_B.TTCM = BIT_SET;
- }
- else
- {
- can->MCTRL_B.TTCM = BIT_RESET;
- }
- if(canConfig->autoBusOffManage == ENABLE)
- {
- can->MCTRL_B.ALBOFFM = BIT_SET;
- }
- else
- {
- can->MCTRL_B.ALBOFFM = BIT_RESET;
- }
- if(canConfig->autoWakeUpMode == ENABLE)
- {
- can->MCTRL_B.AWUPCFG = BIT_SET;
- }
- else
- {
- can->MCTRL_B.AWUPCFG = BIT_RESET;
- }
- if(canConfig->nonAutoRetran == ENABLE)
- {
- can->MCTRL_B.ARTXMD = BIT_SET;
- }
- else
- {
- can->MCTRL_B.ARTXMD = BIT_RESET;
- }
- if(canConfig->rxFIFOLockMode == ENABLE)
- {
- can->MCTRL_B.RXFLOCK = BIT_SET;
- }
- else
- {
- can->MCTRL_B.RXFLOCK = BIT_RESET;
- }
- if(canConfig->txFIFOPriority == ENABLE)
- {
- can->MCTRL_B.TXFPCFG = BIT_SET;
- }
- else
- {
- can->MCTRL_B.TXFPCFG = BIT_RESET;
- }
- /** Set the bit timing register */
- can->BITTIM &= (uint32_t)0x3fffffff;
- can->BITTIM |= (uint32_t)canConfig->mode << 30;
- can->BITTIM_B.RSYNJW = canConfig->syncJumpWidth;
- can->BITTIM_B.TIMSEG1 = canConfig->timeSegment1;
- can->BITTIM_B.TIMSEG2 = canConfig->timeSegment2;
- can->BITTIM_B.BRPSC = canConfig->prescaler - 1;
- /** Request leave initialisation */
- can->MCTRL_B.INITREQ = BIT_RESET;
- wait_ack = 0;
- /** Wait the acknowledge */
- while(((can->MSTS_B.INITFLG) != BIT_RESET) && (wait_ack != 0x0000FFFF))
- {
- wait_ack++;
- }
- /** Check acknowledge */
- if(((can->MSTS_B.INITFLG) != BIT_RESET))
- {
- initStatus = ERROR;
- }
- else
- {
- initStatus = SUCCESS;
- }
- }
- return initStatus;
- }
- /*!
- * @brief Congig the CAN peripheral according to the specified parameters in the filterConfig.
- *
- * @param can: Select the CAN peripheral which can be CAN1 or CAN2.
- *
- * @param filterConfig :Point to a CAN_FILTER_CONFIG_T structure.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_ConfigFilter(CAN_T* can, CAN_FILTER_CONFIG_T* filterConfig)
- {
- can->FCTRL_B.FINITEN = BIT_SET;
- can->FACT &= ~(1 << filterConfig->filterNumber);
- /** Filter Scale */
- if(filterConfig->filterScale == CAN_FILTER_SCALE_16BIT)
- {
- /** 16-bit scale for the filter */
- can->FSCFG &= ~(1 << filterConfig->filterNumber);
- can->sFilterRegister[filterConfig->filterNumber].FBANK1 =
- ((0x0000FFFF & filterConfig->filterMaskIdLow) << 16) |
- (0x0000FFFF & filterConfig->filterIdLow);
- can->sFilterRegister[filterConfig->filterNumber].FBANK2 =
- ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) |
- (0x0000FFFF & filterConfig->filterIdHigh);
- }
- if(filterConfig->filterScale == CAN_FILTER_SCALE_32BIT)
- {
- can->FSCFG |= (1 << filterConfig->filterNumber);
- can->sFilterRegister[filterConfig->filterNumber].FBANK1 =
- ((0x0000FFFF & filterConfig->filterIdHigh) << 16) |
- (0x0000FFFF & filterConfig->filterIdLow);
- can->sFilterRegister[filterConfig->filterNumber].FBANK2 =
- ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) |
- (0x0000FFFF & filterConfig->filterMaskIdLow);
- }
- /** Filter Mode */
- if(filterConfig->filterMode == CAN_FILTER_MODE_IDMASK)
- {
- can->FMCFG &= ~(1 << filterConfig->filterNumber);
- }
- else
- {
- can->FMCFG |= (1 << filterConfig->filterNumber);
- }
- /** Filter FIFO assignment */
- if(filterConfig->filterFIFO == CAN_FILTER_FIFO_0)
- {
- can->FFASS &= ~(1 << filterConfig->filterNumber);
- }
- if(filterConfig->filterFIFO == CAN_FILTER_FIFO_1)
- {
- can->FFASS |= (1 << filterConfig->filterNumber);
- }
- /** Filter activation */
- if(filterConfig->filterActivation == ENABLE)
- {
- can->FACT |= (1 << filterConfig->filterNumber);
- }
- can->FCTRL_B.FINITEN = BIT_RESET;
- }
- /*!
- * @brief Initialize a CAN_Config_T structure with the initial value.
- *
- * @param canConfig :Point to a CAN_Config_T structure.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_ConfigStructInit(CAN_Config_T* canConfig)
- {
- canConfig->timeTrigComMode = DISABLE;
- canConfig->autoBusOffManage = DISABLE;
- canConfig->autoWakeUpMode = DISABLE;
- canConfig->nonAutoRetran = DISABLE;
- canConfig->rxFIFOLockMode = DISABLE;
- canConfig->txFIFOPriority = DISABLE;
- canConfig->mode = CAN_MODE_NORMAL;
- canConfig->syncJumpWidth = CAN_SJW_1;
- canConfig->timeSegment1 = CAN_TIME_SEGMENT1_4;
- canConfig->timeSegment2 = CAN_TIME_SEGMENT2_3;
- canConfig->prescaler = 1;
- }
- /*!
- * @brief Enables the DBG Freeze for CAN.
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_EnableDBGFreeze(CAN_T* can)
- {
- can->MCTRL_B.DBGFRZE = ENABLE;
- }
- /*!
- * @brief Disable the DBG Freeze for CAN.
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_DisableDBGFreeze(CAN_T* can)
- {
- can->MCTRL_B.DBGFRZE = DISABLE;
- }
- /*!
- * @brief Enables the CAN Time TriggerOperation communication mode.
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_EnableTTCComMode(CAN_T* can)
- {
- can->MCTRL_B.TTCM = ENABLE;
- can->sTxMailBox[0].TXDLEN_B.TXTS = BIT_SET;
- can->sTxMailBox[1].TXDLEN_B.TXTS = BIT_SET;
- can->sTxMailBox[2].TXDLEN_B.TXTS = BIT_SET;
- }
- /*!
- * @brief Disable the CAN Time TriggerOperation communication mode.
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_DisableTTCComMode(CAN_T* can)
- {
- can->MCTRL_B.TTCM = DISABLE;
- can->sTxMailBox[0].TXDLEN_B.TXTS = BIT_RESET;
- can->sTxMailBox[1].TXDLEN_B.TXTS = BIT_RESET;
- can->sTxMailBox[2].TXDLEN_B.TXTS = BIT_RESET;
- }
- /*!
- * @brief Initiates the transmission of a message.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param TxMessage: pointer to a CAN_TX_MESSAGE_T structure.
- *
- * @retval The number of the mailbox which is used for transmission or 3 if No mailbox is empty.
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_TxMessage(CAN_T* can, CAN_TX_MESSAGE_T* TxMessage)
- {
- uint8_t transmit_milbox = 0;
- /** Select one empty transmit mailbox */
- if((can->TXSTS & 0x04000000) == 0x04000000)
- {
- transmit_milbox = 0;
- }
- else if((can->TXSTS & 0x08000000) == 0x08000000)
- {
- transmit_milbox = 1;
- }
- else if((can->TXSTS & 0x10000000) == 0x10000000)
- {
- transmit_milbox = 2;
- } else
- {
- return 3; //!< No mailbox is empty
- }
- /** Set up the Id */
- can->sTxMailBox[transmit_milbox].TXMID &= 0x00000001;
- if(TxMessage->typeID == CAN_TYPEID_STD)
- {
- can->sTxMailBox[transmit_milbox].TXMID |= (TxMessage->stdID << 21) | (TxMessage->remoteTxReq);
- } else
- {
- can->sTxMailBox[transmit_milbox].TXMID |= (TxMessage->extID << 3) | (TxMessage->typeID) | (TxMessage->remoteTxReq);
- }
- /** Set up the TXDLEN */
- TxMessage->dataLengthCode &= 0x0F;
- can->sTxMailBox[transmit_milbox].TXDLEN &= (uint32_t)0xFFFFFFF0;
- can->sTxMailBox[transmit_milbox].TXDLEN |= TxMessage->dataLengthCode;
- /** Set up the data field */
- can->sTxMailBox[transmit_milbox].TXMDL = ((uint32_t)TxMessage->data[3] << 24) | ((uint32_t)TxMessage->data[2] << 16)
- | ((uint32_t)TxMessage->data[1] << 8) | ((uint32_t)TxMessage->data[0]);
- can->sTxMailBox[transmit_milbox].TXMDH = ((uint32_t)TxMessage->data[7] << 24) | ((uint32_t)TxMessage->data[6] << 16)
- | ((uint32_t)TxMessage->data[5] << 8) | ((uint32_t)TxMessage->data[4]);
- /** Request transmission */
- can->sTxMailBox[transmit_milbox].TXMID |= 0x00000001;
- return transmit_milbox;
- }
- /*!
- * @brief Checks the transmission of a message.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param transmitMailbox: the number of the mailbox
- *
- * @retval state: 0: Status of transmission is Failed
- * 1: Status of transmission is Ok
- * 2: transmit pending
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_TxMessageStatus(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox)
- {
- uint32_t state = 0;
- switch (TxMailbox)
- {
- case (CAN_TX_MAILBIX_0):
- state = can->TXSTS & (0x00000001 | 0x00000002 | 0x04000000);
- break;
- case (CAN_TX_MAILBIX_1):
- state = can->TXSTS & (0x00000100 | 0x00000200 | 0x08000000);
- break;
- case (CAN_TX_MAILBIX_2):
- state = can->TXSTS & (0x00010000 | 0x00020000 | 0x10000000);
- break;
- default:
- state = 0;
- break;
- }
- switch (state)
- {
- /** transmit pending */
- case (0x0): state = 2;
- break;
- /* transmit failed */
- case (0x00000001 | 0x04000000): state = 0;
- break;
- case (0x00000100 | 0x08000000): state = 0;
- break;
- case (0x00010000 | 0x10000000): state = 0;
- break;
- /* transmit succeeded */
- case (0x00000001 | 0x00000002 | 0x04000000):state = 1;
- break;
- case (0x00000100 | 0x00000200 | 0x08000000):state = 1;
- break;
- case (0x00010000 | 0x00020000 | 0x10000000):state = 1;
- break;
- default: state = 0;
- break;
- }
- return (uint8_t) state;
- }
- /*!
- * @brief Cancels a transmit request.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param mailBox: the number of the mailbox
- * This parameter can be one of the following values:
- * @arg CAN_TX_MAILBIX_0 : Tx mailbox 0
- * @arg CAN_TX_MAILBIX_1 : Tx mailbox 1
- * @arg CAN_TX_MAILBIX_2 : Tx mailbox 2
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_CancelTxMailbox(CAN_T* can, CAN_TX_MAILBIX_T TxMailbox)
- {
- switch (TxMailbox)
- {
- case CAN_TX_MAILBIX_0:
- can->TXSTS_B.ABREQFLG0 = BIT_SET;
- break;
- case CAN_TX_MAILBIX_1:
- can->TXSTS_B.ABREQFLG1 = BIT_SET;
- break;
- case CAN_TX_MAILBIX_2:
- can->TXSTS_B.ABREQFLG2 = BIT_SET;
- break;
- default:
- break;
- }
- }
- /*!
- * @brief Receives a message and save to a CAN_RX_MESSAGE_T structure.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param FIFONumber: Receive FIFO number.
- * This parameter can be one of the following values:
- * @arg CAN_RX_FIFO_0 : Receive FIFO 0
- * @arg CAN_RX_FIFO_1 : Receive FIFO 1
- *
- * @param RxMessage: pointer to a structure to receive the message.
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_RxMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber, CAN_RX_MESSAGE_T* RxMessage)
- {
- /* Get the Id */
- RxMessage->typeID = ((uint8_t)0x04 & (can->sRxMailBox[FIFONumber].RXMID));
- if(RxMessage->typeID == CAN_TYPEID_STD)
- {
- RxMessage->stdID = (can->sRxMailBox[FIFONumber].RXMID >> 21) & 0x000007FF;
- }
- else
- {
- RxMessage->extID = (can->sRxMailBox[FIFONumber].RXMID >> 3) & 0x1FFFFFFF;
- }
- RxMessage->remoteTxReq = can->sRxMailBox[FIFONumber].RXMID_B.RFTXREQ;
- RxMessage->dataLengthCode = can->sRxMailBox[FIFONumber].RXDLEN_B.DLCODE;
- RxMessage->filterMatchIndex = can->sRxMailBox[FIFONumber].RXDLEN_B.FMIDX;
- /** Get the data field */
- RxMessage->data[0] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE1;
- RxMessage->data[1] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE2;
- RxMessage->data[2] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE3;
- RxMessage->data[3] = can->sRxMailBox[FIFONumber].RXMDL_B.DATABYTE4;
- RxMessage->data[4] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE5;
- RxMessage->data[5] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE6;
- RxMessage->data[6] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE7;
- RxMessage->data[7] = can->sRxMailBox[FIFONumber].RXMDH_B.DATABYTE8;
- if(FIFONumber == CAN_RX_FIFO_0)
- {
- can->RXF0_B.RFOM0 = BIT_SET;
- }
- else
- {
- can->RXF1_B.RFOM1 = BIT_SET;
- }
- }
- /*!
- * @brief Releases the specified FIFO.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param FIFONumber: Receive FIFO number
- * This parameter can be one of the following values:
- * @arg CAN_RX_FIFO_0 : Receive FIFO 0
- * @arg CAN_RX_FIFO_1 : Receive FIFO 1
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_ReleaseFIFO(CAN_T* can, CAN_RX_FIFO_T FIFONumber)
- {
- if(FIFONumber == CAN_RX_FIFO_0)
- {
- can->RXF0_B.RFOM0 = BIT_SET;
- }
- else
- {
- can->RXF1_B.RFOM1 = BIT_SET;
- }
- }
- /*!
- * @brief Returns the number of pending messages.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param FIFONumber: Receive FIFO number
- * This parameter can be one of the following values:
- * @arg CAN_RX_FIFO_0 : Receive FIFO 0
- * @arg CAN_RX_FIFO_1 : Receive FIFO 1
- *
- * @retval The number of pending message.
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_PendingMessage(CAN_T* can, CAN_RX_FIFO_T FIFONumber)
- {
- if(FIFONumber == CAN_RX_FIFO_0)
- {
- return can->RXF0 & 0x03;
- }
- else
- {
- return can->RXF1 & 0x03;
- }
- }
- /*!
- * @brief Select the CAN Operation mode
- *
- * @param can: Select the CAN peripheral.
- *
- * @param operatingMode: CAN Operating Mode
- * This parameter can be one of the following values:
- * @arg CAN_OPERATING_MODE_INIT : Initialization mode
- * @arg CAN_OPERATING_MODE_NORMAL: Normal mode
- * @arg CAN_OPERATING_MODE_SLEEP : sleep mode
- *
- * @retval modeState:status of the requested mode
- * 0:CAN failed entering the specific mode
- * 1:CAN Succeed entering the specific mode
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_OperatingMode(CAN_T* can, CAN_OPERATING_MODE_T operatingMode)
- {
- uint8_t states = 0;
- uint32_t time_out = 0x0000FFFF;
- if(operatingMode == CAN_OPERATING_MODE_INIT)
- {
- can->MCTRL_B.SLEEPREQ = BIT_RESET;
- can->MCTRL_B.INITREQ = BIT_SET;
- while((can->MSTS_B.INITFLG != BIT_SET && can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
- {
- time_out --;
- }
- if((can->MSTS_B.INITFLG == BIT_SET && can->MSTS_B.SLEEPFLG == BIT_RESET))
- {
- states = 1;
- }
- }
- else if(operatingMode == CAN_OPERATING_MODE_NORMAL)
- {
- can->MCTRL_B.SLEEPREQ = BIT_RESET;
- can->MCTRL_B.INITREQ = BIT_RESET;
- time_out = 0x0000FFFF;
- while((can->MSTS_B.INITFLG != BIT_RESET || can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
- {
- time_out --;
- }
- if((can->MSTS_B.INITFLG == BIT_RESET || can->MSTS_B.SLEEPFLG == BIT_RESET))
- {
- states = 1;
- }
- }
- else if(operatingMode == CAN_OPERATING_MODE_SLEEP)
- {
- can->MCTRL_B.SLEEPREQ = BIT_SET;
- can->MCTRL_B.INITREQ = BIT_RESET;
- time_out = 0x0000FFFF;
- while((can->MSTS_B.INITFLG != BIT_RESET && can->MSTS_B.SLEEPFLG != BIT_SET) && (time_out != 0))
- {
- time_out --;
- }
- if((can->MSTS_B.INITFLG == BIT_RESET && can->MSTS_B.SLEEPFLG == BIT_SET))
- {
- states = 1;
- }
- }
- return states ;
- }
- /*!
- * @brief Into the low power mode.
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval status: Status of entering sleep mode.
- * 0: Enter sleep fail
- * 1: Enter sleep success
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_SleepMode(CAN_T* can)
- {
- can->MCTRL_B.SLEEPREQ = BIT_SET;
- can->MCTRL_B.INITREQ = BIT_RESET;
- if((can->MSTS_B.INITFLG == BIT_RESET && can->MSTS_B.SLEEPFLG == BIT_SET))
- {
- return 1;
- }
- return 0;
- }
- /*!
- * @brief Wakes the CAN up.
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval status: Status of waking the CAN up
- * 0: WakeUp CAN fail,
- * 1: WakeUp CAN success
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_WakeUpMode(CAN_T* can)
- {
- uint32_t time_out = 0x0000FFFF;
- can->MCTRL_B.SLEEPREQ = BIT_RESET;
- while((can->MSTS_B.SLEEPFLG != BIT_RESET) && (time_out != 0))
- {
- time_out --;
- }
- if(can->MSTS_B.SLEEPFLG == BIT_RESET)
- {
- return 1;
- }
- return 0;
- }
- /*!
- * @brief Read the can's last error code (LERRC)
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval The Last Error Code.
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_ReadLastErrorCode(CAN_T* can)
- {
- return can->ERRSTS_B.LERRC;
- }
- /*!
- * @brief Read the can Receive Error Counter(RXERRCNT)
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval CAN Receive Error Counter.
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_ReadRxErrorCounter(CAN_T* can)
- {
- return can->ERRSTS_B.RXERRCNT;
- }
- /*!
- * @brief Read the LSB of the 9-bit can Transmit Error Counter(TXERRCNT).
- *
- * @param can: Select the CAN peripheral.
- *
- * @retval Least Significant Byte Of The 9-Bit Transmit Error Counter.
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_ReadLSBTxErrorCounter(CAN_T* can)
- {
- return can->ERRSTS_B.TXERRCNT;
- }
- /*!
- * @brief Enables the specified can interrupts.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param interrupts: specifies the CAN interrupt sources
- * This parameter can be any combination of the following values:
- * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
- * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt
- * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
- * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
- * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt
- * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
- * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
- * @arg CAN_INT_ERRW : Error warning Interrupt
- * @arg CAN_INT_ERRP : Error passive Interrupt
- * @arg CAN_INT_BOF : Bus-off Interrupt
- * @arg CAN_INT_LEC : Last error record code Interrupt
- * @arg CAN_INT_ERR : Error Interrupt
- * @arg CAN_INT_WUP : Wake-up Interrupt
- * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_EnableInterrupt(CAN_T* can, uint32_t interrupts)
- {
- can->INTEN |= interrupts;
- }
- /*!
- * @brief Disable the specified can interrupts.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param interrupts: specifies the CAN interrupt sources
- * This parameter can be any combination of the following values:
- * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
- * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt
- * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
- * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
- * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt
- * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
- * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
- * @arg CAN_INT_ERRW : Error warning Interrupt
- * @arg CAN_INT_ERRP : Error passive Interrupt
- * @arg CAN_INT_BOF : Bus-off Interrupt
- * @arg CAN_INT_LEC : Last error record code Interrupt
- * @arg CAN_INT_ERR : Error Interrupt
- * @arg CAN_INT_WUP : Wake-up Interrupt
- * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_DisableInterrupt(CAN_T* can, uint32_t interrupts)
- {
- can->INTEN &= ~interrupts;
- }
- /*!
- * @brief Read whether the specified CAN flag is set or not.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param flag: specifies the CAN flag.
- * This parameter can be one of the following values:
- * @arg CAN_FLAG_ERRW : Error Warning Flag
- * @arg CAN_FLAG_ERRP : Error Passive Flag
- * @arg CAN_FLAG_BOF : Bus-Off Flag
- * @arg CAN_FLAG_LERRC : Last error record code Flag
- * @arg CAN_FLAG_WUPI : Wake up Flag
- * @arg CAN_FLAG_SLEEP : Sleep acknowledge Flag
- * @arg CAN_FLAG_F0MP : FIFO 0 Message Pending Flag
- * @arg CAN_FLAG_F0FULL : FIFO 0 Full Flag
- * @arg CAN_FLAG_F0OVR : FIFO 0 Overrun Flag
- * @arg CAN_FLAG_F1MP : FIFO 1 Message Pending Flag
- * @arg CAN_FLAG_F1FULL : FIFO 1 Full Flag
- * @arg CAN_FLAG_F1OVR : FIFO 1 Overrun Flag
- * @arg CAN_FLAG_REQC0 : Request MailBox0 Flag
- * @arg CAN_FLAG_REQC1 : Request MailBox1 Flag
- * @arg CAN_FLAG_REQC2 : Request MailBox2 Flag
- *
- * @retval flag staus: RESET or SET
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_ReadStatusFlag(CAN_T* can, CAN_FLAG_T flag)
- {
- uint8_t status = 0;
- if((flag & 0x00F00000) != RESET )
- {
- if((can->ERRSTS & (flag & 0x000FFFFF)) != RESET)
- {
- status = SET;
- }
- else
- {
- status = RESET;
- }
- }
- else if((flag & 0x01000000) != RESET )
- {
- if((can->MSTS & (flag & 0x000FFFFF)) != RESET )
- {
- status = SET;
- }
- else
- {
- status = RESET ;
- }
- }
- else if((flag & 0x08000000) != RESET )
- {
- if((can->TXSTS & (flag & 0x000FFFFF)) != RESET )
- {
- status = SET;
- }
- else
- {
- status = RESET;
- }
- }
- else if((flag & 0x02000000) != RESET )
- {
- if((can->RXF0 & (flag & 0x000FFFFF)) != RESET )
- {
- status = SET;
- }
- else
- {
- status = RESET;
- }
- }
- else
- {
- if((can->RXF1 & (flag & 0x000FFFFF)) != RESET)
- {
- status = SET;
- }
- else
- {
- status = RESET;
- }
- }
- return status;
- }
- /*!
- * @brief Clears the CAN's pending flags.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param flag: specifies the CAN flag.
- * This parameter can be one of the following values:
- * @arg CAN_FLAG_LERRC : Last error record code Flag
- * @arg CAN_FLAG_WUPI : Wake up Flag
- * @arg CAN_FLAG_SLEEP : Sleep acknowledge Flag
- * @arg CAN_FLAG_F0FULL: FIFO 0 Full Flag
- * @arg CAN_FLAG_F0OVR : FIFO 0 Overrun Flag
- * @arg CAN_FLAG_F1FULL: FIFO 1 Full Flag
- * @arg CAN_FLAG_F1OVR : FIFO 1 Overrun Flag
- * @arg CAN_FLAG_REQC0 : Request MailBox0 Flag
- * @arg CAN_FLAG_REQC1 : Request MailBox1 Flag
- * @arg CAN_FLAG_REQC2 : Request MailBox2 Flag
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_ClearStatusFlag(CAN_T* can, CAN_FLAG_T flag)
- {
- uint32_t flagtmp = 0;
- /** ERRSTS register */
- if(flag == 0x30F00070)
- {
- can->ERRSTS = RESET;
- }
- else
- {
- flagtmp = flag & 0x000FFFFF;
- if((flag & 0x02000000) != RESET)
- {
- can->RXF0 = flagtmp;
- }
- else if((flag & 0x04000000) != RESET)
- {
- can->RXF1 = flagtmp;
- }
- else if((flag & 0x08000000) != RESET)
- {
- can->TXSTS = flagtmp;
- }
- else
- {
- can->MSTS = flagtmp;
- }
- }
- }
- /*!
- * @brief Read whether the specified can interrupt has occurred or not.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param flag: specifies the CAN interrupt sources
- * This parameter can be one of the following values:
- * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
- * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt
- * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
- * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
- * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt
- * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
- * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
- * @arg CAN_INT_ERRW : Error warning Interrupt
- * @arg CAN_INT_ERRP : Error passive Interrupt
- * @arg CAN_INT_BOF : Bus-off Interrupt
- * @arg CAN_INT_LEC : Last error record code Interrupt
- * @arg CAN_INT_ERR : Error Interrupt
- * @arg CAN_INT_WUP : Wake-up Interrupt
- * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
- *
- * @retval status : SET or RESET
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- uint8_t CAN_ReadIntFlag(CAN_T* can, CAN_INT_T flag)
- {
- uint8_t status = 0;
- if((can->INTEN & flag) != RESET)
- {
- switch (flag)
- {
- case CAN_INT_TXME:
- status = can->TXSTS_B.REQCFLG0 | can->TXSTS_B.REQCFLG1 | can->TXSTS_B.REQCFLG2;
- break;
- case CAN_INT_F0MP:
- status = can->RXF0_B.FMNUM0;
- break;
- case CAN_INT_F0FULL:
- status = can->RXF0_B.FFULLFLG0;
- break;
- case CAN_INT_F0OVR:
- status = can->RXF0_B.FOVRFLG0;
- break;
- case CAN_INT_F1MP:
- status = can->RXF1_B.FMNUM1;
- break;
- case CAN_INT_F1FULL:
- status = can->RXF1_B.FFULLFLG1;
- break;
- case CAN_INT_F1OVR:
- status = can->RXF1_B.FOVRFLG1;
- break;
- case CAN_INT_WUP:
- status = can->MSTS_B.WUPIFLG;
- break;
- case CAN_INT_SLEEP:
- status = can->MSTS_B.SLEEPIFLG;
- break;
- case CAN_INT_ERRW:
- status = can->ERRSTS_B.ERRWFLG;
- break;
- case CAN_INT_ERRP:
- status = can->ERRSTS_B.ERRPFLG;
- break;
- case CAN_INT_BOF:
- status = can->ERRSTS_B.BOFLG;
- break;
- case CAN_INT_LEC:
- status = can->ERRSTS_B.LERRC;
- break;
- case CAN_INT_ERR:
- status = can->MSTS_B.ERRIFLG;
- break;
- default:
- status = RESET;
- break;
- }
- }
- else
- {
- status = RESET;
- }
- return status;
- }
- /*!
- * @brief Clears the can's interrupt flag.
- *
- * @param can: Select the CAN peripheral.
- *
- * @param flag: Interrupt pending bit to clear
- * This parameter can be one of the following values:
- * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt
- * @arg CAN_INT_F0FULL : FIFO 0 full Interrupt
- * @arg CAN_INT_F0OVR : FIFO 0 overrun Interrupt
- * @arg CAN_INT_F1FULL : FIFO 1 full Interrupt
- * @arg CAN_INT_F1OVR : FIFO 1 overrun Interrupt
- * @arg CAN_INT_ERRW : Error warning Interrupt
- * @arg CAN_INT_ERRP : Error passive Interrupt
- * @arg CAN_INT_BOF : Bus-off Interrupt
- * @arg CAN_INT_LEC : Last error record code Interrupt
- * @arg CAN_INT_ERR : Error Interrupt
- * @arg CAN_INT_WUP : Wake-up Interrupt
- * @arg CAN_INT_SLEEP : Sleep acknowledge Interrupt
- *
- * @retval None
- *
- * @note CAN2 applies only to APM32F103xC device.
- */
- void CAN_ClearIntFlag(CAN_T* can, CAN_INT_T flag)
- {
- switch (flag)
- {
- case CAN_INT_TXME:
- can->TXSTS_B.REQCFLG0 = BIT_SET;
- can->TXSTS_B.REQCFLG1 = BIT_SET;
- can->TXSTS_B.REQCFLG2 = BIT_SET;
- break;
- case CAN_INT_F0FULL:
- can->RXF0_B.FFULLFLG0 = BIT_SET;
- break;
- case CAN_INT_F0OVR:
- can->RXF0_B.FOVRFLG0 = BIT_SET;
- break;
- case CAN_INT_F1FULL:
- can->RXF1_B.FFULLFLG1 = BIT_SET;
- break;
- case CAN_INT_F1OVR:
- can->RXF1_B.FOVRFLG1 = BIT_SET;
- break;
- case CAN_INT_WUP:
- can->MSTS_B.WUPIFLG = BIT_SET;
- break;
- case CAN_INT_SLEEP:
- can->MSTS_B.SLEEPIFLG = BIT_SET;
- break;
- case CAN_INT_ERRW:
- can->MSTS_B.ERRIFLG = BIT_SET;
- break;
- case CAN_INT_ERRP:
- can->MSTS_B.ERRIFLG = BIT_SET;
- break;
- case CAN_INT_BOF:
- can->MSTS_B.ERRIFLG = BIT_SET;
- break;
- case CAN_INT_LEC:
- can->ERRSTS_B.LERRC = BIT_RESET;
- can->MSTS_B.ERRIFLG = BIT_SET;
- break;
- case CAN_INT_ERR:
- can->ERRSTS_B.LERRC = BIT_RESET;
- can->MSTS_B.ERRIFLG = BIT_SET;
- break;
- default:
- break;
- }
- }
- /**@} end of group CAN_Fuctions*/
- /**@} end of group CAN_Driver*/
- /**@} end of group Peripherals_Library*/
|