feat: KT mBMS 펌웨어 3종(HW1/2/3) 및 통합 빌드 환경 초기 커밋 (V4.0.0.1)
This commit is contained in:
239
APP_R3323/App/Hardware/can.c
Normal file
239
APP_R3323/App/Hardware/can.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file can.c
|
||||
* @author AMG Energy Solution Team
|
||||
* @version V1.0.0
|
||||
* @date 07-Feb-2022
|
||||
* @brief This file provides all the codes of CAN communication functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2022 AMG</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup mBMS2
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "can.h"
|
||||
#include "string.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* CAN channel definition */
|
||||
/* CAN baudrate definition */
|
||||
#define CAN_BAUDRATE (250000ul)
|
||||
|
||||
/* CAN RX Port/Pin definition */
|
||||
#define CAN_RX_PORT (PortE)
|
||||
#define CAN_RX_PIN (Pin01)
|
||||
#define CAN_RX_FUNC (Func_Can1_Rx)
|
||||
|
||||
/* CAN TX Port/Pin definition */
|
||||
#define CAN_TX_PORT (PortE)
|
||||
#define CAN_TX_PIN (Pin00)
|
||||
#define CAN_TX_FUNC (Func_Can1_Tx)
|
||||
|
||||
#define TX_BUFFER_SIZE 10
|
||||
#define RX_BUFFER_SIZE 320
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
volatile uint16_t RxInPos, RxOutPos;
|
||||
volatile uint32_t RxOverflowCount;
|
||||
uint16_t TxInPos, TxOutPos;
|
||||
stc_can_rxframe_t RxBuf[RX_BUFFER_SIZE];
|
||||
stc_can_txframe_t TxBuf[TX_BUFFER_SIZE];
|
||||
} CAN_Info;
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
CAN_Info Can;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void CAN_RxIrqCallBack(void);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
// Initializes CAN Port
|
||||
void can_init(uint32_t CAN_Baud_Rate)
|
||||
{
|
||||
stc_can_init_config_t stcCanInitCfg;
|
||||
stc_can_filter_t stcFilter;
|
||||
stc_irq_regi_conf_t stcIrqRegiConf;
|
||||
stc_port_init_t stcPortInit;
|
||||
|
||||
MEM_ZERO_STRUCT(stcCanInitCfg);
|
||||
MEM_ZERO_STRUCT(stcFilter);
|
||||
MEM_ZERO_STRUCT(stcIrqRegiConf);
|
||||
MEM_ZERO_STRUCT(stcPortInit);
|
||||
MEM_ZERO_STRUCT(Can);
|
||||
|
||||
stcPortInit.enPinMode = Pin_Mode_Out;
|
||||
stcPortInit.enExInt = Disable;
|
||||
stcPortInit.enPullUp = Enable;
|
||||
|
||||
/* SPI Port/Pin initialization */
|
||||
PORT_Init(CAN_TX_PORT, CAN_TX_PIN, &stcPortInit);
|
||||
|
||||
stcPortInit.enPinMode = Pin_Mode_In;
|
||||
|
||||
PORT_Init(CAN_RX_PORT, CAN_RX_PIN, &stcPortInit);
|
||||
|
||||
// PORT_Init(PortB, Pin03, &stcPortInit);
|
||||
PORT_Init(PortB, Pin04, &stcPortInit);
|
||||
|
||||
//<<Enable can peripheral clock and buffer(ram)
|
||||
PWC_RamOpMdConfig(HighSpeedMd);
|
||||
PWC_RamPwrdownCmd(PWC_RAMPWRDOWN_CAN, Enable);
|
||||
PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_CAN, Enable);
|
||||
|
||||
//<<CAN GPIO config
|
||||
PORT_SetFunc(CAN_RX_PORT, CAN_RX_PIN, CAN_RX_FUNC, Disable);
|
||||
PORT_SetFunc(CAN_TX_PORT, CAN_TX_PIN, CAN_TX_FUNC, Disable);
|
||||
|
||||
//<<Can bit time config
|
||||
// stcCanInitCfg.stcCanBt.PRESC = 4u-1u;//???,??????????
|
||||
switch(CAN_Baud_Rate) {
|
||||
case 1000: // 1000K
|
||||
stcCanInitCfg.stcCanBt.PRESC = 2u-1u;
|
||||
break;
|
||||
case 500: // 500K
|
||||
stcCanInitCfg.stcCanBt.PRESC = 4u-1u;
|
||||
break;
|
||||
case 250: // 125K
|
||||
stcCanInitCfg.stcCanBt.PRESC = 8u-1u;
|
||||
break;
|
||||
case 125: // 100K
|
||||
stcCanInitCfg.stcCanBt.PRESC = 16u-1u;
|
||||
break;
|
||||
default:
|
||||
stcCanInitCfg.stcCanBt.PRESC = 2u-1u;
|
||||
break;
|
||||
}
|
||||
|
||||
// stcCanInitCfg.stcCanBt.PRESC = 1u-1u;
|
||||
stcCanInitCfg.stcCanBt.SEG_1 = 5u-2u;
|
||||
stcCanInitCfg.stcCanBt.SEG_2 = 3u-1u;
|
||||
stcCanInitCfg.stcCanBt.SJW = 3u-1u;
|
||||
|
||||
stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 10u;
|
||||
stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 16u-1u;
|
||||
|
||||
stcCanInitCfg.enCanRxBufAll = CanRxNormal;
|
||||
stcCanInitCfg.enCanRxBufMode = CanRxBufNotStored;
|
||||
stcCanInitCfg.enCanSAck = CanSelfAckDisable; //CanSelfAckEnable;
|
||||
stcCanInitCfg.enCanSTBMode = CanSTBFifoMode;
|
||||
|
||||
CAN_Init(&stcCanInitCfg);
|
||||
|
||||
//<<Can filter config
|
||||
stcFilter.enAcfFormat = CanAllFrames;
|
||||
stcFilter.enFilterSel = CanFilterSel1;
|
||||
stcFilter.u32CODE = 0x00000000u;
|
||||
stcFilter.u32MASK = 0x1FFFFFFFu;
|
||||
CAN_FilterConfig(&stcFilter, Enable);
|
||||
|
||||
//<<Can Irq Enable
|
||||
CAN_IrqCmd(CanRxIrqEn, Enable);
|
||||
CAN_IrqCmd(CanTxPrimaryIrqEn, Enable);
|
||||
|
||||
stcIrqRegiConf.enIRQn = Int005_IRQn;
|
||||
stcIrqRegiConf.enIntSrc = INT_CAN_INT;
|
||||
stcIrqRegiConf.pfnCallback = &CAN_RxIrqCallBack;
|
||||
enIrqRegistration(&stcIrqRegiConf);
|
||||
NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
|
||||
NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
|
||||
NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
|
||||
}
|
||||
|
||||
void CAN_RxIrqCallBack(void)
|
||||
{
|
||||
if (true == CAN_IrqFlgGet(CanRxIrqFlg)) {
|
||||
CAN_IrqFlgClr(CanRxIrqFlg);
|
||||
|
||||
stc_can_rxframe_t received;
|
||||
uint16_t next = (uint16_t)((Can.RxInPos + 1U) % RX_BUFFER_SIZE);
|
||||
/* Always drain the hardware receive slot, even when the software queue is full. */
|
||||
CAN_Receive(&received);
|
||||
if (next == Can.RxOutPos) {
|
||||
Can.RxOverflowCount++;
|
||||
} else {
|
||||
memcpy(&Can.RxBuf[Can.RxInPos], &received, sizeof(received));
|
||||
__DMB();
|
||||
Can.RxInPos = next;
|
||||
}
|
||||
|
||||
// CAN_IrqCmd(CanRxIrqEn, Disable);
|
||||
}
|
||||
if (true == CAN_IrqFlgGet(CanTxPrimaryIrqFlg)) {
|
||||
CAN_IrqFlgClr(CanTxPrimaryIrqFlg);
|
||||
// CAN_IrqCmd(CanRxIrqEn, Enable);
|
||||
}
|
||||
if (true == CAN_IrqFlgGet(CanBusErrorIrqFlg)) {
|
||||
CAN_IrqFlgClr(CanBusErrorIrqFlg);
|
||||
}
|
||||
if (true == CAN_IrqFlgGet(CanArbiLostIrqFlg)) {
|
||||
CAN_IrqFlgClr(CanArbiLostIrqFlg);
|
||||
}
|
||||
NVIC_ClearPendingIRQ(Int005_IRQn);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : uint8_t CAN_GetPacket(CanRxMsg *packet)
|
||||
* Description : Send 1 packet data to CAN Port transmit buffer
|
||||
* Parameters : none
|
||||
* Return : Transmission result (0: buffer empty, 1: buffer has data)
|
||||
*******************************************************************************/
|
||||
uint8_t CAN_GetPacket(stc_can_rxframe_t *packet)
|
||||
{
|
||||
if (Can.RxInPos != Can.RxOutPos) {
|
||||
memcpy(packet, &Can.RxBuf[Can.RxOutPos], sizeof(stc_can_rxframe_t));
|
||||
__DMB();
|
||||
Can.RxOutPos = (uint16_t)((Can.RxOutPos + 1U) % RX_BUFFER_SIZE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CAN_SendPacket(stc_can_txframe_t *packet)
|
||||
{
|
||||
uint32_t timeout = 50000;
|
||||
while ((M4_CAN->TCMD_f.TPE != 0) && (--timeout > 0)) {
|
||||
__NOP();
|
||||
}
|
||||
if (timeout == 0) {
|
||||
M4_CAN->TCMD |= CanPTBTxAbortCmd;
|
||||
}
|
||||
|
||||
CAN_SetFrame(packet);
|
||||
en_can_tx_buf_status_t txSts = CAN_TransmitCmd(CanPTBTxCmd);
|
||||
switch (txSts) {
|
||||
case CanTxBufEmpty: // = 0, ///< TTEN=0 or TTTBM=0: STB is empty
|
||||
// printf("CanTxBufEmpty \r\n");
|
||||
break; ///< TTEN=1 and TTTBM=1: PTB and STB are empty
|
||||
case CanTxBufnotHalfFull: // = 1, ///< TTEN=0 or TTTBM=0: STB is less than or equal to half full
|
||||
// printf("CanTxBufnotHalfFull \r\n");
|
||||
break; ///< TTEN=1 and TTTBM=1: PTB and STB are not empty and not full
|
||||
case CanTxBufHalfFull: // = 2, ///< TTEN=0 or TTTBM=0: STB is more than half full
|
||||
// printf("CanTxBufHalfFull \r\n");
|
||||
break; ///< TTEN=1 and TTTBM=1: None
|
||||
case CanTxBufFull: // = 3, ///< TTEN=0 or TTTBM=0: STB is full
|
||||
// printf("CanTxBufFull \r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// CAN_IrqCmd(CanRxIrqEn, Enable);
|
||||
}
|
||||
|
||||
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/
|
||||
Reference in New Issue
Block a user