/**************************************************************************//** * @file efuse.c * @version V1.00 * $Revision: 0$ * $Date: 20/10/14 15:26 $ * @brief Panchip SoC eFuse driver source file * * @note * Copyright (C) 2020 Panchip Technology Corp. All rights reserved. *****************************************************************************/ #include "PanSeries.h" #include "pan_efuse.h" /** * @brief Read specified one byte from eFuse. * * @param[in] efuse Module name of eFuse, typically EFUSE. * @param[in] addr eFuse address to read data from. * @retval Data read from eFuse. * * @note Unlock register before use this API. */ uint8_t EFUSE_ReadByte(EFUSE_T* efuse, uint32_t addr) { efuse->EF_CMD = EFUSE_CMD_READ; efuse->EF_ADDR = addr; efuse->EF_TRG = EFUSE_TRG_EFUSETRG_GO_Msk; while(efuse->EF_TRG){} return efuse->EF_DAT; } /** * @brief Read multiple data from eFuse. * * @param[in] efuse Module name of eFuse, typically EFUSE. * @param[in] addr eFuse address to read data from. * @param[in] data Buffer to store data read from eFuse. * @param[in] len Number of bytes to read. * @retval true Read success. * @retval false Error occurs while reading. * * @note Unlock register before use this API. */ bool EFUSE_Read(EFUSE_T* efuse, uint32_t addr, uint8_t* data, uint16_t len) { for (size_t i = 0; i < len; i++) { efuse->EF_CMD = EFUSE_CMD_READ; efuse->EF_ADDR = addr + i; efuse->EF_TRG = EFUSE_TRG_EFUSETRG_GO_Msk; while(efuse->EF_TRG){} if (efuse->EF_OP_ERROR) { efuse->EF_OP_ERROR = 1u; // Clear error status reg return false; } data[i] = efuse->EF_DAT; } return true; } /** * @brief Write one byte data to specified eFuse address. * * @param[in] efuse Module name of eFuse, typically EFUSE. * @param[in] addr eFuse address to write data to. * @param[in] data Data to write to eFuse. * @return None. * * @note Unlock register before use this API. */ void EFUSE_WriteByte(EFUSE_T* efuse, uint32_t addr, uint8_t data) { efuse->EF_VDD = (EFUSE_VDD_AVDD_REG_Msk | EFUSE_VDD_DVDD_REG_Msk); efuse->EF_CMD = EFUSE_CMD_PROGRAM; efuse->EF_ADDR = addr; efuse->EF_DAT = data | (data<< 8); //efuse data; bit0-7:data, bit8-15:data confirm efuse->EF_TRG |= EFUSE_TRG_EFUSETRG_GO_Msk; while(efuse->EF_TRG){} efuse->EF_VDD &= ~(EFUSE_VDD_AVDD_REG_Msk); } /** * @brief Write multiple data to eFuse. * * @param[in] efuse Module name of eFuse, typically EFUSE. * @param[in] addr eFuse address to write data to. * @param[in] data Buffer to store data to be write to eFuse. * @param[in] len Number of bytes to write. * @retval true Write success. * @retval false Error occurs while writing. * * @note Unlock register before use this API. */ bool EFUSE_Write(EFUSE_T* efuse, uint32_t addr, uint8_t* data, uint16_t len) { efuse->EF_VDD = (EFUSE_VDD_AVDD_REG_Msk | EFUSE_VDD_DVDD_REG_Msk); //open avdd for (size_t i = 0; i < len; i++) { efuse->EF_CMD = EFUSE_CMD_PROGRAM; efuse->EF_ADDR = addr + i; efuse->EF_DAT = data[i] | (data[i]<< 8); //efuse data; bit0-7:data, bit8-15:data confirm; efuse->EF_TRG |= EFUSE_TRG_EFUSETRG_GO_Msk; while(efuse->EF_TRG){} if (efuse->EF_OP_ERROR) { efuse->EF_OP_ERROR = 1u; // Clear error status reg efuse->EF_VDD &= ~(EFUSE_VDD_AVDD_REG_Msk); // Disconnect AVDD before return return false; } } efuse->EF_VDD &= ~(EFUSE_VDD_AVDD_REG_Msk); return true; } /** * @brief Read multiple data from User Area of eFuse (Address 0xE9 ~ 0xFF). * * @param[in] efuse Module name of eFuse, typically EFUSE. * @param[in] addr eFuse address to read data from, should be in range of 0xE9 ~ 0xFF. * @param[in] data Buffer to store data read from eFuse. * @param[in] len Number of bytes to read. * @retval true Read success. * @retval false Error, illegal parameter (addr or len). * * @note Unlock register before use this API. */ bool EFUSE_UserRead(EFUSE_T* efuse, uint32_t addr, uint8_t* data, uint16_t len) { if ((addr < 0x7C) || (addr > 0x7F) || (addr + len > 0x80)) { return false; } for (size_t i = 0; i < len; i++) { efuse->EF_CMD = EFUSE_CMD_READ; efuse->EF_ADDR = addr + i; efuse->EF_TRG = EFUSE_TRG_EFUSETRG_GO_Msk; while(efuse->EF_TRG){} data[i] = efuse->EF_DAT; } return true; } /** * @brief Write multiple data to User Area of eFuse (Address 0xE9 ~ 0xFF). * * @param[in] efuse Module name of eFuse, typically EFUSE. * @param[in] addr eFuse address to write data to, should be in range of 0xE9 ~ 0xFF. * @param[in] data Buffer to store data to be write to eFuse. * @param[in] len Number of bytes to write. * @retval true Write success. * @retval false Error, illegal parameter (addr or len). * * @note Unlock register before use this API. */ bool EFUSE_UserWrite(EFUSE_T* efuse, uint32_t addr, uint8_t* data, uint16_t len) { if ((addr < 0x7C) || (addr > 0x7F) || (addr + len > 0x80)) { return false; } efuse->EF_VDD = (EFUSE_VDD_AVDD_REG_Msk | EFUSE_VDD_DVDD_REG_Msk); //open avdd for (size_t i = 0; i < len; i++) { efuse->EF_CMD = EFUSE_CMD_PROGRAM; efuse->EF_ADDR = addr + i; efuse->EF_DAT = data[i] | (data[i]<< 8); //efuse data; bit0-7:data, bit8-15:data confirm; efuse->EF_TRG |= EFUSE_TRG_EFUSETRG_GO_Msk; while(efuse->EF_TRG){} } efuse->EF_VDD &= ~(EFUSE_VDD_AVDD_REG_Msk); return true; }