PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_mam.c

260 lines
6.3 KiB
C

/**
* @file fc7xxx_driver_mam.c
* @author Flagchip
* @brief FC7xxx MAM driver source code
* @version 0.1.0
* @date 2023-02-08
*
* @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd.
*
*/
/* ********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024-01-10 Flagchip095 N/A First version for FC7240
******************************************************************************** */
#include "fc7xxx_driver_mam.h"
#include "interrupt_manager.h"
#define MAM0_MIN_ADDR 0x01000000U
#define MAM0_MAX_ADDR 0x4049FFFFU
#define ROM_START_ADDR 0x04800000U
#define ROM_END_ADDR 0x0481FFFFU
#define ROM_BLOCK_SIZE 0x20000U
#define FLASH0_START_ADDR 0x01000000U
#define FLASH0_END_ADDR 0x011FFFFFU
#define FLASH0_BLOCK_SIZE 0x20000U
#define NVR_START_ADDR 0x04400000U
#define NVR_END_ADDR 0x04411FFFU
#define NVR_BLOCK_SIZE 0x20000U
#define NVR_CFG_START_ADDR 0x04420000U
#define NVR_CFG_END_ADDR 0x04431FFFU
#define NVR_CFG_BLOCK_SIZE 0x20000U
#define FLASH1_START_ADDR 0x04000000U
#define FLASH1_END_ADDR 0x0401FFFFU
#define FLASH1_BLOCK_SIZE 0x2000U
#define SRAM_START_ADDR 0x21000000U
#define SRAM_END_ADDR 0x21017FFFU
#define SRAM_BLOCK_SIZE 0x4000U
#define CPU0_DTCM_START_ADDR 0x20000000U
#define CPU0_DTCM_END_ADDR 0x2001FFFFU
#define CPU0_DTCM_BLOCK_SIZE 0x4000U
#define CPU0_ITCM_START_ADDR 0x00000000U
#define CPU0_ITCM_END_ADDR 0x00007FFFU
#define CPU0_ITCM_BLOCK_SIZE 0x4000U
#define AFCB0_START_ADDR 0x40000000U
#define AFCB0_END_ADDR 0x4009FFFFU
#define AFCB0_BLOCK_SIZE 0x1000U
#define AFCB1_START_ADDR 0x40400000U
#define AFCB1_END_ADDR 0x4049FFFFU
#define AFCB1_BLOCK_SIZE 0x1000U
/**
* @brief Get mam information according to the address
*
* @param u32Addr Input address
*/
static MAM_Inf_Type MAM_Get_MAM_Inf(uint32_t u32Addr);
/*************** Local Functions ***************/
static MAM_Inf_Type MAM_Get_MAM_Inf(uint32_t u32Addr)
{
MAM_Inf_Type inf = {.error = 0};
if(MAM0_MIN_ADDR <= u32Addr && u32Addr < MAM0_MAX_ADDR)
{
if(ROM_START_ADDR == u32Addr)
{
inf.block_num = 0;
}
else if(FLASH0_START_ADDR <= u32Addr && u32Addr < FLASH0_END_ADDR)
{
if((u32Addr - FLASH0_START_ADDR)%FLASH0_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - FLASH0_START_ADDR) / FLASH0_BLOCK_SIZE + 1U;
}
else
{
inf.error = 1;
}
}
else if(NVR_START_ADDR <= u32Addr && u32Addr < NVR_END_ADDR)
{
if((u32Addr - NVR_START_ADDR)%NVR_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - NVR_START_ADDR) / NVR_BLOCK_SIZE + 17U;
}
else
{
inf.error = 1;
}
}
else if(NVR_CFG_START_ADDR <= u32Addr && u32Addr < NVR_CFG_END_ADDR)
{
if((u32Addr - NVR_CFG_START_ADDR)%NVR_CFG_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - NVR_CFG_START_ADDR) / NVR_CFG_BLOCK_SIZE + 18U;
}
else
{
inf.error = 1;
}
}
else if(FLASH1_START_ADDR <= u32Addr && u32Addr < FLASH1_END_ADDR)
{
if((u32Addr - FLASH1_START_ADDR)%FLASH1_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - FLASH1_START_ADDR) / FLASH1_BLOCK_SIZE + 19U;
}
else
{
inf.error = 1;
}
}
else if(SRAM_START_ADDR <= u32Addr && u32Addr < SRAM_END_ADDR)
{
if((u32Addr - SRAM_START_ADDR)%SRAM_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - SRAM_START_ADDR) / SRAM_BLOCK_SIZE + 35U;
}
else
{
inf.error = 1;
}
}
else if(CPU0_DTCM_START_ADDR <= u32Addr && u32Addr < CPU0_DTCM_END_ADDR)
{
if((u32Addr - CPU0_DTCM_START_ADDR)%SRAM_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - CPU0_DTCM_START_ADDR) / CPU0_DTCM_BLOCK_SIZE + 43U;
}
else
{
inf.error = 1;
}
}
else if(u32Addr < CPU0_ITCM_END_ADDR)
{
if((u32Addr - CPU0_ITCM_START_ADDR)%CPU0_ITCM_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - CPU0_ITCM_START_ADDR) / CPU0_ITCM_BLOCK_SIZE + 41U;
}
else
{
inf.error = 1;
}
}
else if(AFCB0_START_ADDR <= u32Addr && u32Addr < AFCB0_END_ADDR)
{
if((u32Addr - AFCB0_START_ADDR)%AFCB0_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - AFCB0_START_ADDR) / AFCB0_BLOCK_SIZE + 51U;
}
else
{
inf.error = 1;
}
}
else if(AFCB1_START_ADDR <= u32Addr && u32Addr < AFCB1_END_ADDR)
{
if((u32Addr - AFCB1_START_ADDR)%AFCB1_BLOCK_SIZE == 0U)
{
inf.block_num = (u32Addr - AFCB1_START_ADDR) / AFCB1_BLOCK_SIZE + 211U;
}
else
{
inf.error = 1;
}
}
else
{
inf.error = 1;
}
}
else
{
inf.error = 1;
}
return inf;
}
/***************** Global Functions *******************/
uint8_t MAM_Config(MAM_Master_Type Master, uint32_t u32Addr, uint32_t u32Val)
{
MAM_Inf_Type inf = MAM_Get_MAM_Inf(u32Addr);
uint32_t reg_idx = 0U;
uint32_t bit_idx = 0U;
uint8_t status = 0U;
if(inf.error == 1U)
{
status = 1;
}
else
{
reg_idx = inf.block_num / 8U + 47U*(uint32_t)Master; /* 371 block , 371/8 + 1*/
bit_idx = inf.block_num % 8U;
Mam_HWA_Set_ACR(MAM, reg_idx, u32Val << (bit_idx * 4U));
reg_idx = inf.block_num / 32U + 12U*(uint32_t)Master; /* 371 block , 371/32 + 1*/
bit_idx = inf.block_num % 32U;
Mam_HWA_Set_ACLR(MAM, reg_idx, 1UL << bit_idx);
}
return status;
}
uint8_t MAM_Enable_Wdg(MAM_Master_Type Master,uint32_t u32Addr)
{
uint8_t status = 0U;
uint32_t bit_idx = 0U;
uint32_t regval = 0U;
MAM_Inf_Type inf = MAM_Get_MAM_Inf(u32Addr);
if(Master >= MAM_MASTER_NUM || inf.error == 1U)
{
status = 1;
}
else
{
bit_idx = (uint32_t)Master;
regval = Mam_HWA_Get_Wdgctr(MAM);
regval |= 1UL << bit_idx;
Mam_HWA_Set_Wdgctr(MAM, regval);
}
return status;
}
uint8_t MAM_Disable_Wdg(MAM_Master_Type Master,uint32_t u32Addr)
{
uint8_t status = 0U;
uint32_t regval = 0U;
uint32_t bit_idx = 0U;
MAM_Inf_Type inf = MAM_Get_MAM_Inf(u32Addr);
if(Master >= MAM_MASTER_NUM || inf.error == 1U)
{
status = 1;
}
else
{
bit_idx = (uint32_t)Master;
regval = Mam_HWA_Get_Wdgctr(MAM);
regval &= ~(1U << bit_idx);
Mam_HWA_Set_Wdgctr(MAM, regval);
}
return status;
}