Hi,
I am using LPC54605J512 and trying to read/write OTP. I can read/write Banks 0 and 3 with no problems. However, I cannot write Banks 1 and 2. When I execute OTP_ProgramRegister() to Bank 1 or 2, it returns the error code of “illegal bank.” Do I have to use different API to write Banks 1 and 2? Or, simply the LPC54605J512 has Banks 0 and 3 only?
Regards,
Ohba
I am waiting for another three weeks. Did you confirm Banks 1 and 2 of OTP do not work?
Regards,
Ohba
Sorry for the delay, I am trying to reproduce the issue using a NXPboard. I will update you as soon as possible.
Regards
Sol
Hi,
otpEnableBankWriteLock API must be called to enable the appropriate register before calling otpProgramReg API function.
Please check you are not disabling the banks, for example:
Example 1: “otpEnableBankReadLock(0x3, 0x3, 0xC, 0x00)” will enable read access to BANK3-REG0, REG1 and disables access to BANK3-REG2, REG3. These access values can be changed by a subsequent call to “otpEnableBankReadLock”.
Example 2: “otpEnableBankReadLock (0x3, 0x6, 0x9, 0x01)” will enable read access to BANK3-REG1, REG2 and disable read access to BANK3-REG3, REG0 and since the write lock mask is also set, these permissions will be set and cannot be changed until reset. Note: The disable mask takes priority if both enable and disable masks are set.
Regards
Sol
Hi,
Thanks for your reply. I still cannot get my program to work for Banks 1 and 2. Again, it works good for Banks 0 and 3. What I have tried so far are:
I would appreciate your help.
Regards,
Ohba
Hello Nobuyuki San,
The procedure for all the Banks it is the same, if you have working Bank 0 and Bank 3, follow the same steps, for the Bank1 and Bank2. The API, it is the same for all the banks also. If you can put an small part of your code, we can try to review it, and see if there is something wrong.
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){}
}
Hello Nobuyuki San,
Here is an example, I am trying with the same Banks 0 and 1 but it is prepared for bank any bank, can you please try?
The example programs 4 words of data each into OTP bank 1 and OTP bank 2. The example uses LPC54018 SDK drivers. The complete SDK for LPC54018 can be downloaded from Welcome | MCUXpresso SDK Builder .
Hi, Soledad,
Many thanks for your sample code. Since I do not have LPC54018 here, I tried your code on LPC54608J512 (LPCXpresso546xx development board) with the LPC54608 SDK. The code failed at
status = OTP_ProgramRegister(BANK1_IDX, 0x0, bank1_word0);
at Line 129. The returned status code is 6109 decimal, which I believe indicates "illegal bank."
I also ran your code on LPC54605J512 (my original board), and got the exactly same result.
Have you successfully run your code on LPC54018?
Regards,
Ohba
It has been three weeks since I posted the last question. I would appreciate any feedback.
Thanks,
Ohba