54LM20A sQSPI behavior is different with 54L15

Hello DevZone,

I have wrote a standard Zephyr display driver for one customer, I used sQSPI and Zephyr MSPI API.

I finished the development, but the QSPI (1-1-4 mode) plot on 54LM20 is different from that on 54L15. The code is same.

display requirement:


nrf54L15 v1.0.0

nrf54lm20 v0.3.4:


You can see that when transmitting the cmd and address, the voltage of D1, D2, D3 is different.
I'm not sure which one is correct.

Here is my code: github.com/.../display_a6ng.c
My NCS version is v3.2.2

Best regards,
Jayant

Parents Reply Children
  • I don't have a v0.5.4 DK now. I'll test that when I get this. Thanks.

    By the way, due to the customer's requirement, I change the repo to private.

    So I paste some of the code here in case you need it.:

    int a6ng_bus_write(const struct device *dev, const uint8_t *buf, size_t size)
    {
        struct a6ng_data *data = dev->data;
        const struct a6ng_config *config = dev->config;
    
        __ASSERT(buf != NULL, "Data pointer is NULL");
    
        if (size > config->framebuffer_size) {
            LOG_ERR("Data size %d exceeds framebuffer size %d", size, config->framebuffer_size);
            return -EINVAL;
        }
    
        if (size % (config->width * config->gray_scale_bits / 8) != 0) {
            LOG_ERR("Data size %d is not a multiple of the screen width %d", size, config->width);
            return -EINVAL;
        }
    
    #if IS_ENABLED(CONFIG_A6NG_LINE_MODE_SPI)
        data->pixels_packet.cmd = (A6NG_OPCODE_SPI_DISPLAY_WRITE & 0xff000000) >> 24;
        data->pixels_packet.address = A6NG_OPCODE_SPI_DISPLAY_WRITE & 0x00ffffff;
        data->pixels_xfer.timeout = 2500; // 640 * 480 * 8 bits / 1Mbps = 2457.6 ms, add some margin
    #elif IS_ENABLED(CONFIG_A6NG_LINE_MODE_QSPI)
        data->pixels_packet.cmd = (A6NG_OPCODE_QSPI_DISPLAY_WRITE & 0xff000000) >> 24;
        data->pixels_packet.address = A6NG_OPCODE_QSPI_DISPLAY_WRITE & 0x00ffffff;
        data->pixels_xfer.timeout = 700; // 640 * 480 * 8 bits / (4 * 1Mbps) = 614.4 ms, add some margin
    #else
    #error "Please select line mode for A6NG display"
    #endif
    
        data->pixels_packet.dir = MSPI_TX;
        data->pixels_packet.num_bytes = size;
        data->pixels_packet.data_buf = (uint8_t *)buf;
        data->pixels_packet.cb_mask = MSPI_BUS_NO_CB;
    
        data->pixels_xfer.packets = &data->pixels_packet;
        data->pixels_xfer.num_packet = 1;
    
    #if IS_ENABLED(CONFIG_A6NG_LINE_MODE_SPI)
        data->mspi_dev_cfg.io_mode = MSPI_IO_MODE_SINGLE; // 1-1-1 (standard SPI)
    #elif IS_ENABLED(CONFIG_A6NG_LINE_MODE_QSPI)
        data->mspi_dev_cfg.io_mode = MSPI_IO_MODE_QUAD_1_1_4; // 1-1-4 (QSPI)
    #else
    #error "Please select line mode for A6NG display"
    #endif
        mspi_dev_config(config->bus, &config->mspi_id, MSPI_DEVICE_CONFIG_IO_MODE, &data->mspi_dev_cfg);
    
        return mspi_transceive(config->bus, &config->mspi_id, &data->pixels_xfer);
    }
    
    void a6ng_set_default_data(const struct device *dev)
    {
        const struct a6ng_config *config = dev->config;
        struct a6ng_data *data = dev->data;
    
        // prepare default MSPI configuration
        struct mspi_dev_cfg cfg = {
            .ce_num = config->ce_num,
            .freq = config->frequency,
            .io_mode = MSPI_IO_MODE_SINGLE,       // 1-1-1 (standard SPI)
            .data_rate = MSPI_DATA_RATE_SINGLE,   // SDR
            .cpp = MSPI_CPP_MODE_0,               // CPOL = 0, CPHA = 0
            .endian = MSPI_XFER_BIG_ENDIAN,       // big endian
            .ce_polarity = MSPI_CE_ACTIVE_LOW,    // active low
            .dqs_enable = false,   
        };
        memcpy(&data->mspi_dev_cfg, &cfg, sizeof(struct mspi_dev_cfg));
    
        // Configure MSPI bus
        mspi_dev_config(config->bus, &config->mspi_id, MSPI_DEVICE_CONFIG_ALL, &data->mspi_dev_cfg);
    
        // prepare default transfer configuration for register access
        struct mspi_xfer reg_xfer = {
            .async = false,
            .xfer_mode = MSPI_PIO,
            .tx_dummy = 0,
            .rx_dummy = 0,
            .cmd_length = 1,   // OPCODE [7:0]
            .addr_length = 1,  // Register address 
            .hold_ce = false, 
            .ce_sw_ctrl.gpio.port = config->mspi_id.ce.port,
            .ce_sw_ctrl.gpio.pin = config->mspi_id.ce.pin,
            .ce_sw_ctrl.gpio.dt_flags = config->mspi_id.ce.dt_flags,
            .ce_sw_ctrl.delay = 3, 
            .priority = MSPI_XFER_PRIORITY_HIGH,
            .packets = &(data->reg_packet),
            .num_packet = 1,
            .timeout = 5,
        };
        memcpy(&data->reg_xfer, &reg_xfer, sizeof(struct mspi_xfer));
    
        // prepare default transfer configuration for pixel data access
        struct mspi_xfer display_xfer = {
            .async = false,
            .xfer_mode = MSPI_PIO,
            .tx_dummy = 0,
            .rx_dummy = 0,
            .cmd_length = 1,  // OPCODE [31:24]
            .addr_length = 3, // OPCODE [23:0]
            .hold_ce = false,
            .ce_sw_ctrl.gpio.port = config->mspi_id.ce.port,
            .ce_sw_ctrl.gpio.pin = config->mspi_id.ce.pin,
            .ce_sw_ctrl.gpio.dt_flags = config->mspi_id.ce.dt_flags,
            .ce_sw_ctrl.delay = 3, 
            .priority = MSPI_XFER_PRIORITY_HIGH,
            .packets = &(data->pixels_packet),
            .num_packet = 1,
            .timeout = 1000, // display data transfer may take longer time
        };
        memcpy(&data->pixels_xfer, &display_xfer, sizeof(struct mspi_xfer));
    
    
    }
    
    

  • Do let me know if you see any issues on the v0.5.4 DK with engineering B.

    Kenneth

  • Hello,

    I got the 54LM20DK v0.7.0, the result is same as 54LM20DK v0.3.4.

    The NCS version is v3.2.4.

    Now this doesn't affect the normal qspi communication. It is just different with 54l15.

    I'm not sure if there is any specification about this. Just let you know.

  • Thank you for the update, I am in contact with the team now.

    Kenneth

  • Hello again,

    Can you confirm that you have bias-pull-ups enabled on the pins in question for the nRF54LM20A?

    Ref for instance:

    	sqspi_default: sqspi_default {
    		group1 {
    			psels = <NRF_PSEL(SDP_MSPI_SCK, 2, 1)>,
    				<NRF_PSEL(SDP_MSPI_CS0, 2, 5)>,
    				<NRF_PSEL(SDP_MSPI_DQ0, 2, 2)>;
    			nordic,drive-mode = <NRF_DRIVE_E0E1>;
    		};
    		group2 {
    			psels = <NRF_PSEL(SDP_MSPI_DQ1, 2, 4)>,
    				<NRF_PSEL(SDP_MSPI_DQ2, 2, 3)>,
    				<NRF_PSEL(SDP_MSPI_DQ3, 2, 0)>;
    			nordic,drive-mode = <NRF_DRIVE_E0E1>;
    			bias-pull-up;
    		};
    	};

    Kenneth

Related