diff --git a/Libraries/PeriphDrivers/Source/AES/aes_me30.c b/Libraries/PeriphDrivers/Source/AES/aes_me30.c new file mode 100644 index 00000000000..63603f4cf83 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/AES/aes_me30.c @@ -0,0 +1,155 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "mxc_device.h" +#include "mxc_errors.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "aes_revb.h" +#include "trng.h" +#include "trng_revb.h" + +/* ************************************************************************* */ +/* Global Control/Configuration functions */ +/* ************************************************************************* */ + +int MXC_AES_Init(void) +{ +#ifndef MSDK_NO_GPIO_CLK_INIT + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_AES); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TRNG); +#endif + + return MXC_AES_RevB_Init((mxc_aes_revb_regs_t *)MXC_AES); +} + +void MXC_AES_EnableInt(uint32_t interrupt) +{ + MXC_AES_RevB_EnableInt((mxc_aes_revb_regs_t *)MXC_AES, interrupt); +} + +void MXC_AES_DisableInt(uint32_t interrupt) +{ + MXC_AES_RevB_DisableInt((mxc_aes_revb_regs_t *)MXC_AES, interrupt); +} + +int MXC_AES_IsBusy(void) +{ + return MXC_AES_RevB_IsBusy((mxc_aes_revb_regs_t *)MXC_AES); +} + +int MXC_AES_Shutdown(void) +{ + int error = MXC_AES_RevB_Shutdown((mxc_aes_revb_regs_t *)MXC_AES); + + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_AES); + + return error; +} + +void MXC_AES_DMACallback(int ch, int error) +{ + MXC_AES_RevB_DMACallback(ch, error); +} + +void MXC_AES_GenerateKey(void) +{ + // Generating a random key is part of the TRNG block. + MXC_TRNG_RevB_GenerateKey((mxc_trng_revb_regs_t *)MXC_TRNG); +} + +void MXC_AES_SetKeySize(mxc_aes_keys_t key) +{ + MXC_AES_RevB_SetKeySize((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_keys_t)key); +} + +mxc_aes_keys_t MXC_AES_GetKeySize(void) +{ + return MXC_AES_RevB_GetKeySize((mxc_aes_revb_regs_t *)MXC_AES); +} + +void MXC_AES_FlushInputFIFO(void) +{ + MXC_AES_RevB_FlushInputFIFO((mxc_aes_revb_regs_t *)MXC_AES); +} + +void MXC_AES_FlushOutputFIFO(void) +{ + MXC_AES_RevB_FlushOutputFIFO((mxc_aes_revb_regs_t *)MXC_AES); +} + +void MXC_AES_Start(void) +{ + MXC_AES_RevB_Start((mxc_aes_revb_regs_t *)MXC_AES); +} + +uint32_t MXC_AES_GetFlags(void) +{ + return MXC_AES_RevB_GetFlags((mxc_aes_revb_regs_t *)MXC_AES); +} + +void MXC_AES_ClearFlags(uint32_t flags) +{ + MXC_AES_RevB_ClearFlags((mxc_aes_revb_regs_t *)MXC_AES, flags); +} + +int MXC_AES_Generic(mxc_aes_req_t *req) +{ + return MXC_AES_RevB_Generic((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req); +} + +int MXC_AES_Encrypt(mxc_aes_req_t *req) +{ + return MXC_AES_RevB_Encrypt((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req); +} + +int MXC_AES_Decrypt(mxc_aes_req_t *req) +{ + return MXC_AES_RevB_Decrypt((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req); +} + +int MXC_AES_TXDMAConfig(void *src_addr, int len) +{ + return MXC_AES_RevB_TXDMAConfig(src_addr, len); +} + +int MXC_AES_RXDMAConfig(void *dest_addr, int len) +{ + return MXC_AES_RevB_RXDMAConfig(dest_addr, len); +} + +int MXC_AES_GenericAsync(mxc_aes_req_t *req, uint8_t enc) +{ + return MXC_AES_RevB_GenericAsync((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req, + enc); +} + +int MXC_AES_EncryptAsync(mxc_aes_req_t *req) +{ + return MXC_AES_RevB_EncryptAsync((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req); +} + +int MXC_AES_DecryptAsync(mxc_aes_req_t *req) +{ + return MXC_AES_RevB_DecryptAsync((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req); +} + +void MXC_AES_SetExtKey(const void *key, mxc_aes_keys_t len) +{ + MXC_AES_RevB_SetExtKey((mxc_aeskeys_revb_regs_t *)MXC_AESKEYS, key, len); +} diff --git a/Libraries/PeriphDrivers/Source/CRC/crc_me30.c b/Libraries/PeriphDrivers/Source/CRC/crc_me30.c new file mode 100644 index 00000000000..cf4819eb767 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/CRC/crc_me30.c @@ -0,0 +1,99 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "mxc_device.h" +#include "mxc_errors.h" +#include "mxc_assert.h" +#include "mxc_sys.h" + +#include "crc.h" +#include "crc_reva.h" + +/* ************************************************************************* */ +/* Global Control/Configuration functions */ +/* ************************************************************************* */ + +int MXC_CRC_Init(void) +{ +#ifndef MSDK_NO_GPIO_CLK_INIT + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_CRC); +#endif + + MXC_CRC_RevA_Init((mxc_crc_reva_regs_t *)MXC_CRC); + + return E_NO_ERROR; +} + +int MXC_CRC_Shutdown(void) +{ + int error = MXC_CRC_RevA_Shutdown((mxc_crc_reva_regs_t *)MXC_CRC); + + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_CRC); + + return error; +} + +void MXC_CRC_Handler(int ch, int error) +{ + MXC_CRC_RevA_Handler(ch, error); +} + +void MXC_CRC_SetDirection(mxc_crc_bitorder_t bitOrder) +{ + MXC_CRC_RevA_SetDirection((mxc_crc_reva_regs_t *)MXC_CRC, (mxc_crc_reva_bitorder_t)bitOrder); +} + +mxc_crc_bitorder_t MXC_CRC_GetDirection(void) +{ + return MXC_CRC_RevA_GetDirection((mxc_crc_reva_regs_t *)MXC_CRC); +} + +void MXC_CRC_SwapDataIn(mxc_crc_bitorder_t bitOrder) +{ + MXC_CRC_RevA_SwapDataIn((mxc_crc_reva_regs_t *)MXC_CRC, (mxc_crc_reva_bitorder_t)bitOrder); +} + +void MXC_CRC_SwapDataOut(mxc_crc_bitorder_t bitOrder) +{ + MXC_CRC_RevA_SwapDataOut((mxc_crc_reva_regs_t *)MXC_CRC, (mxc_crc_reva_bitorder_t)bitOrder); +} + +void MXC_CRC_SetPoly(uint32_t poly) +{ + MXC_CRC_RevA_SetPoly((mxc_crc_reva_regs_t *)MXC_CRC, poly); +} + +uint32_t MXC_CRC_GetPoly(void) +{ + return MXC_CRC_RevA_GetPoly((mxc_crc_reva_regs_t *)MXC_CRC); +} + +uint32_t MXC_CRC_GetResult(void) +{ + return MXC_CRC_RevA_GetResult((mxc_crc_reva_regs_t *)MXC_CRC); +} + +int MXC_CRC_Compute(mxc_crc_req_t *req) +{ + return MXC_CRC_RevA_Compute((mxc_crc_reva_regs_t *)MXC_CRC, (mxc_crc_reva_req_t *)req); +} + +int MXC_CRC_ComputeAsync(mxc_crc_req_t *req) +{ + return MXC_CRC_RevA_ComputeAsync((mxc_crc_reva_regs_t *)MXC_CRC, (mxc_crc_reva_req_t *)req); +} diff --git a/Libraries/PeriphDrivers/Source/DMA/dma_me30.c b/Libraries/PeriphDrivers/Source/DMA/dma_me30.c new file mode 100644 index 00000000000..a0483bd536d --- /dev/null +++ b/Libraries/PeriphDrivers/Source/DMA/dma_me30.c @@ -0,0 +1,161 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/****** Includes *******/ +#include +#include +#include "mxc_device.h" +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "mxc_sys.h" +#include "dma.h" +#include "dma_reva.h" + +/***** Definitions *****/ + +/******* Globals *******/ + +/****** Functions ******/ + +int MXC_DMA_Init(void) +{ +#ifndef MSDK_NO_GPIO_CLK_INIT + if (!MXC_SYS_IsClockEnabled(MXC_SYS_PERIPH_CLOCK_DMA)) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_DMA); + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_DMA); + } +#endif + + return MXC_DMA_RevA_Init((mxc_dma_reva_regs_t *)MXC_DMA); +} + +void MXC_DMA_DeInit(void) +{ + return MXC_DMA_RevA_DeInit((mxc_dma_reva_regs_t *)MXC_DMA); +} + +int MXC_DMA_AcquireChannel(void) +{ + return MXC_DMA_RevA_AcquireChannel((mxc_dma_reva_regs_t *)MXC_DMA); +} + +int MXC_DMA_ReleaseChannel(int ch) +{ + return MXC_DMA_RevA_ReleaseChannel(ch); +} + +int MXC_DMA_ConfigChannel(mxc_dma_config_t config, mxc_dma_srcdst_t srcdst) +{ + return MXC_DMA_RevA_ConfigChannel(config, srcdst); +} + +int MXC_DMA_AdvConfigChannel(mxc_dma_adv_config_t advConfig) +{ + return MXC_DMA_RevA_AdvConfigChannel(advConfig); +} + +int MXC_DMA_SetSrcDst(mxc_dma_srcdst_t srcdst) +{ + return MXC_DMA_RevA_SetSrcDst(srcdst); +} + +int MXC_DMA_GetSrcDst(mxc_dma_srcdst_t *srcdst) +{ + return MXC_DMA_RevA_GetSrcDst(srcdst); +} + +int MXC_DMA_SetSrcReload(mxc_dma_srcdst_t srcdst) +{ + return MXC_DMA_RevA_SetSrcReload(srcdst); +} + +int MXC_DMA_GetSrcReload(mxc_dma_srcdst_t *srcdst) +{ + return MXC_DMA_RevA_GetSrcReload(srcdst); +} + +int MXC_DMA_SetCallback(int ch, void (*callback)(int, int)) +{ + return MXC_DMA_RevA_SetCallback(ch, callback); +} + +int MXC_DMA_SetChannelInterruptEn(int ch, bool chdis, bool ctz) +{ + return MXC_DMA_RevA_SetChannelInterruptEn(ch, chdis, ctz); +} + +int MXC_DMA_ChannelEnableInt(int ch, int flags) +{ + return MXC_DMA_RevA_ChannelEnableInt(ch, flags); +} + +int MXC_DMA_ChannelDisableInt(int ch, int flags) +{ + return MXC_DMA_RevA_ChannelDisableInt(ch, flags); +} + +int MXC_DMA_ChannelGetFlags(int ch) +{ + return MXC_DMA_RevA_ChannelGetFlags(ch); +} + +int MXC_DMA_ChannelClearFlags(int ch, int flags) +{ + return MXC_DMA_RevA_ChannelClearFlags(ch, flags); +} + +int MXC_DMA_EnableInt(int ch) +{ + return MXC_DMA_RevA_EnableInt((mxc_dma_reva_regs_t *)MXC_DMA, ch); +} + +int MXC_DMA_DisableInt(int ch) +{ + return MXC_DMA_RevA_DisableInt((mxc_dma_reva_regs_t *)MXC_DMA, ch); +} + +int MXC_DMA_Start(int ch) +{ + return MXC_DMA_RevA_Start(ch); +} + +int MXC_DMA_Stop(int ch) +{ + return MXC_DMA_RevA_Stop(ch); +} + +mxc_dma_ch_regs_t *MXC_DMA_GetCHRegs(int ch) +{ + return MXC_DMA_RevA_GetCHRegs(ch); +} + +void MXC_DMA_Handler(void) +{ + MXC_DMA_RevA_Handler((mxc_dma_reva_regs_t *)MXC_DMA); +} + +int MXC_DMA_MemCpy(void *dest, void *src, int len, mxc_dma_complete_cb_t callback) +{ + return MXC_DMA_RevA_MemCpy((mxc_dma_reva_regs_t *)MXC_DMA, dest, src, len, callback); +} + +int MXC_DMA_DoTransfer(mxc_dma_config_t config, mxc_dma_srcdst_t firstSrcDst, + mxc_dma_trans_chain_t callback) +{ + return MXC_DMA_RevA_DoTransfer((mxc_dma_reva_regs_t *)MXC_DMA, config, firstSrcDst, callback); +} diff --git a/Libraries/PeriphDrivers/Source/FLC/flc_me30.c b/Libraries/PeriphDrivers/Source/FLC/flc_me30.c new file mode 100644 index 00000000000..961a912434c --- /dev/null +++ b/Libraries/PeriphDrivers/Source/FLC/flc_me30.c @@ -0,0 +1,345 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/* **** Includes **** */ +#include +#include "mxc_device.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "flc.h" +#include "flc_reva.h" +#include "flc_common.h" +#include "mcr_regs.h" // For ECCEN registers. + +//****************************************************************************** +void MXC_FLC_ME17_Flash_Operation(void) +{ + /* + This function should be called after modifying the contents of flash memory. + It flushes the instruction caches and line fill buffer. + + It should be called _afterwards_ because after flash is modified the cache + may contain instructions that may no longer be valid. _Before_ the + flash modifications the ICC may contain relevant cached instructions related to + the incoming flash instructions (especially relevant in the case of external memory), + and these instructions will be valid up until the point that the modifications are made. + + The line fill buffer is a FLC-related buffer that also may no longer be valid. + It's flushed by reading 2 pages of flash. + */ + + /* Flush all instruction caches */ + MXC_GCR->sysctrl |= MXC_F_GCR_SYSCTRL_ICC0_FLUSH; + + /* Wait for flush to complete */ + while (MXC_GCR->sysctrl & MXC_F_GCR_SYSCTRL_ICC0_FLUSH) {} + + // Clear the line fill buffer by reading 2 pages from flash + volatile uint32_t *line_addr; + volatile uint32_t __unused line; // __unused attribute removes warning + line_addr = (uint32_t *)(MXC_FLASH_MEM_BASE); + line = *line_addr; + line_addr = (uint32_t *)(MXC_FLASH_MEM_BASE + MXC_FLASH_PAGE_SIZE); + line = *line_addr; +} + +//****************************************************************************** +int MXC_FLC_ME17_GetByAddress(mxc_flc_regs_t **flc, uint32_t addr) +{ + if ((addr >= MXC_FLASH_MEM_BASE) && (addr < (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE))) { + *flc = MXC_FLC0; + } else if ((addr >= MXC_INFO_MEM_BASE) && (addr < (MXC_INFO_MEM_BASE + MXC_INFO_MEM_SIZE))) { + *flc = MXC_FLC0; + } else { + return E_BAD_PARAM; + } + + return E_NO_ERROR; +} + +//****************************************************************************** +int MXC_FLC_ME17_GetPhysicalAddress(uint32_t addr, uint32_t *result) +{ + if ((addr >= MXC_FLASH_MEM_BASE) && (addr < (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE))) { + *result = addr & (MXC_FLASH_MEM_SIZE - 1); + } else if ((addr >= MXC_INFO_MEM_BASE) && (addr < (MXC_INFO_MEM_BASE + MXC_INFO_MEM_SIZE))) { + *result = (addr & (MXC_INFO_MEM_SIZE - 1)) + MXC_FLASH_MEM_SIZE; + } else { + return E_BAD_PARAM; + } + + return E_NO_ERROR; +} + +//****************************************************************************** +int MXC_FLC_Init(void) +{ + return E_NO_ERROR; +} + +//****************************************************************************** +#if IAR_PRAGMAS +#pragma section = ".flashprog" +#else +__attribute__((section(".flashprog"))) +#endif +int MXC_FLC_Busy(void) +{ + return MXC_FLC_RevA_Busy(); +} + +//****************************************************************************** +#if IAR_PRAGMAS +#pragma section = ".flashprog" +#else +__attribute__((section(".flashprog"))) +#endif +int MXC_FLC_PageErase(uint32_t address) +{ + int err; + uint32_t addr; + mxc_flc_regs_t *flc = NULL; + + // Get FLC Instance + if ((err = MXC_FLC_ME17_GetByAddress(&flc, address)) != E_NO_ERROR) { + return err; + } + + if ((err = MXC_FLC_ME17_GetPhysicalAddress(address, &addr)) < E_NO_ERROR) { + return err; + } + + err = MXC_FLC_RevA_PageErase((mxc_flc_reva_regs_t *)flc, addr); + + // Flush the cache + MXC_FLC_ME17_Flash_Operation(); + + return err; +} + +//****************************************************************************** +#if IAR_PRAGMAS +#pragma section = ".flashprog" +#else +__attribute__((section(".flashprog"))) +#endif +// make sure to disable ICC with ICC_Disable(); before Running this function +int MXC_FLC_Write128(uint32_t address, uint32_t *data) +{ + int err; + mxc_flc_regs_t *flc = NULL; + uint32_t addr; + + // Address checked if it is 128-bit aligned + if (address & 0xF) { + return E_BAD_PARAM; + } + + // Get FLC Instance + if ((err = MXC_FLC_ME17_GetByAddress(&flc, address)) != E_NO_ERROR) { + return err; + } + + if ((err = MXC_FLC_ME17_GetPhysicalAddress(address, &addr)) < E_NO_ERROR) { + return err; + } + + err = MXC_FLC_RevA_Write128((mxc_flc_reva_regs_t *)flc, addr, data); + + // Flush the cache + MXC_FLC_ME17_Flash_Operation(); + + return err; +} + +//****************************************************************************** +int MXC_FLC_Write32(uint32_t address, uint32_t data) +{ + uint32_t addr, aligned; + int err; + mxc_flc_regs_t *flc = NULL; + + // Address checked if it is byte addressable + if (address & 0x3) { + return E_BAD_PARAM; + } + + // Align address to 128-bit word + aligned = address & 0xfffffff0; + + // Get FLC Instance + if ((err = MXC_FLC_ME17_GetByAddress(&flc, address)) != E_NO_ERROR) { + return err; + } + + if ((err = MXC_FLC_ME17_GetPhysicalAddress(aligned, &addr)) < E_NO_ERROR) { + return err; + } + + err = MXC_FLC_RevA_Write32Using128((mxc_flc_reva_regs_t *)flc, address, data, addr); + + // Flush the cache + MXC_FLC_ME17_Flash_Operation(); + + return err; +} + +//****************************************************************************** +int MXC_FLC_MassErase(void) +{ + int err, i; + mxc_flc_regs_t *flc; + + for (i = 0; i < MXC_FLC_INSTANCES; i++) { + flc = MXC_FLC_GET_FLC(i); + + err = MXC_FLC_RevA_MassErase((mxc_flc_reva_regs_t *)flc); + + // Flush the cache + MXC_FLC_ME17_Flash_Operation(); + + if (err != E_NO_ERROR) { + return err; + } + } + + return E_NO_ERROR; +} + +//****************************************************************************** +int MXC_FLC_UnlockInfoBlock(uint32_t address) +{ + int err; + mxc_flc_regs_t *flc; + + if ((err = MXC_FLC_ME17_GetByAddress(&flc, address)) != E_NO_ERROR) { + return err; + } + + return MXC_FLC_RevA_UnlockInfoBlock((mxc_flc_reva_regs_t *)flc, address); +} + +//****************************************************************************** +int MXC_FLC_LockInfoBlock(uint32_t address) +{ + int err; + mxc_flc_regs_t *flc; + + if ((err = MXC_FLC_ME17_GetByAddress(&flc, address)) != E_NO_ERROR) { + return err; + } + + return MXC_FLC_RevA_LockInfoBlock((mxc_flc_reva_regs_t *)flc, address); +} + +//****************************************************************************** +int MXC_FLC_Write(uint32_t address, uint32_t length, uint32_t *buffer) +{ + return MXC_FLC_Com_Write(address, length, buffer); +} + +//****************************************************************************** +void MXC_FLC_Read(int address, void *buffer, int len) +{ + MXC_FLC_Com_Read(address, buffer, len); +} + +//****************************************************************************** +int MXC_FLC_EnableInt(uint32_t flags) +{ + return MXC_FLC_RevA_EnableInt(flags); +} + +//****************************************************************************** +int MXC_FLC_DisableInt(uint32_t flags) +{ + return MXC_FLC_RevA_DisableInt(flags); +} + +//****************************************************************************** +int MXC_FLC_GetFlags(void) +{ + return MXC_FLC_RevA_GetFlags(); +} + +//****************************************************************************** +int MXC_FLC_ClearFlags(uint32_t flags) +{ + return MXC_FLC_RevA_ClearFlags(flags); +} + +//****************************************************************************** +int MXC_FLC_BlockPageWrite(uint32_t address) +{ + if (address < MXC_FLASH_MEM_BASE || address > (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE)) { + return E_INVALID; + } + + return MXC_FLC_RevA_BlockPageWrite(address, MXC_FLASH_MEM_BASE); +} + +//****************************************************************************** +int MXC_FLC_BlockPageRead(uint32_t address) +{ + if (address < MXC_FLASH_MEM_BASE || address > (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE)) { + return E_INVALID; + } + + return MXC_FLC_RevA_BlockPageRead(address, MXC_FLASH_MEM_BASE); +} + +//****************************************************************************** +volatile uint32_t *MXC_FLC_GetWELR(uint32_t address, uint32_t page_num) +{ + uint32_t reg_num; + reg_num = page_num >> + 5; // Divide by 32 to get WELR register number containing the page lock bit + + if (address < MXC_FLASH_MEM_BASE || address > (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE)) { + return NULL; + } + + switch (reg_num) { + case 0: + return &(MXC_FLC->welr0); + case 1: + return &(MXC_FLC->welr1); + } + + return NULL; +} + +//****************************************************************************** +volatile uint32_t *MXC_FLC_GetRLR(uint32_t address, uint32_t page_num) +{ + uint32_t reg_num; + reg_num = page_num >> 5; // Divide by 32 to get RLR register number containing the page lock bit + + if (address < MXC_FLASH_MEM_BASE || address > (MXC_FLASH_MEM_BASE + MXC_FLASH_MEM_SIZE)) { + return NULL; + } + + switch (reg_num) { + case 0: + return &(MXC_FLC->rlr0); + case 1: + return &(MXC_FLC->rlr1); + } + + return NULL; +} diff --git a/Libraries/PeriphDrivers/Source/GPIO/gpio_me30.c b/Libraries/PeriphDrivers/Source/GPIO/gpio_me30.c new file mode 100644 index 00000000000..5b3312315d7 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/GPIO/gpio_me30.c @@ -0,0 +1,430 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/* **** Includes **** */ +#include +#include "mxc_device.h" +#include "mxc_assert.h" +#include "gpio.h" +#include "gpio_reva.h" +#include "gpio_common.h" +#include "mxc_sys.h" +#include "lpgcr_regs.h" +#include "mcr_regs.h" +#include "pwrseq_regs.h" + +/* **** Definitions **** */ +// Pin 3.0 Definitions +#define P30_DATA_OUT(pin_mask) ((pin_mask & (1 << 0)) == (1 << 0) ? MXC_F_MCR_GPIO3_CTRL_P30_DO : 0) +#define P30_OUT_EN(pin_mask) ((pin_mask & (1 << 0)) == (1 << 0) ? MXC_F_MCR_GPIO3_CTRL_P30_OE : 0) +#define P30_PULL_DIS(pin_mask) ((pin_mask & (1 << 0)) == (1 << 0) ? MXC_F_MCR_GPIO3_CTRL_P30_PE : 0) +#define P30_DATA_IN(pin_mask) ((pin_mask & (1 << 0)) == (1 << 0) ? MXC_F_MCR_GPIO3_CTRL_P30_IN : 0) +#define PDOWN_OUT_EN(pin_mask) \ + ((pin_mask & (1 << 0)) == (1 << 0) ? MXC_F_MCR_OUTEN_PDOWN_OUT_EN : 0) + +// Pin 3.1 Definitions +#define P31_DATA_OUT(pin_mask) ((pin_mask & (1 << 1)) == (1 << 1) ? MXC_F_MCR_GPIO3_CTRL_P31_DO : 0) +#define P31_OUT_EN(pin_mask) ((pin_mask & (1 << 1)) == (1 << 1) ? MXC_F_MCR_GPIO3_CTRL_P31_OE : 0) +#define P31_PULL_DIS(pin_mask) ((pin_mask & (1 << 1)) == (1 << 1) ? MXC_F_MCR_GPIO3_CTRL_P31_PE : 0) +#define P31_DATA_IN(pin_mask) ((pin_mask & (1 << 1)) == (1 << 1) ? MXC_F_MCR_GPIO3_CTRL_P31_IN : 0) +#define SQWAVE_OUT_EN(pin_mask) ((pin_mask & (1 << 1)) == (1 << 1) ? MXC_F_MCR_OUTEN_SQWOUT_EN : 0) + +/* **** Globals **** */ + +/* **** Functions **** */ +int MXC_GPIO_Init(uint32_t portmask) +{ + if (portmask & 0x1) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_GPIO0); + } + + if (portmask & 0x2) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_GPIO1); + } + + if (portmask & 0x4) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_GPIO2); + } + + return MXC_GPIO_Common_Init(portmask); +} + +int MXC_GPIO_Shutdown(uint32_t portmask) +{ + if (portmask & 0x1) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_GPIO0); + } + + if (portmask & 0x2) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_GPIO1); + } + + if (portmask & 0x4) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_GPIO2); + } + + return E_NO_ERROR; +} + +int MXC_GPIO_Reset(uint32_t portmask) +{ + if (portmask & 0x1) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_GPIO0); + } + + if (portmask & 0x2) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_GPIO1); + } + + if (portmask & 0x4) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET_GPIO2); + } + + return E_NO_ERROR; +} + +int MXC_GPIO_Config(const mxc_gpio_cfg_t *cfg) +{ + int port, error; + mxc_gpio_regs_t *gpio = cfg->port; + + port = MXC_GPIO_GET_IDX(cfg->port); + + MXC_GPIO_Init(1 << port); + + if (MXC_GPIO_GetConfigLock() == MXC_GPIO_CONFIG_LOCKED) { + // Configuration is locked. Ignore any attempts to change it. + return E_NO_ERROR; + } + + // Configure the vssel + error = MXC_GPIO_SetVSSEL(gpio, cfg->vssel, cfg->mask); + if (error != E_NO_ERROR) { + return error; + } + + if (cfg->port == MXC_GPIO3) { + switch (cfg->func) { + case MXC_GPIO_FUNC_IN: + MXC_MCR->gpio3_ctrl &= ~(P30_OUT_EN(cfg->mask) | P31_OUT_EN(cfg->mask)); + MXC_MCR->outen &= ~(SQWAVE_OUT_EN(cfg->mask) | PDOWN_OUT_EN(cfg->mask)); + break; + + case MXC_GPIO_FUNC_OUT: + MXC_MCR->gpio3_ctrl |= P30_OUT_EN(cfg->mask) | P31_OUT_EN(cfg->mask); + MXC_MCR->outen &= ~(SQWAVE_OUT_EN(cfg->mask) | PDOWN_OUT_EN(cfg->mask)); + break; + + case MXC_GPIO_FUNC_ALT1: + MXC_MCR->gpio3_ctrl |= P30_OUT_EN(cfg->mask) | P31_OUT_EN(cfg->mask); + MXC_MCR->outen |= SQWAVE_OUT_EN(cfg->mask) | PDOWN_OUT_EN(cfg->mask); + break; + + default: + return E_NOT_SUPPORTED; + } + + switch (cfg->pad) { + case MXC_GPIO_PAD_NONE: + MXC_MCR->gpio3_ctrl |= P30_PULL_DIS(cfg->mask) | P31_PULL_DIS(cfg->mask); + break; + + case MXC_GPIO_PAD_PULL_UP: + case MXC_GPIO_PAD_WEAK_PULL_UP: + MXC_MCR->gpio3_ctrl |= P30_DATA_OUT(cfg->mask) | P31_DATA_OUT(cfg->mask); + MXC_MCR->gpio3_ctrl &= ~(P30_PULL_DIS(cfg->mask) | P31_PULL_DIS(cfg->mask)); + break; + + case MXC_GPIO_PAD_PULL_DOWN: + case MXC_GPIO_PAD_WEAK_PULL_DOWN: + MXC_MCR->gpio3_ctrl &= ~(P30_DATA_OUT(cfg->mask) | P31_DATA_OUT(cfg->mask)); + MXC_MCR->gpio3_ctrl &= ~(P30_PULL_DIS(cfg->mask) | P31_PULL_DIS(cfg->mask)); + break; + + default: + return E_NOT_SUPPORTED; + } + } else { + // Configure alternate function + error = MXC_GPIO_RevA_SetAF((mxc_gpio_reva_regs_t *)gpio, cfg->func, cfg->mask); + if (error != E_NO_ERROR) { + return error; + } + + // Configure the pad + switch (cfg->pad) { + case MXC_GPIO_PAD_NONE: + gpio->padctrl0 &= ~cfg->mask; + gpio->padctrl1 &= ~cfg->mask; + break; + + case MXC_GPIO_PAD_WEAK_PULL_UP: + gpio->padctrl0 |= cfg->mask; + gpio->padctrl1 &= ~cfg->mask; + gpio->ps &= ~cfg->mask; + break; + + case MXC_GPIO_PAD_PULL_UP: + gpio->padctrl0 |= cfg->mask; + gpio->padctrl1 &= ~cfg->mask; + gpio->ps |= cfg->mask; + break; + + case MXC_GPIO_PAD_WEAK_PULL_DOWN: + gpio->padctrl0 &= ~cfg->mask; + gpio->padctrl1 |= cfg->mask; + gpio->ps &= ~cfg->mask; + break; + + case MXC_GPIO_PAD_PULL_DOWN: + gpio->padctrl0 &= ~cfg->mask; + gpio->padctrl1 |= cfg->mask; + gpio->ps |= cfg->mask; + break; + + default: + return E_BAD_PARAM; + } + } + + // Configure the drive strength + if (cfg->func == MXC_GPIO_FUNC_IN) { + return E_NO_ERROR; + } else { + return MXC_GPIO_SetDriveStrength(gpio, cfg->drvstr, cfg->mask); + } +} + +/* ************************************************************************** */ +uint32_t MXC_GPIO_InGet(mxc_gpio_regs_t *port, uint32_t mask) +{ + uint32_t in = 0; + + if (port == MXC_GPIO3) { + if (MXC_MCR->gpio3_ctrl & P30_DATA_IN(mask)) { + in |= MXC_GPIO_PIN_0; + } + + if (MXC_MCR->gpio3_ctrl & P31_DATA_IN(mask)) { + in |= MXC_GPIO_PIN_1; + } + + return in; + } + + return MXC_GPIO_RevA_InGet((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_OutSet(mxc_gpio_regs_t *port, uint32_t mask) +{ + if (port == MXC_GPIO3) { + MXC_MCR->gpio3_ctrl |= P30_DATA_OUT(mask) | P31_DATA_OUT(mask); + return; + } + + MXC_GPIO_RevA_OutSet((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_OutClr(mxc_gpio_regs_t *port, uint32_t mask) +{ + if (port == MXC_GPIO3) { + MXC_MCR->gpio3_ctrl &= ~(P30_DATA_OUT(mask) | P31_DATA_OUT(mask)); + return; + } + + MXC_GPIO_RevA_OutClr((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +uint32_t MXC_GPIO_OutGet(mxc_gpio_regs_t *port, uint32_t mask) +{ + uint32_t out = 0; + + if (port == MXC_GPIO3) { + if (MXC_MCR->gpio3_ctrl & P30_DATA_OUT(mask)) { + out |= MXC_GPIO_PIN_0; + } + + if (MXC_MCR->gpio3_ctrl & P31_DATA_OUT(mask)) { + out |= MXC_GPIO_PIN_1; + } + + return out; + } + + return MXC_GPIO_RevA_OutGet((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_OutPut(mxc_gpio_regs_t *port, uint32_t mask, uint32_t val) +{ + if (port == MXC_GPIO3) { + uint32_t gpio3_cp = MXC_MCR->gpio3_ctrl & ~(P30_DATA_OUT(mask) | P31_DATA_OUT(mask)); + + MXC_MCR->gpio3_ctrl = gpio3_cp | P30_DATA_OUT((mask & val)) | P31_DATA_OUT((mask & val)); + return; + } + + MXC_GPIO_RevA_OutPut((mxc_gpio_reva_regs_t *)port, mask, val); +} + +/* ************************************************************************** */ +void MXC_GPIO_OutToggle(mxc_gpio_regs_t *port, uint32_t mask) +{ + if (port == MXC_GPIO3) { + MXC_MCR->gpio3_ctrl ^= P30_DATA_OUT(mask) | P31_DATA_OUT(mask); + return; + } + + MXC_GPIO_RevA_OutToggle((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +int MXC_GPIO_IntConfig(const mxc_gpio_cfg_t *cfg, mxc_gpio_int_pol_t pol) +{ + if (cfg->port == MXC_GPIO3) { + if (pol != MXC_GPIO_INT_BOTH) { + return E_NOT_SUPPORTED; + } + + return E_NO_ERROR; + } + + return MXC_GPIO_RevA_IntConfig(cfg, pol); +} + +/* ************************************************************************** */ +void MXC_GPIO_EnableInt(mxc_gpio_regs_t *port, uint32_t mask) +{ + if (port == MXC_GPIO3) { + MXC_PWRSEQ->lpwken3 |= mask; + return; + } + + MXC_GPIO_RevA_EnableInt((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_DisableInt(mxc_gpio_regs_t *port, uint32_t mask) +{ + if (port == MXC_GPIO3) { + MXC_PWRSEQ->lpwken3 &= ~mask; + return; + } + + MXC_GPIO_RevA_DisableInt((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_RegisterCallback(const mxc_gpio_cfg_t *cfg, mxc_gpio_callback_fn func, void *cbdata) +{ + MXC_GPIO_Common_RegisterCallback(cfg, func, cbdata); +} + +/* ************************************************************************** */ +void MXC_GPIO_Handler(unsigned int port) +{ + MXC_GPIO_Common_Handler(port); +} + +/* ************************************************************************** */ +void MXC_GPIO_ClearFlags(mxc_gpio_regs_t *port, uint32_t flags) +{ + if (port == MXC_GPIO3) { + MXC_PWRSEQ->lpwkst3 = flags; + return; + } + + MXC_GPIO_RevA_ClearFlags((mxc_gpio_reva_regs_t *)port, flags); +} + +/* ************************************************************************** */ +uint32_t MXC_GPIO_GetFlags(mxc_gpio_regs_t *port) +{ + if (port == MXC_GPIO3) { + return MXC_PWRSEQ->lpwkst3; + } + + return MXC_GPIO_RevA_GetFlags((mxc_gpio_reva_regs_t *)port); +} + +/* ************************************************************************** */ +int MXC_GPIO_SetVSSEL(mxc_gpio_regs_t *port, mxc_gpio_vssel_t vssel, uint32_t mask) +{ + if (port == MXC_GPIO3) { + if (vssel == MXC_GPIO_VSSEL_VDDIO) { + return E_NOT_SUPPORTED; + } + + return E_NO_ERROR; + } + + return MXC_GPIO_RevA_SetVSSEL((mxc_gpio_reva_regs_t *)port, vssel, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_SetWakeEn(mxc_gpio_regs_t *port, uint32_t mask) +{ + if (port == MXC_GPIO3) { + MXC_PWRSEQ->lpwken3 |= mask; + return; + } + + MXC_GPIO_RevA_SetWakeEn((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_ClearWakeEn(mxc_gpio_regs_t *port, uint32_t mask) +{ + if (port == MXC_GPIO3) { + MXC_PWRSEQ->lpwken3 &= ~mask; + return; + } + + MXC_GPIO_RevA_ClearWakeEn((mxc_gpio_reva_regs_t *)port, mask); +} + +/* ************************************************************************** */ +uint32_t MXC_GPIO_GetWakeEn(mxc_gpio_regs_t *port) +{ + if (port == MXC_GPIO3) { + return MXC_PWRSEQ->lpwken3; + } + + return MXC_GPIO_RevA_GetWakeEn((mxc_gpio_reva_regs_t *)port); +} + +/* ************************************************************************** */ +int MXC_GPIO_SetDriveStrength(mxc_gpio_regs_t *port, mxc_gpio_drvstr_t drvstr, uint32_t mask) +{ + return MXC_GPIO_RevA_SetDriveStrength((mxc_gpio_reva_regs_t *)port, drvstr, mask); +} + +/* ************************************************************************** */ +void MXC_GPIO_SetConfigLock(mxc_gpio_config_lock_t locked) +{ + MXC_GPIO_Common_SetConfigLock(locked); +} + +/* ************************************************************************** */ +mxc_gpio_config_lock_t MXC_GPIO_GetConfigLock(void) +{ + return MXC_GPIO_Common_GetConfigLock(); +} diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me30.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me30.c new file mode 100644 index 00000000000..dacc6e77d78 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me30.c @@ -0,0 +1,413 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include +#include +#include +#include "mxc_device.h" +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "mxc_sys.h" +#include "mxc_delay.h" +#include "i2c_regs.h" +#include "dma_regs.h" +#include "i2c.h" +#include "i2c_reva.h" + +/* **** Variable Declaration **** */ +uint32_t interruptCheck = MXC_F_I2C_INTFL0_ADDR_MATCH | MXC_F_I2C_INTFL0_DNR_ERR; + +/* **** Function Prototypes **** */ + +/* ************************************************************************* */ +/* Control/Configuration functions */ +/* ************************************************************************* */ +int MXC_I2C_Init(mxc_i2c_regs_t *i2c, int masterMode, unsigned int slaveAddr) +{ + if (i2c == NULL) { + return E_NULL_PTR; + } + +#ifndef MSDK_NO_GPIO_CLK_INIT + MXC_I2C_Shutdown(i2c); // Clear everything out + + if (i2c == MXC_I2C0) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C0); + MXC_GPIO_Config(&gpio_cfg_i2c0); + } else if (i2c == MXC_I2C1) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C1); + MXC_GPIO_Config(&gpio_cfg_i2c1); + } else if (i2c == MXC_I2C2) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C2); + MXC_GPIO_Config(&gpio_cfg_i2c2); + } else { + return E_NO_DEVICE; + } +#endif // MSDK_NO_GPIO_CLK_INIT + + return MXC_I2C_RevA_Init((mxc_i2c_reva_regs_t *)i2c, masterMode, slaveAddr); +} + +int MXC_I2C_SetSlaveAddr(mxc_i2c_regs_t *i2c, unsigned int slaveAddr, int idx) +{ + if (idx != 0) { + // MAX32655 only supports one slave device + return E_NOT_SUPPORTED; + } + + return MXC_I2C_RevA_SetSlaveAddr((mxc_i2c_reva_regs_t *)i2c, slaveAddr, idx); +} + +int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) +{ + // Configure GPIO for I2C + if (i2c == MXC_I2C0) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C0); + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_I2C0); + } else if (i2c == MXC_I2C1) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C1); + MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C1); + } else if (i2c == MXC_I2C2) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C2); + MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C2); + } else { + return E_NO_DEVICE; + } + + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) +{ + // Configure GPIO for I2C + if (i2c == MXC_I2C0) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_I2C0); + } else if (i2c == MXC_I2C1) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C1); + } else if (i2c == MXC_I2C2) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C2); + } else { + return E_NO_DEVICE; + } + + return E_NO_ERROR; +} + +int MXC_I2C_SetFrequency(mxc_i2c_regs_t *i2c, unsigned int hz) +{ + return MXC_I2C_RevA_SetFrequency((mxc_i2c_reva_regs_t *)i2c, hz); +} + +int MXC_I2C_GetFrequency(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_GetFrequency((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_ReadyForSleep(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_ReadyForSleep((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable) +{ + return MXC_I2C_RevA_SetClockStretching((mxc_i2c_reva_regs_t *)i2c, enable); +} + +int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + +/* ************************************************************************* */ +/* Low-level functions */ +/* ************************************************************************* */ +int MXC_I2C_Start(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_Start((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_Stop(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_Stop((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_WriteByte(mxc_i2c_regs_t *i2c, unsigned char byte) +{ + return MXC_I2C_RevA_WriteByte((mxc_i2c_reva_regs_t *)i2c, byte); +} + +int MXC_I2C_ReadByte(mxc_i2c_regs_t *i2c, unsigned char *byte, int ack) +{ + return MXC_I2C_RevA_ReadByte((mxc_i2c_reva_regs_t *)i2c, byte, ack); +} + +int MXC_I2C_ReadByteInteractive(mxc_i2c_regs_t *i2c, unsigned char *byte, mxc_i2c_getAck_t getAck) +{ + return MXC_I2C_RevA_ReadByteInteractive((mxc_i2c_reva_regs_t *)i2c, byte, + (mxc_i2c_reva_getAck_t)getAck); +} + +int MXC_I2C_Write(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len) +{ + return MXC_I2C_RevA_Write((mxc_i2c_reva_regs_t *)i2c, bytes, len); +} + +int MXC_I2C_Read(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len, int ack) +{ + return MXC_I2C_RevA_Read((mxc_i2c_reva_regs_t *)i2c, bytes, len, ack); +} + +int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len) +{ + return MXC_I2C_RevA_ReadRXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len); +} + +int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, + mxc_i2c_dma_complete_cb_t callback) +{ + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); +} + +int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_GetRXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len) +{ + return MXC_I2C_RevA_WriteTXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len); +} + +int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, + mxc_i2c_dma_complete_cb_t callback) +{ + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); +} + +int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_GetTXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_ClearRXFIFO(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_ClearRXFIFO((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_ClearTXFIFO(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_ClearTXFIFO((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_GetFlags(mxc_i2c_regs_t *i2c, unsigned int *flags0, unsigned int *flags1) +{ + return MXC_I2C_RevA_GetFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_ClearFlags(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1) +{ + MXC_I2C_RevA_ClearFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_EnableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1) +{ + MXC_I2C_RevA_EnableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_DisableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1) +{ + MXC_I2C_RevA_DisableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_EnablePreload(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_EnablePreload((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_DisablePreload(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_DisablePreload((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_EnableGeneralCall(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_EnableGeneralCall((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_DisableGeneralCall((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout) +{ + MXC_I2C_RevA_SetTimeout((mxc_i2c_reva_regs_t *)i2c, timeout); +} + +unsigned int MXC_I2C_GetTimeout(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_GetTimeout((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_Recover(mxc_i2c_regs_t *i2c, unsigned int retries) +{ + return MXC_I2C_RevA_Recover((mxc_i2c_reva_regs_t *)i2c, retries); +} + +/* ************************************************************************* */ +/* Transaction level functions */ +/* ************************************************************************* */ + +int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req) +{ + return MXC_I2C_RevA_MasterTransaction((mxc_i2c_reva_req_t *)req); +} + +int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req) +{ + return MXC_I2C_RevA_MasterTransactionAsync((mxc_i2c_reva_req_t *)req); +} + +int MXC_I2C_MasterTransactionDMA(mxc_i2c_req_t *req) +{ + return MXC_I2C_RevA_MasterTransactionDMA((mxc_i2c_reva_req_t *)req, MXC_DMA); +} + +int MXC_I2C_SlaveTransaction(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback) +{ + return MXC_I2C_RevA_SlaveTransaction((mxc_i2c_reva_regs_t *)i2c, + (mxc_i2c_reva_slave_handler_t)callback, interruptCheck); +} + +int MXC_I2C_SlaveTransactionAsync(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback) +{ + return MXC_I2C_RevA_SlaveTransactionAsync( + (mxc_i2c_reva_regs_t *)i2c, (mxc_i2c_reva_slave_handler_t)callback, interruptCheck); +} + +int MXC_I2C_SetRXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes) +{ + return MXC_I2C_RevA_SetRXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes); +} + +int MXC_I2C_GetRXThreshold(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_GetRXThreshold((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_SetTXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes) +{ + return MXC_I2C_RevA_SetTXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes); +} + +int MXC_I2C_GetTXThreshold(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_GetTXThreshold((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_AsyncStop(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_AsyncStop((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_AbortAsync(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_AbortAsync((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_AsyncHandler(mxc_i2c_regs_t *i2c) +{ + MXC_I2C_RevA_AsyncHandler((mxc_i2c_reva_regs_t *)i2c, interruptCheck); +} + +void MXC_I2C_DMACallback(int ch, int error) +{ + MXC_I2C_RevA_DMACallback(ch, error); +} diff --git a/Libraries/PeriphDrivers/Source/ICC/icc_me30.c b/Libraries/PeriphDrivers/Source/ICC/icc_me30.c new file mode 100644 index 00000000000..1a9cc8cdda7 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/ICC/icc_me30.c @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/* **** Includes **** */ +#include "mxc_device.h" +#include "mxc_errors.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "icc.h" +#include "icc_reva.h" +#include "icc_common.h" + +/* **** Definitions **** */ + +/* **** Globals **** */ + +/* **** Functions **** */ + +/* ****************************************************************************** +Maxim Internal Use + * ****************************************************************************** */ + +int MXC_ICC_ID(mxc_icc_regs_t *icc, mxc_icc_info_t cid) +{ + return MXC_ICC_RevA_ID((mxc_icc_reva_regs_t *)icc, cid); +} + +void MXC_ICC_Enable(mxc_icc_regs_t *icc) +{ + MXC_ICC_RevA_Enable((mxc_icc_reva_regs_t *)icc); +} + +void MXC_ICC_Disable(mxc_icc_regs_t *icc) +{ + MXC_ICC_RevA_Disable((mxc_icc_reva_regs_t *)icc); +} + +void MXC_ICC_Flush(mxc_icc_regs_t *icc) +{ + MXC_ICC_Disable(icc); + MXC_ICC_Enable(icc); +} diff --git a/Libraries/PeriphDrivers/Source/LP/lp_me30.c b/Libraries/PeriphDrivers/Source/LP/lp_me30.c new file mode 100644 index 00000000000..a041107d1ca --- /dev/null +++ b/Libraries/PeriphDrivers/Source/LP/lp_me30.c @@ -0,0 +1,254 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ +#include "mxc_device.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "gcr_regs.h" +#include "mcr_regs.h" +#include "lp.h" +#include "lpcmp.h" + +#ifndef __riscv +/* ARM */ +#define SET_SLEEPDEEP(X) (SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk) +#define CLR_SLEEPDEEP(X) (SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk) +#else +/* RISCV */ +/* These bits do not exist for RISCV core */ +#define SET_SLEEPDEEP(X) +#define CLR_SLEEPDEEP(X) +#endif + +void MXC_LP_EnterSleepMode(void) +{ + MXC_LP_ClearWakeStatus(); + + /* Clear SLEEPDEEP bit */ + CLR_SLEEPDEEP(); + + /* Go into Sleep mode and wait for an interrupt to wake the processor */ + __WFI(); +} + +void MXC_LP_EnterLowPowerMode(void) +{ + MXC_LP_ClearWakeStatus(); + MXC_MCR->ctrl |= MXC_F_MCR_CTRL_ERTCO_EN; // Enabled for deep sleep mode + + /* Set SLEEPDEEP bit */ + SET_SLEEPDEEP(); + + /* Go into low power mode and wait for an interrupt to wake the processor */ + MXC_GCR->pm |= MXC_S_GCR_PM_MODE_LPM; + __WFI(); +} + +void MXC_LP_EnterMicroPowerMode(void) +{ + MXC_LP_ClearWakeStatus(); + MXC_MCR->ctrl |= MXC_F_MCR_CTRL_ERTCO_EN; // Enabled for deep sleep mode + + /* Set SLEEPDEEP bit */ + SET_SLEEPDEEP(); + + /* Go into Deepsleep mode and wait for an interrupt to wake the processor */ + MXC_GCR->pm |= MXC_S_GCR_PM_MODE_UPM; // UPM mode + __WFI(); +} + +void MXC_LP_EnterStandbyMode(void) +{ + MXC_LP_ClearWakeStatus(); + MXC_MCR->ctrl |= MXC_F_MCR_CTRL_ERTCO_EN; // Enabled for deep sleep mode + + /* Set SLEEPDEEP bit */ + SET_SLEEPDEEP(); + + /* Go into standby mode and wait for an interrupt to wake the processor */ + MXC_GCR->pm |= MXC_S_GCR_PM_MODE_STANDBY; // standby mode + __WFI(); +} + +void MXC_LP_EnterBackupMode(void) +{ + MXC_LP_ClearWakeStatus(); + + MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE; + MXC_GCR->pm |= MXC_S_GCR_PM_MODE_BACKUP; + + while (1) {} + // Should never reach this line - device will jump to backup vector on exit from background mode. +} + +void MXC_LP_EnterPowerDownMode(void) +{ + MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE; + MXC_GCR->pm |= MXC_S_GCR_PM_MODE_POWERDOWN; + + while (1) {} + // Should never reach this line - device will reset on exit from shutdown mode. +} + +void MXC_LP_SetOVR(mxc_lp_ovr_t ovr) +{ + //not supported yet +} + +void MXC_LP_BandgapOn(void) +{ + MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_BG_DIS; +} + +void MXC_LP_BandgapOff(void) +{ + MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_BG_DIS; +} + +int MXC_LP_BandgapIsOn(void) +{ + return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_BG_DIS); +} + +void MXC_LP_ClearWakeStatus(void) +{ + /* Write 1 to clear */ + MXC_PWRSEQ->lpwkst0 = 0xFFFFFFFF; + MXC_PWRSEQ->lpwkst1 = 0xFFFFFFFF; + MXC_PWRSEQ->lpwkst2 = 0xFFFFFFFF; + MXC_PWRSEQ->lpwkst3 = 0xFFFFFFFF; + MXC_PWRSEQ->lppwst = 0xFFFFFFFF; +} + +void MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t *wu_pins) +{ + MXC_GCR->pm |= MXC_F_GCR_PM_GPIO_WE; + + switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) { + case MXC_GPIO_PORT_0: + MXC_PWRSEQ->lpwken0 |= wu_pins->mask; + break; + + case MXC_GPIO_PORT_1: + MXC_PWRSEQ->lpwken1 |= wu_pins->mask; + break; + case MXC_GPIO_PORT_2: + MXC_PWRSEQ->lpwken2 |= wu_pins->mask; + break; + case MXC_GPIO_PORT_3: + MXC_PWRSEQ->lpwken3 |= wu_pins->mask; + break; + } +} + +void MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t *wu_pins) +{ + switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) { + case MXC_GPIO_PORT_0: + MXC_PWRSEQ->lpwken0 &= ~wu_pins->mask; + break; + + case MXC_GPIO_PORT_1: + MXC_PWRSEQ->lpwken1 &= ~wu_pins->mask; + break; + case MXC_GPIO_PORT_2: + MXC_PWRSEQ->lpwken2 &= ~wu_pins->mask; + break; + case MXC_GPIO_PORT_3: + MXC_PWRSEQ->lpwken3 &= ~wu_pins->mask; + break; + } + + if (MXC_PWRSEQ->lpwken3 == 0 && MXC_PWRSEQ->lpwken2 == 0 && MXC_PWRSEQ->lpwken1 == 0 && + MXC_PWRSEQ->lpwken0 == 0) { + MXC_GCR->pm &= ~MXC_F_GCR_PM_GPIO_WE; + } +} + +void MXC_LP_EnableRTCAlarmWakeup(void) +{ + MXC_GCR->pm |= MXC_F_GCR_PM_RTC_WE; +} + +void MXC_LP_DisableRTCAlarmWakeup(void) +{ + MXC_GCR->pm &= ~MXC_F_GCR_PM_RTC_WE; +} + +void MXC_LP_EnableTimerWakeup(mxc_tmr_regs_t *tmr) +{ + MXC_ASSERT(MXC_TMR_GET_IDX(tmr) > 3); + + if (tmr == MXC_TMR4) { + MXC_PWRSEQ->lppwen |= MXC_F_PWRSEQ_LPPWEN_TMR4; + } else { + MXC_PWRSEQ->lppwen |= MXC_F_PWRSEQ_LPPWEN_TMR5; + } +} + +void MXC_LP_DisableTimerWakeup(mxc_tmr_regs_t *tmr) +{ + MXC_ASSERT(MXC_TMR_GET_IDX(tmr) > 3); + + if (tmr == MXC_TMR4) { + MXC_PWRSEQ->lppwen &= ~MXC_F_PWRSEQ_LPPWEN_TMR4; + } else { + MXC_PWRSEQ->lppwen &= ~MXC_F_PWRSEQ_LPPWEN_TMR5; + } +} + +void MXC_LP_EnableWUTAlarmWakeup(void) +{ + MXC_GCR->pm |= MXC_F_GCR_PM_WUT_WE; +} + +void MXC_LP_DisableWUTAlarmWakeup(void) +{ + MXC_GCR->pm &= ~MXC_F_GCR_PM_WUT_WE; +} + +void MXC_LP_EnableLPCMPWakeup(mxc_lpcmp_cmpsel_t cmp) +{ + MXC_ASSERT((cmp >= MXC_LPCMP_CMP0) && (cmp <= MXC_LPCMP_CMP3)); + + if (cmp == MXC_LPCMP_CMP0) { + MXC_PWRSEQ->lppwen |= MXC_F_PWRSEQ_LPPWEN_AINCOMP0; + } else { + MXC_PWRSEQ->lppwen |= MXC_F_PWRSEQ_LPPWEN_LPCMP; + } +} + +void MXC_LP_DisableLPCMPWakeup(mxc_lpcmp_cmpsel_t cmp) +{ + MXC_ASSERT((cmp >= MXC_LPCMP_CMP0) && (cmp <= MXC_LPCMP_CMP3)); + + if (cmp == MXC_LPCMP_CMP0) { + MXC_PWRSEQ->lppwen &= ~MXC_F_PWRSEQ_LPPWEN_AINCOMP0; + } else { + MXC_PWRSEQ->lppwen &= ~MXC_F_PWRSEQ_LPPWEN_LPCMP; + } +} + +int MXC_LP_ConfigDeepSleepClocks(uint32_t mask) +{ + if (!(mask & (MXC_F_GCR_PM_IBRO_PD | MXC_F_GCR_PM_IPO_PD))) { + return E_BAD_PARAM; + } + + MXC_GCR->pm |= mask; + return E_NO_ERROR; +} diff --git a/Libraries/PeriphDrivers/Source/RTC/rtc_me30.c b/Libraries/PeriphDrivers/Source/RTC/rtc_me30.c new file mode 100644 index 00000000000..6d6eefe2757 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/RTC/rtc_me30.c @@ -0,0 +1,283 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "mxc_device.h" +#include "rtc_regs.h" +#include "rtc.h" +#include "mxc_sys.h" +#include "mxc_delay.h" +#include "gpio_regs.h" +#include "mxc_errors.h" +#include "mcr_regs.h" +#include "rtc_reva.h" +#include "tmr.h" +#include "trimsir_regs.h" + +#define SUBSECOND_MSEC_0 200 +#define SEARCH_STEPS 7 +#define SEARCH_TARGET 0x30d400 /* 1/2 of 32 MHz periods in 32.768 kHz */ + +#define RTCX1x_MASK 0x1F /* 5 bits */ +#define RTCX2x_MASK 0x1F /* 5 bits */ + +#define NOM_32K_FREQ 32768 +#define TICKS_PER_RTC 122 + +/* Converts a time in milleseconds to the equivalent RSSA register value. */ +#define MSEC_TO_RSSA(x) (unsigned int)(0x100000000ULL - ((x * 4096) / 1000)) + +/********************************************/ +/* Maxim Function Mapping */ +/********************************************/ + +int MXC_RTC_EnableInt(uint32_t mask) +{ + return MXC_RTC_RevA_EnableInt((mxc_rtc_reva_regs_t *)MXC_RTC, mask); +} + +int MXC_RTC_DisableInt(uint32_t mask) +{ + return MXC_RTC_RevA_DisableInt((mxc_rtc_reva_regs_t *)MXC_RTC, mask); +} + +int MXC_RTC_SetTimeofdayAlarm(uint32_t ras) +{ + return MXC_RTC_RevA_SetTimeofdayAlarm((mxc_rtc_reva_regs_t *)MXC_RTC, ras); +} + +int MXC_RTC_SetSubsecondAlarm(uint32_t rssa) +{ + return MXC_RTC_RevA_SetSubsecondAlarm((mxc_rtc_reva_regs_t *)MXC_RTC, rssa); +} + +int MXC_RTC_Start(void) +{ + return MXC_RTC_RevA_Start((mxc_rtc_reva_regs_t *)MXC_RTC); +} + +int MXC_RTC_Stop(void) +{ + return MXC_RTC_RevA_Stop((mxc_rtc_reva_regs_t *)MXC_RTC); +} + +int MXC_RTC_Init(uint32_t sec, uint16_t ssec) +{ + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERTCO_EN; + + return MXC_RTC_RevA_Init((mxc_rtc_reva_regs_t *)MXC_RTC, sec, (ssec & MXC_F_RTC_SSEC_SSEC)); +} + +int MXC_RTC_SquareWaveStart(mxc_rtc_freq_sel_t ft) +{ + MXC_GPIO_Config(&gpio_cfg_rtcsqw); + MXC_MCR->outen |= MXC_F_MCR_OUTEN_SQWOUT_EN; + + return MXC_RTC_RevA_SquareWave((mxc_rtc_reva_regs_t *)MXC_RTC, MXC_RTC_REVA_SQUARE_WAVE_ENABLED, + ft); +} + +int MXC_RTC_SquareWaveStop(void) +{ + MXC_MCR->outen &= ~(MXC_F_MCR_OUTEN_SQWOUT_EN); + + return MXC_RTC_RevA_SquareWave((mxc_rtc_reva_regs_t *)MXC_RTC, + MXC_RTC_REVA_SQUARE_WAVE_DISABLED, 0); +} + +int MXC_RTC_Trim(int8_t trm) +{ + return MXC_RTC_RevA_Trim((mxc_rtc_reva_regs_t *)MXC_RTC, trm); +} + +int MXC_RTC_GetFlags(void) +{ + return MXC_RTC_RevA_GetFlags((mxc_rtc_reva_regs_t *)MXC_RTC); +} + +int MXC_RTC_ClearFlags(int flags) +{ + return MXC_RTC_RevA_ClearFlags((mxc_rtc_reva_regs_t *)MXC_RTC, flags); +} + +int MXC_RTC_GetSubSecond(void) +{ + return MXC_RTC_RevA_GetSubSecond((mxc_rtc_reva_regs_t *)MXC_RTC); +} + +int MXC_RTC_GetSecond(void) +{ + return MXC_RTC_RevA_GetSecond((mxc_rtc_reva_regs_t *)MXC_RTC); +} + +int MXC_RTC_GetSubSeconds(uint32_t *ssec) +{ + MXC_RTC->ctrl &= ~MXC_F_RTC_CTRL_RDY; // Ensure valid data is in SSEC register + while (!(MXC_RTC->ctrl & MXC_F_RTC_CTRL_RDY)) {} + + return MXC_RTC_RevA_GetSubSeconds((mxc_rtc_reva_regs_t *)MXC_RTC, ssec); +} + +int MXC_RTC_GetSeconds(uint32_t *sec) +{ + MXC_RTC->ctrl &= ~MXC_F_RTC_CTRL_RDY; // Ensure valid data is in SEC register + while (!(MXC_RTC->ctrl & MXC_F_RTC_CTRL_RDY)) {} + + return MXC_RTC_RevA_GetSeconds((mxc_rtc_reva_regs_t *)MXC_RTC, sec); +} + +int MXC_RTC_GetTime(uint32_t *sec, uint32_t *subsec) +{ + return MXC_RTC_RevA_GetTime((mxc_rtc_reva_regs_t *)MXC_RTC, sec, subsec); +} + +int MXC_RTC_GetBusyFlag(void) +{ + return MXC_RTC_RevA_GetBusyFlag((mxc_rtc_reva_regs_t *)MXC_RTC); +} + +int MXC_RTC_TrimCrystal(void) +{ +#if TARGET_NUM == 78000 + /* MAX78000 does not have the ERFO clock which the Trim function requires */ + return E_NOT_SUPPORTED; +#endif + + unsigned int search_step, elapsed; + unsigned int upper, lower, trim, oldtrim, bestTrim, bestElapsed, bestElapsedDiff; + unsigned int freq = NOM_32K_FREQ; + int retval; + + /* Determine starting point for internal load capacitors */ + upper = RTCX1x_MASK; + lower = 0; + trim = (upper + lower) / 2; + + /* Initialize best trim variables */ + bestTrim = trim; + bestElapsed = bestElapsedDiff = SEARCH_TARGET; + + /* Init timer to count 32 MHz periods */ + mxc_tmr_cfg_t tmr_cfg; + tmr_cfg.pres = MXC_TMR_PRES_1; + tmr_cfg.mode = MXC_TMR_MODE_CONTINUOUS; + tmr_cfg.bitMode = MXC_TMR_BIT_MODE_32; + tmr_cfg.clock = MXC_TMR_APB_CLK; + tmr_cfg.cmp_cnt = 0xFFFFFFFF; + tmr_cfg.pol = 0; + MXC_TMR_Init(MXC_TMR3, &tmr_cfg, FALSE); + + /* Clear out any previous configuration */ + MXC_RTC_DisableInt(MXC_F_RTC_CTRL_TOD_ALARM_IE | MXC_F_RTC_CTRL_SSEC_ALARM_IE | + MXC_F_RTC_CTRL_RDY_IE); + MXC_RTC_ClearFlags(MXC_RTC_GetFlags()); + + MXC_RTC->oscctrl &= ~(MXC_F_RTC_OSCCTRL_BYPASS | MXC_F_RTC_OSCCTRL_SQW_32K); + + /* Setup SSEC Alarm */ + MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE); + retval = MXC_RTC_SetSubsecondAlarm(MSEC_TO_RSSA(SUBSECOND_MSEC_0)); + if (retval != E_NO_ERROR) { + return retval; + } + MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE); + + /* Trim loop */ + search_step = 0; + while (search_step < SEARCH_STEPS) { + /* Set new trim point */ + oldtrim = trim; + trim = (lower + upper) / 2; + if ((search_step > 0) && (trim == oldtrim)) { + /* Found trim value */ + break; + } + + /* Set the trim values */ + MXC_SETFIELD(MXC_TRIMSIR->rtc, MXC_F_TRIMSIR_RTC_X1TRIM, + (trim << MXC_F_TRIMSIR_RTC_X1TRIM_POS)); + MXC_SETFIELD(MXC_TRIMSIR->rtc, MXC_F_TRIMSIR_RTC_X2TRIM, + (trim << MXC_F_TRIMSIR_RTC_X2TRIM_POS)); + + /* Sleep to settle new caps */ + MXC_Delay(MXC_DELAY_MSEC(10)); + + /* Start 200 msec sampling window */ + MXC_TMR_Stop(MXC_TMR3); + MXC_TMR_SetCount(MXC_TMR3, 0); + + /* Wait for an RTC edge */ + MXC_RTC_ClearFlags(MXC_RTC_GetFlags()); + while (!(MXC_RTC->ctrl & MXC_F_RTC_CTRL_SSEC_ALARM)) {} + + MXC_TMR_Start(MXC_TMR3); + + /* Wait for an RTC edge */ + MXC_RTC_ClearFlags(MXC_RTC_GetFlags()); + while (!(MXC_RTC->ctrl & MXC_F_RTC_CTRL_SSEC_ALARM)) {} + + /* Capture the TMR count and adjust for processing delay */ + elapsed = MXC_TMR_GetCount(MXC_TMR3); + MXC_TMR_Stop(MXC_TMR3); + elapsed += 810; + + /* Binary search for optimal trim value */ + if (elapsed > SEARCH_TARGET) { + /* Too slow */ + upper = trim; + + /* Record best setting */ + if ((elapsed - SEARCH_TARGET) <= bestElapsedDiff) { + bestElapsedDiff = elapsed - SEARCH_TARGET; + bestElapsed = elapsed; + bestTrim = trim; + } + } else { + /* Too fast */ + lower = trim; + + /* Record best setting */ + if ((SEARCH_TARGET - elapsed) <= bestElapsedDiff) { + bestElapsedDiff = SEARCH_TARGET - elapsed; + bestElapsed = elapsed; + bestTrim = trim; + } + } + + search_step++; + } + + /* Apply the closest trim setting */ + MXC_SETFIELD(MXC_TRIMSIR->rtc, MXC_F_TRIMSIR_RTC_X1TRIM, + (bestTrim << MXC_F_TRIMSIR_RTC_X1TRIM_POS)); + MXC_SETFIELD(MXC_TRIMSIR->rtc, MXC_F_TRIMSIR_RTC_X2TRIM, + (bestTrim << MXC_F_TRIMSIR_RTC_X2TRIM_POS)); + + /* Adjust 32K freq if we can't get close enough to 32768 Hz */ + if (bestElapsed >= SEARCH_TARGET) { + freq -= (((bestElapsed - SEARCH_TARGET) + (TICKS_PER_RTC / 2 - 1)) / TICKS_PER_RTC); + } else { + freq += (((SEARCH_TARGET - bestElapsed) + (TICKS_PER_RTC / 2 - 1)) / TICKS_PER_RTC); + } + + /* Clear hardware state */ + MXC_TMR_Stop(MXC_TMR3); + MXC_TMR_Shutdown(MXC_TMR3); + MXC_RTC_ClearFlags(MXC_RTC_GetFlags()); + + return freq; +} diff --git a/Libraries/PeriphDrivers/Source/SPI/spi_me30.c b/Libraries/PeriphDrivers/Source/SPI/spi_me30.c new file mode 100644 index 00000000000..da6225abb7b --- /dev/null +++ b/Libraries/PeriphDrivers/Source/SPI/spi_me30.c @@ -0,0 +1,526 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include +#include +#include +#include + +#include "mxc_device.h" +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "mxc_sys.h" +#include "mxc_delay.h" +#include "spi_reva1.h" +#include "dma.h" + +/* **** Definitions **** */ + +/* ************************************************************************** */ +int MXC_SPI_Init(mxc_spi_regs_t *spi, int masterMode, int quadModeUsed, int numSlaves, + unsigned ssPolarity, unsigned int hz, mxc_spi_pins_t pins) +{ + int spi_num; + + spi_num = MXC_SPI_GET_IDX(spi); + MXC_ASSERT(spi_num >= 0); + + if (numSlaves > MXC_SPI_SS_INSTANCES) { + return E_BAD_PARAM; + } + + // Check if frequency is too high + if ((spi_num == 0) && (hz > PeripheralClock)) { + return E_BAD_PARAM; + } + + if ((spi_num == 1) && (hz > SystemCoreClock)) { + return E_BAD_PARAM; + } + +#ifndef MSDK_NO_GPIO_CLK_INIT + mxc_gpio_cfg_t gpio_cfg_spi; + gpio_cfg_spi.pad = MXC_GPIO_PAD_NONE; + gpio_cfg_spi.port = MXC_GPIO0; + + // Set VDDIO level + if (pins.vddioh) { + gpio_cfg_spi.vssel = MXC_GPIO_VSSEL_VDDIOH; + } else { + gpio_cfg_spi.vssel = MXC_GPIO_VSSEL_VDDIO; + } + + // Configure GPIO for spi + if (spi == MXC_SPI1) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1); + +#if (TARGET != MAX78000 || TARGET_NUM == 32655) + + //Define pins + if (pins.ss1) { + gpio_cfg_spi.mask = MXC_GPIO_PIN_26; + gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2; + MXC_GPIO_Config(&gpio_cfg_spi); + } + + if (pins.ss2) { + gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2; + gpio_cfg_spi.mask = MXC_GPIO_PIN_27; + MXC_GPIO_Config(&gpio_cfg_spi); + } + +#endif + //clear mask + gpio_cfg_spi.mask = 0; + + // check rest of the pins + if (pins.clock) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_23; + } + + if (pins.miso) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_22; + } + + if (pins.mosi) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_21; + } + + if (pins.sdio2) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_24; + } + + if (pins.sdio3) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_25; + } + + if (pins.ss0) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_20; + } + + gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT1; +#ifdef MXC_SPI0 + } else if (spi == MXC_SPI0) { + MXC_SYS_Reset_Periph(MXC_SYS_RESET1_SPI0); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0); + + //Define pins + if (pins.ss1) { + gpio_cfg_spi.mask = MXC_GPIO_PIN_11; + gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2; + MXC_GPIO_Config(&gpio_cfg_spi); + } + + if (pins.ss2) { + gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT2; + gpio_cfg_spi.mask = MXC_GPIO_PIN_10; + MXC_GPIO_Config(&gpio_cfg_spi); + } + + //clear mask + gpio_cfg_spi.mask = 0; + + // check rest of the pins + if (pins.clock) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_7; + } + + if (pins.miso) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_6; + } + + if (pins.mosi) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_5; + } + + if (pins.sdio2) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_8; + } + + if (pins.sdio3) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_9; + } + + if (pins.ss0) { + gpio_cfg_spi.mask |= MXC_GPIO_PIN_4; + } + + gpio_cfg_spi.func = MXC_GPIO_FUNC_ALT1; +#endif + } else { + return E_NO_DEVICE; + } + + MXC_GPIO_Config(&gpio_cfg_spi); +#else + (void)pins; +#endif // MSDK_NO_GPIO_CLK_INIT + + return MXC_SPI_RevA1_Init((mxc_spi_reva_regs_t *)spi, masterMode, quadModeUsed, numSlaves, + ssPolarity, hz); +} + +int MXC_SPI_Shutdown(mxc_spi_regs_t *spi) +{ + int spi_num; + spi_num = MXC_SPI_GET_IDX(spi); + MXC_ASSERT(spi_num >= 0); + (void)spi_num; + + MXC_SPI_RevA1_Shutdown((mxc_spi_reva_regs_t *)spi); + + if (spi == MXC_SPI1) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI1); +#ifdef MXC_SPI0 + } else if (spi == MXC_SPI0) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPI0); +#endif + } else { + return E_NO_DEVICE; + } + + return E_NO_ERROR; +} + +int MXC_SPI_ReadyForSleep(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_ReadyForSleep((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_GetPeripheralClock(mxc_spi_regs_t *spi) +{ + int retval; + + if (spi == MXC_SPI1) { + retval = PeripheralClock; +#ifdef MXC_SPI0 // SPI0 is not accessible from the RISC core. + } else if (spi == MXC_SPI0) { + int sys_clk = (MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL) >> + MXC_F_GCR_CLKCTRL_SYSCLK_SEL_POS; + switch (sys_clk) { + case MXC_SYS_CLOCK_IPO: + retval = IPO_FREQ; + break; + case MXC_SYS_CLOCK_IBRO: + retval = IBRO_FREQ; + break; + case MXC_SYS_CLOCK_ISO: + retval = ISO_FREQ; + break; + case MXC_SYS_CLOCK_INRO: + retval = INRO_FREQ; + break; + case MXC_SYS_CLOCK_ERTCO: + retval = ERTCO_FREQ; + break; + case MXC_SYS_CLOCK_EXTCLK: + retval = EXTCLK_FREQ; + break; +#if TARGET_NUM == 32655 || TARGET_NUM == 32680 + case MXC_SYS_CLOCK_ERFO: + retval = ERFO_FREQ; + break; +#endif + default: + return E_BAD_STATE; + } +#endif // MXC_SPI0 + } else { + return E_BAD_PARAM; + } + + retval /= 2; + + return retval; +} + +int MXC_SPI_SetFrequency(mxc_spi_regs_t *spi, unsigned int hz) +{ + return MXC_SPI_RevA1_SetFrequency((mxc_spi_reva_regs_t *)spi, hz); +} + +unsigned int MXC_SPI_GetFrequency(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetFrequency((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_SetDataSize(mxc_spi_regs_t *spi, int dataSize) +{ + return MXC_SPI_RevA1_SetDataSize((mxc_spi_reva_regs_t *)spi, dataSize); +} + +int MXC_SPI_GetDataSize(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetDataSize((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_SetSlave(mxc_spi_regs_t *spi, int ssIdx) +{ + return MXC_SPI_RevA1_SetSlave((mxc_spi_reva_regs_t *)spi, ssIdx); +} + +int MXC_SPI_GetSlave(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetSlave((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_SetWidth(mxc_spi_regs_t *spi, mxc_spi_width_t spiWidth) +{ + return MXC_SPI_RevA1_SetWidth((mxc_spi_reva_regs_t *)spi, spiWidth); +} + +mxc_spi_width_t MXC_SPI_GetWidth(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetWidth((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_SetMTMode(mxc_spi_regs_t *spi, int mtMode) +{ + return MXC_SPI_RevA1_SetMTMode((mxc_spi_reva_regs_t *)spi, mtMode); +} + +int MXC_SPI_GetMTMode(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetMTMode((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_SetMode(mxc_spi_regs_t *spi, mxc_spi_mode_t spiMode) +{ + return MXC_SPI_RevA1_SetMode((mxc_spi_reva_regs_t *)spi, spiMode); +} + +mxc_spi_mode_t MXC_SPI_GetMode(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetMode((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_StartTransmission(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_StartTransmission((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_GetActive(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetActive((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_AbortTransmission(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_AbortTransmission((mxc_spi_reva_regs_t *)spi); +} + +unsigned int MXC_SPI_ReadRXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len) +{ + return MXC_SPI_RevA1_ReadRXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len); +} + +unsigned int MXC_SPI_GetRXFIFOAvailable(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetRXFIFOAvailable((mxc_spi_reva_regs_t *)spi); +} + +unsigned int MXC_SPI_WriteTXFIFO(mxc_spi_regs_t *spi, unsigned char *bytes, unsigned int len) +{ + return MXC_SPI_RevA1_WriteTXFIFO((mxc_spi_reva_regs_t *)spi, bytes, len); +} + +unsigned int MXC_SPI_GetTXFIFOAvailable(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetTXFIFOAvailable((mxc_spi_reva_regs_t *)spi); +} + +void MXC_SPI_ClearRXFIFO(mxc_spi_regs_t *spi) +{ + MXC_SPI_RevA1_ClearRXFIFO((mxc_spi_reva_regs_t *)spi); +} + +void MXC_SPI_ClearTXFIFO(mxc_spi_regs_t *spi) +{ + MXC_SPI_RevA1_ClearTXFIFO((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_SetRXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes) +{ + return MXC_SPI_RevA1_SetRXThreshold((mxc_spi_reva_regs_t *)spi, numBytes); +} + +unsigned int MXC_SPI_GetRXThreshold(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetRXThreshold((mxc_spi_reva_regs_t *)spi); +} + +int MXC_SPI_SetTXThreshold(mxc_spi_regs_t *spi, unsigned int numBytes) +{ + return MXC_SPI_RevA1_SetTXThreshold((mxc_spi_reva_regs_t *)spi, numBytes); +} + +unsigned int MXC_SPI_GetTXThreshold(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetTXThreshold((mxc_spi_reva_regs_t *)spi); +} + +unsigned int MXC_SPI_GetFlags(mxc_spi_regs_t *spi) +{ + return MXC_SPI_RevA1_GetFlags((mxc_spi_reva_regs_t *)spi); +} + +void MXC_SPI_ClearFlags(mxc_spi_regs_t *spi) +{ + MXC_SPI_RevA1_ClearFlags((mxc_spi_reva_regs_t *)spi); +} + +void MXC_SPI_EnableInt(mxc_spi_regs_t *spi, unsigned int intEn) +{ + MXC_SPI_RevA1_EnableInt((mxc_spi_reva_regs_t *)spi, intEn); +} + +void MXC_SPI_DisableInt(mxc_spi_regs_t *spi, unsigned int intDis) +{ + MXC_SPI_RevA1_DisableInt((mxc_spi_reva_regs_t *)spi, intDis); +} + +int MXC_SPI_MasterTransaction(mxc_spi_req_t *req) +{ + return MXC_SPI_RevA1_MasterTransaction((mxc_spi_reva_req_t *)req); +} + +int MXC_SPI_MasterTransactionAsync(mxc_spi_req_t *req) +{ + return MXC_SPI_RevA1_MasterTransactionAsync((mxc_spi_reva_req_t *)req); +} + +int MXC_SPI_MasterTransactionDMA(mxc_spi_req_t *req) +{ + int reqselTx = -1; + int reqselRx = -1; + + int spi_num; + + spi_num = MXC_SPI_GET_IDX(req->spi); + MXC_ASSERT(spi_num >= 0); + + if (req->txData != NULL) { + switch (spi_num) { + case 0: + reqselTx = MXC_DMA_REQUEST_SPI1TX; + break; + + case 1: + reqselTx = MXC_DMA_REQUEST_SPI0TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (req->rxData != NULL) { + switch (spi_num) { + case 0: + reqselRx = MXC_DMA_REQUEST_SPI1RX; + break; + + case 1: + reqselRx = MXC_DMA_REQUEST_SPI0RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_SPI_RevA1_MasterTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx, + MXC_DMA); +} + +int MXC_SPI_SlaveTransaction(mxc_spi_req_t *req) +{ + return MXC_SPI_RevA1_SlaveTransaction((mxc_spi_reva_req_t *)req); +} + +int MXC_SPI_SlaveTransactionAsync(mxc_spi_req_t *req) +{ + return MXC_SPI_RevA1_SlaveTransactionAsync((mxc_spi_reva_req_t *)req); +} + +int MXC_SPI_SlaveTransactionDMA(mxc_spi_req_t *req) +{ + int reqselTx = -1; + int reqselRx = -1; + + int spi_num; + + spi_num = MXC_SPI_GET_IDX(req->spi); + MXC_ASSERT(spi_num >= 0); + + if (req->txData != NULL) { + switch (spi_num) { + case 0: + reqselTx = MXC_DMA_REQUEST_SPI1TX; + break; + + case 1: + reqselTx = MXC_DMA_REQUEST_SPI0TX; + break; + + default: + return E_BAD_PARAM; + break; + } + } + + if (req->rxData != NULL) { + switch (spi_num) { + case 0: + reqselRx = MXC_DMA_REQUEST_SPI1RX; + break; + + case 1: + reqselRx = MXC_DMA_REQUEST_SPI0RX; + break; + + default: + return E_BAD_PARAM; + break; + } + } + + return MXC_SPI_RevA1_SlaveTransactionDMA((mxc_spi_reva_req_t *)req, reqselTx, reqselRx, + MXC_DMA); +} + +int MXC_SPI_SetDefaultTXData(mxc_spi_regs_t *spi, unsigned int defaultTXData) +{ + return MXC_SPI_RevA1_SetDefaultTXData((mxc_spi_reva_regs_t *)spi, defaultTXData); +} + +void MXC_SPI_AbortAsync(mxc_spi_regs_t *spi) +{ + MXC_SPI_RevA1_AbortAsync((mxc_spi_reva_regs_t *)spi); +} + +void MXC_SPI_AsyncHandler(mxc_spi_regs_t *spi) +{ + MXC_SPI_RevA1_AsyncHandler((mxc_spi_reva_regs_t *)spi); +} + +void MXC_SPI_HWSSControl(mxc_spi_regs_t *spi, int state) +{ + MXC_SPI_RevA1_HWSSControl((mxc_spi_reva_regs_t *)spi, state); +} diff --git a/Libraries/PeriphDrivers/Source/SYS/pins_me30.c b/Libraries/PeriphDrivers/Source/SYS/pins_me30.c new file mode 100644 index 00000000000..79c0d33bc52 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/SYS/pins_me30.c @@ -0,0 +1,163 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "gpio.h" +#include "mxc_device.h" + +/***** Definitions *****/ + +/***** Global Variables *****/ + +// clang-format off +const mxc_gpio_cfg_t gpio_cfg_extclk = { MXC_GPIO0, (MXC_GPIO_PIN_12 | MXC_GPIO_PIN_13), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_i2c0 = { MXC_GPIO0, (MXC_GPIO_PIN_10 | MXC_GPIO_PIN_11), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_i2c1 = { MXC_GPIO0, (MXC_GPIO_PIN_16 | MXC_GPIO_PIN_17), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_i2c2 = { MXC_GPIO0, (MXC_GPIO_PIN_30 | MXC_GPIO_PIN_31), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_uart0 = { MXC_GPIO0, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart0_flow = { MXC_GPIO0, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart0_flow_disable = { MXC_GPIO0, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), MXC_GPIO_FUNC_IN, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart1 = { MXC_GPIO0, (MXC_GPIO_PIN_12 | MXC_GPIO_PIN_13), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart1_flow = { MXC_GPIO0, (MXC_GPIO_PIN_14 | MXC_GPIO_PIN_15), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart1_flow_disable = { MXC_GPIO0, (MXC_GPIO_PIN_14 | MXC_GPIO_PIN_15), MXC_GPIO_FUNC_IN, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart2 = { MXC_GPIO1, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart2_flow = { MXC_GPIO0, (MXC_GPIO_PIN_30 | MXC_GPIO_PIN_31), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart2_flow_disable = { MXC_GPIO0, (MXC_GPIO_PIN_30 | MXC_GPIO_PIN_31), MXC_GPIO_FUNC_IN, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_uart3 = { MXC_GPIO2, (MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t antenna_ctrl0 = { MXC_GPIO1, (MXC_GPIO_PIN_8 | MXC_GPIO_PIN_9), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t antenna_ctrl1 = { MXC_GPIO1, (MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +// Timers are only defined once, depending on package, each timer could be mapped to other pins +const mxc_gpio_cfg_t gpio_cfg_tmr0 = { MXC_GPIO0, (MXC_GPIO_PIN_2), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr0b = { MXC_GPIO0, (MXC_GPIO_PIN_3), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr1 = { MXC_GPIO0, (MXC_GPIO_PIN_14), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr1b = { MXC_GPIO0, (MXC_GPIO_PIN_15), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr1_MapB = { MXC_GPIO0, (MXC_GPIO_PIN_20), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr2 = { MXC_GPIO0, (MXC_GPIO_PIN_26), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr2b = { MXC_GPIO0, (MXC_GPIO_PIN_27), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr3 = { MXC_GPIO1, (MXC_GPIO_PIN_6), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_tmr3b = { MXC_GPIO1, (MXC_GPIO_PIN_7), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_i2s0 = { MXC_GPIO1, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3 | MXC_GPIO_PIN_4 | MXC_GPIO_PIN_5), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_i2s0_clkext = { MXC_GPIO0, MXC_GPIO_PIN_14, MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_rtcsqw = { MXC_GPIO3, MXC_GPIO_PIN_1, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0}; + +const mxc_gpio_cfg_t gpio_cfg_pt0 = { MXC_GPIO0, MXC_GPIO_PIN_18, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_pt1 = { MXC_GPIO0, MXC_GPIO_PIN_19, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_pt2 = { MXC_GPIO0, MXC_GPIO_PIN_16, MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_pt3 = { MXC_GPIO0, MXC_GPIO_PIN_17, MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +// 1-Wire pins need to be at 3.3V so that MXC_GPIO_VSSEL_VDDIOH is selected. +const mxc_gpio_cfg_t gpio_cfg_owm = { MXC_GPIO0, (MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_owmb = { MXC_GPIO0, (MXC_GPIO_PIN_18 | MXC_GPIO_PIN_19), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_adc_ain0 = { MXC_GPIO2, MXC_GPIO_PIN_0, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_adc_ain1 = { MXC_GPIO2, MXC_GPIO_PIN_1, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_adc_ain2 = { MXC_GPIO2, MXC_GPIO_PIN_2, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_adc_ain3 = { MXC_GPIO2, MXC_GPIO_PIN_3, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_adc_ain4 = { MXC_GPIO2, MXC_GPIO_PIN_4, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_adc_ain5 = { MXC_GPIO2, MXC_GPIO_PIN_5, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_adc_ain6 = { MXC_GPIO2, MXC_GPIO_PIN_6, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_adc_ain7 = { MXC_GPIO2, MXC_GPIO_PIN_7, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_rv_jtag = { MXC_GPIO1, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1 | MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), + MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_cmp0 = { MXC_GPIO2, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_cmp1 = { MXC_GPIO2, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_cmp2 = { MXC_GPIO2, (MXC_GPIO_PIN_4 | MXC_GPIO_PIN_5), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_cmp3 = { MXC_GPIO2, (MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +// SPI v2 Pin Definitions +const mxc_gpio_cfg_t gpio_cfg_spi0_standard = { MXC_GPIO0, (MXC_GPIO_PIN_5 | MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi0_3wire = { MXC_GPIO0, (MXC_GPIO_PIN_5 | MXC_GPIO_PIN_7), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi0_dual = { MXC_GPIO0, (MXC_GPIO_PIN_5 | MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi0_quad = { MXC_GPIO0, (MXC_GPIO_PIN_5 | MXC_GPIO_PIN_6 | MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8 | MXC_GPIO_PIN_9), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +const mxc_gpio_cfg_t gpio_cfg_spi1_standard = { MXC_GPIO0, (MXC_GPIO_PIN_21 | MXC_GPIO_PIN_22 | MXC_GPIO_PIN_23), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi1_3wire = { MXC_GPIO0, (MXC_GPIO_PIN_21 | MXC_GPIO_PIN_23), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi1_dual = { MXC_GPIO0, (MXC_GPIO_PIN_21 | MXC_GPIO_PIN_22 | MXC_GPIO_PIN_23), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi1_quad = { MXC_GPIO0, (MXC_GPIO_PIN_21 | MXC_GPIO_PIN_22 | MXC_GPIO_PIN_23 | MXC_GPIO_PIN_24 | MXC_GPIO_PIN_25), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; + +// SPI v2 Target Selects Pin Definitions +const mxc_gpio_cfg_t gpio_cfg_spi0_ts0 = { MXC_GPIO0, MXC_GPIO_PIN_4, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi0_ts1 = { MXC_GPIO0, MXC_GPIO_PIN_26, MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi0_ts2 = { MXC_GPIO0, MXC_GPIO_PIN_27, MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; +const mxc_gpio_cfg_t gpio_cfg_spi1_ts0 = { MXC_GPIO0, MXC_GPIO_PIN_20, MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }; diff --git a/Libraries/PeriphDrivers/Source/SYS/sys_me30.c b/Libraries/PeriphDrivers/Source/SYS/sys_me30.c new file mode 100644 index 00000000000..4ad2ab85b67 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/SYS/sys_me30.c @@ -0,0 +1,605 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * @file mxc_sys.c + * @brief System layer driver. + * @details This driver is used to control the system layer of the device. + */ + +/* **** Includes **** */ +#include +#include +#include "mxc_device.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "mxc_delay.h" +#include "lpgcr_regs.h" +#include "gcr_regs.h" +#include "fcr_regs.h" +#include "mcr_regs.h" +#include "pwrseq_regs.h" +#include "aes.h" +#include "flc.h" + +/** + * @ingroup mxc_sys + * @{ + */ + +/* **** Definitions **** */ +#define MXC_SYS_CLOCK_TIMEOUT MSEC(1) + +// DAP Lock macros +#define INFOBLOCK_DAP_LOCK_OFFSET 0x30 +#define DAP_LOCK_SEQUENCE_01 0x5A5AA5A5 +#define DAP_LOCK_SEQUENCE_23 0xFFFFFFFF + +/* **** Globals **** */ + +/* Symbol defined when loading RISCV image */ +extern uint32_t _binary_riscv_bin_start; + +/* **** Functions **** */ + +/* ************************************************************************** */ +int MXC_SYS_GetUSN(uint8_t *usn, uint8_t *checksum) +{ + int err = E_NO_ERROR; + uint32_t *infoblock = (uint32_t *)MXC_INFO0_MEM_BASE; + + if (usn == NULL) { + return E_NULL_PTR; + } + + /* Read the USN from the info block */ + MXC_FLC_UnlockInfoBlock(MXC_INFO0_MEM_BASE); + + memset(usn, 0, MXC_SYS_USN_CHECKSUM_LEN); + + usn[0] = (infoblock[0] & 0x007F8000) >> 15; + usn[1] = (infoblock[0] & 0x7F800000) >> 23; + usn[2] = (infoblock[1] & 0x0000007F) << 1; + usn[2] |= (infoblock[0] & 0x80000000) >> 31; + usn[3] = (infoblock[1] & 0x00007F80) >> 7; + usn[4] = (infoblock[1] & 0x007F8000) >> 15; + usn[5] = (infoblock[1] & 0x7F800000) >> 23; + usn[6] = (infoblock[2] & 0x007F8000) >> 15; + usn[7] = (infoblock[2] & 0x7F800000) >> 23; + usn[8] = (infoblock[3] & 0x0000007F) << 1; + usn[8] |= (infoblock[2] & 0x80000000) >> 31; + usn[9] = (infoblock[3] & 0x00007F80) >> 7; + usn[10] = (infoblock[3] & 0x007F8000) >> 15; + + /* If requested, verify and return the checksum */ + if (checksum != NULL) { + uint8_t check_csum[MXC_SYS_USN_CHECKSUM_LEN]; + uint8_t aes_key[MXC_SYS_USN_CHECKSUM_LEN] = { 0 }; // NULL Key (per checksum spec) + + checksum[0] = ((infoblock[3] & 0x7F800000) >> 23); + checksum[1] = ((infoblock[4] & 0x007F8000) >> 15); + + err = MXC_AES_Init(); + if (err) { + MXC_FLC_LockInfoBlock(MXC_INFO0_MEM_BASE); + return err; + } + + // Set NULL Key + MXC_AES_SetExtKey((const void *)aes_key, MXC_AES_128BITS); + + // Compute Checksum + mxc_aes_req_t aes_req; + aes_req.length = MXC_SYS_USN_CHECKSUM_LEN / 4; + aes_req.inputData = (uint32_t *)usn; + aes_req.resultData = (uint32_t *)check_csum; + aes_req.keySize = MXC_AES_128BITS; + aes_req.encryption = MXC_AES_ENCRYPT_EXT_KEY; + aes_req.callback = NULL; + + err = MXC_AES_Generic(&aes_req); + if (err) { + MXC_FLC_LockInfoBlock(MXC_INFO0_MEM_BASE); + return err; + } + + MXC_AES_Shutdown(); + + // Verify Checksum + if (check_csum[0] != checksum[1] || check_csum[1] != checksum[0]) { + MXC_FLC_LockInfoBlock(MXC_INFO0_MEM_BASE); + return E_INVALID; + } + } + + /* Add the info block checksum to the USN */ + usn[11] = ((infoblock[3] & 0x7F800000) >> 23); + usn[12] = ((infoblock[4] & 0x007F8000) >> 15); + + MXC_FLC_LockInfoBlock(MXC_INFO0_MEM_BASE); + + return err; +} + +/* ************************************************************************** */ +int MXC_SYS_GetRevision(void) +{ + return MXC_GCR->revision; +} + +/* ************************************************************************** */ +int MXC_SYS_IsClockEnabled(mxc_sys_periph_clock_t clock) +{ + /* The mxc_sys_periph_clock_t enum uses enum values that are the offset by 32 and 64 for the perckcn1 register. */ + if (clock > 63) { + clock -= 64; + return !(MXC_LPGCR->pclkdis & (0x1 << clock)); + } else if (clock > 31) { + clock -= 32; + return !(MXC_GCR->pclkdis1 & (0x1 << clock)); + } else { + return !(MXC_GCR->pclkdis0 & (0x1 << clock)); + } +} + +/* ************************************************************************** */ +void MXC_SYS_ClockDisable(mxc_sys_periph_clock_t clock) +{ + /* The mxc_sys_periph_clock_t enum uses enum values that are the offset by 32 and 64 for the perckcn1 register. */ + if (clock > 63) { + clock -= 64; + MXC_LPGCR->pclkdis |= (0x1 << clock); + } else if (clock > 31) { + clock -= 32; + MXC_GCR->pclkdis1 |= (0x1 << clock); + } else { + MXC_GCR->pclkdis0 |= (0x1 << clock); + } +} + +/* ************************************************************************** */ +void MXC_SYS_ClockEnable(mxc_sys_periph_clock_t clock) +{ + /* The mxc_sys_periph_clock_t enum uses enum values that are the offset by 32 and 64 for the perckcn1 register. */ + if (clock > 63) { + clock -= 64; + MXC_LPGCR->pclkdis &= ~(0x1 << clock); + } else if (clock > 31) { + clock -= 32; + MXC_GCR->pclkdis1 &= ~(0x1 << clock); + } else { + MXC_GCR->pclkdis0 &= ~(0x1 << clock); + } +} +/* ************************************************************************** */ +void MXC_SYS_RTCClockEnable() +{ + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERTCO_EN; +} + +/* ************************************************************************** */ +int MXC_SYS_RTCClockDisable(void) +{ + /* Check that the RTC is not the system clock source */ + if ((MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL) != MXC_S_GCR_CLKCTRL_SYSCLK_SEL_ERTCO) { + MXC_GCR->clkctrl &= ~MXC_F_GCR_CLKCTRL_ERTCO_EN; + return E_NO_ERROR; + } else { + return E_BAD_STATE; + } +} + +#if TARGET_NUM == 32655 +/******************************************************************************/ +void MXC_SYS_RTCClockPowerDownEn(void) +{ + MXC_MCR->ctrl |= MXC_F_MCR_CTRL_32KOSC_EN; +} + +/******************************************************************************/ +void MXC_SYS_RTCClockPowerDownDis(void) +{ + MXC_MCR->ctrl &= ~MXC_F_MCR_CTRL_32KOSC_EN; +} +#endif //TARGET_NUM == 32655 + +/******************************************************************************/ +int MXC_SYS_ClockSourceEnable(mxc_sys_system_clock_t clock) +{ + switch (clock) { + case MXC_SYS_CLOCK_IPO: + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_IPO_EN; + return MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_IPO_RDY); + break; + + case MXC_SYS_CLOCK_IBRO: + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_IBRO_EN; + return MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_IBRO_RDY); + break; + + case MXC_SYS_CLOCK_EXTCLK: + // No "RDY" bit to monitor, so just configure the GPIO + return MXC_GPIO_Config(&gpio_cfg_extclk); + break; + + case MXC_SYS_CLOCK_INRO: + // The 80k clock is always enabled + return MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_INRO_RDY); + break; + + case MXC_SYS_CLOCK_ERFO: + MXC_GCR->btleldoctrl |= MXC_F_GCR_BTLELDOCTRL_LDOTXEN | MXC_F_GCR_BTLELDOCTRL_LDORXEN; + + /* Initialize kickstart circuit + Select Kick start circuit clock source- IPO/ISO + */ + MXC_FCR->erfoks = ((MXC_S_FCR_ERFOKS_KSCLKSEL_ISO) + /* Set Drive strengh - 0x1,0x2,0x3 */ + | ((0x1) << MXC_F_FCR_ERFOKS_KSERFODRIVER_POS) + /* Set kick count 1-127 */ + | (0x8) + /* Set double pulse length On/Off*/ + | (0 & MXC_F_FCR_ERFOKS_KSERFO2X) + /* Enable On/Off */ + | (MXC_F_FCR_ERFOKS_KSERFO_EN)); + + /* Enable ERFO */ + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERFO_EN; + return MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_ERFO_RDY); + break; + + case MXC_SYS_CLOCK_ERTCO: + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERTCO_EN; + return MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_ERTCO_RDY); + break; + + default: + return E_BAD_PARAM; + break; + } +} + +/******************************************************************************/ +int MXC_SYS_ClockSourceDisable(mxc_sys_system_clock_t clock) +{ + uint32_t current_clock; + + current_clock = MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL; + + // Don't turn off the clock we're running on + if (clock == current_clock) { + return E_BAD_PARAM; + } + + switch (clock) { + case MXC_SYS_CLOCK_IPO: + MXC_GCR->clkctrl &= ~MXC_F_GCR_CLKCTRL_IPO_EN; + break; + + case MXC_SYS_CLOCK_IBRO: + MXC_GCR->clkctrl &= ~MXC_F_GCR_CLKCTRL_IBRO_EN; + break; + + case MXC_SYS_CLOCK_EXTCLK: + /* + There's not a great way to disable the external clock. + Deinitializing the GPIO here may have unintended consequences + for application code. + Selecting a different system clock source is sufficient + to "disable" the EXT_CLK source. + */ + break; + + case MXC_SYS_CLOCK_INRO: + // The 80k clock is always enabled + break; + + case MXC_SYS_CLOCK_ERFO: + MXC_GCR->clkctrl &= ~MXC_F_GCR_CLKCTRL_ERFO_EN; + break; + + case MXC_SYS_CLOCK_ERTCO: + MXC_GCR->clkctrl &= ~MXC_F_GCR_CLKCTRL_ERTCO_EN; + break; + + default: + return E_BAD_PARAM; + } + + return E_NO_ERROR; +} + +/* ************************************************************************** */ +int MXC_SYS_Clock_Timeout(uint32_t ready) +{ +#ifdef __riscv + // The current RISC-V implementation is to block until the clock is ready. + // We do not have access to a system tick in the RV core. + while (!(MXC_GCR->clkctrl & ready)) {} + return E_NO_ERROR; +#else +#ifndef BOARD_ME17_TESTER + // Start timeout, wait for ready + MXC_DelayAsync(MXC_SYS_CLOCK_TIMEOUT, NULL); + + do { + if (MXC_GCR->clkctrl & ready) { + MXC_DelayAbort(); + return E_NO_ERROR; + } + } while (MXC_DelayCheck() == E_BUSY); + + return E_TIME_OUT; +#else + + return E_NO_ERROR; +#endif + +#endif // __riscv +} +/* ************************************************************************** */ +int MXC_SYS_Clock_Select(mxc_sys_system_clock_t clock) +{ + uint32_t current_clock; + int err = E_NO_ERROR; + + // Save the current system clock + current_clock = MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL; + + switch (clock) { + case MXC_SYS_CLOCK_ISO: + + // Enable ISO clock + if (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_ISO_EN)) { + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ISO_EN; + + // Check if ISO clock is ready + if (MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_ISO_RDY) != E_NO_ERROR) { + return E_TIME_OUT; + } + } + + // Set ISO clock as System Clock + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, + MXC_S_GCR_CLKCTRL_SYSCLK_SEL_ISO); + + break; + case MXC_SYS_CLOCK_IPO: + + // Enable IPO clock + if (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_IPO_EN)) { + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_IPO_EN; + + // Check if IPO clock is ready + if (MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_IPO_RDY) != E_NO_ERROR) { + return E_TIME_OUT; + } + } + + // Set IPO clock as System Clock + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, + MXC_S_GCR_CLKCTRL_SYSCLK_SEL_IPO); + + break; + + case MXC_SYS_CLOCK_IBRO: + + // Enable IBRO clock + if (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_IBRO_EN)) { + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_IBRO_EN; + + // Check if IBRO clock is ready + if (MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_IBRO_RDY) != E_NO_ERROR) { + return E_TIME_OUT; + } + } + + // Set IBRO clock as System Clock + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, + MXC_S_GCR_CLKCTRL_SYSCLK_SEL_IBRO); + + break; + + case MXC_SYS_CLOCK_EXTCLK: + /* + There's not "EXT_CLK RDY" bit for the ME17, so we'll + blindly enable (configure GPIO) the external clock every time. + */ + err = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_EXTCLK); + if (err) + return err; + + // Set EXT clock as System Clock + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, + MXC_S_GCR_CLKCTRL_SYSCLK_SEL_EXTCLK); + + break; + + case MXC_SYS_CLOCK_ERFO: + + // Enable ERFO clock + if (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_ERFO_EN)) { + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERFO_EN; + + // Check if ERFO clock is ready + if (MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_ERFO_RDY) != E_NO_ERROR) { + return E_TIME_OUT; + } + } + + // Set ERFO clock as System Clock + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, + MXC_S_GCR_CLKCTRL_SYSCLK_SEL_ERFO); + + break; + + case MXC_SYS_CLOCK_INRO: + // Set INRO clock as System Clock + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, + MXC_S_GCR_CLKCTRL_SYSCLK_SEL_INRO); + + break; + + case MXC_SYS_CLOCK_ERTCO: + + // Enable ERTCO clock + if (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_ERTCO_EN)) { + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERTCO_EN; + + // Check if ERTCO clock is ready + if (MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_ERTCO_RDY) != E_NO_ERROR) { + return E_TIME_OUT; + } + } + + // Set ERTCO clock as System Clock + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, + MXC_S_GCR_CLKCTRL_SYSCLK_SEL_ERTCO); + + break; + + default: + return E_BAD_PARAM; + } + + // Wait for system clock to be ready + if (MXC_SYS_Clock_Timeout(MXC_F_GCR_CLKCTRL_SYSCLK_RDY) != E_NO_ERROR) { + // Restore the old system clock if timeout + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_SEL, current_clock); + + return E_TIME_OUT; + } + + // Update the system core clock + SystemCoreClockUpdate(); + + return E_NO_ERROR; +} + +/* ************************************************************************** */ +void MXC_SYS_SetClockDiv(mxc_sys_system_clock_div_t div) +{ + /* Return if this setting is already current */ + if (div == MXC_SYS_GetClockDiv()) { + return; + } + + MXC_SETFIELD(MXC_GCR->clkctrl, MXC_F_GCR_CLKCTRL_SYSCLK_DIV, div); + + SystemCoreClockUpdate(); +} + +/* ************************************************************************** */ +mxc_sys_system_clock_div_t MXC_SYS_GetClockDiv(void) +{ + return (MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_DIV); +} + +/* ************************************************************************** */ +void MXC_SYS_Reset_Periph(mxc_sys_reset_t reset) +{ + /* The mxc_sys_reset_t enum uses enum values that are the offset by 32 and 64 for the rst register. */ + if (reset > 63) { + reset -= 64; + MXC_LPGCR->rst = (0x1 << reset); + while (MXC_LPGCR->rst & (0x1 << reset)) {} + } else if (reset > 31) { + reset -= 32; + MXC_GCR->rst1 = (0x1 << reset); + while (MXC_GCR->rst1 & (0x1 << reset)) {} + } else { + MXC_GCR->rst0 = (0x1 << reset); + while (MXC_GCR->rst0 & (0x1 << reset)) {} + } +} + +/* ************************************************************************** */ +void MXC_SYS_RISCVRun(void) +{ + /* Disable the the RSCV */ + MXC_GCR->pclkdis1 |= MXC_F_GCR_PCLKDIS1_CPU1; + + /* Set the interrupt vector base address */ + MXC_FCR->urvbootaddr = (uint32_t)&_binary_riscv_bin_start; + + /* Power up the RSCV */ + MXC_GCR->pclkdis1 &= ~(MXC_F_GCR_PCLKDIS1_CPU1); + + /* CPU1 reset */ + MXC_GCR->rst1 |= MXC_F_GCR_RST1_CPU1; +} + +/* ************************************************************************** */ +void MXC_SYS_RISCVShutdown(void) +{ + /* Disable the the RSCV */ + MXC_GCR->pclkdis1 |= MXC_F_GCR_PCLKDIS1_CPU1; +} + +/* ************************************************************************** */ +uint32_t MXC_SYS_RiscVClockRate(void) +{ + // If in LPM mode and the PCLK is selected as the RV32 clock source, + if (((MXC_GCR->pm & MXC_F_GCR_PM_MODE) == MXC_S_GCR_PM_MODE_LPM) && + (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_LPMCLKSEL)) { + return ISO_FREQ; + } else { + return PeripheralClock; + } +} + +/* ************************************************************************** */ +int MXC_SYS_LockDAP_Permanent(void) +{ +#ifdef DEBUG + // Locking the DAP is not supported while in DEBUG. + // To use this function, build for release ("make release") + // or set DEBUG = 0 + // (see https://analogdevicesinc.github.io/msdk/USERGUIDE/#build-tables) + return E_NOT_SUPPORTED; +#else + int err; + uint32_t info_blk_addr; + uint32_t lock_sequence[4]; + + // Infoblock address to write lock sequence to + info_blk_addr = MXC_INFO_MEM_BASE + INFOBLOCK_DAP_LOCK_OFFSET; + + // Set lock sequence + lock_sequence[0] = DAP_LOCK_SEQUENCE_01; + lock_sequence[1] = DAP_LOCK_SEQUENCE_01; + lock_sequence[2] = DAP_LOCK_SEQUENCE_23; + lock_sequence[3] = DAP_LOCK_SEQUENCE_23; + + // Initialize FLC + MXC_FLC_Init(); + + // Unlock infoblock + MXC_FLC_UnlockInfoBlock(info_blk_addr); + + // Write DAP lock sequence to infoblock + err = MXC_FLC_Write128(info_blk_addr, lock_sequence); + + // Re-lock infoblock + MXC_FLC_LockInfoBlock(info_blk_addr); + + return err; +#endif +} + +/**@} end of mxc_sys */ diff --git a/Libraries/PeriphDrivers/Source/TMR/tmr_me30.c b/Libraries/PeriphDrivers/Source/TMR/tmr_me30.c new file mode 100644 index 00000000000..8c4404d6b6a --- /dev/null +++ b/Libraries/PeriphDrivers/Source/TMR/tmr_me30.c @@ -0,0 +1,388 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "tmr.h" +#include "tmr_revb.h" +#include "tmr_common.h" +#include "lpgcr_regs.h" +#include "stdbool.h" + +int MXC_TMR_Init(mxc_tmr_regs_t *tmr, mxc_tmr_cfg_t *cfg, bool init_pins) +{ + int tmr_id = MXC_TMR_GET_IDX(tmr); + uint8_t clockSource = MXC_TMR_CLK0; + + if (cfg == NULL) { + return E_NULL_PTR; + } + + MXC_ASSERT(tmr_id >= 0); + + switch (cfg->clock) { + case MXC_TMR_ISO_CLK: + if (tmr_id > 3) { // Timers 4-5 do not support this clock source + return E_NOT_SUPPORTED; + } + + clockSource = MXC_TMR_CLK1; + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ISO); + MXC_TMR_RevB_SetClockSourceFreq((mxc_tmr_revb_regs_t *)tmr, ISO_FREQ); + break; + + case MXC_TMR_IBRO_CLK: + if (tmr_id > 3) { // Timers 4-5 do not support this clock source + return E_NOT_SUPPORTED; + } + + clockSource = MXC_TMR_CLK2; + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_TMR_RevB_SetClockSourceFreq((mxc_tmr_revb_regs_t *)tmr, IBRO_FREQ); + break; + + case MXC_TMR_IBRO_DIV8_CLK: + if (tmr_id != 5) { // Only timer 5 supports this clock source + return E_NOT_SUPPORTED; + } + + clockSource = MXC_TMR_CLK1; + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + MXC_TMR_RevB_SetClockSourceFreq((mxc_tmr_revb_regs_t *)tmr, (IBRO_FREQ / 8)); + break; + +#if (TARGET_NUM != 32680) + case MXC_TMR_ERTCO_CLK: + if (tmr_id == 4) { + clockSource = MXC_TMR_CLK1; + } else if (tmr_id < 4) { + clockSource = MXC_TMR_CLK3; + } else { // Timers 5 do not support this clock source + return E_NOT_SUPPORTED; + } + + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); + MXC_TMR_RevB_SetClockSourceFreq((mxc_tmr_revb_regs_t *)tmr, ERTCO_FREQ); + break; +#endif + + case MXC_TMR_INRO_CLK: + if (tmr_id < 4) { // Timers 0-3 do not support this clock source + return E_NOT_SUPPORTED; + } + + clockSource = MXC_TMR_CLK2; + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_INRO); + MXC_TMR_RevB_SetClockSourceFreq((mxc_tmr_revb_regs_t *)tmr, INRO_FREQ); + break; + + default: + MXC_TMR_RevB_SetClockSourceFreq((mxc_tmr_revb_regs_t *)tmr, PeripheralClock); + break; + } + +#ifndef MSDK_NO_GPIO_CLK_INIT + //enable peripheral clock and configure gpio pins + switch (tmr_id) { + case 0: + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_TMR0); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TMR0); + + if (init_pins) { + if (cfg->bitMode != MXC_TMR_BIT_MODE_16B) { + MXC_GPIO_Config(&gpio_cfg_tmr0); + } else { + MXC_GPIO_Config(&gpio_cfg_tmr0b); + } + } + + break; + + case 1: + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_TMR1); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TMR1); + + if (init_pins) { + if (cfg->bitMode != MXC_TMR_BIT_MODE_16B) { + MXC_GPIO_Config(&gpio_cfg_tmr1); + } else { + MXC_GPIO_Config(&gpio_cfg_tmr1b); + } + } + + break; + + case 2: + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_TMR2); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TMR2); + + if (init_pins) { + if (cfg->bitMode != MXC_TMR_BIT_MODE_16B) { + MXC_GPIO_Config(&gpio_cfg_tmr2); + } else { + MXC_GPIO_Config(&gpio_cfg_tmr2b); + } + } + + break; + + case 3: + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_TMR3); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TMR3); + + if (init_pins) { + if (cfg->bitMode != MXC_TMR_BIT_MODE_16B) { + MXC_GPIO_Config(&gpio_cfg_tmr3); + } else { + MXC_GPIO_Config(&gpio_cfg_tmr3b); + } + } + + break; + + case 4: + MXC_SYS_Reset_Periph(MXC_SYS_RESET_TMR4); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TMR4); + break; + + case 5: + MXC_SYS_Reset_Periph(MXC_SYS_RESET_TMR5); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TMR5); + break; + } +#else + (void)init_pins; +#endif + + return MXC_TMR_RevB_Init((mxc_tmr_revb_regs_t *)tmr, cfg, clockSource); +} + +void MXC_TMR_Shutdown(mxc_tmr_regs_t *tmr) +{ + MXC_ASSERT(MXC_TMR_GET_IDX(tmr) >= 0); + + MXC_TMR_RevB_Shutdown((mxc_tmr_revb_regs_t *)tmr); + + // System settigns + //diasble peripheral clock + if (tmr == MXC_TMR0) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_TMR0); + } + + if (tmr == MXC_TMR1) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_TMR1); + } + + if (tmr == MXC_TMR2) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_TMR2); + } + + if (tmr == MXC_TMR3) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_TMR3); + } + + if (tmr == MXC_TMR4) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_TMR4); + } + + if (tmr == MXC_TMR5) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_TMR5); + } +} + +void MXC_TMR_Start(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_RevB_Start((mxc_tmr_revb_regs_t *)tmr); +} + +void MXC_TMR_Stop(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_RevB_Stop((mxc_tmr_revb_regs_t *)tmr); +} + +int MXC_TMR_SetPWM(mxc_tmr_regs_t *tmr, uint32_t pwm) +{ + return MXC_TMR_RevB_SetPWM((mxc_tmr_revb_regs_t *)tmr, pwm); +} + +uint32_t MXC_TMR_GetCompare(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_RevB_GetCompare((mxc_tmr_revb_regs_t *)tmr); +} + +uint32_t MXC_TMR_GetCapture(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_RevB_GetCapture((mxc_tmr_revb_regs_t *)tmr); +} + +uint32_t MXC_TMR_GetPeriod(mxc_tmr_regs_t *tmr, mxc_tmr_clock_t clock, uint32_t prescalar, + uint32_t frequency) +{ + uint32_t clockFrequency = PeripheralClock; + int tmr_id = MXC_TMR_GET_IDX(tmr); + + MXC_ASSERT(tmr_id >= 0); + + if (tmr_id > 3) { + switch (clock) { + case MXC_TMR_APB_CLK: + clockFrequency = IBRO_FREQ; + break; + +#if (TARGET_NUM != 32680) + case MXC_TMR_ERTCO_CLK: + clockFrequency = ERTCO_FREQ; + break; +#endif + + case MXC_TMR_INRO_CLK: + clockFrequency = INRO_FREQ; + break; + + case MXC_TMR_IBRO_DIV8_CLK: + clockFrequency = IBRO_FREQ / 8; + break; + + default: + break; + } + } else { + switch (clock) { + case MXC_TMR_APB_CLK: + clockFrequency = PeripheralClock; + break; + + case MXC_TMR_ISO_CLK: + clockFrequency = ISO_FREQ; + break; + + case MXC_TMR_IBRO_CLK: + clockFrequency = IBRO_FREQ; + break; + +#if (TARGET_NUM != 32680) + case MXC_TMR_ERTCO_CLK: + clockFrequency = ERTCO_FREQ; + break; +#endif + + default: + break; + } + } + + return MXC_TMR_RevB_GetPeriod((mxc_tmr_revb_regs_t *)tmr, clockFrequency, prescalar, frequency); +} + +uint32_t MXC_TMR_GetCount(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_RevB_GetCount((mxc_tmr_revb_regs_t *)tmr); +} + +void MXC_TMR_ClearFlags(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_RevB_ClearFlags((mxc_tmr_revb_regs_t *)tmr); +} + +uint32_t MXC_TMR_GetFlags(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_RevB_GetFlags((mxc_tmr_revb_regs_t *)tmr); +} + +void MXC_TMR_EnableInt(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_RevB_EnableInt((mxc_tmr_revb_regs_t *)tmr); +} + +void MXC_TMR_DisableInt(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_RevB_DisableInt((mxc_tmr_revb_regs_t *)tmr); +} + +void MXC_TMR_EnableWakeup(mxc_tmr_regs_t *tmr, mxc_tmr_cfg_t *cfg) +{ + MXC_TMR_RevB_EnableWakeup((mxc_tmr_revb_regs_t *)tmr, cfg); +} + +void MXC_TMR_DisableWakeup(mxc_tmr_regs_t *tmr, mxc_tmr_cfg_t *cfg) +{ + MXC_TMR_RevB_DisableWakeup((mxc_tmr_revb_regs_t *)tmr, cfg); +} + +void MXC_TMR_SetCompare(mxc_tmr_regs_t *tmr, uint32_t cmp_cnt) +{ + MXC_TMR_RevB_SetCompare((mxc_tmr_revb_regs_t *)tmr, cmp_cnt); +} + +void MXC_TMR_SetCount(mxc_tmr_regs_t *tmr, uint32_t cnt) +{ + MXC_TMR_RevB_SetCount((mxc_tmr_revb_regs_t *)tmr, cnt); +} + +void MXC_TMR_Delay(mxc_tmr_regs_t *tmr, uint32_t us) +{ + MXC_TMR_Common_Delay(tmr, us); +} + +void MXC_TMR_TO_Start(mxc_tmr_regs_t *tmr, uint32_t us) +{ + MXC_TMR_RevB_TO_Start((mxc_tmr_revb_regs_t *)tmr, us); +} + +int MXC_TMR_TO_Check(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_Common_TO_Check(tmr); +} + +void MXC_TMR_TO_Stop(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_Common_TO_Stop(tmr); +} + +void MXC_TMR_TO_Clear(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_Common_TO_Clear(tmr); +} + +unsigned int MXC_TMR_TO_Elapsed(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_Common_TO_Elapsed(tmr); +} + +unsigned int MXC_TMR_TO_Remaining(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_Common_TO_Remaining(tmr); +} + +void MXC_TMR_SW_Start(mxc_tmr_regs_t *tmr) +{ + MXC_TMR_Common_SW_Start(tmr); +} + +unsigned int MXC_TMR_SW_Stop(mxc_tmr_regs_t *tmr) +{ + return MXC_TMR_Common_SW_Stop(tmr); +} + +int MXC_TMR_GetTime(mxc_tmr_regs_t *tmr, uint32_t ticks, uint32_t *time, mxc_tmr_unit_t *units) +{ + return MXC_TMR_RevB_GetTime((mxc_tmr_revb_regs_t *)tmr, ticks, time, units); +} + +int MXC_TMR_GetTicks(mxc_tmr_regs_t *tmr, uint32_t time, mxc_tmr_unit_t units, uint32_t *ticks) +{ + return MXC_TMR_RevB_GetTicks((mxc_tmr_revb_regs_t *)tmr, time, units, ticks); +} diff --git a/Libraries/PeriphDrivers/Source/TRNG/trng_me30.c b/Libraries/PeriphDrivers/Source/TRNG/trng_me30.c new file mode 100644 index 00000000000..0875de46e2d --- /dev/null +++ b/Libraries/PeriphDrivers/Source/TRNG/trng_me30.c @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "mxc_device.h" +#include "mxc_errors.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "trng_revb.h" +#include "trng.h" + +/* ************************************************************************* */ +/* Global Control/Configuration functions */ +/* ************************************************************************* */ + +/********************************************************/ + +int MXC_TRNG_Init(void) +{ +#ifndef MSDK_NO_GPIO_CLK_INIT + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TRNG); +#endif + + MXC_TRNG_RevB_Init(); + + return E_NO_ERROR; +} + +void MXC_TRNG_EnableInt(void) +{ + MXC_TRNG_RevB_EnableInt((mxc_trng_revb_regs_t *)MXC_TRNG); +} + +void MXC_TRNG_DisableInt(void) +{ + MXC_TRNG_RevB_DisableInt((mxc_trng_revb_regs_t *)MXC_TRNG); +} + +int MXC_TRNG_Shutdown(void) +{ + int error = MXC_TRNG_RevB_Shutdown(); + + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_TRNG); + + return error; +} + +void MXC_TRNG_Handler(void) +{ + MXC_TRNG_RevB_Handler((mxc_trng_revb_regs_t *)MXC_TRNG); +} + +/* ************************************************************************* */ +/* True Random Number Generator (TRNG) functions */ +/* ************************************************************************* */ + +int MXC_TRNG_RandomInt(void) +{ + return MXC_TRNG_RevB_RandomInt((mxc_trng_revb_regs_t *)MXC_TRNG); +} + +int MXC_TRNG_Random(uint8_t *data, uint32_t len) +{ + return MXC_TRNG_RevB_Random(data, len); +} + +void MXC_TRNG_RandomAsync(uint8_t *data, uint32_t len, mxc_trng_complete_t callback) +{ + MXC_TRNG_RevB_RandomAsync((mxc_trng_revb_regs_t *)MXC_TRNG, data, len, callback); +} + +int MXC_TRNG_HealthTest(void) +{ + if ((MXC_SYS_GetRevision() & 0xF0) == 0xA0) { // ME17 Rev. A does not support health tests. + return E_NOT_SUPPORTED; + } + + return MXC_TRNG_RevB_HealthTest((mxc_trng_revb_regs_t *)MXC_TRNG); +} diff --git a/Libraries/PeriphDrivers/Source/UART/uart_me30.c b/Libraries/PeriphDrivers/Source/UART/uart_me30.c new file mode 100644 index 00000000000..32b722c786c --- /dev/null +++ b/Libraries/PeriphDrivers/Source/UART/uart_me30.c @@ -0,0 +1,528 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "uart.h" +#include "mxc_device.h" +#include "mxc_pins.h" +#include "mxc_assert.h" +#include "uart_revb.h" +#include "uart_common.h" +#include "lpgcr_regs.h" +#include "dma.h" + +void MXC_UART_DMACallback(int ch, int error) +{ + MXC_UART_RevB_DMACallback(ch, error); +} + +int MXC_UART_AsyncCallback(mxc_uart_regs_t *uart, int retVal) +{ + return MXC_UART_RevB_AsyncCallback((mxc_uart_revb_regs_t *)uart, retVal); +} + +int MXC_UART_AsyncStop(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_AsyncStop((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock) +{ +#ifndef MSDK_NO_GPIO_CLK_INIT + int retval; + + retval = MXC_UART_Shutdown(uart); + + if (retval) { + return retval; + } + + switch (clock) { +#if TARGET_NUM != 32680 + case MXC_UART_ERTCO_CLK: + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); + break; +#endif + + case MXC_UART_IBRO_CLK: + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO); + break; + + default: + break; + } + + switch (MXC_UART_GET_IDX(uart)) { + case 0: + MXC_GPIO_Config(&gpio_cfg_uart0); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_UART0); + break; + + case 1: + MXC_GPIO_Config(&gpio_cfg_uart1); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_UART1); + break; + + case 2: + MXC_GPIO_Config(&gpio_cfg_uart2); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_UART2); + break; + + case 3: + MXC_GPIO_Config(&gpio_cfg_uart3); + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_UART3); + break; + + default: + return E_BAD_PARAM; + } +#endif // MSDK_NO_GPIO_CLK_INIT + + return MXC_UART_RevB_Init((mxc_uart_revb_regs_t *)uart, baud, clock); +} + +int MXC_UART_Shutdown(mxc_uart_regs_t *uart) +{ + switch (MXC_UART_GET_IDX(uart)) { + case 0: + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_UART0); + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_UART0); + break; + + case 1: + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_UART1); + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_UART1); + break; + + case 2: + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_UART2); + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_UART2); + break; + + case 3: + MXC_SYS_Reset_Periph(MXC_SYS_RESET_UART3); + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_UART3); + break; + + default: + return E_BAD_PARAM; + } + + return E_NO_ERROR; +} + +int MXC_UART_ReadyForSleep(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_ReadyForSleep((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_SetFrequency(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock) +{ + int freq; + unsigned mod = 0; + unsigned clkDiv = 0; + + if (MXC_UART_GET_IDX(uart) < 0) { + return E_BAD_PARAM; + } + + // check if the uart is LPUART + if (uart == MXC_UART3) { + // OSR default value + uart->osr = 5; + + switch (clock) { + case MXC_UART_IBRO_CLK: + uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_PERIPHERAL_CLOCK; + clkDiv = ((IBRO_FREQ) / baud); + mod = ((IBRO_FREQ) % baud); + break; + + case MXC_UART_ERTCO_CLK: + // Only supports up to 9600 baud with ERTCO clock. + if (baud > 9600) { + return E_NOT_SUPPORTED; + } + + uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_EXTERNAL_CLOCK; + uart->ctrl |= MXC_F_UART_CTRL_FDM; + if (baud == 9600) { + clkDiv = 7; + mod = 0; + } else { + clkDiv = ((ERTCO_FREQ * 2) / baud); + mod = ((ERTCO_FREQ * 2) % baud); + } + + if (baud > 2400) { + uart->osr = 0; + } else { + uart->osr = 1; + } + break; + + default: + return E_BAD_PARAM; + } + + if (!clkDiv || mod > (baud / 2)) { + clkDiv++; + } + uart->clkdiv = clkDiv; + + freq = MXC_UART_GetFrequency(uart); + } else { + if (clock == MXC_UART_ERTCO_CLK) { + return E_BAD_PARAM; + } + + freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, baud, clock); + } + + if (freq > 0) { + // Enable baud clock and wait for it to become ready. + uart->ctrl |= MXC_F_UART_CTRL_BCLKEN; + while (((uart->ctrl & MXC_F_UART_CTRL_BCLKRDY) >> MXC_F_UART_CTRL_BCLKRDY_POS) == 0) {} + } + + return freq; +} + +int MXC_UART_GetFrequency(mxc_uart_regs_t *uart) +{ + int periphClock = 0; + + if (MXC_UART_GET_IDX(uart) < 0) { + return E_BAD_PARAM; + } + + // check if UART is LP UART + if (uart == MXC_UART3) { + if ((uart->ctrl & MXC_F_UART_CTRL_BCLKSRC) == + MXC_S_UART_REVB_CTRL_BCLKSRC_PERIPHERAL_CLOCK) { + periphClock = IBRO_FREQ; + } else if ((uart->ctrl & MXC_F_UART_CTRL_BCLKSRC) == + MXC_S_UART_REVB_CTRL_BCLKSRC_EXTERNAL_CLOCK) { + periphClock = ERTCO_FREQ * 2; + } else { + return E_NOT_SUPPORTED; + } + return (periphClock / uart->clkdiv); + } else { + return MXC_UART_RevB_GetFrequency((mxc_uart_revb_regs_t *)uart); + } +} + +int MXC_UART_SetDataSize(mxc_uart_regs_t *uart, int dataSize) +{ + return MXC_UART_RevB_SetDataSize((mxc_uart_revb_regs_t *)uart, dataSize); +} + +int MXC_UART_SetStopBits(mxc_uart_regs_t *uart, mxc_uart_stop_t stopBits) +{ + return MXC_UART_RevB_SetStopBits((mxc_uart_revb_regs_t *)uart, stopBits); +} + +int MXC_UART_SetParity(mxc_uart_regs_t *uart, mxc_uart_parity_t parity) +{ + return MXC_UART_RevB_SetParity((mxc_uart_revb_regs_t *)uart, parity); +} + +int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rtsThreshold) +{ + if (flowCtrl == MXC_UART_FLOW_EN) { + switch (MXC_UART_GET_IDX(uart)) { + case 0: + MXC_GPIO_Config(&gpio_cfg_uart0_flow); + break; + + case 1: + MXC_GPIO_Config(&gpio_cfg_uart1_flow); + break; + + case 2: + MXC_GPIO_Config(&gpio_cfg_uart2_flow); + break; + + default: + return E_BAD_PARAM; + } + } else { + switch (MXC_UART_GET_IDX(uart)) { + case 0: + MXC_GPIO_Config(&gpio_cfg_uart0_flow_disable); + break; + + case 1: + MXC_GPIO_Config(&gpio_cfg_uart1_flow_disable); + break; + + case 2: + MXC_GPIO_Config(&gpio_cfg_uart2_flow_disable); + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_UART_RevB_SetFlowCtrl((mxc_uart_revb_regs_t *)uart, flowCtrl, rtsThreshold); +} + +int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock) +{ + return MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, clock); +} + +int MXC_UART_GetActive(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetActive((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_AbortTransmission(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_AbortTransmission((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_ReadCharacterRaw(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_ReadCharacterRaw((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_WriteCharacterRaw(mxc_uart_regs_t *uart, uint8_t character) +{ + return MXC_UART_RevB_WriteCharacterRaw((mxc_uart_revb_regs_t *)uart, character); +} + +int MXC_UART_ReadCharacter(mxc_uart_regs_t *uart) +{ + return MXC_UART_Common_ReadCharacter(uart); +} + +int MXC_UART_WriteCharacter(mxc_uart_regs_t *uart, uint8_t character) +{ + return MXC_UART_Common_WriteCharacter(uart, character); +} + +int MXC_UART_Read(mxc_uart_regs_t *uart, uint8_t *buffer, int *len) +{ + return MXC_UART_RevB_Read((mxc_uart_revb_regs_t *)uart, buffer, len); +} + +int MXC_UART_Write(mxc_uart_regs_t *uart, const uint8_t *byte, int *len) +{ + return MXC_UART_RevB_Write((mxc_uart_revb_regs_t *)uart, byte, len); +} + +unsigned int MXC_UART_ReadRXFIFO(mxc_uart_regs_t *uart, unsigned char *bytes, unsigned int len) +{ + return MXC_UART_RevB_ReadRXFIFO((mxc_uart_revb_regs_t *)uart, bytes, len); +} + +int MXC_UART_ReadRXFIFODMA(mxc_uart_regs_t *uart, unsigned char *bytes, unsigned int len, + mxc_uart_dma_complete_cb_t callback) +{ + mxc_dma_config_t config; + + int uart_num = MXC_UART_GET_IDX(uart); + + switch (uart_num) { + case 0: + config.reqsel = MXC_DMA_REQUEST_UART0RX; + break; + + case 1: + config.reqsel = MXC_DMA_REQUEST_UART1RX; + break; + + case 2: + config.reqsel = MXC_DMA_REQUEST_UART2RX; + break; + + case 3: + config.reqsel = MXC_DMA_REQUEST_UART3RX; + break; + + default: + return E_BAD_PARAM; + break; + } + + return MXC_UART_RevB_ReadRXFIFODMA((mxc_uart_revb_regs_t *)uart, bytes, len, callback, config); +} + +unsigned int MXC_UART_GetRXFIFOAvailable(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetRXFIFOAvailable((mxc_uart_revb_regs_t *)uart); +} + +unsigned int MXC_UART_WriteTXFIFO(mxc_uart_regs_t *uart, const unsigned char *bytes, + unsigned int len) +{ + return MXC_UART_RevB_WriteTXFIFO((mxc_uart_revb_regs_t *)uart, bytes, len); +} + +int MXC_UART_WriteTXFIFODMA(mxc_uart_regs_t *uart, const unsigned char *bytes, unsigned int len, + mxc_uart_dma_complete_cb_t callback) +{ + mxc_dma_config_t config; + + int uart_num = MXC_UART_GET_IDX(uart); + switch (uart_num) { + case 0: + config.reqsel = MXC_DMA_REQUEST_UART0TX; + break; + + case 1: + config.reqsel = MXC_DMA_REQUEST_UART1TX; + break; + + case 2: + config.reqsel = MXC_DMA_REQUEST_UART2TX; + break; + + case 3: + config.reqsel = MXC_DMA_REQUEST_UART3TX; + break; + + default: + return E_BAD_PARAM; + break; + } + + return MXC_UART_RevB_WriteTXFIFODMA((mxc_uart_revb_regs_t *)uart, bytes, len, callback, config); +} + +unsigned int MXC_UART_GetTXFIFOAvailable(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetTXFIFOAvailable((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_ClearRXFIFO(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_ClearRXFIFO((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_ClearTXFIFO(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_ClearTXFIFO((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_SetRXThreshold(mxc_uart_regs_t *uart, unsigned int numBytes) +{ + return MXC_UART_RevB_SetRXThreshold((mxc_uart_revb_regs_t *)uart, numBytes); +} + +unsigned int MXC_UART_GetRXThreshold(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetRXThreshold((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_SetTXThreshold(mxc_uart_regs_t *uart, unsigned int numBytes) +{ + return E_NOT_SUPPORTED; +} + +unsigned int MXC_UART_GetTXThreshold(mxc_uart_regs_t *uart) +{ + return E_NOT_SUPPORTED; +} + +unsigned int MXC_UART_GetFlags(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetFlags((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_ClearFlags(mxc_uart_regs_t *uart, unsigned int flags) +{ + return MXC_UART_RevB_ClearFlags((mxc_uart_revb_regs_t *)uart, flags); +} + +int MXC_UART_EnableInt(mxc_uart_regs_t *uart, unsigned int intEn) +{ + return MXC_UART_RevB_EnableInt((mxc_uart_revb_regs_t *)uart, intEn); +} + +int MXC_UART_DisableInt(mxc_uart_regs_t *uart, unsigned int intDis) +{ + return MXC_UART_RevB_DisableInt((mxc_uart_revb_regs_t *)uart, intDis); +} + +unsigned int MXC_UART_GetStatus(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetStatus((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_Transaction(mxc_uart_req_t *req) +{ + return MXC_UART_RevB_Transaction((mxc_uart_revb_req_t *)req); +} + +int MXC_UART_TransactionAsync(mxc_uart_req_t *req) +{ + return MXC_UART_RevB_TransactionAsync((mxc_uart_revb_req_t *)req); +} + +int MXC_UART_TransactionDMA(mxc_uart_req_t *req) +{ + return MXC_UART_RevB_TransactionDMA((mxc_uart_revb_req_t *)req); +} + +int MXC_UART_AbortAsync(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_AbortAsync((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_AsyncHandler(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_AsyncHandler((mxc_uart_revb_regs_t *)uart); +} + +uint32_t MXC_UART_GetAsyncTXCount(mxc_uart_req_t *req) +{ + return req->txCnt; +} + +uint32_t MXC_UART_GetAsyncRXCount(mxc_uart_req_t *req) +{ + return req->rxCnt; +} + +int MXC_UART_SetAutoDMAHandlers(mxc_uart_regs_t *uart, bool enable) +{ + return MXC_UART_RevB_SetAutoDMAHandlers((mxc_uart_revb_regs_t *)uart, enable); +} + +int MXC_UART_SetTXDMAChannel(mxc_uart_regs_t *uart, unsigned int channel) +{ + return MXC_UART_RevB_SetTXDMAChannel((mxc_uart_revb_regs_t *)uart, channel); +} + +int MXC_UART_GetTXDMAChannel(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetTXDMAChannel((mxc_uart_revb_regs_t *)uart); +} + +int MXC_UART_SetRXDMAChannel(mxc_uart_regs_t *uart, unsigned int channel) +{ + return MXC_UART_RevB_SetRXDMAChannel((mxc_uart_revb_regs_t *)uart, channel); +} + +int MXC_UART_GetRXDMAChannel(mxc_uart_regs_t *uart) +{ + return MXC_UART_RevB_GetTXDMAChannel((mxc_uart_revb_regs_t *)uart); +} diff --git a/Libraries/PeriphDrivers/Source/WDT/wdt_me30.c b/Libraries/PeriphDrivers/Source/WDT/wdt_me30.c new file mode 100644 index 00000000000..0c761e70c7e --- /dev/null +++ b/Libraries/PeriphDrivers/Source/WDT/wdt_me30.c @@ -0,0 +1,161 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/* **** Includes **** */ +#include "mxc_device.h" +#include "mxc_errors.h" +#include "mxc_assert.h" +#include "mxc_sys.h" +#include "wdt.h" +#include "wdt_revb.h" + +/* **** Functions **** */ + +int MXC_WDT_Init(mxc_wdt_regs_t *wdt, mxc_wdt_cfg_t *cfg) +{ +#ifndef MSDK_NO_GPIO_CLK_INIT + if (wdt == MXC_WDT0) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_WDT0); + } else if (wdt == MXC_WDT1) { + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_WDT1); + } else { + return E_BAD_PARAM; + } +#endif + + MXC_WDT_RevB_Init((mxc_wdt_revb_regs_t *)wdt, (mxc_wdt_revb_cfg_t *)cfg); + + return E_NO_ERROR; +} + +int MXC_WDT_Shutdown(mxc_wdt_regs_t *wdt) +{ + if (wdt == MXC_WDT0) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_WDT0); + } else if (wdt == MXC_WDT1) { + MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_WDT1); + } else { + return E_BAD_PARAM; + } + + return E_NO_ERROR; +} + +void MXC_WDT_SetIntPeriod(mxc_wdt_regs_t *wdt, mxc_wdt_cfg_t *cfg) +{ + MXC_WDT_RevB_SetIntPeriod((mxc_wdt_revb_regs_t *)wdt, (mxc_wdt_revb_cfg_t *)cfg); +} + +void MXC_WDT_SetResetPeriod(mxc_wdt_regs_t *wdt, mxc_wdt_cfg_t *cfg) +{ + MXC_WDT_RevB_SetResetPeriod((mxc_wdt_revb_regs_t *)wdt, (mxc_wdt_revb_cfg_t *)cfg); +} + +void MXC_WDT_Enable(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_Enable((mxc_wdt_revb_regs_t *)wdt); +} + +void MXC_WDT_Disable(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_Disable((mxc_wdt_revb_regs_t *)wdt); +} + +void MXC_WDT_EnableInt(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_EnableInt((mxc_wdt_revb_regs_t *)wdt, MXC_WDT_REVB_ENABLE); +} + +void MXC_WDT_DisableInt(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_EnableInt((mxc_wdt_revb_regs_t *)wdt, MXC_WDT_REVB_DISABLE); +} + +void MXC_WDT_EnableReset(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_EnableReset((mxc_wdt_revb_regs_t *)wdt, MXC_WDT_REVB_ENABLE); +} + +void MXC_WDT_DisableReset(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_EnableReset((mxc_wdt_revb_regs_t *)wdt, MXC_WDT_REVB_DISABLE); +} + +void MXC_WDT_ResetTimer(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_ResetTimer((mxc_wdt_revb_regs_t *)wdt); +} + +int MXC_WDT_GetResetFlag(mxc_wdt_regs_t *wdt) +{ + return MXC_WDT_RevB_GetResetFlag((mxc_wdt_revb_regs_t *)wdt); +} + +void MXC_WDT_ClearResetFlag(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_ClearResetFlag((mxc_wdt_revb_regs_t *)wdt); +} + +int MXC_WDT_GetIntFlag(mxc_wdt_regs_t *wdt) +{ + return MXC_WDT_RevB_GetIntFlag((mxc_wdt_revb_regs_t *)wdt); +} + +void MXC_WDT_ClearIntFlag(mxc_wdt_regs_t *wdt) +{ + MXC_WDT_RevB_ClearIntFlag((mxc_wdt_revb_regs_t *)wdt); +} + +int MXC_WDT_SetClockSource(mxc_wdt_regs_t *wdt, mxc_wdt_clock_t clock_source) +{ + const uint8_t clock_source_num = 8; + uint8_t idx = 0; + uint8_t instance = 0; + +#if TARGET_NUM == 32655 || TARGET_NUM == 78000 + mxc_wdt_clock_t clock_sources[2][8] = { + { MXC_WDT_PCLK, MXC_WDT_IBRO_CLK, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { MXC_WDT_IBRO_CLK, MXC_WDT_INRO_CLK, MXC_WDT_ERTCO_CLK, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + }; +#elif TARGET_NUM == 32680 + mxc_wdt_clock_t clock_sources[2][8] = { + { MXC_WDT_PCLK, MXC_WDT_IBRO_CLK, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { MXC_WDT_IBRO_CLK, 0xFF, MXC_WDT_INRO_CLK, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } + }; +#else +#error ME17 WDT driver does not support given target number. +#endif + + if (wdt == MXC_WDT0) { + instance = 0; + } else if (wdt == MXC_WDT1) { + instance = 1; + } else { + return E_BAD_PARAM; + } + + for (idx = 0; idx < clock_source_num; idx++) { + if (clock_sources[instance][idx] == clock_source) { + break; + } + } + + MXC_WDT_RevB_SetClockSource((mxc_wdt_revb_regs_t *)wdt, idx); + + return E_NO_ERROR; +} diff --git a/Libraries/PeriphDrivers/Source/WUT/wut_me30.c b/Libraries/PeriphDrivers/Source/WUT/wut_me30.c new file mode 100644 index 00000000000..7f6f8689381 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/WUT/wut_me30.c @@ -0,0 +1,370 @@ +/****************************************************************************** + * + * Copyright (C) 2024 Analog Devices, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/* **** Includes **** */ +#include +#include "mxc_device.h" +#include "mxc_assert.h" +#include "wut.h" +#include "wut_reva.h" +#include "trimsir_regs.h" + +/* **** Definitions **** */ + +/* Clock rate the BLE DBB counter */ +#ifndef BB_CLK_RATE_HZ +#define BB_CLK_RATE_HZ 1000000 +#endif + +/* Higher values will produce a more accurate measurement, but will consume more power */ +#define WUT_TRIM_TICKS 0x1000 + +/* **** Globals **** */ + +/* **** Local Variables **** */ + +/* Used for the asynchronous trim procedure */ +static uint32_t wutCnt0_async, snapshot0_async, bestTrim_async, bestDiff_async; +static int capAdded_async; +static int trimPending; +static mxc_wut_complete_cb_t cb_async; + +/* **** Functions **** */ + +/* ************************************************************************** */ +void MXC_WUT_Init(mxc_wut_regs_t *wut, mxc_wut_pres_t pres) +{ +#ifndef MSDK_NO_GPIO_CLK_INIT + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO); +#endif + MXC_WUT_RevA_Init((mxc_wut_reva_regs_t *)wut, pres); +} + +void MXC_WUT_Shutdown(mxc_wut_regs_t *wut) +{ + MXC_WUT_RevA_Shutdown((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************** */ +void MXC_WUT_Enable(mxc_wut_regs_t *wut) +{ + MXC_WUT_RevA_Enable((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************** */ +void MXC_WUT_Disable(mxc_wut_regs_t *wut) +{ + MXC_WUT_RevA_Disable((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************** */ +void MXC_WUT_Config(mxc_wut_regs_t *wut, const mxc_wut_cfg_t *cfg) +{ + MXC_WUT_RevA_Config((mxc_wut_reva_regs_t *)wut, (mxc_wut_reva_cfg_t *)cfg); +} + +/* ************************************************************************** */ +uint32_t MXC_WUT_GetCompare(mxc_wut_regs_t *wut) +{ + return MXC_WUT_RevA_GetCompare((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************* */ +uint32_t MXC_WUT_GetCount(mxc_wut_regs_t *wut) +{ + return MXC_WUT_RevA_GetCount((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************* */ +void MXC_WUT_IntClear(mxc_wut_regs_t *wut) +{ + MXC_WUT_RevA_IntClear((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************* */ +uint32_t MXC_WUT_IntStatus(mxc_wut_regs_t *wut) +{ + return MXC_WUT_RevA_IntStatus((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************* */ +void MXC_WUT_SetCompare(mxc_wut_regs_t *wut, uint32_t cmp_cnt) +{ + MXC_WUT_RevA_SetCompare((mxc_wut_reva_regs_t *)wut, cmp_cnt); +} + +/* ************************************************************************* */ +void MXC_WUT_SetCount(mxc_wut_regs_t *wut, uint32_t cnt) +{ + MXC_WUT_RevA_SetCount((mxc_wut_reva_regs_t *)wut, cnt); +} + +/* ************************************************************************* */ +int MXC_WUT_GetTicks(mxc_wut_regs_t *wut, uint32_t time, mxc_wut_unit_t units, uint32_t *ticks) +{ + return MXC_WUT_RevA_GetTicks((mxc_wut_reva_regs_t *)wut, ERTCO_FREQ, time, units, ticks); +} + +/* ************************************************************************* */ +int MXC_WUT_GetTime(mxc_wut_regs_t *wut, uint32_t ticks, uint32_t *time, mxc_wut_unit_t *units) +{ + return MXC_WUT_RevA_GetTime((mxc_wut_reva_regs_t *)wut, ERTCO_FREQ, ticks, time, + (mxc_wut_reva_unit_t *)units); +} + +/* ************************************************************************** */ +void MXC_WUT_Edge(mxc_wut_regs_t *wut) +{ + MXC_WUT_RevA_Edge((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************** */ +void MXC_WUT_Store(mxc_wut_regs_t *wut) +{ + MXC_WUT_RevA_Store((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************** */ +void MXC_WUT_RestoreBBClock(mxc_wut_regs_t *wut, uint32_t dbbFreq) +{ + MXC_WUT_RevA_RestoreBBClock((mxc_wut_reva_regs_t *)wut, dbbFreq, ERTCO_FREQ); +} + +/* ************************************************************************** */ +uint32_t MXC_WUT_GetSleepTicks(mxc_wut_regs_t *wut) +{ + return MXC_WUT_RevA_GetSleepTicks((mxc_wut_reva_regs_t *)wut); +} + +/* ************************************************************************** */ +void MXC_WUT_Delay_MS(mxc_wut_regs_t *wut, uint32_t waitMs) +{ + MXC_WUT_RevA_Delay_MS((mxc_wut_reva_regs_t *)wut, waitMs, ERTCO_FREQ); +} + +/* ************************************************************************** */ +static void MXC_WUT_GetWUTSync(mxc_wut_regs_t *wut, uint32_t *wutCnt, uint32_t *snapshot) +{ + MXC_WUT_RevA_Edge((mxc_wut_reva_regs_t *)wut); + *wutCnt = wut->cnt; + *snapshot = wut->snapshot; +} + +/* ************************************************************************** */ +static void MXC_WUT_SetTrim(uint32_t trimValue) +{ + MXC_SETFIELD(MXC_TRIMSIR->rtc, MXC_F_TRIMSIR_RTC_X1TRIM, + (trimValue << MXC_F_TRIMSIR_RTC_X1TRIM_POS)); + MXC_SETFIELD(MXC_TRIMSIR->rtc, MXC_F_TRIMSIR_RTC_X2TRIM, + (trimValue << MXC_F_TRIMSIR_RTC_X2TRIM_POS)); +} + +/* ************************************************************************** */ +static int MXC_WUT_StartTrim(mxc_wut_regs_t *wut) +{ + uint32_t wutCnt0, wutCnt1; + uint32_t snapshot0, snapshot1; + uint32_t trimValue; + + /* Make sure the WUT is running in compare mode */ + if (!(wut->ctrl & MXC_F_WUT_REVA_CTRL_TEN)) { + return E_UNINITIALIZED; + } + + /* Make sure that DBB counter is running */ + MXC_WUT_GetWUTSync(wut, &wutCnt0, &snapshot0); + MXC_WUT_GetWUTSync(wut, &wutCnt1, &snapshot1); + if (snapshot0 == snapshot1) { + return E_UNINITIALIZED; + } + + /* Start with existing trim value */ + trimValue = (MXC_TRIMSIR->rtc & MXC_F_TRIMSIR_RTC_X1TRIM) >> MXC_F_TRIMSIR_RTC_X1TRIM_POS; + MXC_WUT_SetTrim(trimValue); + + /* Initialize the variables */ + bestTrim_async = trimValue; + bestDiff_async = 0xFFFF; + + /* Get the initial snapshot */ + MXC_WUT_GetWUTSync(wut, &wutCnt0_async, &snapshot0_async); + + trimPending = 1; + + return E_NO_ERROR; +} + +/* ************************************************************************** */ +int MXC_WUT_Handler(mxc_wut_regs_t *wut) +{ + uint32_t wutCnt1; + uint32_t snapshot1; + uint32_t trimValue; + uint32_t snapTicks, wutTicks; + uint64_t calcTicks; + int trimComplete; + mxc_wut_complete_cb_t cbTemp; + + /* Clear the interrupt flags */ + MXC_WUT_IntClear(wut); + + if (!trimPending) { + return E_NO_ERROR; + } + + /* Store the snapshot */ + MXC_WUT_GetWUTSync(wut, &wutCnt1, &snapshot1); + snapTicks = snapshot1 - snapshot0_async; + wutTicks = wutCnt1 - wutCnt0_async; + + /* Calculate the ideal number of DBB ticks in WUT_TRIM_TICKS */ + calcTicks = ((uint64_t)wutTicks * (uint64_t)BB_CLK_RATE_HZ) / (uint64_t)32768; + + trimComplete = 0; + trimValue = (MXC_TRIMSIR->rtc & MXC_F_TRIMSIR_RTC_X1TRIM) >> MXC_F_TRIMSIR_RTC_X1TRIM_POS; + + if (snapTicks > calcTicks) { + /* See if we're closer to the calculated value */ + if ((snapTicks - calcTicks) <= bestDiff_async) { + bestDiff_async = snapTicks - calcTicks; + bestTrim_async = trimValue; + } + + /* Running slow, reduce cap */ + if (trimValue == 0) { + /* We're maxed out on trim range */ + trimComplete = 1; + } + trimValue--; + + if (capAdded_async == 1) { + /* We've hit an inflection point */ + trimComplete = 1; + } + capAdded_async = -1; + + } else if (snapTicks < calcTicks) { + /* See if we're closer to the calculated value */ + if ((calcTicks - snapTicks) <= bestDiff_async) { + bestDiff_async = calcTicks - snapTicks; + bestTrim_async = trimValue; + } + + /* Running fast, increase cap */ + if (trimValue == 0x1f) { + /* We're maxed out on trim range */ + trimComplete = 1; + } + trimValue++; + + if (capAdded_async == -1) { + /* We've hit an inflection point */ + trimComplete = 1; + } + capAdded_async = 1; + + } else { + /* Just right */ + bestTrim_async = trimValue; + trimComplete = 1; + } + + if (trimComplete) { + /* Apply the best trim value */ + MXC_WUT_SetTrim(bestTrim_async); + + trimPending = 0; + + /* Call the callback */ + if (cb_async != NULL) { + cbTemp = cb_async; + cb_async = NULL; + cbTemp(E_NO_ERROR); + } + + return E_NO_ERROR; + } + + /* Start the next step */ + MXC_WUT_SetTrim(trimValue); + MXC_WUT_GetWUTSync(wut, &wutCnt0_async, &snapshot0_async); + + if (cb_async != NULL) { + /* Prime the compare interrupt */ + wut->cmp = wut->cnt + WUT_TRIM_TICKS - 1; + } + + /* Return E_BUSY to indicate the trim procedure is still running */ + return E_BUSY; +} + +/* ************************************************************************** */ +int MXC_WUT_TrimCrystal(mxc_wut_regs_t *wut) +{ + int err, i; + + /* Clear the async callback pointer */ + cb_async = NULL; + + /* Start the trim procedure */ + err = MXC_WUT_StartTrim(wut); + if (err != E_NO_ERROR) { + return err; + } + do { + for (i = 0; i < (WUT_TRIM_TICKS - 1); i++) { + MXC_WUT_RevA_Edge((mxc_wut_reva_regs_t *)wut); + } + } while (MXC_WUT_Handler(wut) != E_NO_ERROR); + + return E_NO_ERROR; +} + +/* ************************************************************************** */ +int MXC_WUT_TrimCrystalAsync(mxc_wut_regs_t *wut, mxc_wut_complete_cb_t cb) +{ + int err; + + if (cb == NULL) { + return E_NULL_PTR; + } + + /* Save the callback */ + cb_async = cb; + + /* Start the trim procedure */ + err = MXC_WUT_StartTrim(wut); + if (err != E_NO_ERROR) { + return err; + } + + /* Prime the compare interrupt */ + wut->cmp = wut->cnt + WUT_TRIM_TICKS - 1; + + return E_NO_ERROR; +} + +/* ************************************************************************** */ +int MXC_WUT_TrimPending(mxc_wut_regs_t *wut) +{ + if (trimPending) { + return E_BUSY; + } + + return E_NO_ERROR; +}