7 Replies Latest reply on Mar 5, 2018 6:55 PM by tkuw

    Configuration Register - S25FL512S QUAD mode

    SimonTemplat

      Hi, I tried to run S70FL01GS flash in quad spi mode. Based on datasheet this memory is a dual die stack of two S25FL512S die. I tryied to change QUAD bit in Configuration Register (CR1), but without success. I used Low Level Driver with my own hal functions, whitch works when I read ID or read/write/erease some data in flash memory. I will be really grateful for your help

        • 1. Re: Configuration Register - S25FL512S QUAD mode
          tkuw

          Hi,

           

          I assume you are using SLLD v13.2.1, if not, please let me know your SLLD version.

          Could you share a code snippet that shows how you use SLLD functions (slld_WRROp or slld_WRRCmd)?

           

          Best Regards,

          Takahiro

          1 of 1 people found this helpful
          • 2. Re: Configuration Register - S25FL512S QUAD mode
            SimonTemplat

            I'm using SLLD v16.2.1 (at least that is value of SLLD_VERSION constant)

            Code:

            uint8_t output[1];

            DEVSTATUS status = dev_not_busy;

            SLLD_STATUS ret_val = SLLD_OK;

            uint8_t statusreg[2] = { 0x00, 0x01}; //SR1, CR. SR2

             

            spi_init();

            nrf_delay_ms(300);

            ret_val = slld_WRROp(0, &statusreg[0], &statusreg[1], NULL, &status);

            NRF_LOG_INFO("slld_WRROp %d", ret_val);

             

            ret_val = slld_RDIDCmd(0, output, 1);

            NRF_LOG_INFO("ID  0x%2x, %2d", output[0], ret_val);

             

            ret_val = slld_RCRCmd(0, output); //Configuration Register 1 (CR1)

            NRF_LOG_INFO("CR1 0x%2x, %2d", output[0], ret_val);

             

            ret_val = slld_RDSRCmd(0, output);

            NRF_LOG_INFO("SR1 0x%2x, %2d", output[0], ret_val);

             

            ret_val = slld_RDSR2Cmd(0, output);

            NRF_LOG_INFO("SR2 0x%2x, %2d", output[0], ret_val);

            spi_uninit();

            • 3. Re: Configuration Register - S25FL512S QUAD mode
              tkuw

              Thanks for sharing the code.

              In your code, you write 0x01 to CR. Since the QUAD bit is assigned in bit 1 of CR, you need to write 0x02.

               

              Best Regards,

              Takahiro

              • 4. Re: Configuration Register - S25FL512S QUAD mode
                SimonTemplat

                Yes, I know that

                The problem is: slld_WRROp or slld_RCRCmd function seems not working correctly (doesn't meter if i  send 0x01, 0x02 or something else),  output result of read status or configuration registers is is always 0. This is the reason why turning flash on quad spi mode seams impossible.

                I don't think it is mistake in my slld_hal FLASH_WRITE, FLASH_READ functions implementation, because slld_ReadOp and slld_WriteOp works correctly.

                Sorry if problem description wasn't perfect in first question

                • 5. Re: Configuration Register - S25FL512S QUAD mode
                  tkuw

                  Understood.

                   

                  Just in case, please let me double check your HAL implementation. Could you share slld_hal.c?

                  And is it possible to capture waveform by logic analyzer or oscilloscope?

                   

                  Best Regards,

                  Takahiro

                  • 6. Re: Configuration Register - S25FL512S QUAD mode
                    SimonTemplat

                    My slld_hal.c :

                    #include <stdio.h>

                    #include "slld_targetspecific.h"

                    #include "slld.h"

                    #include "slld_hal.h"

                     

                    SLLD_STATUS FLASH_READ(BYTE device_num, /* device number to which operation will be done */

                    BYTE command, /* write a single command byte to flash */

                    ADDRESS sys_addr, /* system address to be used */

                    BYTE *data_buffer, /* Pointer to the data buffer containing data to be written */

                    int Number_Of_Read_Bytes /* number of bytes to be read */

                    ) {

                        SLLD_STATUS status = SLLD_OK;

                        uint32_t err_code = 0;

                        uint8_t u8sys_addr[3] = { sys_addr & 0x000000ff, ((sys_addr & 0x0000ff00)

                                >> 8), ((sys_addr & 0x00ff0000) >> 16) }, Number_Of_Dummy_Bytes;

                     

                        uint8_t message[] = { command, u8sys_addr[2], u8sys_addr[1], u8sys_addr[0],    0, 0, 0 };

                     

                        switch (command) {

                        case SPI_FAST_READ_CMD:

                        case SPI_FAST_READ_4B_CMD:

                        case SPI_DUALIO_RD_CMD:

                        case SPI_DUALIO_RD_4B_CMD:

                        case SPI_QUADIO_RD_CMD:

                        case SPI_QUADIO_RD_4B_CMD:

                        case SPI_OTPR_CMD: {

                            Number_Of_Dummy_Bytes = 1;

                            break;

                        }

                        case SPI_RES_CMD: {

                            Number_Of_Dummy_Bytes = 3;

                            break;

                        }

                        default: {

                            Number_Of_Dummy_Bytes = 0;

                            break;

                        }

                        }

                     

                        BYTE temp_data_buffer[Number_Of_Dummy_Bytes + Number_Of_Read_Bytes];

                        if (ADDRESS_NOT_USED == sys_addr) {

                            err_code = spi_read_write(message, 1, temp_data_buffer,

                                    Number_Of_Dummy_Bytes + Number_Of_Read_Bytes);

                        } else {

                            err_code = spi_read_write(message, 4, temp_data_buffer,

                                    Number_Of_Dummy_Bytes + Number_Of_Read_Bytes);

                        }

                        memcpy(data_buffer, &temp_data_buffer[Number_Of_Dummy_Bytes], Number_Of_Read_Bytes);

                     

                        return (0 == err_code) ? SLLD_OK : SLLD_E_HAL_ERROR; //KT

                    }

                     

                    SLLD_STATUS FLASH_WRITE(BYTE device_num, /* device number to which operation will be done */

                    BYTE command, /* write a single command byte to flash */

                    ADDRESS sys_addr, /* system address to be used */

                    BYTE *data_buffer, /* Pointer to the data buffer containing data to be written */

                    int Number_Of_Written_Bytes /* number of bytes to be written */

                    ) {

                        SLLD_STATUS status = SLLD_OK;

                        uint32_t err_code = 0;

                        uint8_t u8sys_addr[3] = { sys_addr & 0x000000ff, ((sys_addr & 0x0000ff00)

                                >> 8), ((sys_addr & 0x00ff0000) >> 16) };

                        uint8_t message[Number_Of_Written_Bytes + 4];

                     

                        message[0] = command;

                        if (sys_addr == ADDRESS_NOT_USED) {

                            err_code = spi_read_write(message, 1, NULL, 0);

                            return (0 == err_code) ? SLLD_OK : SLLD_E_HAL_ERROR;

                        }

                     

                        message[1] = u8sys_addr[2];

                        message[2] = u8sys_addr[1];

                        message[3] = u8sys_addr[0];

                        for (int cnt = 4; cnt < Number_Of_Written_Bytes + 4; cnt++) {

                            message[cnt] = data_buffer[cnt - 4];

                        }

                     

                        err_code = spi_read_write(message, sizeof(message) / sizeof(message[0]),NULL, 0);

                        return (0 == err_code) ? SLLD_OK : SLLD_E_HAL_ERROR;

                     

                    }

                     

                    Unfortunately i can't capture a waveform (it wasn't designed on pcb design of my device)

                    • 7. Re: Configuration Register - S25FL512S QUAD mode
                      tkuw

                      I think your FLASH_WRITE() issues wrong sequence in the WRR command case.

                       

                      If you would like to write SR=0x00 and CR=0x02, the WRR command sequence should be 3-byte cycles like 0x01(WRR) - 0x00(SR) - 0x02(CR). The WRR sequence does not contain address cycle so sys_adder == ADDRESS_NOT_USED. In this case, your FLASH_WRITE() writes 1 byte command and then returns without writing SR and CR values.

                       

                      Best Regards,

                      Takahiro