feat: KT mBMS 펌웨어 3종(HW1/2/3) 및 통합 빌드 환경 초기 커밋 (V4.0.0.1)

This commit is contained in:
2026-11-05 14:31:31 +09:00
commit c52dc2f348
10803 changed files with 4642514 additions and 0 deletions

View File

@@ -0,0 +1,496 @@
/**
******************************************************************************
* @file adc.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the codes of adc control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include <includes.h>
#include "adc.h"
#include "delay.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/*
* If you remap the mapping between the channel and the pin with the function
* ADC_ChannelRemap, define ADC_CH_REMAP as non-zero, otherwise define as 0.
*/
#define ADC_CH_REMAP (0u)
/* ADC clock selection definition. */
#define ADC_CLK_PCLK (1u)
#define ADC_CLK_MPLLQ (2u)
#define ADC_CLK_UPLLR (3u)
/* ADC1 channel definition for this example. */
#define ADC1_SA_NORMAL_CHANNEL (ADC1_CH0 | ADC1_CH1 | ADC1_CH2 | ADC1_CH3 | ADC1_CH4 | ADC1_CH5 | ADC1_CH6 | ADC1_CH7)
#define ADC1_SA_CHANNEL (ADC1_SA_NORMAL_CHANNEL)
#define ADC1_SA_CHANNEL_COUNT (8u)
#define ADC1_CHANNEL (ADC1_SA_CHANNEL)
/* ADC1 channel sampling time. ADC1_CH0 ADC1_CH1 ADC1_CH2 ADC1_CH3 ADC1_CH4 ADC1_CH5 ADC1_CH6 ADC1_CH7 */
#define ADC1_SA_CHANNEL_SAMPLE_TIME { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }
/* ADC2 channel definition for this example. */
#define ADC2_SA_NORMAL_CHANNEL (ADC2_CH6 | ADC2_CH7)
#define ADC2_SA_CHANNEL (ADC2_SA_NORMAL_CHANNEL)
#define ADC2_SA_CHANNEL_COUNT (2u)
/* ADC2 channel sampling time. ADC2_CH6(AD_10), ADC2_CH7(AD_11) */
#define ADC2_SA_CHANNEL_SAMPLE_TIME { 0x30, 0x30 }
#define ADC2_CHANNEL (ADC2_SA_CHANNEL)
/* DMA definition for ADC1. */
#define ADC1_SA_DMA_UNIT (M4_DMA1)
#define ADC1_SA_DMA_CH (DmaCh0)
#define ADC1_SA_DMA_PWC (PWC_FCG0_PERIPH_DMA1)
#define ADC1_SA_DMA_TRGSRC (EVT_ADC1_EOCA)
#define ADC1_SA_DMA_IRQ_NUM (INT_DMA1_TC0)
#define ADC1_SA_DMA_INT_CB (Dma1Btc0_IrqHandler)
#define ADC1_DMA_IRQ_NVIC_NUM (Int030_IRQn)
/* DMA definition for ADC2. */
#define ADC2_SA_DMA_UNIT (M4_DMA1)
#define ADC2_SA_DMA_CH (DmaCh2)
#define ADC2_SA_DMA_PWC (PWC_FCG0_PERIPH_DMA1)
#define ADC2_SA_DMA_TRGSRC (EVT_ADC2_EOCA)
#define ADC2_SA_DMA_IRQ_NUM (INT_DMA1_TC2)
#define ADC2_SA_DMA_INT_CB (Dma1Btc2_IrqHandler)
#define ADC2_DMA_IRQ_NVIC_NUM (Int031_IRQn)
#define ADC1_SA_DMA_BUFFER_MAX (1024 / ADC1_SA_CHANNEL_COUNT)
#define ADC2_SA_DMA_BUFFER_MAX (1024 / ADC2_SA_CHANNEL_COUNT)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
// DMA Buffer
uint16_t Adc1DmaSaBuff[ADC1_SA_DMA_BUFFER_MAX][ADC1_SA_CHANNEL_COUNT];
uint16_t Adc2DmaSaBuff[ADC2_SA_DMA_BUFFER_MAX][ADC2_SA_CHANNEL_COUNT];
uint8_t m_u8Adc1DmaIrqFlag = 0u;
uint8_t m_u8Adc2DmaIrqFlag = 0u;
/* Private function prototypes -----------------------------------------------*/
void AdcConfig(void);
void AdcInitConfig(void);
void AdcChannelConfig(void);
void AdcTriggerConfig(void);
void DmaConfig(void);
void DmaIrqConfig(void);
void DmaIrqRegister(stc_irq_regi_conf_t *pstcCfg, uint32_t u32Priority);
void AdcSetChannelPinMode(const M4_ADC_TypeDef *ADCx,
uint32_t u32Channel,
en_pin_mode_t enMode);
/* Private functions ---------------------------------------------------------*/
/**
*******************************************************************************
** \brief ADC configuration, including clock configuration, initial configuration,
** channel configuration and trigger source configuration.
**
** \param None.
**
** \retval None.
**
******************************************************************************/
void AdcConfig(void)
{
// stc_port_init_t stcPortInit;
// /* configuration structure initialization */
// MEM_ZERO_STRUCT(stcPortInit);
// stcPortInit.enPinMode = Pin_Mode_Out;
// stcPortInit.enExInt = Disable;
// stcPortInit.enPullUp = Disable;
// /* Test Port/Pin initialization */
// PORT_Init(PortE, Pin00, &stcPortInit);
AdcInitConfig();
AdcChannelConfig();
AdcTriggerConfig();
memset(Adc1DmaSaBuff, 0xAA, sizeof(Adc1DmaSaBuff));
memset(Adc2DmaSaBuff, 0xBB, sizeof(Adc2DmaSaBuff));
}
/**
*******************************************************************************
** \brief ADC initial configuration.
**
******************************************************************************/
void AdcInitConfig(void)
{
stc_adc_init_t stcAdcInit;
MEM_ZERO_STRUCT(stcAdcInit);
stcAdcInit.enResolution = AdcResolution_12Bit;
stcAdcInit.enDataAlign = AdcDataAlign_Right;
stcAdcInit.enAutoClear = AdcClren_Enable;
stcAdcInit.enScanMode = AdcMode_SAContinuous;
stcAdcInit.enRschsel = AdcRschsel_Restart;
/* 1. Enable ADC1. */
PWC_Fcg3PeriphClockCmd(PWC_FCG3_PERIPH_ADC1, Enable);
/* 2. Initialize ADC1. */
ADC_Init(M4_ADC1, &stcAdcInit);
/* 1. Enable ADC2. */
PWC_Fcg3PeriphClockCmd(PWC_FCG3_PERIPH_ADC2, Enable);
/* 2. Initialize ADC2. */
ADC_Init(M4_ADC2, &stcAdcInit);
}
/**
*******************************************************************************
** \brief ADC channel configuration.
**
******************************************************************************/
void AdcChannelConfig(void)
{
uint8_t au8Adc1SaSampTime[ADC1_SA_CHANNEL_COUNT] = ADC1_SA_CHANNEL_SAMPLE_TIME;
uint8_t au8Adc2SaSampTime[ADC2_SA_CHANNEL_COUNT] = ADC2_SA_CHANNEL_SAMPLE_TIME;
stc_adc_ch_cfg_t stcChCfg;
MEM_ZERO_STRUCT(stcChCfg);
/**************************** Add ADC1 channels ****************************/
/* 1. Set the ADC pin to analog mode. */
AdcSetChannelPinMode(M4_ADC1, ADC1_CHANNEL, Pin_Mode_Ana);
stcChCfg.u32Channel = ADC1_SA_CHANNEL;
stcChCfg.u8Sequence = ADC_SEQ_A;
stcChCfg.pu8SampTime = au8Adc1SaSampTime;
/* 2. Add ADC channel. */
ADC_AddAdcChannel(M4_ADC1, &stcChCfg);
/**************************** Add ADC2 channels ****************************/
/* 1. Set the ADC pin to analog mode. */
AdcSetChannelPinMode(M4_ADC2, ADC2_CHANNEL, Pin_Mode_Ana);
stcChCfg.u32Channel = ADC2_SA_CHANNEL;
stcChCfg.u8Sequence = ADC_SEQ_A;
stcChCfg.pu8SampTime = au8Adc2SaSampTime;
/* 2. Add ADC channel. */
ADC_AddAdcChannel(M4_ADC2, &stcChCfg);
}
/**
*******************************************************************************
** \brief ADC trigger source configuration.
**
******************************************************************************/
void AdcTriggerConfig(void)
{
stc_adc_trg_cfg_t stcTrgCfg;
MEM_ZERO_STRUCT(stcTrgCfg);
/*
* If select an event(@ref en_event_src_t) to trigger ADC,
* AOS must be enabled first.
*/
PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);
/* Trigger ADC1 sequence A. */
stcTrgCfg.u8Sequence = ADC_SEQ_A;
stcTrgCfg.enTrgSel = AdcTrgsel_TRGX0;
stcTrgCfg.enInTrg0 = EVT_ADC1_EOCA;
ADC_ConfigTriggerSrc(M4_ADC1, &stcTrgCfg);
// ADC_TriggerSrcCmd(M4_ADC1, ADC_SEQ_A, Enable);
/* ADC1 sequence A will be started by software. */
ADC_TriggerSrcCmd(M4_ADC1, ADC_SEQ_A, Disable);
/* Trigger ADC2 sequence A. */
stcTrgCfg.u8Sequence = ADC_SEQ_A;
stcTrgCfg.enTrgSel = AdcTrgsel_TRGX0;
stcTrgCfg.enInTrg0 = EVT_ADC2_EOCA;
ADC_ConfigTriggerSrc(M4_ADC2, &stcTrgCfg);
/* ADC2 sequence A will be started by software. */
ADC_TriggerSrcCmd(M4_ADC2, ADC_SEQ_A, Disable);
}
/**
*******************************************************************************
** \brief DMA configuration for ADC1 and ADC2, including initial configuration
** and interrupt configuration.
**
******************************************************************************/
void DmaConfig(void)
{
DmaInitConfig();
DmaIrqConfig();
}
/**
*******************************************************************************
** \brief DMA initial configuration.
**
******************************************************************************/
void DmaInitConfig(void)
{
stc_dma_config_t stcDmaCfg;
MEM_ZERO_STRUCT(stcDmaCfg);
stcDmaCfg.u16BlockSize = ADC1_SA_CHANNEL_COUNT;
stcDmaCfg.u16TransferCnt = ADC1_SA_DMA_BUFFER_MAX * ADC1_SA_CHANNEL_COUNT;
stcDmaCfg.u32SrcAddr = (uint32_t)(&M4_ADC1->DR0);
stcDmaCfg.u32DesAddr = (uint32_t)(&Adc1DmaSaBuff[0][0]);
stcDmaCfg.u16DesRptSize = ADC1_SA_DMA_BUFFER_MAX * ADC1_SA_CHANNEL_COUNT;
stcDmaCfg.u16SrcRptSize = ADC1_SA_CHANNEL_COUNT;
stcDmaCfg.u32DmaLlp = 0u;
stcDmaCfg.stcSrcNseqCfg.u16Cnt = 0u;
stcDmaCfg.stcSrcNseqCfg.u32Offset = 0u;
stcDmaCfg.stcDesNseqCfg.u16Cnt = 0u;
stcDmaCfg.stcDesNseqCfg.u32Offset = 0u;
stcDmaCfg.stcDmaChCfg.enSrcInc = AddressIncrease;
stcDmaCfg.stcDmaChCfg.enDesInc = AddressIncrease;
stcDmaCfg.stcDmaChCfg.enSrcRptEn = Enable;
stcDmaCfg.stcDmaChCfg.enDesRptEn = Enable;
stcDmaCfg.stcDmaChCfg.enSrcNseqEn = Disable;
stcDmaCfg.stcDmaChCfg.enDesNseqEn = Disable;
stcDmaCfg.stcDmaChCfg.enTrnWidth = Dma16Bit;
stcDmaCfg.stcDmaChCfg.enLlpEn = Disable;
/* Enable DMA interrupt. */
stcDmaCfg.stcDmaChCfg.enIntEn = Enable;
PWC_Fcg0PeriphClockCmd(ADC1_SA_DMA_PWC, Enable);
DMA_InitChannel(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, &stcDmaCfg);
DMA_Cmd(ADC1_SA_DMA_UNIT, Enable);
DMA_ChannelCmd(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, Enable);
DMA_ClearIrqFlag(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, TrnCpltIrq);
/* AOS must be enabled to use DMA */
/* AOS enabled at first. */
/* If you have enabled AOS before, then the following statement is not needed. */
PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);
DMA_SetTriggerSrc(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, ADC1_SA_DMA_TRGSRC);
// DMA ADC2 SA
stcDmaCfg.u16BlockSize = ADC2_SA_CHANNEL_COUNT;
stcDmaCfg.u16TransferCnt = ADC2_SA_DMA_BUFFER_MAX * ADC2_SA_CHANNEL_COUNT; //
stcDmaCfg.u32SrcAddr = (uint32_t)(&M4_ADC2->DR6);
stcDmaCfg.u32DesAddr = (uint32_t)(&Adc2DmaSaBuff[0][0]);
stcDmaCfg.u16DesRptSize = ADC2_SA_DMA_BUFFER_MAX * ADC2_SA_CHANNEL_COUNT;
stcDmaCfg.u16SrcRptSize = ADC2_SA_CHANNEL_COUNT;
PWC_Fcg0PeriphClockCmd(ADC2_SA_DMA_PWC, Enable);
DMA_InitChannel(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, &stcDmaCfg);
DMA_Cmd(ADC2_SA_DMA_UNIT, Enable);
DMA_ChannelCmd(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, Enable);
DMA_ClearIrqFlag(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, TrnCpltIrq);
DMA_SetTriggerSrc(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, ADC2_SA_DMA_TRGSRC);
}
/**
*******************************************************************************
** \brief DMA initial configuration.
**
******************************************************************************/
void DmaReloadConfig(uint8_t nAdc)
{
if (nAdc == 0) {
DMA_SetBlockSize(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, ADC1_SA_CHANNEL_COUNT);
DMA_SetTransferCnt(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, ADC1_SA_DMA_BUFFER_MAX * ADC1_SA_CHANNEL_COUNT);
DMA_Cmd(ADC1_SA_DMA_UNIT, Enable);
DMA_ChannelCmd(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, Enable);
} else {
DMA_SetBlockSize(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, ADC2_SA_CHANNEL_COUNT);
DMA_SetTransferCnt(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, ADC2_SA_DMA_BUFFER_MAX * ADC2_SA_CHANNEL_COUNT);
DMA_Cmd(ADC2_SA_DMA_UNIT, Enable);
DMA_ChannelCmd(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, Enable);
}
}
/**
*******************************************************************************
** \brief DMA interrupt configuration.
**
** \note DMA NVIC number: [Int030_IRQn, Int031_IRQn]
**
******************************************************************************/
void DmaIrqConfig(void)
{
stc_irq_regi_conf_t stcAdcIrqCfg;
stcAdcIrqCfg.enIntSrc = ADC1_SA_DMA_IRQ_NUM;
stcAdcIrqCfg.enIRQn = ADC1_DMA_IRQ_NVIC_NUM;
stcAdcIrqCfg.pfnCallback = &ADC1_SA_DMA_INT_CB;
DmaIrqRegister(&stcAdcIrqCfg, DDL_IRQ_PRIORITY_DEFAULT);
stcAdcIrqCfg.enIntSrc = ADC2_SA_DMA_IRQ_NUM;
stcAdcIrqCfg.enIRQn = ADC2_DMA_IRQ_NVIC_NUM;
stcAdcIrqCfg.pfnCallback = &ADC2_SA_DMA_INT_CB;
DmaIrqRegister(&stcAdcIrqCfg, DDL_IRQ_PRIORITY_DEFAULT);
}
/**
*******************************************************************************
** \brief DMA IRQ register function.
**
******************************************************************************/
void DmaIrqRegister(stc_irq_regi_conf_t *pstcCfg, uint32_t u32Priority)
{
int16_t s16Vnum = pstcCfg->enIRQn;
if ((s16Vnum == ADC1_DMA_IRQ_NVIC_NUM) || (s16Vnum == ADC2_DMA_IRQ_NVIC_NUM)) {
if (Ok != enIrqRegistration(pstcCfg)) return;
} else {
return;
}
NVIC_ClearPendingIRQ(pstcCfg->enIRQn);
NVIC_SetPriority(pstcCfg->enIRQn, u32Priority);
NVIC_EnableIRQ(pstcCfg->enIRQn);
}
/**
*******************************************************************************
** \brief Config the pin which is mapping the channel to analog or digit mode.
**
******************************************************************************/
void AdcSetChannelPinMode(const M4_ADC_TypeDef *ADCx,
uint32_t u32Channel,
en_pin_mode_t enMode)
{
stc_port_init_t stcPortInit;
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = enMode;
stcPortInit.enPullUp = Disable;
if (M4_ADC1 == ADCx) {
PORT_Init(PortA, Pin00, &stcPortInit);
PORT_Init(PortA, Pin01, &stcPortInit);
PORT_Init(PortA, Pin02, &stcPortInit);
PORT_Init(PortA, Pin03, &stcPortInit);
PORT_Init(PortA, Pin04, &stcPortInit);
PORT_Init(PortA, Pin05, &stcPortInit);
PORT_Init(PortA, Pin06, &stcPortInit);
PORT_Init(PortA, Pin07, &stcPortInit);
} else if (M4_ADC2 == ADCx) {
PORT_Init(PortC, Pin00, &stcPortInit);
PORT_Init(PortC, Pin01, &stcPortInit);
}
}
/**
*******************************************************************************
** \brief DMA IRQ callbacks.
**
******************************************************************************/
void Dma1Btc0_IrqHandler(void)
{
DMA_ClearIrqFlag(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, BlkTrnCpltIrq);
DMA_ClearIrqFlag(ADC1_SA_DMA_UNIT, ADC1_SA_DMA_CH, TrnCpltIrq);
m_u8Adc1DmaIrqFlag = true;
// PORT_ResetBits(PortE, Pin00);
NVIC_ClearPendingIRQ(ADC1_DMA_IRQ_NVIC_NUM);
}
void Dma1Btc2_IrqHandler(void)
{
DMA_ClearIrqFlag(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, BlkTrnCpltIrq);
DMA_ClearIrqFlag(ADC2_SA_DMA_UNIT, ADC2_SA_DMA_CH, TrnCpltIrq);
m_u8Adc2DmaIrqFlag = true;
// PORT_ResetBits(PortE, Pin00);
NVIC_ClearPendingIRQ(ADC2_DMA_IRQ_NVIC_NUM);
}
uint8_t GetAdcIrgFlag(uint8_t nAdc)
{
uint8_t result = false;
if (nAdc == 0) {
result = m_u8Adc1DmaIrqFlag;
m_u8Adc1DmaIrqFlag = false;
} else {
result = m_u8Adc2DmaIrqFlag;
m_u8Adc2DmaIrqFlag = false;
}
return result;
}
uint16_t AvgAdc1DmaValue(uint16_t ch)
{
uint32_t sum = 0;
for (int i = 0; i < ADC1_SA_DMA_BUFFER_MAX; i++)
sum += Adc1DmaSaBuff[i][ch];
return (uint16_t)(sum / ADC1_SA_DMA_BUFFER_MAX);
}
//VI(Voltage and Current) port Initialize
void ADC_Port_Init(void)
{
/* Config ADCs. */
AdcConfig();
/* Config DMA. */
DmaConfig();
}
uint16_t AvgAdc2DmaValue(uint16_t ch)
{
__IO uint32_t sum = 0;
for (int i = 0; i < ADC2_SA_DMA_BUFFER_MAX; i++) {
sum += Adc2DmaSaBuff[i][ch];
}
return (uint32_t)(sum / ADC2_SA_DMA_BUFFER_MAX);
}
uint32_t CheckAdc2DmaValue(uint16_t ch)
{
__IO uint32_t sum = 0;
for (int i = 0; i < ADC2_SA_DMA_BUFFER_MAX; i++) {
if (sum < Adc2DmaSaBuff[i][ch])
sum = Adc2DmaSaBuff[i][ch];
}
return sum;
}
#ifdef CONSOLE_DEBUG
void DisplayAdc2DmaBufferValue(uint8_t ch)
{
for (int i = 0; i < ADC2_SA_DMA_BUFFER_MAX; i++) {
printf("(%3d), %04X\r\n", i, Adc2DmaSaBuff[i][ch]);
delay_os_ms(1);
}
}
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,58 @@
/**
******************************************************************************
* @file adc.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of adc control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _ADC_H
#define _ADC_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
#define ADC_VBASE 3300 // 3.3V
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void DmaInitConfig(void);
void DmaReloadConfig(uint8_t nAdc);
void ADC_Port_Init(void);
uint8_t GetAdcIrgFlag(uint8_t nAdc);
/****** ADC1 for Temperature **************************************************/
uint16_t AvgAdc1DmaValue(uint16_t ch);
uint16_t GetAdc1DmaBufferValue(uint16_t ch, uint16_t no);
void DisplayAdc1DmaBufferValue(void);
/****** ADC2 for VI ***********************************************************/
uint16_t AvgAdc2DmaValue(uint16_t ch);
uint16_t GetAdc2DmaBufferValue(uint16_t ch, uint16_t no);
void DisplayAdc2DmaBufferValue(uint8_t ch);
uint32_t CheckAdc2DmaValue(uint16_t ch);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
/*
bq769x0.h - Battery management system based on bq769x0 for Arduino
Copyright (C) 2015 Martin J ger (m.jaeger@posteo.de)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#ifndef _BQ769X0_H_
#define _BQ769X0_H_
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
// can be reduced to save some memory if smaller ICs are used
#define MAX_NUMBER_OF_CELLS 15
#define MAX_NUMBER_OF_THERMISTORS 3
// IC type/size
#define bq76920 1
#define bq76930 2
#define bq76940 3
// initialization, status update and shutdown
void bq769x0_construct(void);
int bq769x0_begin(uint8_t alertPin, uint8_t bootPin);
int bq769x0_checkStatus(void); // returns 0 if everything is OK
void bq769x0_updateData(void);
void bq769x0_shutdown(void);
uint8_t bq769x0_updateBalancingSwitches(uint16_t sBal, uint8_t mode);
// charging control
bool enableCharging(void);
void disableCharging(void);
bool enableDischarging(void);
void disableDischarging(void);
// limit settings (for battery protection)
long setShortCircuitProtection(long current_mA, int delay_us);
long setOvercurrentChargeProtection(long current_mA, int delay_ms);
long setOvercurrentDischargeProtection(long current_mA, int delay_ms);
int setCellUndervoltageProtection(int voltage_mV, int delay_s);
int setCellOvervoltageProtection(int voltage_mV, int delay_s);
// battery status
uint16_t getNumberOfCells(void);
uint32_t getBatteryVoltage(void);
uint32_t getBatterySumVoltage(void);
uint16_t getCellVoltage(uint16_t idCell);
int getMinCellVoltage(void);
int getMaxCellVoltage(void);
float getTemperatureDegC(uint8_t channel);
float getTemperatureDegF(uint8_t channel);
uint16_t getCellBalStatus(void);
uint8_t getAfeStatus(void);
uint8_t getAfeCtrl1(void);
uint8_t getAfeCtrl2(void);
uint8_t getAfeProtect(uint8_t id);
uint8_t getAfeUvTrip(void);
uint8_t getAfeOvTrip(void);
uint8_t bq769x0_getAlertStatus(void);
void bq769x0_ResetAlert(void);
// Methods
bool determineAddressAndCrc(void);
void updateVoltages(void);
void updateCurrent(bool ignoreCCReadyFlag);
void updateTemperatures(void);
uint8_t readRegister(uint8_t address);
void writeRegister(uint8_t address, int data);
void updateAdcGain2(int32_t Gain2);
#endif // _BQ769X0_H_
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,243 @@
/*
registers.h - Battery management system based on bq769x0 for Arduino
Copyright (C) 2015 Martin J ger (m.jaeger@posteo.de)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
/**
******************************************************************************
* @file bq76940_i2c.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of bq76940 i2c 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BQ76940_REG_H
#define __BQ76940_REG_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
// register map
#define SYS_STAT 0x00
#define CELLBAL1 0x01
#define CELLBAL2 0x02
#define CELLBAL3 0x03
#define SYS_CTRL1 0x04
#define SYS_CTRL2 0x05
#define PROTECT1 0x06
#define PROTECT2 0x07
#define PROTECT3 0x08
#define OV_TRIP 0x09
#define UV_TRIP 0x0A
#define CC_CFG 0x0B
#define VC1_HI_BYTE 0x0C
#define VC1_LO_BYTE 0x0D
#define VC2_HI_BYTE 0x0E
#define VC2_LO_BYTE 0x0F
#define VC3_HI_BYTE 0x10
#define VC3_LO_BYTE 0x11
#define VC4_HI_BYTE 0x12
#define VC4_LO_BYTE 0x13
#define VC5_HI_BYTE 0x14
#define VC5_LO_BYTE 0x15
#define VC6_HI_BYTE 0x16
#define VC6_LO_BYTE 0x17
#define VC7_HI_BYTE 0x18
#define VC7_LO_BYTE 0x19
#define VC8_HI_BYTE 0x1A
#define VC8_LO_BYTE 0x1B
#define VC9_HI_BYTE 0x1C
#define VC9_LO_BYTE 0x1D
#define VC10_HI_BYTE 0x1E
#define VC10_LO_BYTE 0x1F
#define VC11_HI_BYTE 0x20
#define VC11_LO_BYTE 0x21
#define VC12_HI_BYTE 0x22
#define VC12_LO_BYTE 0x23
#define VC13_HI_BYTE 0x24
#define VC13_LO_BYTE 0x25
#define VC14_HI_BYTE 0x26
#define VC14_LO_BYTE 0x27
#define VC15_HI_BYTE 0x28
#define VC15_LO_BYTE 0x29
#define BAT_HI_BYTE 0x2A
#define BAT_LO_BYTE 0x2B
#define TS1_HI_BYTE 0x2C
#define TS1_LO_BYTE 0x2D
#define TS2_HI_BYTE 0x2E
#define TS2_LO_BYTE 0x2F
#define TS3_HI_BYTE 0x30
#define TS3_LO_BYTE 0x31
#define CC_HI_BYTE 0x32
#define CC_LO_BYTE 0x33
#define ADCGAIN1 0x50
#define ADCOFFSET 0x51
#define ADCGAIN2 0x59
// function from TI reference design
#define LOW_BYTE(Data) (uint8_t)(0xff & Data)
#define HIGH_BYTE(Data) (uint8_t)(0xff & (Data >> 8))
// for bit clear operations of the SYS_STAT register
#define STAT_CC_READY (0x80)
#define STAT_DEVICE_XREADY (0x20)
#define STAT_OVRD_ALERT (0x10)
#define STAT_UV (0x08)
#define STAT_OV (0x04)
#define STAT_SCD (0x02)
#define STAT_OCD (0x01)
#define STAT_FLAGS (0x3F)
/* Exported constants --------------------------------------------------------*/
// maps for settings in protection registers
const int SCD_delay_setting [4] =
{ 70, 100, 200, 400 }; // us
const int SCD_threshold_setting [8] =
{ 44, 67, 89, 111, 133, 155, 178, 200 }; // mV
const int OCD_delay_setting [8] =
{ 8, 20, 40, 80, 160, 320, 640, 1280 }; // ms
const int OCD_threshold_setting [16] =
{ 17, 22, 28, 33, 39, 44, 50, 56, 61, 67, 72, 78, 83, 89, 94, 100 }; // mV
const uint8_t UV_delay_setting [4] = { 1, 4, 8, 16 }; // s
const uint8_t OV_delay_setting [4] = { 1, 2, 4, 8 }; // s
typedef union regSYS_STAT {
struct
{
uint8_t OCD :1;
uint8_t SCD :1;
uint8_t OV :1;
uint8_t UV :1;
uint8_t OVRD_ALERT :1;
uint8_t DEVICE_XREADY :1;
uint8_t WAKE :1;
uint8_t CC_READY :1;
} bits;
uint8_t regByte;
} regSYS_STAT_t;
typedef union regSYS_CTRL1 {
struct
{
uint8_t SHUT_B :1;
uint8_t SHUT_A :1;
uint8_t RSVD1 :1;
uint8_t TEMP_SEL :1;
uint8_t ADC_EN :1;
uint8_t RSVD2 :2;
uint8_t LOAD_PRESENT :1;
} bits;
uint8_t regByte;
} regSYS_CTRL1_t;
typedef union regSYS_CTRL2 {
struct
{
uint8_t CHG_ON :1;
uint8_t DSG_ON :1;
uint8_t WAKE_T :2;
uint8_t WAKE_EN :1;
uint8_t CC_ONESHOT :1;
uint8_t CC_EN :1;
uint8_t DELAY_DIS :1;
} bits;
uint8_t regByte;
} regSYS_CTRL2_t;
typedef union regPROTECT1 {
struct
{
uint8_t SCD_THRESH :3;
uint8_t SCD_DELAY :2;
uint8_t RSVD :2;
uint8_t RSNS :1;
} bits;
uint8_t regByte;
} regPROTECT1_t;
typedef union regPROTECT2 {
struct
{
uint8_t OCD_THRESH :4;
uint8_t OCD_DELAY :3;
uint8_t RSVD :1;
} bits;
uint8_t regByte;
} regPROTECT2_t;
typedef union regPROTECT3 {
struct
{
uint8_t RSVD :4;
uint8_t OV_DELAY :2;
uint8_t UV_DELAY :2;
} bits;
uint8_t regByte;
} regPROTECT3_t;
typedef union regCELLBAL
{
struct
{
uint8_t RSVD :3;
uint8_t CB5 :1;
uint8_t CB4 :1;
uint8_t CB3 :1;
uint8_t CB2 :1;
uint8_t CB1 :1;
} bits;
uint8_t regByte;
} regCELLBAL_t;
typedef union regVCELL
{
struct
{
uint8_t VC_HI;
uint8_t VC_LO;
} bytes;
uint16_t regWord;
} regVCELL_t;
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,62 @@
/**
******************************************************************************
* @file buck.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the codes of buck control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "buck.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Buck on/off Port/Pin definition */
#define BUCK_ONOFF_PORT (PortA)
#define BUCK_ONOFF_PIN (Pin11)
// Relay port definitions
#define BUCK_ON PORT_ResetBits(BUCK_ONOFF_PORT, BUCK_ONOFF_PIN);
#define BUCK_OFF PORT_SetBits(BUCK_ONOFF_PORT, BUCK_ONOFF_PIN);
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
// Relay IO Initialize
void Buck_ctrl_Init(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enPinOType = Pin_OType_Od;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* Relay Control Port/Pin initialization */
PORT_Init(BUCK_ONOFF_PORT, BUCK_ONOFF_PIN, &stcPortInit);
BUCK_ON;
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,39 @@
/**
******************************************************************************
* @file buck.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of buck control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _BUCK_H
#define _BUCK_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void Buck_ctrl_Init(void); // Initialize
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,65 @@
/**
******************************************************************************
* @file buzzer.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the codes of buzzer control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "buzzer.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Define port and pin for device address */
#define BUZZER_PORT (PortE)
#define BUZZER_PIN (Pin02)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
//Relay IO Initialize
void Buzzer_Init(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* LED Port/Pin initialization */
PORT_Init(BUZZER_PORT, BUZZER_PIN, &stcPortInit);
PORT_ResetBits(BUZZER_PORT, BUZZER_PIN);
}
void Buzzer(uint8_t onoff)
{
if (onoff) PORT_SetBits(BUZZER_PORT, BUZZER_PIN);
else PORT_ResetBits(BUZZER_PORT, BUZZER_PIN);
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,43 @@
/**
******************************************************************************
* @file buzzer.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of buzzer control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _BUZZER_H
#define _BUZZER_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void Buzzer_Init(void); //Initialize
void Buzzer(uint8_t onoff);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View 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>&copy; 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******/

View File

@@ -0,0 +1,39 @@
/**
******************************************************************************
* @file can.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CAN_H
#define __CAN_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void can_init(uint32_t CAN_Baud_Rate);
uint8_t CAN_GetPacket(stc_can_rxframe_t *packet);
void CAN_SendPacket(stc_can_txframe_t *packet);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,126 @@
/**
******************************************************************************
* @file delay.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the code of the delay 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "delay.h"
#include "includes.h" //ucos use
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define SYS_CLOCK 200
#define SYSTICK_LOAD 200000
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private prototype functions -----------------------------------------------*/
// OS is called the delay function delay
// ticks:Delay number of beats
void delay_ostimedly(uint32_t ticks)
{
#ifdef CPU_CFG_CRITICAL_METHOD
OS_ERR err;
OSTimeDly(ticks,OS_OPT_TIME_PERIODIC, &err);//UCOSIII delay adoption cycle mode
#else
OSTimeDly(ticks); //UCOSII delay
#endif
}
void delay_us1(uint32_t us)
{
uint32_t udelay = us * 10;
for (int i = 0; i < udelay; i++)
{
i = i;
}
}
void delay_us(uint32_t us)
{
uint32_t usec = us * SYS_CLOCK;
uint32_t temp = CPU_REG_NVIC_ST_CURRENT;
uint32_t comp = temp + usec;
if (temp < usec)
{
comp = SYSTICK_LOAD - (usec - temp); // 200 - 100 = 100, 200000 - 100 = 199900, 200000 + 100
while ((comp < temp) || (temp < usec))
{
temp = CPU_REG_NVIC_ST_CURRENT;
}
}
else
{
comp = temp - usec;
while (comp < temp)
{
temp = CPU_REG_NVIC_ST_CURRENT;
}
}
}
void delay_ns1(uint32_t ns)
{
uint32_t nsec = ns / 1;
uint32_t temp = CPU_REG_NVIC_ST_CURRENT;
uint32_t comp = temp + nsec;
if (temp < nsec)
{
comp = SYSTICK_LOAD - (nsec - temp); // 200 - 100 = 100, 200000 - 100 = 199900, 200000 + 100
while ((comp < temp) || (temp < nsec))
{
temp = CPU_REG_NVIC_ST_CURRENT;
}
}
else
{
comp = temp - nsec;
while (comp < temp)
{
temp = CPU_REG_NVIC_ST_CURRENT;
}
}
}
void delay_ns(uint32_t ns)
{
for (uint32_t i = 0; i < ns; i++)
{
__NOP();
}
}
void delay_os_ms(uint32_t ms)
{
OS_ERR err;
OSTimeDlyHMSM(0, 0, (ms / 1000), (ms % 1000),
OS_OPT_TIME_HMSM_STRICT,
&err);
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,71 @@
/**
******************************************************************************
* @file delay.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the delay 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DELAY_H
#define __DELAY_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void delay_init(uint32_t SYSCLK);
void delay_ms(uint32_t nms);
void delay_us(uint32_t us);
void delay_ns(uint32_t ns);
void delay_os_ms(uint32_t ms);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,86 @@
/**
******************************************************************************
* @file dev_addr.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the codes of device address 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "dev_addr.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Define port and pin for device address */
#define DEV_ADDR_0_PORT (PortB)
#define DEV_ADDR_0_PIN (Pin10)
#define DEV_ADDR_1_PORT (PortE)
#define DEV_ADDR_1_PIN (Pin15)
#define DEV_ADDR_2_PORT (PortE)
#define DEV_ADDR_2_PIN (Pin14)
#define DEV_ADDR_3_PORT (PortE)
#define DEV_ADDR_3_PIN (Pin13)
//#define DEV_ADDR_4_PORT (PortE)
//#define DEV_ADDR_4_PIN (Pin01)
//#define DEV_ADDR_5_PORT (PortE)
//#define DEV_ADDR_5_PIN (Pin01)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
//Relay IO Initialize
void DevAddrInit(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_In;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Enable;
/* LED Port/Pin initialization */
PORT_Init(DEV_ADDR_0_PORT, DEV_ADDR_0_PIN, &stcPortInit);
PORT_Init(DEV_ADDR_1_PORT, DEV_ADDR_1_PIN, &stcPortInit);
PORT_Init(DEV_ADDR_2_PORT, DEV_ADDR_2_PIN, &stcPortInit);
PORT_Init(DEV_ADDR_3_PORT, DEV_ADDR_3_PIN, &stcPortInit);
}
uint8_t GetDevAddr(void)
{
uint8_t result = 0;
result |= (!PORT_GetBit(DEV_ADDR_0_PORT, DEV_ADDR_0_PIN) << 3);
result |= (!PORT_GetBit(DEV_ADDR_1_PORT, DEV_ADDR_1_PIN) << 2);
result |= (!PORT_GetBit(DEV_ADDR_2_PORT, DEV_ADDR_2_PIN) << 1);
result |= (!PORT_GetBit(DEV_ADDR_3_PORT, DEV_ADDR_3_PIN) << 0);
return result;
}

View File

@@ -0,0 +1,47 @@
/**
******************************************************************************
* @file dev_addr.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of device address 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _DEV_ADDR_H
#define _DEV_ADDR_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
//Relay port definitions
void DevAddrInit(void); // Initialize
void DevAddrDeInit(void); // DeInitialize
uint8_t GetDevAddr(void);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,253 @@
/**
******************************************************************************
* @file flash_if.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the flash memory 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "flash_if.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
FW_INFO fwinfo;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Unlocks Flash for write access
* @param None
* @retval None
*/
void FLASH_If_Init(void)
{
/* Unlock EFM. */
EFM_Unlock();
/* Enable flash. */
EFM_FlashCmd(Enable);
}
/**
* @brief This function does an erase of all user flash area
* @param StartSector: start of user flash area
* @retval 0: user flash area successfully erased
* 1: error occurred
*/
uint32_t FLASH_If_Erase(uint32_t StartSector, uint32_t uSize)
{
uint32_t UserStartSector, UserEndSector, i = 0;
/* Unlock EFM. */
EFM_Unlock();
/* Enable flash. */
EFM_FlashCmd(Enable);
/* Wait flash ready. */
while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY))
{
;
}
/* Get the sector where start the user flash area */
UserStartSector = StartSector;
UserEndSector = (StartSector + uSize);
for(i = UserStartSector; i <= UserEndSector; i += SECTOR_SIZE)
{
/* Reload IWDG counter */
WDT_RefreshCounter();
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (EFM_SectorErase(i) != Ok)
{
/* Error occurred while page erase */
return (1);
}
}
/* Lock EFM. */
EFM_Lock();
return (0);
}
/**
* @brief This function does an erase of all user flash area
* @param StartSector: start of user flash area
* @retval 0: user flash area successfully erased
* 1: error occurred
*/
uint32_t FLASH_If_SingleSectorErase(uint32_t SectorAddr)
{
uint32_t result = 0;
/* Unlock EFM. */
EFM_Unlock();
/* Enable flash. */
EFM_FlashCmd(Enable);
/* Wait flash ready. */
while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY))
{
;
}
/* Reload IWDG counter */
WDT_RefreshCounter();
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (EFM_SectorErase(SectorAddr) != Ok)
{
/* Error occurred while page erase */
result = (1);
}
/* Lock EFM. */
EFM_Lock();
return result;
}
/**
* @brief This function writes a data buffer in flash (data are 32-bit aligned).
* @note After writing data buffer, the flash content is checked.
* @param FlashAddress: start address for writing data buffer
* @param Data: pointer on data buffer
* @param DataLength: length of data buffer (unit is 32-bit word)
* @retval 0: Data successfully written to Flash memory
* 1: Error occurred while writing data in Flash memory
* 2: Written Data in flash memory is different from expected one
*/
uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data, uint32_t DataLength)
{
uint32_t i = 0;
uint32_t result = 0;
/* Unlock EFM. */
EFM_Unlock();
/* Enable flash. */
EFM_FlashCmd(Enable);
/* Wait flash ready. */
while(Set != EFM_GetFlagStatus(EFM_FLAG_RDY))
{
;
}
for (i = 0; (i < DataLength) && (*FlashAddress <= (mBMS_FW_DN_END_ADDRESS - 4)); i++)
{
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (EFM_SingleProgram(*FlashAddress, *(uint32_t *)(Data + i)) == Ok)
{
/* Check the written value */
if (*(uint32_t*)*FlashAddress != *(uint32_t *)(Data + i))
{
/* Flash content doesn't match SRAM content */
result = 2;
break;
}
/* Increment FLASH destination address */
*FlashAddress += 4;
}
else
{
/* Error occurred while writing data in Flash memory */
result = 1;
break;
}
}
/* Lock EFM. */
EFM_Lock();
return result;
}
///**
// * @brief Returns the write protection status of user flash area.
// * @param None
// * @retval 0: No write protected sectors inside the user flash area
// * 1: Some sectors inside the user flash area are write protected
// */
//uint16_t FLASH_If_GetWriteProtectionStatus(void)
//{
// uint32_t UserStartSector = FLASH_Sector_1;
// /* Get the sector where start the user flash area */
// UserStartSector = GetSector(APPLICATION_ADDRESS);
// /* Check if there are write protected sectors inside the user flash area */
// if ((FLASH_OB_GetWRP() >> (UserStartSector/8)) == (0xFFF >> (UserStartSector/8)))
// { /* No write protected sectors inside the user flash area */
// return 1;
// }
// else
// { /* Some sectors inside the user flash area are write protected */
// return 0;
// }
//}
///**
// * @brief Disables the write protection of user flash area.
// * @param None
// * @retval 1: Write Protection successfully disabled
// * 2: Error: Flash write unprotection failed
// */
//uint32_t FLASH_If_DisableWriteProtection(void)
//{
// __IO uint32_t UserStartSector = FLASH_Sector_1, UserWrpSectors = OB_WRP_Sector_1;
// /* Get the sector where start the user flash area */
// UserStartSector = GetSector(APPLICATION_ADDRESS);
// /* Mark all sectors inside the user flash area as non protected */
// UserWrpSectors = 0xFFF-((1 << (UserStartSector/8))-1);
//
// /* Unlock the Option Bytes */
// FLASH_OB_Unlock();
// /* Disable the write protection for all sectors inside the user flash area */
// FLASH_OB_WRPConfig(UserWrpSectors, DISABLE);
// /* Start the Option Bytes programming process. */
// if (FLASH_OB_Launch() != FLASH_COMPLETE)
// {
// /* Error: Flash write unprotection failed */
// return (2);
// }
// /* Write Protection successfully disabled */
// return (1);
//}
/**
* @}
*/
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,99 @@
/**
******************************************************************************
* @file flash_if.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the flash memory 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FLASH_IF_H
#define __FLASH_IF_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
typedef struct
{
uint32_t AppFileSize;
uint8_t BootVer[4];
uint8_t AppVer[4];
uint8_t FileName[30];
uint8_t BootUpdate;
uint8_t AppUpdate;
} FW_INFO;
/* Exported constants --------------------------------------------------------*/
/* Base address of the Flash sectors */
#define SECTOR_SIZE 8192 // 0X2000
#define ADDR_FLASH_SECTOR_00 ((uint32_t)0x00000000) /* Base @ of Sector 0, 8 Kbyte */
#define ADDR_FLASH_SECTOR_01 ((uint32_t)0x00002000) /* Base @ of Sector 1, 8 Kbyte */
#define ADDR_FLASH_SECTOR_02 ((uint32_t)0x00004000) /* Base @ of Sector 2, 8 Kbyte */
#define ADDR_FLASH_SECTOR_03 ((uint32_t)0x00006000) /* Base @ of Sector 3, 8 Kbyte */
#define ADDR_FLASH_SECTOR_04 ((uint32_t)0x00008000) /* Base @ of Sector 4, 8 Kbyte */
#define ADDR_FLASH_SECTOR_05 ((uint32_t)0x0000A000) /* Base @ of Sector 5, 8 Kbyte */
#define ADDR_FLASH_SECTOR_06 ((uint32_t)0x0000C000) /* Base @ of Sector 6, 8 Kbyte */
#define ADDR_FLASH_SECTOR_07 ((uint32_t)0x0000E000) /* Base @ of Sector 7, 8 Kbyte */
#define ADDR_FLASH_SECTOR_08 ((uint32_t)0x00010000) /* Base @ of Sector 8, 8 Kbyte */
#define ADDR_FLASH_SECTOR_09 ((uint32_t)0x00012000) /* Base @ of Sector 9, 8 Kbyte */
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x00014000) /* Base @ of Sector 10, 8 Kbyte */
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x00016000) /* Base @ of Sector 11, 8 Kbyte */
#define ADDR_FLASH_SECTOR_12 ((uint32_t)0x00018000) /* Base @ of Sector 12, 8 Kbyte */
#define ADDR_FLASH_SECTOR_13 ((uint32_t)0x0001A000) /* Base @ of Sector 13, 8 Kbyte */
#define ADDR_FLASH_SECTOR_14 ((uint32_t)0x0001C000) /* Base @ of Sector 14, 8 Kbyte */
#define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0001E000) /* Base @ of Sector 15, 8 Kbyte */
#define ADDR_FLASH_SECTOR_16 ((uint32_t)0x00020000) /* Base @ of Sector 16, 8 Kbyte */
#define ADDR_FLASH_SECTOR_32 ((uint32_t)0x00040000) /* Base @ of Sector 32, 8 Kbyte */
#define ADDR_FLASH_SECTOR_48 ((uint32_t)0x00060000) /* Base @ of Sector 1, 16 Kbyte */
/* Define the address from where user application will be loaded.
Note: the 1st sector 0x00000000-0x00020000 is reserved for the IAP code */
#define mBMS_FW_RN_ADDRESS ADDR_FLASH_SECTOR_16
#define mBMS_FW_DN_ADDRESS ADDR_FLASH_SECTOR_48
/* End of the Flash address */
#define mBMS_FW_DN_END_ADDRESS ((uint32_t)0x00080000)
/* Define the user application size */
#define mBMS_FW_FLASH_SIZE (mBMS_FW_DN_END_ADDRESS - mBMS_FW_DN_ADDRESS)
#define mBMS_FW_PACKET_SIZE 0x800 // 2048
#define mBMS_CALIB_BASE_ADDR ADDR_FLASH_SECTOR_14
#define mBMS_FW_INFO_BASE_ADDR ADDR_FLASH_SECTOR_15
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void FLASH_If_Init(void);
uint32_t FLASH_If_Erase(uint32_t StartSector, uint32_t uSize);
uint32_t FLASH_If_SingleSectorErase(uint32_t SectorAddr);
uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data, uint32_t DataLength);
uint16_t FLASH_If_GetWriteProtectionStatus(void);
uint32_t FLASH_If_DisableWriteProtection(void);
extern FW_INFO fwinfo;
#endif /* __FLASH_IF_H */
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,217 @@
/**
******************************************************************************
* @file i2c.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the codes of i2c 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "i2c.h"
#include "delay.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Define I2C unit used for the example */
#define I2C_UNIT (M4_I2C1)
/* Define BQ Series device address */
#define BQ_ADDRESS (0x50u)
#define BQ_ADR_LEN (1u)
/* Define port and pin for SDA and SCL */
#define I2C_SCL_PORT (PortD)
#define I2C_SCL_PIN (Pin01)
#define I2C_SDA_PORT (PortD)
#define I2C_SDA_PIN (Pin00)
#define I2C_GPIO_SCL_FUNC (Func_I2c1_Scl)
#define I2C_GPIO_SDA_FUNC (Func_I2c1_Sda)
#define I2C_FCG_USE (PWC_FCG1_PERIPH_I2C1)
#define TIMEOUT (0x40000ul)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
******************************************************************************
** \brief I2C memory write
**
** \param u8DevAddr The slave address
** \param u8Addr The register address
** \param pu8Data Pointer to the data buffer
** \param u32Size Data size
** \param u32TimeOut Time out count
** \retval en_result_t Enumeration value:
** - Ok: Success
** - Error: Receive NACK
** - ErrorTimeout: Time out
******************************************************************************/
en_result_t I2C_Reg_Write(uint16_t u8DevAddr, uint8_t u8RegAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
en_result_t enRet;
I2C_Cmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Disable);
enRet = I2C_Start(I2C_UNIT, u32TimeOut);
if (Ok == enRet)
{
enRet = I2C_TransAddr(I2C_UNIT, u8DevAddr, I2CDirTrans, u32TimeOut);
if (Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u8RegAddr, BQ_ADR_LEN, u32TimeOut);
if (Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, pu8Data, u32Size, u32TimeOut);
}
}
}
I2C_Stop(I2C_UNIT, u32TimeOut);
I2C_Cmd(I2C_UNIT, Disable);
return enRet;
}
/**
******************************************************************************
** \brief I2C memory read
**
** \param u8DevAddr The slave address
** \param u8Addr The register address
** \param pu8Data Pointer to the data buffer
** \param u32Size Data size
** \param u32TimeOut Time out count
** \retval en_result_t Enumeration value:
** - Ok: Success
** - ErrorTimeout: Time out
******************************************************************************/
en_result_t I2C_Reg_Read(uint8_t u8DevAddr, uint8_t u8RegAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
en_result_t enRet;
I2C_Cmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Disable);
enRet = I2C_Start(I2C_UNIT, u32TimeOut);
if (Ok == enRet)
{
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirTrans, u32TimeOut);
if (Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u8RegAddr, BQ_ADR_LEN, u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_Restart(I2C_UNIT, u32TimeOut);
if (Ok == enRet)
{
if (1ul == u32Size)
{
I2C_AckConfig(I2C_UNIT, I2c_NACK);
}
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);
if (Ok == enRet)
{
enRet = I2C_MasterDataReceiveAndStop(I2C_UNIT, pu8Data, u32Size, u32TimeOut);
}
I2C_AckConfig(I2C_UNIT, I2c_ACK);
}
}
}
}
if (Ok != enRet)
{
I2C_Stop(I2C_UNIT, u32TimeOut);
}
I2C_Cmd(I2C_UNIT, Disable);
return enRet;
}
/**
******************************************************************************
** \brief Initialize the I2C peripheral for e2prom
** \param None
** \retval en_result_t Enumeration value:
** - Ok: Success
** - ErrorTimeout: Time out
******************************************************************************/
static en_result_t E2_Initialize(void)
{
stc_i2c_init_t stcI2cInit;
en_result_t enRet;
float32_t fErr;
I2C_DeInit(I2C_UNIT);
/* Initialize I2C port*/
PORT_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_GPIO_SCL_FUNC, Disable);
PORT_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_GPIO_SDA_FUNC, Disable);
/* Enable I2C Peripheral*/
PWC_Fcg1PeriphClockCmd(I2C_FCG_USE, Enable);
MEM_ZERO_STRUCT(stcI2cInit);
stcI2cInit.u32ClockDiv = I2C_CLK_DIV8;
stcI2cInit.u32Baudrate = 100000ul;
stcI2cInit.u32SclTime = 0ul;
enRet = I2C_Init(I2C_UNIT, &stcI2cInit, &fErr);
I2C_BusWaitCmd(I2C_UNIT, Enable);
return enRet;
}
void I2c_Config(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* SPI Port/Pin initialization */
PORT_Init(I2C_SCL_PORT, I2C_SCL_PIN, &stcPortInit);
stcPortInit.enPinMode = Pin_Mode_In;
PORT_Init(I2C_SDA_PORT, I2C_SDA_PIN, &stcPortInit);
E2_Initialize();
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,46 @@
/**
******************************************************************************
* @file i2c.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the spi communication.
******************************************************************************
* @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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __I2C_H
#define __I2C_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void I2c_Config(void);
en_result_t I2C_Reg_Write(uint16_t u8DevAddr, uint8_t u8RegAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut);
en_result_t I2C_Reg_Read(uint8_t u8DevAddr, uint8_t u8RegAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,45 @@
/**
******************************************************************************
* @file iwdg.c
* @author AMG Energy Solution Application Team
* @version V1.0.0
* @date 25-January-2022
* @brief Watchdog Service Routines.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "iwdg.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* WDT count cycle definition */
#define WDT_COUNT_CYCLE (16384u)
/* Reset source definition */
#define RESET_WDT_TRIGGER (0u)
#define RESET_OTHER_TRIGGER (1u)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
//Initialize watch-dog
void IWDG_Init(void)
{
stc_wdt_init_t stcWdtInit;
/* configure structure initialization */
MEM_ZERO_STRUCT(stcWdtInit);
stcWdtInit.enClkDiv = WdtPclk3Div8192;
stcWdtInit.enCountCycle = WdtCountCycle16384;
stcWdtInit.enRefreshRange = WdtRefresh100Pct; //WdtRefresh0To25Pct;
stcWdtInit.enSleepModeCountEn = Disable;
stcWdtInit.enRequestType = WdtTriggerResetRequest;
WDT_Init(&stcWdtInit);
/* First refresh to start WDT */
WDT_RefreshCounter();
}

View File

@@ -0,0 +1,19 @@
#ifndef _IWDG_H
#define _IWDG_H
//////////////////////////////////////////////////////////////////////////////////
//This program is for educational purposes only, without the author's permission, may not be used for any other purpose
//ALIENTEK STM32F407 Development Board
//Independent watch-dog driver code
//Hot Atomic @ALIENTEK
//Forum: www.openedv.com
//Date created: 2015/9/1
//Version: V1.0
//All rights reserved pirated reserved.
//Copyright(C) Guangzhou wing electronic technology limited company 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
#include "hc32_ddl.h"
void IWDG_Init(void); //Initialize
#endif

View File

@@ -0,0 +1,161 @@
/**
******************************************************************************
* @file led.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the code of the led control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "led.h"
#include "delay.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//LED port definitions
/* LED RUN(GREEN) Port/Pin definition */
#define LED_BD_PORT (PortB)
#define LED_BD_PIN (Pin08)
/* LED RUN(GREEN) Port/Pin definition */
#define LED_G_PORT (PortE)
#define LED_G_PIN (Pin08)
/* LED ALARM (RED) Port/Pin definition */
#define LED_R_PORT (PortE)
#define LED_R_PIN (Pin07)
/* LED SOC Port/Pin definition */
#define LED_SOC_3_PORT (PortE)
#define LED_SOC_3_PIN (Pin09)
#define LED_SOC_2_PORT (PortE)
#define LED_SOC_2_PIN (Pin10)
#define LED_SOC_1_PORT (PortE)
#define LED_SOC_1_PIN (Pin11)
#define LED_SOC_0_PORT (PortE)
#define LED_SOC_0_PIN (Pin12)
/* LED0~3 toggle definition */
#define LED_G_TOGGLE() (PORT_Toggle(LED_G_PORT, LED_G_PIN))
#define LED_R_TOGGLE() (PORT_Toggle(LED_R_PORT, LED_R_PIN))
#define LED_S0C_0_TOGGLE() (PORT_Toggle(LED_SOC_0_PIN, LED_SOC_0_PIN))
#define LED_S0C_1_TOGGLE() (PORT_Toggle(LED_SOC_1_PIN, LED_SOC_1_PIN))
#define LED_S0C_2_TOGGLE() (PORT_Toggle(LED_SOC_2_PIN, LED_SOC_2_PIN))
#define LED_S0C_3_TOGGLE() (PORT_Toggle(LED_SOC_3_PIN, LED_SOC_3_PIN))
#define DLY_MS (200ul)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
// LED class IO
void LED_Init(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* LED Port/Pin initialization */
PORT_Init(LED_BD_PORT, LED_BD_PIN, &stcPortInit);
PORT_Init(LED_G_PORT, LED_G_PIN, &stcPortInit);
PORT_Init(LED_R_PORT, LED_R_PIN, &stcPortInit);
PORT_Init(LED_SOC_0_PORT, LED_SOC_0_PIN, &stcPortInit);
PORT_Init(LED_SOC_1_PORT, LED_SOC_1_PIN, &stcPortInit);
PORT_Init(LED_SOC_2_PORT, LED_SOC_2_PIN, &stcPortInit);
PORT_Init(LED_SOC_3_PORT, LED_SOC_3_PIN, &stcPortInit);
}
void LED_SelfTest(void)
{
LED_Off(LED_ALL);
delay_os_ms(DLY_MS);
for (int i = 0; i < 6; i++) {
LED_On((LED_CONTROL)i);
if (i > 0) LED_Off((LED_CONTROL)(i - 1));
delay_os_ms(DLY_MS);
}
LED_Off(LED_ALL);
delay_os_ms(DLY_MS);
LED_On(LED_G);
}
void LED_On(LED_CONTROL flag)
{
switch (flag) {
case (LED_CONTROL)0: PORT_SetBits(LED_G_PORT, LED_G_PIN); break;
case (LED_CONTROL)1: PORT_SetBits(LED_R_PORT, LED_R_PIN); break;
case (LED_CONTROL)2: PORT_SetBits(LED_SOC_0_PORT, LED_SOC_0_PIN); break;
case (LED_CONTROL)3: PORT_SetBits(LED_SOC_1_PORT, LED_SOC_1_PIN); break;
case (LED_CONTROL)4: PORT_SetBits(LED_SOC_2_PORT, LED_SOC_2_PIN); break;
case (LED_CONTROL)5: PORT_SetBits(LED_SOC_3_PORT, LED_SOC_3_PIN); break;
case (LED_CONTROL)6: PORT_ResetBits(LED_BD_PORT, LED_BD_PIN); break;
case (LED_CONTROL)7:
PORT_SetBits(LED_G_PORT, LED_G_PIN);
PORT_SetBits(LED_R_PORT, LED_R_PIN);
PORT_SetBits(LED_SOC_0_PORT, LED_SOC_0_PIN);
PORT_SetBits(LED_SOC_1_PORT, LED_SOC_1_PIN);
PORT_SetBits(LED_SOC_2_PORT, LED_SOC_2_PIN);
PORT_SetBits(LED_SOC_3_PORT, LED_SOC_3_PIN);
break;
}
}
void LED_Off(LED_CONTROL flag)
{
switch (flag) {
case (LED_CONTROL)0: PORT_ResetBits(LED_G_PORT, LED_G_PIN); break;
case (LED_CONTROL)1: PORT_ResetBits(LED_R_PORT, LED_R_PIN); break;
case (LED_CONTROL)2: PORT_ResetBits(LED_SOC_0_PORT, LED_SOC_0_PIN); break;
case (LED_CONTROL)3: PORT_ResetBits(LED_SOC_1_PORT, LED_SOC_1_PIN); break;
case (LED_CONTROL)4: PORT_ResetBits(LED_SOC_2_PORT, LED_SOC_2_PIN); break;
case (LED_CONTROL)5: PORT_ResetBits(LED_SOC_3_PORT, LED_SOC_3_PIN); break;
case (LED_CONTROL)6: PORT_SetBits(LED_BD_PORT, LED_BD_PIN); break;
case (LED_CONTROL)7:
PORT_ResetBits(LED_G_PORT, LED_G_PIN);
PORT_ResetBits(LED_R_PORT, LED_R_PIN);
PORT_ResetBits(LED_SOC_0_PORT, LED_SOC_0_PIN);
PORT_ResetBits(LED_SOC_1_PORT, LED_SOC_1_PIN);
PORT_ResetBits(LED_SOC_2_PORT, LED_SOC_2_PIN);
PORT_ResetBits(LED_SOC_3_PORT, LED_SOC_3_PIN);
break;
}
}
void BD_LED_Toggle(void)
{
PORT_Toggle(LED_BD_PORT, LED_BD_PIN);
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,58 @@
/**
******************************************************************************
* @file led.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the led control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _LED_H
#define _LED_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
typedef enum {
LED_G = 0, /* 0: GREEN LED */
LED_R, /* 1: RED LED */
LED_SOC_0, /* 2: SOC 0 LED */
LED_SOC_1, /* 3: SOC 1 LED */
LED_SOC_2, /* 4: SOC 2 LED */
LED_SOC_3, /* 5: SOC 3 LED */
LED_BD, /* 6: Board LED */
LED_ALL /* 7: All LED */
} LED_CONTROL;
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void LED_Init(void); //Initialize
void LED_SelfTest(void);
void LED_On(LED_CONTROL flag);
void LED_Off(LED_CONTROL flag);
void BD_LED_Toggle(void);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,180 @@
/**
******************************************************************************
* File Name : can_comm.c
* Description : This file provides code for the configuration
* of the CAN communication instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "malloc.h"
//Memory pool (4-byte alignment)
__align(4) uint8_t membase[MEM_MAX_SIZE]; // __attribute__((at(0x10000000))); //CMM within the memory pool
//Memory management tables
__align(4) uint16_t memmapbase[MEM_ALLOC_TABLE_SIZE]; // __attribute__((at(0X10000000 + MEM3_MAX_SIZE))); //Internal CCM pools MAP
//Memory management parameters
const uint32_t memtblsize = MEM_ALLOC_TABLE_SIZE; //Memory table size
const uint32_t memblksize = MEM_BLOCK_SIZE; //Memory block size
const uint32_t memsize = MEM_MAX_SIZE; //Total memory size
//Memory management controller
struct _m_mallco_dev mallco_dev =
{
mymem_init, //Memory initialization
mem_perused, //Memory usage
membase, //Memory pool
memmapbase, //Memory management tables
0, //Memory management is not ready
};
//Copy memory
//*des:Destination address
//*src:Source address
//n:Need to copy memory length (bytes)
void mymemcpy(void *des,void *src,uint32_t n)
{
uint8_t *xdes = des;
uint8_t *xsrc = src;
while(n--) *xdes++ = *xsrc++;
}
//Setting memory
//*s:Memory address
//c :The value to be set
//count:Need to set the memory size(Bytes)
void mymemset(void*s,uint8_t c,uint32_t count)
{
uint8_t *xs = s;
while(count--) *xs++=c;
}
//Memory management class
//memx:Belongs to a block of memory
void mymem_init(void)
{
mymemset(mallco_dev.memmap, 0, memtblsize * 2); // Memory status table is cleared to zero
mymemset(mallco_dev.membase, 0, memsize); // Memory pool all data to zero
mallco_dev.memrdy = 1; // Memory initialized OK
}
//Get memory usage
//memx:Belongs to a block of memory
//Return value: usage (0~100)
uint8_t mem_perused(void)
{
uint32_t used = 0;
uint32_t i;
for (i = 0; i < memtblsize; i++)
{
if (mallco_dev.memmap[i]) used++;
}
return (used * 100) / (memtblsize);
}
// Memory allocation (internal call)
// size:Amount of memory to allocate (in bytes)
// The return value:0XFFFFFFFF,To indicate an error; the other, the memory offset
uint32_t _mem_malloc(uint32_t size)
{
signed long offset = 0;
uint16_t nmemb; // Required number of memory blocks
uint16_t cmemb = 0; // Number of contiguous blocks of free memory
uint32_t i;
if (!mallco_dev.memrdy) mallco_dev.init(); // Is not initialized, perform the initialization
if (size == 0) return 0XFFFFFFFF; // Do not need to allocate
nmemb = size / memblksize; // Gets the required number of contiguous blocks of memory allocated
if (size % memblksize) nmemb++;
for (offset = memtblsize - 1; offset >= 0; offset--) // Search the entire memory control
{
if (!mallco_dev.memmap[offset]) cmemb++; // Increase the number of contiguous blocks of free memory
else cmemb = 0; // Contiguous blocks of memory to zero
if (cmemb == nmemb) // Find nmemb consecutive empty memory blocks
{
for (i = 0; i < nmemb; i++) // Mark a block of memory is not empty
{
mallco_dev.memmap[offset+i] = nmemb;
}
return (offset*memblksize); // Returns the offset address
}
}
return 0XFFFFFFFF; // Not found consistent with allocated memory block
}
//Free memory (internal call)
//offset:Memory address of offset
//Return values: 0, release success; 1, release failed;
uint8_t _mem_free(uint32_t offset)
{
int i;
if (!mallco_dev.memrdy) // Is not initialized, perform the initialization
{
mallco_dev.init();
return 1; // Not initialized
}
if (offset < memsize) // Offset within the memory pool.
{
int index = offset / memblksize; // Offset where the memory block number
int nmemb=mallco_dev.memmap[index]; // Number of memory blocks
for (i = 0; i < nmemb; i++) // Zero out memory blocks
{
mallco_dev.memmap[index+i] = 0;
}
return 0;
} else return 2; // Offset Super.
}
//Free memory (external call)
//ptr:Memory address
void myfree(void *ptr)
{
uint32_t offset;
if (ptr == NULL) return; // Address 0.
offset = (uint32_t)ptr - (uint32_t)mallco_dev.membase;
_mem_free(offset); //Free up memory
}
//Allocating memory(External call)
//size:Memory size (in bytes)
//Return values: the first address of the allocated memory.
void *mymalloc(uint32_t size)
{
uint32_t offset;
offset = _mem_malloc(size);
if (offset == 0XFFFFFFFF) return NULL;
else return (void*)((uint32_t)mallco_dev.membase + offset);
}
//Reallocating memory (external call)
//*ptr:The old memory address
//size:Amount of memory to allocate (in bytes)
//Return values: the first address of the newly allocated memory.
void *myrealloc(void *ptr,uint32_t size)
{
uint32_t offset;
offset = _mem_malloc(size);
if (offset == 0XFFFFFFFF) return NULL;
else
{
mymemcpy((void*)((uint32_t)mallco_dev.membase + offset), ptr, size); // Copy the old memory contents to the new memory
myfree(ptr); // Free old memory
return (void*)((uint32_t)mallco_dev.membase + offset); // Returns a new memory address
}
}

View File

@@ -0,0 +1,78 @@
/**
******************************************************************************
* @file malloc.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides code for the configuration of
* the memory heap instances.
******************************************************************************
* @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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __malloc_H
#define __malloc_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
#ifndef NULL
#define NULL 0
#endif
// Define three memory pools
#define MEM_BLOCK_SIZE 32 // Block size is 32 bytes
#define MEM_MAX_SIZE (20 * 1024) // Maximum memory management 20k
#define MEM_ALLOC_TABLE_SIZE (MEM_MAX_SIZE / MEM_BLOCK_SIZE) // Memory table size
//Memory management controller
struct _m_mallco_dev
{
void (*init)(void); // Initialize
uint8_t (*perused)(void); // Memory usage
uint8_t *membase; // Memory pool management SRAMBANK a region of memory
uint16_t *memmap; // Memory status table
uint8_t memrdy; // Memory management is ready to
};
extern struct _m_mallco_dev mallco_dev; //Defined in malloc.c
void mymemset(void *s,uint8_t c,uint32_t count); // Setting memory
void mymemcpy(void *des,void *src,uint32_t n); // Copy memory
void mymem_init(void); // Memory initialization function (external/internal calls)
uint8_t mem_perused(void); // For memory usage (external/internal calls)
////////////////////////////////////////////////////////////////////////////////
//Users call a function
void myfree(void *ptr); // Memory release (external call)
void *mymalloc(uint32_t size); // Memory allocation (external call)
void *myrealloc(void *ptr, uint32_t size); // Reallocating memory (external call)
#ifdef __cplusplus
}
#endif
#endif /*__ brtc_H */
/**
* @}
*/
/**
* @}
*/
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,135 @@
/**
******************************************************************************
* @file relay.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the codes of relay control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "relay.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//Relay port definitions
/* Charge Relay Port/Pin definition */
#define CHG_RLY_PORT (PortC)
#define CHG_RLY_PIN (Pin09)
/* Discharge Relay Port/Pin definition */
#define DSG_RLY_PORT (PortD)
#define DSG_RLY_PIN (Pin15)
/* Pre-Charge Relay Port/Pin definition */
#define PCHG_RLY_PORT (PortD)
#define PCHG_RLY_PIN (Pin13)
/* Charge Relay Status Port/Pin definition */
#define CHG_RLY_STS_PORT (PortC)
#define CHG_RLY_STS_PIN (Pin08)
/* Discharge Relay Status Port/Pin definition */
#define DSG_RLY_STS_PORT (PortD)
#define DSG_RLY_STS_PIN (Pin14)
/* Discharge Relay Status Port/Pin definition */
#define PCHG_RLY_STS_PORT (PortD)
#define PCHG_RLY_STS_PIN (Pin12)
// Relay port definitions
#define CHG_RLY_OFF PORT_ResetBits(CHG_RLY_PORT , CHG_RLY_PIN );
#define CHG_RLY_ON PORT_SetBits (CHG_RLY_PORT , CHG_RLY_PIN );
#define DSG_RLY_OFF PORT_ResetBits(DSG_RLY_PORT , DSG_RLY_PIN );
#define DSG_RLY_ON PORT_SetBits (DSG_RLY_PORT , DSG_RLY_PIN );
#define PRE_CHG_RLY_ON PORT_ResetBits(PCHG_RLY_PORT, PCHG_RLY_PIN);
#define PRE_CHG_RLY_OFF PORT_SetBits (PCHG_RLY_PORT, PCHG_RLY_PIN);
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
// Relay IO Initialize
void Relay_Init(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enPinOType = Pin_OType_Od;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* Relay Control Port/Pin initialization */
PORT_Init(CHG_RLY_PORT , CHG_RLY_PIN , &stcPortInit);
PORT_Init(DSG_RLY_PORT , DSG_RLY_PIN , &stcPortInit);
PORT_Init(PCHG_RLY_PORT, PCHG_RLY_PIN, &stcPortInit);
CHG_RLY_OFF;
DSG_RLY_OFF;
PRE_CHG_RLY_OFF;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_In;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* Relay Status Port/Pin initialization */
PORT_Init(CHG_RLY_STS_PORT , CHG_RLY_STS_PIN , &stcPortInit);
PORT_Init(DSG_RLY_STS_PORT , DSG_RLY_STS_PIN , &stcPortInit);
PORT_Init(PCHG_RLY_STS_PORT, PCHG_RLY_STS_PIN, &stcPortInit);
}
void Relay_On(uint8_t id)
{
switch (id) {
case '0': DSG_RLY_ON; break;
case '1': CHG_RLY_ON; break;
case '2': PRE_CHG_RLY_ON; break;
}
}
void Relay_Off(uint8_t id)
{
switch (id) {
case '0': DSG_RLY_OFF; break;
case '1': CHG_RLY_OFF; break;
case '2': PRE_CHG_RLY_OFF; break;
}
}
uint8_t Relay_Status(uint8_t id)
{
uint8_t result = 0;
switch (id) {
case 0: result = PORT_GetBit(DSG_RLY_STS_PORT , DSG_RLY_STS_PIN ); break;
case 1: result = PORT_GetBit(CHG_RLY_STS_PORT , CHG_RLY_STS_PIN ); break;
case 2: result = PORT_GetBit(PCHG_RLY_STS_PORT, PCHG_RLY_STS_PIN); break;
}
return result;
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,45 @@
/**
******************************************************************************
* @file relay.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of relay control 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _RELAY_H
#define _RELAY_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void Relay_Init(void); // Initialize
void Relay_DeInit(void); // DeInitialize
void Relay_On(uint8_t id);
void Relay_Off(uint8_t id);
uint8_t Relay_Status(uint8_t id);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,367 @@
/**
******************************************************************************
* @file rtc_io.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the code of the realtime clock 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
//////////////////////////////////////////////////////////////////////////
//// DS1302.C ////
//// Driver for Real Time Clock ////
//// ////
//// rtc_init() Call after power up////
//// ////
//// rtc_set_datetime(day,mth,year,dow,hour,min) Set the date/time ////
//// ////
//// rtc_get_date(day,mth,year,dow) Get the date ////
//// ////
//// rtc_get_time(hr,min,sec) Get the time ////
//// ////
//// rtc_write_nvr(address,data) Write to NVR ////
//// ////
//// data = rtc_read_nvr(address) Read from NVR ////
//// ////
//////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
//////////////////////////////////////////////////////////////////////////
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "rtc_io.h"
#include "delay.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* RTC IO Port/Pin definition */
#define RTC_IO_CLK_PORT (PortD)
#define RTC_IO_CLK_PIN (Pin11)
#define RTC_IO_DAT_PORT (PortD)
#define RTC_IO_DAT_PIN (Pin10)
#define RTC_IO_RST_PORT (PortD)
#define RTC_IO_RST_PIN (Pin09)
// --------------------------------------------------------------------------------
// RTC-Bus-Line
// --------------------------------------------------------------------------------
#define RTC_CLK_LOW PORT_ResetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN) // rtc data line Low-Level
#define RTC_CLK_HIGH PORT_SetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN) // rtc data line High-Level
#define RTC_DAT_LOW PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line Low-Level
#define RTC_DAT_HIGH PORT_SetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line High-Level
#define RTC_DAT_IN PORT_GetBit(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN) // rtc data line read
#define RTC_RST_LOW PORT_ResetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN) // rtc data line Low-Level
#define RTC_RST_HIGH PORT_SetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN) // rtc data line High-Level
#define CLK_DIV 10
#define Tdc 200 / CLK_DIV // Min.
#define Tcdh 280 / CLK_DIV // Min.
#define Tcdd 800 / CLK_DIV // Max.
#define Tcl 1000 / CLK_DIV // Min.
#define Tch 1000 / CLK_DIV // Min.
#define Tcc 4000 / CLK_DIV // Min.
#define Tcch 240 / CLK_DIV // Min.
#define Tcwh 4000 / CLK_DIV // Min.
#define Tcdz 280 / CLK_DIV // Max.
#define Tccz 280 / CLK_DIV // Max.
#define RD_ADDR_RTC_YEAR 0x8D
#define RD_ADDR_RTC_MONTH 0x89
#define RD_ADDR_RTC_DATE 0x87
#define RD_ADDR_RTC_WDAY 0x8B
#define RD_ADDR_RTC_HOUR 0x85
#define RD_ADDR_RTC_MIN 0x83
#define RD_ADDR_RTC_SEC 0x81
#define WR_ADDR_RTC_YEAR 0x8C
#define WR_ADDR_RTC_MONTH 0x88
#define WR_ADDR_RTC_DATE 0x86
#define WR_ADDR_RTC_WDAY 0x8A
#define WR_ADDR_RTC_HOUR 0x84
#define WR_ADDR_RTC_MIN 0x82
#define WR_ADDR_RTC_SEC 0x80
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private prototype functions -----------------------------------------------*/
// send 'databyte' to 'port'
void outp(uint8_t HighLow);
// read byte from 'port'
uint8_t inp(void);
// 1-Wire Timing Generation
// Pause for exactly 'tick' number of ticks = 0.25us
void tickDelay(uint16_t tick); // Implementation is platform specific
//-----------------------------------------------------------------------------
// Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0).
//
/* Private functions ---------------------------------------------------------*/
void tickDelay(uint16_t tick)
{
delay_us(tick);
}
void RTC_IO_Config(void)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
/* LED Port/Pin initialization */
PORT_Init(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN, &stcPortInit);
PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit);
PORT_Init(RTC_IO_RST_PORT, RTC_IO_RST_PIN, &stcPortInit);
PORT_ResetBits(RTC_IO_CLK_PORT, RTC_IO_CLK_PIN);
PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN);
PORT_ResetBits(RTC_IO_RST_PORT, RTC_IO_RST_PIN);
}
void rtc_dat_config(uint8_t inout)
{
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
if (inout == 1)
{
// Output
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
PORT_ResetBits(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN);
PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit);
}
else
{
// Input
stcPortInit.enPinMode = Pin_Mode_In;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Disable;
PORT_Init(RTC_IO_DAT_PORT, RTC_IO_DAT_PIN, &stcPortInit);
}
}
void outp(uint8_t HighLow)
{
if (HighLow) RTC_DAT_HIGH;
else RTC_DAT_LOW;
}
uint8_t inp(void)
{
return RTC_DAT_IN;
}
void write_ds1302_byte(uint8_t cmd)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
outp((cmd >> i) & 0x01);
delay_ns(Tcl);
RTC_CLK_HIGH;
delay_ns(Tch);
RTC_CLK_LOW;
}
}
void write_ds1302(uint8_t cmd, uint8_t data)
{
rtc_dat_config(1);
RTC_RST_HIGH;
delay_ns(Tcc);
write_ds1302_byte(cmd);
write_ds1302_byte(data);
RTC_RST_LOW;
delay_ns(Tcwh);
}
uint8_t read_ds1302(uint8_t cmd)
{
uint8_t data = 0;
rtc_dat_config(1);
if (cmd == 0)
cmd = cmd;
RTC_RST_HIGH;
delay_ns(Tcc - Tcl);
write_ds1302_byte(cmd);
rtc_dat_config(0);
for (int i = 0; i < 8; i++)
{
delay_ns(Tcdd);
data |= (inp() << i);
delay_ns(Tcl-Tcdd);
RTC_CLK_HIGH;
delay_ns(Tch);
RTC_CLK_LOW;
}
RTC_RST_LOW;
rtc_dat_config(1);
delay_ns(Tcwh);
return (data);
}
void rtc_init(void)
{
uint8_t x;
RTC_IO_Config();
RTC_RST_HIGH;
delay_ns(Tch);
RTC_CLK_LOW;
write_ds1302(0x8e, 0);
write_ds1302(0x90, 0xa6);
x = read_ds1302(0x81);
if ((x & 0x80) != 0)
write_ds1302(0x80, 0);
}
uint8_t bcd2byte(uint8_t bcd)
{
return ((bcd >> 4) * 10) + (bcd & 0x0F);
}
uint8_t byte2bcd(uint8_t byte)
{
return ((byte / 10) << 4) + (byte % 10);
}
void rtc_set_datetime(uint8_t *DateTime)
{
int i = 0;
write_ds1302(WR_ADDR_RTC_YEAR , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_MONTH, byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_DATE , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_HOUR , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_MIN , byte2bcd(DateTime[i++]));
write_ds1302(WR_ADDR_RTC_SEC , byte2bcd(DateTime[i++]));
}
void rtc_get_datetime(uint8_t *DateTime)
{
int i = 0;
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_YEAR));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_MONTH));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_DATE));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_WDAY));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_HOUR));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_MIN));
DateTime[i++] = bcd2byte(read_ds1302(RD_ADDR_RTC_SEC));
}
uint8_t rtc_get_year(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_YEAR));
}
uint8_t rtc_get_month(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_MONTH));
}
uint8_t rtc_get_date(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_DATE));
}
uint8_t rtc_get_wday(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_WDAY));
}
uint8_t rtc_get_hour(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_HOUR));
}
uint8_t rtc_get_min(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_MIN));
}
uint8_t rtc_get_sec(void)
{
return bcd2byte(read_ds1302(RD_ADDR_RTC_SEC));
}
void rtc_get_date1(uint8_t *day, uint8_t *mth, uint8_t *year, uint8_t *dow)
{
*day = read_ds1302(0x87);
*mth = read_ds1302(0x89);
*year = read_ds1302(0x8d);
*dow = read_ds1302(0x8b);
}
void rtc_get_time(uint8_t *hr, uint8_t *min, uint8_t *sec)
{
*hr = read_ds1302(0x85);
*min = read_ds1302(0x83);
*sec = read_ds1302(0x81);
}
void rtc_write_nvr(uint8_t address, uint8_t data)
{
write_ds1302((address << 1) | 0xc0, data);
}
uint8_t rtc_read_nvr(uint8_t address)
{
return (read_ds1302((address << 1) | 0xc1));
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,55 @@
/**
******************************************************************************
* @file rtc_io.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the realtime clock 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _RTC_IO_H_
#define _RTC_IO_H_
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void rtc_init(void);
void rtc_set_datetime(uint8_t *DateTime);
void rtc_get_datetime(uint8_t *DateTime);
uint8_t rtc_get_year(void);
uint8_t rtc_get_month(void);
uint8_t rtc_get_date(void);
uint8_t rtc_get_wday(void);
uint8_t rtc_get_hour(void);
uint8_t rtc_get_min(void);
uint8_t rtc_get_sec(void);
void rtc_write_nvr(uint8_t address, uint8_t data);
uint8_t rtc_read_nvr(uint8_t address);
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,140 @@
/**
******************************************************************************
* @file spi.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the code of the spi communication.
******************************************************************************
* @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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "spi.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* SPI_SCK Port/Pin definition */
#define SPI_SCK_PORT (PortB)
#define SPI_SCK_PIN (Pin13)
#define SPI_SCK_FUNC (Func_Spi3_Sck)
/* SPI_MOSI Port/Pin definition */
#define SPI_MOSI_PORT (PortB)
#define SPI_MOSI_PIN (Pin15)
#define SPI_MOSI_FUNC (Func_Spi3_Mosi)
/* SPI_MISO Port/Pin definition */
#define SPI_MISO_PORT (PortB)
#define SPI_MISO_PIN (Pin14)
#define SPI_MISO_FUNC (Func_Spi3_Miso)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
//Following is the SPI module initialization code, and configured to master mode
//SPI port initialization
//Needle is SPI2 initialization
void Spi_Config(void)
{
stc_spi_init_t stcSpiInit;
stc_port_init_t stcPortInit;
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
stcPortInit.enExInt = Disable;
stcPortInit.enPullUp = Enable;
/* SPI Port/Pin initialization */
PORT_Init(SPI_MISO_PORT, SPI_MISO_PIN, &stcPortInit);
stcPortInit.enPinMode = Pin_Mode_In;
PORT_Init(SPI_MOSI_PORT, SPI_MOSI_PIN, &stcPortInit);
/* configuration structure initialization */
MEM_ZERO_STRUCT(stcSpiInit);
/* Configuration peripheral clock */
PWC_Fcg1PeriphClockCmd(SPI_UNIT_CLOCK, Enable);
/* Configuration SPI pin */
PORT_SetFunc(SPI_SCK_PORT, SPI_SCK_PIN, SPI_SCK_FUNC, Disable);
PORT_SetFunc(SPI_MOSI_PORT, SPI_MOSI_PIN, SPI_MOSI_FUNC, Disable);
PORT_SetFunc(SPI_MISO_PORT, SPI_MISO_PIN, SPI_MISO_FUNC, Disable);
/* Configuration SPI structure */
stcSpiInit.enClkDiv = SpiClkDiv2;
stcSpiInit.enFrameNumber = SpiFrameNumber1;
stcSpiInit.enDataLength = SpiDataLengthBit8;
stcSpiInit.enFirstBitPosition = SpiFirstBitPositionMSB;
stcSpiInit.enSckPolarity = SpiSckIdleLevelLow;
stcSpiInit.enSckPhase = SpiSckOddSampleEvenChange;
stcSpiInit.enReadBufferObject = SpiReadReceiverBuffer;
stcSpiInit.enWorkMode = SpiWorkMode3Line;
stcSpiInit.enTransMode = SpiTransFullDuplex;
stcSpiInit.enCommAutoSuspendEn = Disable;
stcSpiInit.enModeFaultErrorDetectEn = Disable;
stcSpiInit.enParitySelfDetectEn = Disable;
stcSpiInit.enParityEn = Disable;
stcSpiInit.enParity = SpiParityEven;
stcSpiInit.enMasterSlaveMode = SpiModeMaster;
stcSpiInit.stcDelayConfig.enSsSetupDelayOption = SpiSsSetupDelayCustomValue;
stcSpiInit.stcDelayConfig.enSsSetupDelayTime = SpiSsSetupDelaySck1;
stcSpiInit.stcDelayConfig.enSsHoldDelayOption = SpiSsHoldDelayCustomValue;
stcSpiInit.stcDelayConfig.enSsHoldDelayTime = SpiSsHoldDelaySck1;
stcSpiInit.stcDelayConfig.enSsIntervalTimeOption = SpiSsIntervalCustomValue;
stcSpiInit.stcDelayConfig.enSsIntervalTime = SpiSsIntervalSck6PlusPck2;
SPI_Init(SPI_UNIT, &stcSpiInit);
SPI_Cmd(SPI_UNIT, Enable);
}
/**
*******************************************************************************
** \brief SPI flash write byte function
**
** \param [in] u8Data SPI write data to flash
**
** \retval uint8_t SPI receive data from flash
**
******************************************************************************/
uint8_t SpiFlash_WriteReadByte(uint8_t u8Data)
{
uint8_t u8Byte = 0;
/* Wait tx buffer empty */
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSendBufferEmpty))
{
}
/* Send data */
SPI_SendData8(SPI_UNIT, u8Data);
/* Wait rx buffer full */
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagReceiveBufferFull))
{
}
/* Receive data */
u8Byte = SPI_ReceiveData8(SPI_UNIT);
return u8Byte;
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,68 @@
/**
******************************************************************************
* @file spi.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the spi communication.
******************************************************************************
* @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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_H
#define __SPI_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
/* Exported types ------------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
/* SPI_NSS Port/Pin definition */
#define SPI_NSS_PORT (PortB)
#define SPI_NSS_PIN (Pin12)
#define SPI_NSS_HIGH() (PORT_SetBits(SPI_NSS_PORT, SPI_NSS_PIN))
#define SPI_NSS_LOW() (PORT_ResetBits(SPI_NSS_PORT, SPI_NSS_PIN))
/* SPI unit and clock definition */
#define SPI_UNIT (M4_SPI3)
#define SPI_UNIT_CLOCK (PWC_FCG1_PERIPH_SPI3)
/* FLASH parameters */
#define FLASH_PAGE_SIZE (0x100u)
#define FLASH_SECTOR_SIZE (0x1000u)
#define FLASH_MAX_ADDR (0x800000ul)
#define FLASH_DUMMY_BYTE_VALUE (0xffu)
#define FLASH_BUSY_BIT_MASK (0x01u)
/* FLASH instruction */
#define FLASH_INSTR_WRITE_ENABLE (0x06u)
#define FLASH_INSTR_PAGE_PROGRAM (0x02u)
#define FLASH_INSTR_STANDARD_READ (0x03u)
#define FLASH_INSTR_ERASE_4KB_SECTOR (0x20u)
#define FLASH_INSTR_READ_SR1 (0x05u)
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void Spi_Config(void);
uint8_t SpiFlash_WriteReadByte(uint8_t u8Data); //SPI bus read/write bytes
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,341 @@
/**
******************************************************************************
* @file usart.c
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the codes of the usart comm. 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
#include <includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#ifdef CONSOLE_DEBUG
/* USART channel definition */
#define DEBUG_CH (M4_USART1)
/* USART baudrate definition */
#define DEBUG_BAUDRATE (115200ul)
/* USART RX Port/Pin definition */
#define DEBUG_RX_PORT (PortA)
#define DEBUG_RX_PIN (Pin10)
#define DEBUG_RX_FUNC (Func_Usart1_Rx)
/* USART TX Port/Pin definition */
#define DEBUG_TX_PORT (PortA)
#define DEBUG_TX_PIN (Pin09)
#define DEBUG_TX_FUNC (Func_Usart1_Tx)
/* USART interrupt number */
#define DEBUG_RI_NUM (INT_USART1_RI)
#define DEBUG_EI_NUM (INT_USART1_EI)
#define DEBUG_TI_NUM (INT_USART1_TI)
#define DEBUG_TCI_NUM (INT_USART1_TCI)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void debug_port_init(void);
void DebugRxIrqCallback(void); //Serial port 1 interrupt service routine
void DebugTxIrqCallback(void); //Serial port 1 interrupt service routine
void DebugErrIrqCallback(void);
void DebugTxCmpltIrqCallback(void);
#endif /* CONSOLE_DEBUG */
/* Private functions ---------------------------------------------------------*/
/**
*******************************************************************************
** \brief Re-target fputc function.
**
** \param [in] ch
** \param [in] f
**
** \retval int32_t
**
******************************************************************************/
int32_t fputc(int32_t ch, FILE *f)
{
(void)f; /* Prevent unused argument compilation warning */
#ifdef CONSOLE_DEBUG
Debug_PutChar(ch);
#endif // #ifdef CONSOLE_DEBUG
return ch;
}
#ifdef CONSOLE_DEBUG
UART1_Info Uart1;
//Initializes IO serial port 1
//Bound: baud rate
void debug_usart_init(void)
{
en_result_t enRet = Ok;
stc_irq_regi_conf_t stcIrqRegiCfg;
const stc_usart_uart_init_t stcInitCfg = {
UsartIntClkCkNoOutput,
UsartClkDiv_1,
UsartDataBits8,
UsartDataLsbFirst,
UsartOneStopBit,
UsartParityNone,
UsartSampleBit8,
UsartStartBitFallEdge,
UsartRtsEnable,
};
debug_port_init();
/* Initialize UART */
enRet = USART_UART_Init(DEBUG_CH, &stcInitCfg);
if (enRet != Ok)
{
while (1)
{
}
}
/* Set baudrate */
enRet = USART_SetBaudrate(DEBUG_CH, DEBUG_BAUDRATE);
if (enRet != Ok)
{
while (1)
{
}
}
/* Set USART RX IRQ */
stcIrqRegiCfg.enIRQn = Int000_IRQn;
stcIrqRegiCfg.pfnCallback = &DebugRxIrqCallback;
stcIrqRegiCfg.enIntSrc = DEBUG_RI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
/* Set USART RX error IRQ */
stcIrqRegiCfg.enIRQn = Int001_IRQn;
stcIrqRegiCfg.pfnCallback = &DebugErrIrqCallback;
stcIrqRegiCfg.enIntSrc = DEBUG_EI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
/* Set USART TX IRQ */
stcIrqRegiCfg.enIRQn = Int002_IRQn;
stcIrqRegiCfg.pfnCallback = &DebugTxIrqCallback;
stcIrqRegiCfg.enIntSrc = DEBUG_TI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
/* Set USART TX complete IRQ */
stcIrqRegiCfg.enIRQn = Int003_IRQn;
stcIrqRegiCfg.pfnCallback = &DebugTxCmpltIrqCallback;
stcIrqRegiCfg.enIntSrc = DEBUG_TCI_NUM;
enIrqRegistration(&stcIrqRegiCfg);
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
/*Enable RX && RX interupt function*/
USART_FuncCmd(DEBUG_CH, UsartRx, Enable);
// USART_FuncCmd(DEBUG_CH, UsartTx, Enable);
USART_FuncCmd(DEBUG_CH, UsartRxInt, Enable);
// USART_FuncCmd(DEBUG_CH, UsartTxAndTxEmptyInt, Enable);
}
void debug_port_init(void)
{
uint32_t u32Fcg1Periph = PWC_FCG1_PERIPH_USART1 | PWC_FCG1_PERIPH_USART2 | \
PWC_FCG1_PERIPH_USART3 | PWC_FCG1_PERIPH_USART4;
/* Enable peripheral clock */
PWC_Fcg1PeriphClockCmd(u32Fcg1Periph, Enable);
/* Initialize USART IO */
PORT_SetFunc(DEBUG_RX_PORT, DEBUG_RX_PIN, DEBUG_RX_FUNC, Disable);
PORT_SetFunc(DEBUG_TX_PORT, DEBUG_TX_PIN, DEBUG_TX_FUNC, Disable);
}
/**
*******************************************************************************
** \brief Debug RX irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
void DebugRxIrqCallback(void) //Serial port 1 interrupt service routine
{
uint8_t rx_data;
if (Set == USART_GetStatus(DEBUG_CH, UsartRxNoEmpty))
{
rx_data = USART_RecData(DEBUG_CH) & 0xFF; /* Read one byte from the receive data register. */
Uart1.RxBuf[Uart1.RxInPos++] = rx_data;
Uart1.RxInPos %= UART1_RX_BUFFER_SIZE;
if (Uart1.RxInPos == Uart1.RxOutPos)
{
Uart1.RxOutPos++;
Uart1.RxOutPos %= UART1_RX_BUFFER_SIZE;
}
}
NVIC_ClearPendingIRQ(Int000_IRQn);
}
/**
*******************************************************************************
** \brief Debug RX error irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void DebugErrIrqCallback(void)
{
if (Set == USART_GetStatus(DEBUG_CH, UsartFrameErr))
{
USART_ClearStatus(DEBUG_CH, UsartFrameErr);
}
if (Set == USART_GetStatus(DEBUG_CH, UsartParityErr))
{
USART_ClearStatus(DEBUG_CH, UsartParityErr);
}
if (Set == USART_GetStatus(DEBUG_CH, UsartOverrunErr))
{
USART_ClearStatus(DEBUG_CH, UsartOverrunErr);
}
NVIC_ClearPendingIRQ(Int001_IRQn);
}
void DebugTxIrqCallback(void) //Serial port 1 interrupt service routine
{
if (Set == USART_GetStatus(DEBUG_CH, UsartTxEmpty))
{
/* Write one byte to the transmit data register */
USART_SendData(DEBUG_CH, Uart1.TxBuf[Uart1.TxOutPos++]);
Uart1.TxOutPos %= UART1_TX_BUFFER_SIZE;
if (Uart1.TxOutPos == Uart1.TxInPos)
{
/* Disable the USART1 Transmit interrupt */
USART_FuncCmd(DEBUG_CH, UsartTxEmptyInt, Disable);
USART_FuncCmd(DEBUG_CH, UsartTxCmpltInt, Enable);
}
}
NVIC_ClearPendingIRQ(Int002_IRQn);
}
/**
*******************************************************************************
** \brief USART TX complete irq callback function.
**
** \param [in] None
**
** \retval None
**
******************************************************************************/
static void DebugTxCmpltIrqCallback(void)
{
USART_FuncCmd(DEBUG_CH, UsartTxCmpltInt, Disable);
USART_FuncCmd(DEBUG_CH, UsartTx, Disable);
NVIC_ClearPendingIRQ(Int003_IRQn);
}
/*******************************************************************************
* Function Name : void UART1_PutChar(char data)
* Description : Send 1 byte via UART1
* Parameters : ASCII code
* Return : None
*******************************************************************************/
void Debug_PutChar(const uint8_t ascii)
{
while (((Uart1.TxInPos + 1)% UART1_TX_BUFFER_SIZE) == (Uart1.TxOutPos % UART1_TX_BUFFER_SIZE))
USART_FuncCmd(DEBUG_CH, UsartTxAndTxEmptyInt, Enable);
Uart1.TxBuf[Uart1.TxInPos++] = ascii;
Uart1.TxInPos %= UART1_TX_BUFFER_SIZE;
USART_FuncCmd(DEBUG_CH, UsartTxAndTxEmptyInt, Enable);
}
/*******************************************************************************
* Function Name : uint8_t UART1_GetChar(char *data)
* Description : Send 1 byte data to UART1 transmit buffer
* Parameters : none
* Return : Transmission result (0: buffer empty, 1: buffer has data)
*******************************************************************************/
int Debug_GetChar(uint8_t *data)
{
if (Uart1.RxInPos != Uart1.RxOutPos)
{
data[0] = Uart1.RxBuf[Uart1.RxOutPos];
Uart1.RxOutPos++;
Uart1.RxOutPos %= UART1_RX_BUFFER_SIZE;
return 1;
}
else
return 0;
}
/*******************************************************************************
* Function Name : uint8_t UART1_GetChar(char *data)
* Description : Send 1 byte data to UART1 transmit buffer
* Parameters : none
* Return : Transmission result (0: buffer empty, 1: buffer has data)
*******************************************************************************/
uint8_t UART1_GC(void)
{
uint8_t result = 0;
if (Uart1.RxInPos != Uart1.RxOutPos)
{
result = Uart1.RxBuf[Uart1.RxOutPos];
Uart1.RxOutPos++;
Uart1.RxOutPos %= UART1_RX_BUFFER_SIZE;
}
return result;
}
#endif // #ifdef CONSOLE_DEBUG
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,60 @@
/**
******************************************************************************
* @file usart.h
* @author AMG Energy Solution Team
* @version V1.0.0
* @date 07-Feb-2022
* @brief This file provides all the headers of the usart comm. 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>&copy; COPYRIGHT 2022 AMG</center></h2>
******************************************************************************
*/
/** @addtogroup mBMS2
* @{
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H
#define __USART_H
/* Includes ------------------------------------------------------------------*/
#include "hc32_ddl.h"
#ifdef CONSOLE_DEBUG
/* Defines -------------------------------------------------------------------*/
#define UART1_TX_BUFFER_SIZE 1024
#define UART1_RX_BUFFER_SIZE 128
/* Type declarations ---------------------------------------------------------*/
typedef struct{
uint16_t RxInPos, RxOutPos;
uint16_t TxInPos, TxOutPos;
uint8_t RxBuf[UART1_RX_BUFFER_SIZE];
uint8_t TxBuf[UART1_TX_BUFFER_SIZE];
} UART1_Info;
void debug_usart_init(void);
//void uart1_init(uint32_t bound);
int Debug_GetChar(uint8_t *data);
void Debug_PutChar(const uint8_t ascii);
//void UART1_PutStr(uint8_t *str, uint16_t len);
//void UART1_printf(const char *fmt,...);
uint8_t UART1_GC(void);
#endif /* CONSOLE_DEBUG */
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,349 @@
/**
******************************************************************************
* File Name : w25qxx.c
* Description : This file provides code for the configuration
* of w25qxx configuration.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stdio.h"
#include "spi.h"
#include "w25qxx.h"
#include "delay.h"
#include "usart.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint16_t W25QXX_TYPE = W25Q128; // The default is W25Q128
uint8_t W25QXX_BUFFER[4096];
/* Private function prototypes -----------------------------------------------*/
en_result_t SpiFlash_WaitForWriteEnd(void);
/* Private functions ---------------------------------------------------------*/
// 4Kbytes to a Sector
// 16 slices for 1 Block
// W25Q40 : Capacity of 512K bytes, and a total of 16 Block, 128 Sector
// W25Q128: Capacity of 16M bytes, and a total of 128 Block, 4096 Sector
//Initializes IO port SPI FLASH
void W25QXX_Init(void)
{
stc_port_init_t stcPortInit;
/* configure structure initialization */
MEM_ZERO_STRUCT(stcPortInit);
stcPortInit.enPinMode = Pin_Mode_Out;
PORT_Init(SPI_NSS_PORT, SPI_NSS_PIN, &stcPortInit);
SPI_NSS_HIGH();
Spi_Config();
W25QXX_TYPE = W25QXX_ReadID(); // Read FLASH ID.
}
// The status register read W25QXX
// BIT7 6 5 4 3 2 1 0
// SPR RV TB BP2 BP1 BP0 WEL BUSY
// SPR:Default 0, the State Register protection, used with WP
// TB,BP2,BP1,BP0:FLASH write-protect setting
// WEL: write lock
// BUSY: busy flag bits (1, busy; 0, idle)
// Default:0x00
uint8_t W25QXX_ReadSR(void)
{
uint8_t byte = 0;
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_ReadStatusReg); // Sends a read status register command
byte = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE); // Read a byte
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSpiIdle));
SPI_NSS_HIGH();
return byte;
}
// Write W25QXX status register
// Only the SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)You can write!!!
void W25QXX_Write_SR(uint8_t sr)
{
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_WriteStatusReg); // Sending of taking the State register command
SpiFlash_WriteReadByte(sr); // Writes a byte
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSpiIdle));
SPI_NSS_HIGH();
W25QXX_Wait_Busy(); //Waiting to be written to the end
}
//W25QXX write enable
//WEL is set
void W25QXX_Write_Enable(void)
{
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_WriteEnable); // Send written
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSpiIdle));
SPI_NSS_HIGH(); // Cancel selected
}
//W25QXX write protect
//WEL reset
void W25QXX_Write_Disable(void)
{
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_WriteDisable); // Send written
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSpiIdle));
SPI_NSS_HIGH(); // Cancel selected
}
//Read the chip ID
//Return values are as follows:
//0XEF13,Chip and the model is W25Q80
//0XEF14,Chip and the model is W25Q16
//0XEF15,Chip and the model is W25Q32
//0XEF16,Chip and the model is W25Q64
//0XEF17,Chip and the model is W25Q128
uint16_t W25QXX_ReadID(void)
{
uint16_t Temp = 0;
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(0x90);//Send the read ID command
SpiFlash_WriteReadByte(0x00);
SpiFlash_WriteReadByte(0x00);
SpiFlash_WriteReadByte(0x00);
Temp|=SpiFlash_WriteReadByte(0xFF)<<8;
Temp|=SpiFlash_WriteReadByte(0xFF);
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSpiIdle))
{
}
SPI_NSS_HIGH();
return Temp;
}
//Read SPI FLASH
//Starting at the specified address reads the specified length of data
//pBuffer:The data store
//ReadAddr:Read start address(24bit)
//NumByteToRead:Number of bytes to read(Max 65535)
void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)
{
uint16_t i;
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_ReadData); //Send read commands
SpiFlash_WriteReadByte((uint8_t)((ReadAddr)>>16)); //Send 24bit
SpiFlash_WriteReadByte((uint8_t)((ReadAddr)>>8));
SpiFlash_WriteReadByte((uint8_t)ReadAddr);
for(i=0;i<NumByteToRead;i++)
{
pBuffer[i]=SpiFlash_WriteReadByte(0XFF); //Cycle readings
}
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSpiIdle))
{
}
SPI_NSS_HIGH();
}
//SPI in one page (0~65535) written in less than 256 bytes of data
//Start write up to 256 bytes of data at the specified address
//pBuffer:The data store
//WriteAddr:Start writing the address (24bit)
//NumByteToWrite:Number of bytes to be written (up to 256), this number should not exceed the number of remaining bytes of the page!!!
void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t i;
W25QXX_Write_Enable(); //SET WEL
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_PageProgram); //Send a written page command
SpiFlash_WriteReadByte((uint8_t)((WriteAddr)>>16)); //Send 24bit
SpiFlash_WriteReadByte((uint8_t)((WriteAddr)>>8));
SpiFlash_WriteReadByte((uint8_t)WriteAddr);
for(i=0;i<NumByteToWrite;i++)SpiFlash_WriteReadByte(pBuffer[i]);//Circulating wrote
SPI_NSS_HIGH(); //Cancel selected
W25QXX_Wait_Busy(); //Waiting to be written to the end
}
//No test write SPI FLASH
//Must ensure that writes all the data in the range of addresses to 0XFF, or write data in non-0XFF will fail!
//With automatic feed function
//Starting at the specified address to write to the specified length of data, but make sure that the address is out of range!
//pBuffer:The data store
//WriteAddr:Start write address(24bit)
//NumByteToWrite:Number of bytes to write(Max 65535)
//CHECK OK
void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t pageremain;
pageremain=256-WriteAddr%256; //Number of bytes remaining single page
if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//Less than 256 bytes
while(1)
{
W25QXX_Write_Page(pBuffer,WriteAddr,pageremain);
if(NumByteToWrite==pageremain)break;//Write end
else //NumByteToWrite>pageremain
{
pBuffer+=pageremain;
WriteAddr+=pageremain;
NumByteToWrite-=pageremain; //Minus has written a number of bytes
if(NumByteToWrite>256)pageremain=256; //Once you can write to 256 bytes
else pageremain=NumByteToWrite; //Less than 256 bytes
}
};
}
//Write SPI FLASH
//Starting at the specified address to write to the specified length of data
//This function erases the operation!
//pBuffer:The data store
//WriteAddr:Start write address(24bit)
//NumByteToWrite:Number of bytes to write(Max 65535)
void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint32_t secpos;
uint16_t secoff;
uint16_t secremain;
uint16_t i;
uint8_t * W25QXX_BUF;
W25QXX_BUF=W25QXX_BUFFER;
secpos=WriteAddr/4096;//Sector address
secoff=WriteAddr%4096;//In the sector of migration
secremain=4096-secoff;//Slice the remaining space
//printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//Testing
if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//Not greater than 4,096 bytes
while(1)
{
WDT_RefreshCounter();
W25QXX_Read(W25QXX_BUF,secpos*4096,4096);//Read out the contents of an entire sector
for(i=0;i<secremain;i++)//Calibration data
{
if(W25QXX_BUF[secoff+i]!=0XFF)break;//Need to erase
}
if(i<secremain)//Need to erase
{
W25QXX_Erase_Sector(secpos);//Erase this sector
for(i=0;i<secremain;i++) //Copy
{
W25QXX_BUF[i+secoff]=pBuffer[i];
}
W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);//Write the whole sector
}else W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain);//Writing has been erased, write directly to the sector the remaining interval.
if(NumByteToWrite==secremain)break;//Write end
else//Write over
{
secpos++;//Increased sector address 1
secoff=0;//Offset is 0
pBuffer+=secremain; //Offset pointer
WriteAddr+=secremain;//Write the address offset
NumByteToWrite-=secremain; //Diminishing bytes
if(NumByteToWrite>4096)secremain=4096; //Next sector but still not finished
else secremain=NumByteToWrite; //Next slice to finish
}
};
}
//Erase the entire chip
//Wait for long...
void W25QXX_Erase_Chip(void)
{
W25QXX_Write_Enable(); //SET WEL
W25QXX_Wait_Busy();
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_ChipErase); //Send erase command
SPI_NSS_HIGH(); //Cancel selected
W25QXX_Wait_Busy(); //Wait for end of the chip erase
}
//Erase one sector
//Dst_Addr:Sector address set according to actual capacity
//Erasing a mountain at least time: 150ms
void W25QXX_Erase_Sector(uint32_t Dst_Addr)
{
//Monitor Falsh erasure, testing
// printf("fe:%x\r\n",Dst_Addr);
Dst_Addr*=4096;
W25QXX_Write_Enable(); //SET WEL
W25QXX_Wait_Busy();
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_SectorErase); //Send sector erase command
SpiFlash_WriteReadByte((uint8_t)((Dst_Addr)>>16)); //Send 24bit
SpiFlash_WriteReadByte((uint8_t)((Dst_Addr)>>8));
SpiFlash_WriteReadByte((uint8_t)Dst_Addr);
SPI_NSS_HIGH(); //Cancel selected
W25QXX_Wait_Busy(); //Wait for the erase to complete
}
//Waiting for a free
void W25QXX_Wait_Busy(void)
{
while((W25QXX_ReadSR() & 0x01) == 0x01); // Wait for the BUSY emptying
}
//Enter the power off mode
void W25QXX_PowerDown(void)
{
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_PowerDown); //Send the power command
SPI_NSS_HIGH(); //Cancel selected
delay_us(3); //Wait for the TPD
}
//Wake up
void W25QXX_WAKEUP(void)
{
SPI_NSS_LOW(); // Enabling devices
SpiFlash_WriteReadByte(W25X_ReleasePowerDown); // send W25X_PowerDown command 0xAB
SPI_NSS_HIGH(); //Cancel selected
delay_us(3); //Waiting for TRES1
}
/**
*******************************************************************************
** \brief SPI flash wait for write operation end function
**
** \param [in] None
**
** \retval Ok Flash internal operation finish
** \retval ErrorTimeout Flash internal operation timeout
**
******************************************************************************/
en_result_t SpiFlash_WaitForWriteEnd(void)
{
en_result_t enRet = Ok;
uint8_t u8Status = 0u;
uint32_t u32Timeout;
stc_clk_freq_t stcClkFreq;
CLK_GetClockFreq(&stcClkFreq);
u32Timeout = stcClkFreq.sysclkFreq / 1000u;
SPI_NSS_LOW();
SpiFlash_WriteReadByte(FLASH_INSTR_READ_SR1);
do
{
u8Status = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE);
u32Timeout--;
} while ((u32Timeout != 0ul) &&
((u8Status & FLASH_BUSY_BIT_MASK) == FLASH_BUSY_BIT_MASK));
if (FLASH_BUSY_BIT_MASK == u8Status)
{
enRet = ErrorTimeout;
}
while (Reset == SPI_GetFlag(SPI_UNIT, SpiFlagSpiIdle))
{
}
SPI_NSS_HIGH();
return enRet;
}
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/

View File

@@ -0,0 +1,80 @@
#ifndef __W25QXX_H
#define __W25QXX_H
#include "hc32_ddl.h"
//////////////////////////////////////////////////////////////////////////////////
//This program is for educational purposes only, without the author's permission, may not be used for any other purpose
//ALIENTEK STM32F4 Explorer Board
//W25QXX Driver code
//Hot Atomic @ALIENTEK
//Forum: www.openedv.com
//Date modified: 2014/5/6
//Version: V1.0
//All rights reserved pirated reserved.
//Copyright(C) Guangzhou wing electronic technology limited company 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//W25X/Q series chip list
//W25Q80 ID 0XEF13
//W25Q16 ID 0XEF14
//W25Q32 ID 0XEF15
//W25Q64 ID 0XEF16
//W25Q128 ID 0XEF17
#define W25Q40 0XEF12
#define W25Q80 0XEF13
#define W25Q16 0XEF14
#define W25Q32 0XEF15
#define W25Q64 0XEF16
#define W25Q128 0XEF17
#define SPI_FLASH_ADDR (0x00000000)
#define SPI_FLASH_LAST_64K_BLOCK (0x00070000)
#define SPI_FLASH_LAST_32K_BLOCK (0x00078000)
#define SPI_FLASH_LAST_4K_SECTOR (0x0007F000)
#define SPI_FLASH_BLOCK_SIZE (0X10000)
#define SPI_FLASH_SECTOR_SIZE (0X1000)
#define SPI_FLASH_PAGESIZE (0x100) // 256 bytes
#define FLASH_DUMMY_BYTE_VALUE (0xffu)
#define FLASH_BUSY_BIT_MASK (0x01u)
extern uint16_t W25QXX_TYPE; //Define W25QXX chips
//////////////////////////////////////////////////////////////////////////////////
//Instruction list
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_FastReadDual 0x3B
#define W25X_PageProgram 0x02
#define W25X_BlockErase 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_PowerDown 0xB9
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F
void W25QXX_Init(void);
uint16_t W25QXX_ReadID(void); //Read FLASH ID
uint8_t W25QXX_ReadSR(void); //Read status register
void W25QXX_Write_SR(uint8_t sr); //Write status register
void W25QXX_Write_Enable(void); //Write enable
void W25QXX_Write_Disable(void); //Write-protect
void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead); //Read Flash
void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);//Write Flash
void W25QXX_Erase_Chip(void); //All erase
void W25QXX_Erase_Sector(uint32_t Dst_Addr); //Sector erase
void W25QXX_Wait_Busy(void); //Waiting for a free
void W25QXX_PowerDown(void); //Enter the power off mode
void W25QXX_WAKEUP(void); //Wake up
#endif
/*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/