PeripheralDriver_AutoChips_.../inc_src/can_hw.h

1163 lines
30 KiB
C

/* Copyright Statement:
*
* This software/firmware and related documentation ("AutoChips Software") are
* protected under relevant copyright laws. The information contained herein is
* confidential and proprietary to AutoChips Inc. and/or its licensors. Without
* the prior written permission of AutoChips inc. and/or its licensors, any
* reproduction, modification, use or disclosure of AutoChips Software, and
* information contained herein, in whole or in part, shall be strictly
* prohibited.
*
* AutoChips Inc. (C) 2021. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
* RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
* ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
* INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
* TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
* RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
* OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
* SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
* RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
* AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
* CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
*/
/*!
* @file can_hw.h
*
* @brief This file provides CAN hardware definition and declaration.
*
*/
/* PRQA S 4304 EOF */ /* Type conversion. */
#ifndef CAN_HW_H
#define CAN_HW_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* =========================================== Includes =========================================== */
#include "can_drv.h"
/* ============================================ Define ============================================ */
#define CAN_MAX_S_SEG_1 (0xFFUL) /*!< CAN max slow bitrate seg 1 */
#define CAN_MAX_S_SEG_2 (0x7FUL) /*!< CAN max slow bitrate seg 2 */
#define CAN_MAX_S_SJW (0x7FUL) /*!< CAN max slow bitrate sjw */
#define CAN_MAX_S_PRESC (0xFFUL) /*!< CAN max slow bitrate prescaler */
#define CAN_MAX_F_SEG_1 (0x1FUL) /*!< CAN max fast bitrate seg 1 */
#define CAN_MAX_F_SEG_2 (0xFUL) /*!< CAN max fast bitrate seg 2 */
#define CAN_MAX_F_SJW (0xFUL) /*!< CAN max fast bitrate sjw */
#define CAN_MAX_F_PRESC (0xFFUL) /*!< CAN max fast bitrate prescaler */
/* =========================================== Typedef ============================================ */
/* ========================================== Variables =========================================== */
/* ==================================== Functions declaration ===================================== */
/*!
* @brief Write TBUF.
*
* @param[in] base: CAN module
* @param[in] txBuf: pointer to transmission buffer
* @param[in] length: number of buffer bytes
* @return none
*/
void CAN_WriteTbuf(CAN_Type *base, const uint8_t *txBuf, uint8_t length);
/*!
* @brief Write TBUF message data.
*
* @param[in] base: CAN module
* @param[in] txData: pointer to transmission data
* @param[in] length: number of message data bytes
* @return none
*/
void CAN_WriteTbufData(CAN_Type *base, const uint8_t *txData, uint8_t length);
/*!
* @brief Read RBUF.
*
* @param[in] base: CAN module
* @param[out] rxBuf: pointer to receive buffer
* @param[in] length: number of buffer bytes
* @return none
*/
void CAN_ReadRbuf(CAN_Type *base, uint8_t *rxBuf, uint8_t length);
/*!
* @brief Read RBUF message data.
*
* @param[in] base: CAN module
* @param[out] rxData: pointer to receive data
* @param[in] length: number of message data bytes
* @return none
*/
void CAN_ReadRbufData(CAN_Type *base, uint8_t *rxData, uint8_t length);
/*!
* @brief Compute message payload size.
*
* @param[in] dlcValue: DLC value
* @return Payload size
*/
uint8_t CAN_ComputePayloadSize(uint8_t dlcValue);
/*!
* @brief Compute message DLC value.
*
* @param[in] payloadSize: payload size
* @return DLC value
*/
uint8_t CAN_ComputeDlcValue(uint8_t payloadSize);
/*!
* @brief Start transmit frame in the TBUF.
*
* @param[in] base: CAN module
* @param[in] type: CAN transmit buffer type
* - CAN_TRANSMIT_PRIMARY
* - CAN_TRANSMIT_SECONDARY
* @param[in] amount: transmit secondary all or one frames
* - CAN_TRANSMIT_SEC_ALL
* - CAN_TRANSMIT_SEC_ONE
* @return none
*/
void CAN_StartTransmit(CAN_Type *base, can_transmit_buff_t type, can_transmit_sec_amount_t amount);
/*!
* @brief Abort transmitting.
*
* @param[in] base: CAN module
* @param[in] type: CAN transmit buffer type
* - CAN_TRANSMIT_PRIMARY
* - CAN_TRANSMIT_SECONDARY
* @return none
*/
void CAN_AbortTransmit(CAN_Type *base, can_transmit_buff_t type);
/*!
* @brief Set acceptance filter state.
*
* @param[in] base: CAN module
* @param[in] index: filter index
* @param[in] enable: filter enable state
* @return none
*/
void CAN_SetFilterEnable(CAN_Type *base, uint8_t index, bool enable);
/* ===================================== Functions definition ===================================== */
/*!
* @brief Check transmit is busy.
*
* @param[in] base: CAN module
* @param[in] type: CAN transmit buffer type
* - CAN_TRANSMIT_PRIMARY
* - CAN_TRANSMIT_SECONDARY
* @return transmit busy flag
* - false: not busy or STB is not full
* - true: is busy or STB is full
*/
static inline bool CAN_IsTransmitBusy(CAN_Type *base, can_transmit_buff_t type)
{
if (CAN_TRANSMIT_PRIMARY == type)
{
return (((base->CTRL0 & CAN_CTRL0_TPE_Msk) >> CAN_CTRL0_TPE_Pos) != 0U);
}
else
{
return (bool)((uint32_t)CAN_TSSTAT_FULL == ((base->CTRL0 & CAN_CTRL0_TSSTAT_Msk) >> CAN_CTRL0_TSSTAT_Pos));
}
}
/*!
* @brief Check whether is transmitting.
*
* @param[in] base: CAN module
* @param[in] type: CAN transmit buffer type
* - CAN_TRANSMIT_PRIMARY
* - CAN_TRANSMIT_SECONDARY
* @return transmitting status
* - false: not transmitting
* - true: is transmitting
*/
static inline bool CAN_IsTransmitting(CAN_Type *base, can_transmit_buff_t type)
{
if (CAN_TRANSMIT_PRIMARY == type)
{
return (((base->CTRL0 & CAN_CTRL0_TPE_Msk) >> CAN_CTRL0_TPE_Pos) != 0U);
}
else
{
return ((base->CTRL0 & (CAN_CTRL0_TSALL_Msk | CAN_CTRL0_TSONE_Msk)) != 0U);
}
}
/*!
* @brief Check transmission complete flag.
*
* @param[in] base: CAN module
* @param[in] type: CAN transmit buffer type
* - CAN_TRANSMIT_PRIMARY
* - CAN_TRANSMIT_SECONDARY
* @return Transmit status
*/
static inline bool CAN_IsTransmitDone(CAN_Type *base, can_transmit_buff_t type)
{
if (CAN_TRANSMIT_PRIMARY == type)
{
return (((base->CTRL1 & CAN_CTRL1_TPIF_Msk) >> CAN_CTRL1_TPIF_Pos) != 0U);
}
else
{
return (((base->CTRL1 & CAN_CTRL1_TSIF_Msk) >> CAN_CTRL1_TSIF_Pos) != 0U);
}
}
/*!
* @brief Clear transmission complete flag.
*
* @param[in] base: CAN module
* @param[in] type: CAN transmit buffer type
* - CAN_TRANSMIT_PRIMARY
* - CAN_TRANSMIT_SECONDARY
* @return none
*/
static inline void CAN_ClearTransmitFlag(CAN_Type *base, can_transmit_buff_t type)
{
if (CAN_TRANSMIT_PRIMARY == type)
{
base->CTRL1 |= CAN_CTRL1_TPIF_Msk;
}
else
{
base->CTRL1 |= CAN_CTRL1_TSIF_Msk;
}
}
/*!
* @brief Get RBUF message ID.
*
* @param[in] base: CAN module
* @return Message id
*/
static inline uint32_t CAN_GetRbufId(CAN_Type *base)
{
return (base->RBUF.ID_ESI);
}
/*!
* @brief Set RBUF message control.
*
* @param[in] base: CAN module
* @return Message control
*/
static inline uint32_t CAN_GetRbufCtrl(CAN_Type *base)
{
return (base->RBUF.CTRL);
}
/*!
* @brief Set TBUF message ID.
*
* @param[in] base: CAN module
* @param[in] id: message id
* @return none
*/
static inline void CAN_SetTbufId(CAN_Type *base, uint32_t id)
{
base->TBUF.ID_ESI = id;
}
/*!
* @brief Set TBUF message control.
*
* @param[in] base: CAN module
* @param[in] ctrl: message control
* @return none
*/
static inline void CAN_SetTbufCtrl(CAN_Type *base, uint32_t ctrl)
{
base->TBUF.CTRL = ctrl;
}
/*!
* @brief Get transmission time stamp value.
*
* @param[in] base: CAN module
* @return Transmission time stamp value
*/
static inline uint32_t CAN_GetTransTimeStamp(CAN_Type *base)
{
return (base->TBUF.TS[0U]);
}
/*!
* @brief Check bus off status.
*
* @param[in] base: CAN module
* @return Bus off status
*/
static inline bool CAN_IsBusOff(CAN_Type *base)
{
return ((base->CTRL0 & CAN_CTRL0_BUSOFF_Msk) != 0U);
}
/*!
* @brief Forced exit from bus off status.
*
* @param[in] base: CAN module
* @return none
*/
static inline void CAN_ExitBusOff(CAN_Type *base)
{
base->CTRL0 &= ~CAN_CTRL0_BUSOFF_Msk;
}
/*!
* @brief Check transmit active status.
*
* @param[in] base: CAN module
* @return Tactive status
*/
static inline bool CAN_IsTransActive(CAN_Type *base)
{
return (((base->CTRL0 & CAN_CTRL0_TACTIVE_Msk) >> CAN_CTRL0_TACTIVE_Pos) != 0U);
}
/*!
* @brief Check receive active status.
*
* @param[in] base: CAN module
* @return Ractive status
*/
static inline bool CAN_IsRecvActive(CAN_Type *base)
{
return (((base->CTRL0 & CAN_CTRL0_RACTIVE_Msk) >> CAN_CTRL0_RACTIVE_Pos) != 0U);
}
/*!
* @brief Set transmission secondary single shot mode.
*
* @param[in] base: CAN module
* @param[in] enable: tpss mode
* @return none
*/
static inline void CAN_SetTsss(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_TSSS_Msk, CAN_CTRL0_TSSS_Pos, enable);
}
/*!
* @brief Set transmission primary single shot mode.
*
* @param[in] base: CAN module
* @param[in] enable: tpss mode
* @return none
*/
static inline void CAN_SetTpss(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_TPSS_Msk, CAN_CTRL0_TPSS_Pos, enable);
}
/*!
* @brief Set loopback internal mode.
*
* @param[in] base: CAN module
* @param[in] enable: LBMI mode
* @return none
*/
static inline void CAN_SetLoopbackIntMode(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_LBMI_Msk, CAN_CTRL0_LBMI_Pos, enable);
}
/*!
* @brief Set loopback external mode.
*
* @param[in] base: CAN module
* @param[in] enable: LBME mode
* @return none
*/
static inline void CAN_SetLoopbackExtMode(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_LBME_Msk, CAN_CTRL0_LBME_Pos, enable);
}
/*!
* @brief Set software reset state.
*
* @param[in] base: CAN module
* @param[in] enable: reset state
* @return none
*/
static inline void CAN_SetReset(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_RESET_Msk, CAN_CTRL0_RESET_Pos, enable);
}
/*!
* @brief Get software reset state.
*
* @param[in] base: CAN module
* @return Reset state
*/
static inline bool CAN_GetResetState(CAN_Type *base)
{
return (((base->CTRL0 & CAN_CTRL0_RESET_Msk) >> CAN_CTRL0_RESET_Pos) != 0U);
}
/*!
* @brief Set transceiver standby state.
*
* @param[in] base: CAN module
* @param[in] enable: standby enable state
* @return none
*/
static inline void CAN_SetStandby(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_STBY_Msk, CAN_CTRL0_STBY_Pos, enable);
}
/*!
* @brief Get transceiver standby state.
*
* @param[in] base: CAN module
* @return Standby state
*/
static inline bool CAN_GetStandbyState(CAN_Type *base)
{
return (((base->CTRL0 & CAN_CTRL0_STBY_Msk) >> CAN_CTRL0_STBY_Pos) != 0U);
}
/*!
* @brief Set listen only mode.
*
* @param[in] base: CAN module
* @param[in] enable: LOM mode
* @return none
*/
static inline void CAN_SetListenOnlyMode(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_LOM_Msk, CAN_CTRL0_LOM_Pos, enable);
}
/*!
* @brief Set transmit buffer select.
*
* @param[in] base: CAN module
* @param[in] type: CAN transmit buffer type
* - CAN_TRANSMIT_PRIMARY
* - CAN_TRANSMIT_SECONDARY
* @return none
*/
static inline void CAN_SetTbufSelect(CAN_Type *base, can_transmit_buff_t type)
{
base->CTRL0 = ((base->CTRL0 & (~(CAN_CTRL0_TSNEXT_Msk | CAN_CTRL0_TBSEL_Msk | CAN_CTRL0_TPE_Msk | CAN_CTRL0_TSALL_Msk | CAN_CTRL0_TSONE_Msk)))
| (((uint32_t)type << CAN_CTRL0_TBSEL_Pos) & CAN_CTRL0_TBSEL_Msk));
}
/*!
* @brief Get transmit secondary buffer status.
*
* @param[in] base: CAN module
* @return Transmit secondary buffer status
*/
static inline uint8_t CAN_GetTsbufStatus(CAN_Type *base)
{
return (uint8_t)((base->CTRL0 & CAN_CTRL0_TSSTAT_Msk) >> CAN_CTRL0_TSSTAT_Pos);
}
/*!
* @brief Check CAN bus idle status.
*
* @param[in] base: CAN module
* @return Bus idle status
*/
static inline bool CAN_IsIdle(CAN_Type *base)
{
return (((base->CTRL0 & CAN_CTRL0_IDLE_Msk) >> CAN_CTRL0_IDLE_Pos) != 0U);
}
/*!
* @brief Set automatic recovering from bus off disable state.
*
* @param[in] base: CAN module
* @param[in] enable: bus off recovery disable state
* @return none
*/
static inline void CAN_SetBusOffRecDisable(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_BOREC_Msk, CAN_CTRL0_BOREC_Pos, enable);
}
/*!
* @brief Set transmit secondary operation mode.
*
* @param[in] base: CAN module
* @param[in] mode: Transmit secondary operation mode
* - CAN_TSMODE_FIFO
* - CAN_TSMODE_PRIORITY
* @return none
*/
static inline void CAN_SetTransSecMode(CAN_Type *base, can_transmit_sec_mode_t mode)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_TSMODE_Msk, CAN_CTRL0_TSMODE_Pos, (uint32_t)mode);
}
/*!
* @brief Select next transmit secondary buffer.
*
* @param[in] base: CAN module
* @return none
*/
static inline void CAN_SelectNextTsbuf(CAN_Type *base)
{
base->CTRL0 = ((base->CTRL0 & (~(CAN_CTRL0_TPE_Msk | CAN_CTRL0_TSALL_Msk | CAN_CTRL0_TSONE_Msk))) | CAN_CTRL0_TSNEXT_Msk);
}
/*!
* @brief Set CANFD ISO mode.
*
* @param[in] base: CAN module
* @param[in] enable: CAN FD ISO mode
* @return none
*/
static inline void CAN_SetFdIso(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_FDISO_Msk, CAN_CTRL0_FDISO_Pos, enable);
}
/*!
* @brief Get receive buffer status.
*
* @param[in] base: CAN module
* @return Receive buffer status
*/
static inline uint8_t CAN_GetRbufStatus(CAN_Type *base)
{
return (uint8_t)((base->CTRL0 & CAN_CTRL0_RSTAT_Msk) >> CAN_CTRL0_RSTAT_Pos);
}
/*!
* @brief Set DMA receive enable.
*
* @param[in] base: CAN module
* @param[in] enable: DMA receive enable state
* @return none
*/
static inline void CAN_SetDmaRecv(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_DREN_Msk, CAN_CTRL0_DREN_Pos, enable);
}
/*!
* @brief Set receive buffer store all data frames.
*
* @param[in] base: CAN module
* @param[in] enable: receive buffer store all data frames state
* @return none
*/
static inline void CAN_SetRball(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_RBALL_Msk, CAN_CTRL0_RBALL_Pos, enable);
}
/*!
* @brief Release receive buffer.
*
* @param[in] base: CAN module
* @return none
*/
static inline void CAN_ReleaseRbuf(CAN_Type *base)
{
base->CTRL0 = ((base->CTRL0 & (~(CAN_CTRL0_TSNEXT_Msk | CAN_CTRL0_TPE_Msk | CAN_CTRL0_TSALL_Msk | CAN_CTRL0_TSONE_Msk))) | CAN_CTRL0_RREL_Msk);
}
/*!
* @brief Get receive buffer overflow flag.
*
* @param[in] base: CAN module
* @return Receive buffer overflow flag
*/
static inline uint8_t CAN_GetRbufOverflow(CAN_Type *base)
{
return (uint8_t)((base->CTRL0 & CAN_CTRL0_ROV_Msk) >> CAN_CTRL0_ROV_Pos);
}
/*!
* @brief Set receive buffer overflow mode.
*
* @param[in] base: CAN module
* @param[in] mode: receive buffer overflow mode
* - CAN_ROM_OVER_WRITE
* - CAN_ROM_DISCARD
* @return none
*/
static inline void CAN_SetRbufOverflowMode(CAN_Type *base, can_rbuf_overflow_mode_t mode)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_ROM_Msk, CAN_CTRL0_ROM_Pos, (uint32_t)mode);
}
/*!
* @brief Set self acknowledge when LBME = 1.
*
* @param[in] base: CAN module
* @param[in] enable: sack enable state
* @return none
*/
static inline void CAN_SetSelfAck(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->CTRL0, CAN_CTRL0_SACK_Msk, CAN_CTRL0_SACK_Pos, enable);
}
/*!
* @brief Set controller 1 register.
*
* @param[in] base: CAN module
* @param[in] value: CAN controller 1 register value
* @return none
*/
static inline void CAN_SetCtrl1(CAN_Type *base, uint32_t value)
{
base->CTRL1 = value;
}
/*!
* @brief Get CAN controller 1 register.
*
* @param[in] base: CAN module
* @return Controller 1 register value
*/
static inline uint32_t CAN_GetCtrl1(CAN_Type *base)
{
return base->CTRL1;
}
/*!
* @brief Get transmit secondary buffer full flag.
*
* @param[in] base: CAN module
* @return Transmit secondary buffer full flag
*/
static inline bool CAN_GetTsbufFullFlag(CAN_Type *base)
{
return (((base->CTRL1 & CAN_CTRL1_TSFF_Msk) >> CAN_CTRL1_TSFF_Pos) != 0U);
}
/*!
* @brief Set interrupt enable mask.
*
* @param[in] base: CAN module
* @param[in] intMask: interrupt enable mask
* @return none
*/
static inline void CAN_SetIntMask(CAN_Type *base, uint32_t intMask)
{
MODIFY_REG32(base->CTRL1, CAN_IRQ_ALL_ENABLE_MSK, 0, intMask);
}
/*!
* @brief Get error passive flag.
*
* @param[in] base: CAN module
* @return Error passive flag
*/
static inline bool CAN_GetErrorPassiveFlag(CAN_Type *base)
{
return (((base->CTRL1 & CAN_CTRL1_EPASS_Msk) >> CAN_CTRL1_EPASS_Pos) != 0U);
}
/*!
* @brief Get error warning limit flag.
*
* @param[in] base: CAN module
* @return Error warning limit flag
*/
static inline bool CAN_GetErrorWarningFlag(CAN_Type *base)
{
return (((base->CTRL1 & CAN_CTRL1_EWARN_Msk) >> CAN_CTRL1_EWARN_Pos) != 0U);
}
/*!
* @brief Set error warning limit.
*
* @param[in] base: CAN module
* @param[in] ewl: error warning limit (0-15)
* @return none
*/
static inline void CAN_SetErrorWarningLimit(CAN_Type *base, uint8_t ewl)
{
MODIFY_REG32(base->CTRL1, CAN_CTRL1_EWL_Msk, CAN_CTRL1_EWL_Pos, ewl);
}
/*!
* @brief Set Rbuf almost full warning limit.
*
* @param[in] base: CAN module
* @param[in] afwl: almost full warning limit (1 - 12)
* @return none
*/
static inline void CAN_SetAfwl(CAN_Type *base, uint8_t afwl)
{
MODIFY_REG32(base->CTRL1, CAN_CTRL1_AFWL_Msk, CAN_CTRL1_AFWL_Pos, afwl);
}
/*!
* @brief Set CAN normal slow bitrate.
*
* @param[in] base: CAN module
* @param[in] bitrate: pointer to bitrate configuration
* @return none
*/
static inline void CAN_SetSlowBitrate(CAN_Type *base, const can_time_segment_t *bitrate)
{
DEVICE_ASSERT(bitrate != NULL);
DEVICE_ASSERT(bitrate->SEG_2 <= CAN_MAX_S_SEG_2);
DEVICE_ASSERT(bitrate->SJW <= CAN_MAX_S_SJW);
/* PRQA S 0311 ++ */
base->SBITRATE = *(uint32_t *)bitrate;
/* PRQA S 0311 -- */
}
/*!
* @brief Get CAN normal slow bitrate.
*
* @param[in] base: CAN module
* @param[in] bitrate: pointer to bitrate configuration
* @return none
*/
static inline void CAN_GetSlowBitrate(CAN_Type *base, can_time_segment_t *bitrate)
{
DEVICE_ASSERT(bitrate != NULL);
bitrate->SEG_1 = (uint8_t)((base->SBITRATE & CAN_SBITRATE_S_SEG_1_Msk) >> CAN_SBITRATE_S_SEG_1_Pos);
bitrate->SEG_2 = (uint8_t)((base->SBITRATE & CAN_SBITRATE_S_SEG_2_Msk) >> CAN_SBITRATE_S_SEG_2_Pos);
bitrate->SJW = (uint8_t)((base->SBITRATE & CAN_SBITRATE_S_SJW_Msk) >> CAN_SBITRATE_S_SJW_Pos);
bitrate->PRESC = (uint8_t)((base->SBITRATE & CAN_SBITRATE_S_PRESC_Msk) >> CAN_SBITRATE_S_PRESC_Pos);
}
/*!
* @brief Set CAN FD data bitrate.
*
* @param[in] base: CAN module
* @param[in] bitrate: pointer to bitrate configuration
* @return none
*/
static inline void CAN_SetFastBitrate(CAN_Type *base, const can_time_segment_t *bitrate)
{
DEVICE_ASSERT(bitrate != NULL);
DEVICE_ASSERT(bitrate->SEG_1 <= CAN_MAX_F_SEG_1);
DEVICE_ASSERT(bitrate->SEG_2 <= CAN_MAX_F_SEG_2);
DEVICE_ASSERT(bitrate->SJW <= CAN_MAX_F_SJW);
/* PRQA S 0311 ++ */
base->FBITRATE = *(uint32_t *)bitrate;
/* PRQA S 0311 -- */
}
/*!
* @brief Get CAN FD data bitrate.
*
* @param[in] base: CAN module
* @param[in] bitrate: pointer to bitrate configuration
* @return none
*/
static inline void CAN_GetFastBitrate(CAN_Type *base, can_time_segment_t *bitrate)
{
DEVICE_ASSERT(bitrate != NULL);
bitrate->SEG_1 = (uint8_t)((base->FBITRATE & CAN_FBITRATE_F_SEG_1_Msk) >> CAN_FBITRATE_F_SEG_1_Pos);
bitrate->SEG_2 = (uint8_t)((base->FBITRATE & CAN_FBITRATE_F_SEG_2_Msk) >> CAN_FBITRATE_F_SEG_2_Pos);
bitrate->SJW = (uint8_t)((base->FBITRATE & CAN_FBITRATE_F_SJW_Msk) >> CAN_FBITRATE_F_SJW_Pos);
bitrate->PRESC = (uint8_t)((base->FBITRATE & CAN_FBITRATE_F_PRESC_Msk) >> CAN_FBITRATE_F_PRESC_Pos);
}
/*!
* @brief Get arbitration lost capture.
*
* @param[in] base: CAN module
* @return Arbitration lost capture position
*/
static inline uint8_t CAN_GetArbitLostCap(CAN_Type *base)
{
return (uint8_t)((base->ERRINFO & CAN_ERRINFO_ALC_Msk) >> CAN_ERRINFO_ALC_Pos);
}
/*!
* @brief Get kind of bus error.
*
* @param[in] base: CAN module
* @return Kind of bus error
*/
static inline uint8_t CAN_GetKoer(CAN_Type *base)
{
return (uint8_t)((base->ERRINFO & CAN_ERRINFO_KOER_Msk) >> CAN_ERRINFO_KOER_Pos);
}
/*!
* @brief Set SSP offset.
*
* @param[in] base: CAN module
* @param[in] offset: SSP offset (1-0x7f)
* @return none
*/
static inline void CAN_SetSspOffset(CAN_Type *base, uint8_t offset)
{
MODIFY_REG32(base->ERRINFO, CAN_ERRINFO_SSPOFF_Msk, CAN_ERRINFO_SSPOFF_Pos, offset);
}
/*!
* @brief Set TDC enable.
*
* @param[in] base: CAN module
* @param[in] enable: TDC enable state
* @return none
*/
static inline void CAN_SetTdc(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->ERRINFO, CAN_ERRINFO_TDCEN_Msk, CAN_ERRINFO_TDCEN_Pos, enable);
}
/*!
* @brief Get receive error count.
*
* @param[in] base: CAN module
* @return Receive error count
*/
static inline uint8_t CAN_GetReCount(CAN_Type *base)
{
return (uint8_t)((base->ERRINFO & CAN_ERRINFO_RECNT_Msk) >> CAN_ERRINFO_RECNT_Pos);
}
/*!
* @brief Get transmit error count.
*
* @param[in] base: CAN module
* @return Transmit error count
*/
static inline uint8_t CAN_GetTeCount(CAN_Type *base)
{
return (uint8_t)((base->ERRINFO & CAN_ERRINFO_TECNT_Msk) >> CAN_ERRINFO_TECNT_Pos);
}
/*!
* @brief Set time stamp enable.
*
* @param[in] base: CAN module
* @param[in] enable: time stamp enable state
* @return none
*/
static inline void CAN_SetTimeStamp(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->ACFCTRL0, CAN_ACFCTRL0_TIMEEN_Msk, CAN_ACFCTRL0_TIMEEN_Pos, enable);
}
/*!
* @brief Set time stamp position.
*
* @param[in] base: CAN module
* @param[in] pos: time stamp position
* - CAN_TIME_STAMP_SOF
* - CAN_TIME_STAMP_EOF
* @return none
*/
static inline void CAN_SetTimeStampPos(CAN_Type *base, can_time_stamp_pos_t pos)
{
MODIFY_REG32(base->ACFCTRL0, CAN_ACFCTRL0_TIMEPOS_Msk, CAN_ACFCTRL0_TIMEPOS_Pos, (uint32_t)pos);
}
/*!
* @brief Set time stamp counter enable.
*
* @param[in] base: CAN module
* @param[in] enable: time stamp counter enable state
* @return none
*/
static inline void CAN_SetTimeStampCount(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->ACFCTRL0, CAN_ACFCTRL0_TCEN_Msk, CAN_ACFCTRL0_TCEN_Pos, enable);
}
/*!
* @brief Set time stamp clock source.
*
* @param[in] base: CAN module
* @param[in] src: time stamp clock source
* - CAN_TIME_STAMP_CLK_SRC_EXT
* - CAN_TIME_STAMP_CLK_SRC_BIT
* @return none
*/
static inline void CAN_SetTimeStampClkSrc(CAN_Type *base, can_time_stamp_clk_src_t src)
{
MODIFY_REG32(base->ACFCTRL0, CAN_ACFCTRL0_TCSS_Msk, CAN_ACFCTRL0_TCSS_Pos, (uint32_t)src);
}
/*!
* @brief Set acceptance filter index.
*
* @param[in] base: CAN module
* @param[in] index: filter index
* @return none
*/
static inline void CAN_SetAcfIndex(CAN_Type *base, uint8_t index)
{
DEVICE_ASSERT(index < CAN_FILTER_NUM_MAX);
MODIFY_REG32(base->ACFCTRL0, CAN_ACFCTRL0_ACFADR_Msk, CAN_ACFCTRL0_ACFADR_Pos, index);
}
/*!
* @brief Set filter data code.
*
* @param[in] base: CAN module
* @param[in] code: filter data code
* @return none
*/
static inline void CAN_SetAcfCode(CAN_Type *base, uint32_t code)
{
base->ACFCTRL0 &= (~CAN_ACFCTRL0_SELMASK_Msk);
base->ACF = (code & CAN_ACF_ACODE_Msk);
}
/*!
* @brief Set filter data mask + AIDE + AIDEE.
*
* @param[in] base: CAN module
* @param[in] mask: filter data mask + AIDE + AIDEE
* @return none
*/
static inline void CAN_SetAcfMask(CAN_Type *base, uint32_t mask)
{
base->ACFCTRL0 |= CAN_ACFCTRL0_SELMASK_Msk;
base->ACF = mask & (CAN_ACF_ACODE_Msk | CAN_ACF_AIDE_Msk | CAN_ACF_AIDEE_Msk);
}
/*!
* @brief Set VERMEM register.
*
* @param[in] base: CAN module
* @param[in] value: VERMEM register value
* @return none
*/
static inline void CAN_SetVerMem(CAN_Type *base, uint32_t value)
{
base->VERMEM = value;
}
/*!
* @brief Get VERMEM register.
*
* @param[in] base: CAN module
* @return VERMEM register value
*/
static inline uint32_t CAN_GetVerMem(CAN_Type *base)
{
return base->VERMEM;
}
/*!
* @brief Get CAN version.
*
* @param[in] base: CAN module
* @return CAN version
*/
static inline uint32_t CAN_GetVersion(CAN_Type *base)
{
return (base->VERMEM & CAN_VERMEM_VERSION_Msk);
}
/*!
* @brief Set memory ECC protect enable.
*
* @param[in] base: CAN module
* @param[in] enable: ECC protect enable state
* @return none
*/
static inline void CAN_SetMemEcc(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->VERMEM, CAN_VERMEM_MEEN_Msk, CAN_VERMEM_MEEN_Pos, enable);
}
/*!
* @brief Get memory ECC protect enable state.
*
* @param[in] base: CAN module
* @return ECC protect enable state
*/
static inline bool CAN_GetEccState(CAN_Type *base)
{
return (((base->VERMEM & CAN_VERMEM_MEEN_Msk) >> CAN_VERMEM_MEEN_Pos) != 0U);
}
/*!
* @brief Set memory ECC interrupt enable mask.
*
* @param[in] base: CAN module
* @param[in] IntMask: ECC interrupt enable mask
* @return none
*/
static inline void CAN_SetEccIntMask(CAN_Type *base, uint32_t IntMask)
{
MODIFY_REG32(base->VERMEM, (CAN_VERMEM_MDWIE_Msk | CAN_VERMEM_MDEIE_Msk), 0, IntMask);
}
/*!
* @brief Check memory ECC is initialized done.
*
* @param[in] base: CAN module
* @return CAN memory initialization status
*/
static inline bool CAN_IsMemInitDone(CAN_Type *base)
{
return (((base->VERMEM & CAN_VERMEM_MEID_Msk) >> CAN_VERMEM_MEID_Pos) != 0U);
}
/*!
* @brief Get memory ECC error status.
*
* @param[in] base: CAN module
* @return ECC error status
*/
static inline uint8_t CAN_GetEccStatus(CAN_Type *base)
{
return (uint8_t)((base->VERMEM & (CAN_VERMEM_ACFA_Msk | CAN_VERMEM_TXS_Msk | \
CAN_VERMEM_HELOC_Msk)) >> CAN_VERMEM_ACFA_Pos);
}
/*!
* @brief Set memory error bit position 1.
*
* @param[in] base: CAN module
* @param[in] position: memory error bit postion 1
* @return none
*/
static inline void CAN_SetMebp1(CAN_Type *base, uint8_t position)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_MEBP1_Msk, CAN_MEMES_MEBP1_Pos, position);
}
/*!
* @brief Set memory 1st error enable.
*
* @param[in] base: CAN module
* @param[in] enable: memory 1st error enable state
* @return none
*/
static inline void CAN_SetMe1ee(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_ME1EE_Msk, CAN_MEMES_ME1EE_Pos, enable);
}
/*!
* @brief Set memory error bit position 2.
*
* @param[in] base: CAN module
* @param[in] position: memory error bit postion 2
* @return none
*/
static inline void CAN_SetMebp2(CAN_Type *base, uint8_t position)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_MEBP2_Msk, CAN_MEMES_MEBP2_Pos, position);
}
/*!
* @brief Set memory 2nd error enable.
*
* @param[in] base: CAN module
* @param[in] enable: memory 2nd error enable state
* @return none
*/
static inline void CAN_SetMe2ee(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_ME2EE_Msk, CAN_MEMES_ME2EE_Pos, enable);
}
/*!
* @brief Set memory error counter.
*
* @param[in] base: CAN module
* @param[in] count: memory error counter
* @return none
*/
static inline void CAN_SetMeeec(CAN_Type *base, uint8_t count)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_MEEEC_Msk, CAN_MEMES_MEEEC_Pos, count);
}
/*!
* @brief Set memory no error counter.
*
* @param[in] base: CAN module
* @param[in] count: memory no error counter
* @return none
*/
static inline void CAN_SetMenec(CAN_Type *base, uint8_t count)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_MENEC_Msk, CAN_MEMES_MENEC_Pos, count);
}
/*!
* @brief Set memory error location.
*
* @param[in] base: CAN module
* @param[in] location: memory error location
* @return none
*/
static inline void CAN_SetMel(CAN_Type *base, uint8_t location)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_MEL_Msk, CAN_MEMES_MEL_Pos, location);
}
/*!
* @brief Set memory error side.
*
* @param[in] base: CAN module
* @param[in] side: memory error side
* @return none
*/
static inline void CAN_SetMes(CAN_Type *base, uint8_t side)
{
MODIFY_REG32(base->MEMES, CAN_MEMES_MES_Msk, CAN_MEMES_MES_Pos, side);
}
/*!
* @brief Set low pass filter enable for low power mode.
*
* @param[in] base: CAN module
* @param[in] enable: low pass filter enable state
* @return none
*/
static inline void CAN_SetLowPassFilter(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->WAKEUP, CAN_WAKEUP_LPFEN_Msk, CAN_WAKEUP_LPFEN_Pos, enable);
}
/*!
* @brief Set wakeup enable for low power mode.
*
* @param[in] base: CAN module
* @param[in] enable: wakeup enable state
* @return none
*/
static inline void CAN_SetWakeup(CAN_Type *base, bool enable)
{
MODIFY_REG32(base->WAKEUP, CAN_WAKEUP_WUEN_Msk, CAN_WAKEUP_WUEN_Pos, enable);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CAN_HW_H */
/* ============================================= EOF ============================================== */