Hi
I have to access the OTP memory in winbond (W25Q128JW) NOR flash. Whenever i try access the program security register (42h), data is not written in the memory. I am using QUAD SPI protocol to communicate with flash. I use the nordic QSPI library. The General page write and read works fine whenever I try to access the OTP it will be no results.
Here I work with function
/** * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @file * @defgroup qspi_example_main main.c * @{ * @ingroup qspi_example * * @brief QSPI Example Application main file. * * This file contains the source code for a sample application using QSPI. */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include "nrf_drv_qspi.h" #include "nrf_delay.h" #include "app_util_platform.h" #include "app_error.h" #include "boards.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "sdk_config.h" #include "SEGGER_RTT.h" #include "SEGGER_RTT_Conf.h" #define QSPI_STD_CMD_WRSR 0x1 #define QSPI_STD_CMD_WRSR2 0x31 #define QSPI_STD_CMD_WRSR3 0x11 #define QSPI_STD_CMD_RSTEN 0x66 #define QSPI_STD_CMD_RST 0x99 #define WRITE_ENABLE 0x06 #define STATUS_REG1 0x05 #define READ_STATUS 0x35 #define READ_STATUS1 0x05 #define READ_STATUS3 0x15 #define SENDAA 0xAA #define SEND55 0x55 #define MANUFATURER_ID 0x94 #define FLASH_CMD_READ_SECURITY_REG 0x48 #define FLASH_CMD_PROGRAM_SECURITY_REG 0x42 #define FLASH_CMD_ERASE_SECURITY_REG 0x44 #define READ_JDEC 0x9F #define DEVICE_ADDRESS 0x002000 #define DEVICE_ADDRESS_READ 0x002000 void readStatusRegister(void); #define QSPI_TEST_DATA_SIZE 256 #define DATA_MINIMUM 20 #define WAIT_FOR_PERIPH() do { \ while (!m_finished) {} \ m_finished = false; \ } while (0) uint8_t initDeviceName[]={0x42,0x00,0x20,0x00,0X4E, 0X49, 0X56, 0X49}; uint8_t senddata[]={0x48,0x00,0x20,0x00,0xFF}; uint8_t deviceName[10]={0,0,0,0,0,0,0,0,0,0}; uint8_t sendBuffer[13]; uint32_t addree=0x002000; uint8_t dummybyte[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; static volatile bool m_finished = false; static void qspi_handler(nrf_drv_qspi_evt_t event, void * p_context) { UNUSED_PARAMETER(event); UNUSED_PARAMETER(p_context); m_finished = true; SEGGER_RTT_printf(0,"QSPI handler\r\n"); } void otpEnable(void) { uint32_t err_code; uint8_t send80=0x80; // uint8_t status1; uint8_t sent55=0x55; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode =SENDAA,//AAh .length = NRF_QSPI_CINSTR_LEN_2B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = false }; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &sent55, NULL); APP_ERROR_CHECK(err_code); cinstr_cfg.opcode=QSPI_STD_CMD_WRSR;//01h cinstr_cfg.wren = true; nrf_gpio_pin_clear( NRF_GPIO_PIN_MAP(0,16)); err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &send80, NULL); APP_ERROR_CHECK(err_code); nrf_gpio_pin_set( NRF_GPIO_PIN_MAP(0,16)); } void newwrite() { uint32_t err_code; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode =FLASH_CMD_PROGRAM_SECURITY_REG, .length = NRF_QSPI_CINSTR_LEN_1B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = true }; m_finished = false; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); APP_ERROR_CHECK(err_code); SEGGER_RTT_printf(0,"newwrite--%d",err_code); err_code = nrf_drv_qspi_write(&initDeviceName[0], 1, addree); SEGGER_RTT_printf(0,"newwrite--%d--%c\n",err_code,initDeviceName[0]); APP_ERROR_CHECK(err_code); } void newRead() { uint32_t err_code; uint8_t name=0; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode =FLASH_CMD_READ_SECURITY_REG, .length = NRF_QSPI_CINSTR_LEN_1B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = false }; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); SEGGER_RTT_printf(0,"newread--%d",err_code); APP_ERROR_CHECK(err_code); err_code = nrf_drv_qspi_read(&name, 1, addree); SEGGER_RTT_printf(0,"newread--%d--%X\n",err_code,name); APP_ERROR_CHECK(err_code); } void flashwrite(void) { ret_code_t err_code; m_finished = false; err_code = nrf_drv_qspi_write(&initDeviceName[0], 12, DEVICE_ADDRESS); APP_ERROR_CHECK(err_code); WAIT_FOR_PERIPH(); readStatusRegister(); SEGGER_RTT_printf(0,"device-%s-%d\n",initDeviceName,err_code); } void flashread(void) { ret_code_t err_code; m_finished = false; err_code = nrf_drv_qspi_read(&deviceName[0], 12, DEVICE_ADDRESS); APP_ERROR_CHECK(err_code); WAIT_FOR_PERIPH(); SEGGER_RTT_printf(0,"device-%s-%c\n",deviceName,deviceName[0]); for(int i=0;i<10;i++) { SEGGER_RTT_printf(0,"%c",deviceName[i]); } } void readStatusRegister(void) { uint8_t read=0,read1=0,read2=0; uint32_t err_code; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = READ_STATUS, .length = QSPI_CINSTRCONF_LENGTH_2B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = false }; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, &read); APP_ERROR_CHECK(err_code); cinstr_cfg.opcode=READ_STATUS1; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, &read1); APP_ERROR_CHECK(err_code); cinstr_cfg.opcode=READ_STATUS3; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, &read2); APP_ERROR_CHECK(err_code); // for(int i=0;i<3;i++) { SEGGER_RTT_printf(0,"StatusRead-%X-%x-%X\n",read2,read,read1); } } void writeEnableData(void) { uint32_t err_code; nrf_gpio_pin_clear( NRF_GPIO_PIN_MAP(0,16)); nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = WRITE_ENABLE, .length = QSPI_CINSTRCONF_LENGTH_1B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = false }; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL,NULL); APP_ERROR_CHECK(err_code); nrf_gpio_pin_set( NRF_GPIO_PIN_MAP(0,16)); nrf_delay_ms(100); } void ProgramSecurityRegister() { uint32_t err_code; // m_finished = false; uint8_t storeAddress[6]; storeAddress[0]=0x00; storeAddress[1]=0x10; storeAddress[2]=0x01; storeAddress[4]=0x34; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = FLASH_CMD_PROGRAM_SECURITY_REG, .length = QSPI_CINSTRCONF_LENGTH_5B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = true }; nrf_gpio_pin_clear( NRF_GPIO_PIN_MAP(0,16)); err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg,&storeAddress[0], NULL); // nrf_delay_ms(100); APP_ERROR_CHECK(err_code); readStatusRegister(); nrf_gpio_pin_set( NRF_GPIO_PIN_MAP(0,16)); } void ReadSecurityRegister() { uint32_t err_code; // m_finished = false; uint8_t storeAddress[5]; storeAddress[0]=0x00; storeAddress[1]=0x10; storeAddress[2]=0x01; storeAddress[3]=0xFF; // // uint8_t rxdata[4]={0,0,0,0}; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = FLASH_CMD_READ_SECURITY_REG, .length = QSPI_CINSTRCONF_LENGTH_2B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = false }; nrf_gpio_pin_clear( NRF_GPIO_PIN_MAP(0,16)); // err_code= nrfx_qspi_lfm_start(&cinstr_cfg); err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg,&storeAddress[0],&deviceName[0]); APP_ERROR_CHECK(err_code); nrf_gpio_pin_set( NRF_GPIO_PIN_MAP(0,16)); for(int i=0;i<sizeof(deviceName);i++) { SEGGER_RTT_printf(0,"device-%x\n",deviceName[i]); } } void FlashOtpErase(void) { ret_code_t err_code; m_finished = false; uint8_t address[4]; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = FLASH_CMD_ERASE_SECURITY_REG, .length = NRF_QSPI_CINSTR_LEN_4B, .io2_level = true, .io3_level = true, .wipwait = true, .wren = true }; address[0]=0x00; address[1]=0x10; address[2]=0x01; nrf_gpio_pin_clear( NRF_GPIO_PIN_MAP(0,16)); err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &address[0], NULL); SEGGER_RTT_printf(0,"errorcodeflasherase-%X",err_code); APP_ERROR_CHECK(err_code); nrf_gpio_pin_set( NRF_GPIO_PIN_MAP(0,16)); } void readJdec(void) { uint32_t err_code; uint8_t read[4]; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = READ_JDEC, .length = NRF_QSPI_CINSTR_LEN_4B, .io2_level = false, .io3_level = false, .wipwait = false, .wren = false }; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, &read[0]); SEGGER_RTT_printf(0,"errorcodeflasherase-%X\n",err_code); for(int i =0;i<4;i++) { SEGGER_RTT_printf(0,"jdec-%X",read[i]); } } void readuniqueid(void) { uint32_t err_code; uint8_t readone[8]; uint8_t sent[4]={0,0,0,0}; nrf_qspi_cinstr_conf_t cinstr_cfg = { .opcode = READ_JDEC, .length = NRF_QSPI_CINSTR_LEN_8B, .io2_level = false, .io3_level = false, .wipwait = false, .wren = false }; err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, &sent[0], &readone[0]); SEGGER_RTT_printf(0,"errorcodeflasherase-%X\n",err_code); for(int i =0;i<8;i++) { SEGGER_RTT_printf(0,"ubique-%X",readone[i]); } } int main(void) { // uint32_t i; uint32_t err_code; err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); NRF_LOG_INFO("" "QSPI write and read example using 24bit addressing mode"); nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(0,16)); nrf_drv_qspi_config_t config = { .xip_offset = 0, .pins = { .sck_pin = NRF_GPIO_PIN_MAP(0,19), .csn_pin = NRF_GPIO_PIN_MAP(0,16), .io0_pin = NRF_GPIO_PIN_MAP(0,14), .io1_pin = NRF_GPIO_PIN_MAP(0,23), .io2_pin = NRF_GPIO_PIN_MAP(1,15), .io3_pin = NRF_GPIO_PIN_MAP(0,13), }, .prot_if = { .readoc = NRF_QSPI_READOC_READ4O, // 0x6B read command .writeoc = NRF_QSPI_WRITEOC_PP4O, // 0x32 write command .addrmode = NRF_QSPI_ADDRMODE_24BIT, .dpmconfig = false }, .phy_if = { .sck_delay = 100, .dpmen = false, .spi_mode = NRF_QSPI_MODE_0, .sck_freq = NRF_QSPI_FREQ_32MDIV4, // start with low 2 Mhz speed }, .irq_priority = 3 }; err_code = nrf_drv_qspi_init(&config, qspi_handler, NULL); APP_ERROR_CHECK(err_code); NRF_LOG_INFO("QSPI example started."); SEGGER_RTT_printf(0,"QSPI Started\r\n"); readJdec(); ProgramSecurityRegister(); ReadSecurityRegister(); readStatusRegister(); while(1) { } } /** @} */