Hi, soledad,
I fully agree with you. If I can write data to banks 0 and 3, I should be able to write data to banks 1 and 2, too. So, I am baffled. Here is my code. I hope it makes sense. I ran this code on LPCXpresso546xx Eval Board Rev. D, and got the same results (I could not write data to banks 1 and 2).
Thanks again for your help.
Ohba
/**********************/
#include <stdbool.h>
#include "board.h"
#include "pin_mux.h"
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "fsl_rng.h"
#include "fsl_otp.h"
#include "fsl_clock.h"
#include "fsl_reset.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define OPT_BASE_ADDRESS (0x40015000u)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
uint32_t readOtp( int bank, int reg_index ){ //Read OTP register at bank/reg_index, bank can be 0, 1, 2, or 3. reg_index can be 0, 1, 2, or 3.
int rc;
otp_word_t enable_mask = 0;
int reg_offset = 0;
uint32_t *offset;
switch( reg_index ){
case 0: enable_mask = 0x01; reg_offset = 0x00; break;
case 1: enable_mask = 0x02; reg_offset = 0x04; break;
case 2: enable_mask = 0x04; reg_offset = 0x08; break;
case 3: enable_mask = 0x08; reg_offset = 0x0C; break;
default: enable_mask = 0; break;
}
rc = OTP_EnableBankReadLock( bank, enable_mask, 0x00u, 0x00u );
if( rc != kStatus_Success ){
PRINTF( "OTP_EnableBankReadLock() failed and returned %x\r\n", rc );
return 0;
}
else{
//PRINTF( "OTP_EnableBankReadLock(%d) succeeded\r\n" );
}
offset = (uint32_t *)(OPT_BASE_ADDRESS+bank*0x10+reg_offset);
return *offset;
}
/*Write data to OTP bank's reg_index. Bank can be 0, 1, 2, or 3. reg_index can be 0, 1, 2 or 3*/
bool writeOtp( uint32_t bank_index, uint32_t reg_index, uint32_t data ){
if( reg_index != 2 && reg_index != 3 ){ //Registers 0 and 1 are reserved for system use.
PRINTF( "You can write data to register 2 or 3 only.\r\n" );
return false;
}
int rc, rc_prog;
uint32_t bank_mask = 0;
switch( bank_index ){
case 0: bank_mask = 0x01; break;
case 1: bank_mask = 0x02; break;
case 2: bank_mask = 0x04; break;
case 3: bank_mask = 0x08; break;
default: bank_mask = 0; break;
}
rc = OTP_EnableBankWriteMask( bank_mask ); //Enable write access of the specified bank
if( rc != kStatus_Success ){
PRINTF( "OTP_EnableBankWriteMask() failed and returned %d (0x%x)\r\n", rc, rc );
return false;
}
uint32_t enable_mask = 0;
uint32_t disable_mask = 0;
switch( reg_index ){
case 0: enable_mask = 0x01; break;
case 1: enable_mask = 0x02; break;
case 2: enable_mask = 0x04; break;
case 3: enable_mask = 0x08; break;
default: enable_mask = 0; break;
}
disable_mask = enable_mask;
rc = OTP_EnableBankWriteLock( bank_index, enable_mask, 0, 0 ); //Enable write access of the specified register
if( rc != kStatus_Success ){
PRINTF( "OTP_EnableBankWriteLock() failed and returned %d (0x%x)\r\n", rc, rc );
return false;
}
rc = OTP_EnableBankReadLock( bank_index, enable_mask, 0, 0 ); //Enable read access of the specified register, is this really needed?
if( rc != kStatus_Success ){
PRINTF( "OTP_EnableBankReadLock() failed and returned %d (0x%x)\r\n", rc, rc );
return false;
}
rc_prog = OTP_ProgramRegister( bank_index, reg_index, data ); //Write data to the OTP of bank_index & reg_index
if( rc_prog != kStatus_Success ){
PRINTF( "OTP_ProgramRegister() failed and returned %d (0x%x)\r\n", rc_prog, rc_prog );
}
rc = OTP_EnableBankReadLock( bank_index, 0, disable_mask, 0 ); //Disable read access of the specified register, is this really needed?
if( rc != kStatus_Success ){
PRINTF( "OTP_EnableBankReadLock() failed and returned %d (0x%x)\r\n", rc, rc );
return false;
}
rc = OTP_EnableBankWriteLock( bank_index, 0, disable_mask, 0 ); //Disable write access of the specified register
if( rc != kStatus_Success ){
PRINTF( "OTP_EnableBankWriteLock() failed and returned %d (0x%x)\r\n", rc, rc );
return false;
}
rc = OTP_DisableBankWriteMask( bank_mask ); //Disable write access of the specified bank
if( rc != kStatus_Success ){
PRINTF( "OTP_DisableBankWriteMask() failed and returned %d (0x%x)\r\n", rc, rc );
return false;
}
if( rc_prog != kStatus_Success )
return false;
else
return true;
}
void dumpOtp(){
int bank, reg_index;
uint32_t d32;
for( bank = 0; bank < 4; bank++ ){
PRINTF( "OTP bank %d:\t", bank );
for( reg_index = 0; reg_index < 4; reg_index++ ){
d32 = readOtp( bank, reg_index );
PRINTF( "reg%d=%08X\t", reg_index, d32 );
}
PRINTF( "\r\n" );
}
}
int main(void)
{
uint32_t version;
/* Init hardware*/
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
/* enable clock to OTP and reset it */
CLOCK_EnableClock(kCLOCK_Otp);
RESET_PeripheralReset(kOTP_RST_SHIFT_RSTn);
BOARD_InitPins();
/* main clock needs to be set to 12 MHz in order to use OTP */
BOARD_BootClockFRO12M();
BOARD_InitDebugConsole();
/* Get version of driver in ROM */
version = OTP_GetDriverVersion();
PRINTF("OTP ROM API driver version: 0x%X\r\n\r\n", version);
int bank, reg;
uint32_t data;
for( bank = 0; bank < 4; bank++ ){
for( reg = 2; reg < 4; reg++ ){
data = 0x00000000u;
PRINTF( "Writing 0x%08X to bank%d register%d... ", data, bank, reg );
if( writeOtp( bank, reg, data ) ){
PRINTF( " Succeeded.\r\n" );
}
else{
//PRINTF( "Failed.\r\n" );
}
}
}
dumpOtp();
PRINTF( "Program finished.\r\n" );
while(true){}
}