Configuration Register - S25FL512S QUAD mode

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

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

0 Likes
1 Solution

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

View solution in original post

0 Likes
7 Replies
TakahiroK_16
Employee
Employee
100 replies posted 50 replies posted 25 solutions authored

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

Anonymous
Not applicable

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();

0 Likes

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

0 Likes
Anonymous
Not applicable

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

0 Likes

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

0 Likes
Anonymous
Not applicable

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)

0 Likes

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

0 Likes