最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

spi - STM32H7A3 QSPI RAM on OctoSPI Peripheral - issues with HAL Functions - Stack Overflow

programmeradmin0浏览0评论

This is a cross-post from the ST Community Forum, where I posted this question yesterday evening, but did not get any response so far. (Link: )

my Setup: I have a Shield for a STM32 H7A3 Nucleo (144 pins) with an ISSI IS62WVS2568FBLL Quad-SPI SRAM connected to the Octo-SPI Peripheral. I use an oscilloscope with a built-in logic-analyzer for debugging. The datasheet of the SRAM can be found here: .pdf

short description of the issue(s): when I add an address phase to the OSPI transfer, the peripheral does nothing, the HAL functions goes into the timeout after 5 s (default timeout). But I can send and receive on one or all 4 lines, if I do not add an address phase - and I see the Chip Select, Clock and Data-Lines changing on the scope. The second issue is: data are not written to the read buffer in single-line mode, even if I see them coming over the bus on the scope.

CubeMX Setup: The Octo-SPI Peripheral is configured as showed in the Screenshot below. I followed the instructions of the Application Node AN5050. There are some insecurities, because I did not figure out what "Delay Block" means. But it seems to have no effect, no matter if I en- or disable it, there is no change in the outcome.

Code:

this function reads the Mode Register in SPI mode (on one data line):

static uint8_t rOS_SRAM_ModReg_read(void) {
// @brief   read Mode Register
// @mode    u8 * mode: mode return value
// @return  u8 status: 0 = OK (no error)

   OSPI_RegularCmdTypeDef cmd = {0};

   cmd.Instruction              = SRAM_CMD_RDMR;                            // instruction: read mode register
   cmd.InstructionMode          = HAL_OSPI_INSTRUCTION_1_LINE;              // use SPI (1 line)
   cmd.InstructionSize          = HAL_OSPI_INSTRUCTION_8_BITS;              // size of the instruction

   cmd.DataMode             = HAL_OSPI_DATA_1_LINE;                     // data mode: 1 Line
   cmd.NbData                   = 1;                                        // number of data transfered with the command
   cmd.DummyCycles              = 0x00;                                     // number of dummy cycles before data phase

   HAL_StatusTypeDef status;
   status = HAL_OSPI_Command(hSramOSPI, &cmd, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
   if(HAL_OK != status) {
       return(1);
   }

   status = HAL_OSPI_Receive(hSramOSPI, SRAM_buf, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
   if (HAL_OK != status) {
       return(1);
   } else {
       SRAM_modereg = SRAM_buf[0];
   }

   return(0);
}

the next function should read data from the SRAM in Quad-mode (4 data lines):

static uint8_t rOS_SRAM_read(uint32_t addr, uint8_t * pData, uint32_t dataSz) {
// @brief   read from SRAM in Quad-Mode (Blocking)
// @param   u32 addr: address
// @oaram   u8* data: read buffer pointer
// @param   u32 dataSz: # of data to be read
// @return  u8 status: 0 = OK (no error)

if (pData && dataSz) {
    OSPI_RegularCmdTypeDef cmd = {0};
    cmd.Instruction             = SRAM_CMD_READ;                            // instruction byte
    cmd.InstructionSize         = HAL_OSPI_INSTRUCTION_8_BITS;              // size of the instruction

    cmd.Address                 = addr;                                     // data address
    cmd.AddressSize             = HAL_OSPI_ADDRESS_24_BITS;                 // size of the address (typ. 24 bit)

    cmd.NbData                  = dataSz;                                   // number of data transfered with the command

    if(SRAM_quad) {
        cmd.InstructionMode         = HAL_OSPI_INSTRUCTION_4_LINES;             // mode of the instruction
        #ifndef SRAM_NOADDR
        cmd.AddressMode             = HAL_OSPI_ADDRESS_4_LINES;                 // send an address?
        #endif
        cmd.DataMode                = HAL_OSPI_DATA_4_LINES;                    // data mode: send data or just command
        cmd.DummyCycles             = 0x2;                                      // number of dummy cycles before data phase
    } else {
        cmd.InstructionMode         = HAL_OSPI_INSTRUCTION_1_LINE;              // mode of the instruction
        #ifndef SRAM_NOADDR
        cmd.AddressMode             = HAL_OSPI_ADDRESS_1_LINE;                  // send an address?
        #endif
        cmd.DataMode                = HAL_OSPI_DATA_1_LINE;                     // data mode: send data or just command
    }

    HAL_StatusTypeDef status;
    status = HAL_OSPI_Command(hSramOSPI, &cmd, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
    if(HAL_OK != status) {
        return(1);
    }

    status = HAL_OSPI_Receive(hSramOSPI, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
    if (HAL_OK != status) {
        return(1);
    }
}

return(0);
}

Issues / Problems:

The first function has the issue, that the variable >>SRAM_modereg<< is set to 0, because the rx buffer contains only zeroes. I assume that this happens, because the SRAM sends the data back on the same line which is used for TX (Line D0). I can see that on the scope. Eventually HAL expects the Chip to send the data on the 2nd line - which would be the MISO Line in a standard SPI setup, but the Chip uses the "MOSI" (D0) Line to send the data?

The second function has the issue that nothing happens, when I enable one or multiple lines for the Address phase. If I disable the address-Phase I see activity on the bus in the scope, either with one line or with 4 lines, depending on if I set the chip to Quad-Mode or not. The chip clearly responds, and even the data are transfered into the buffers, even if it is gibberish. But at least the hardware does something.

Question(s):

How do I have to set up the Regular Command struct in a way, that in single line mode (e.g. when reading the Mode register), the data are read from the "MOSI" (D0) line instead of the "MISO" (D1) line. As explained above, the HAL functions seems to expect the data on the "MISO" (D1) line, but the Chip sends on the D0 Line.

What am I doing wrong with the setup of the data read function? Why does the Peripheral remain completely dead when I set >>cmd.AddressMode<< to anything other than >>HAL_OSPI_ADDRESS_NONE<< ? I can not see any reason why the HAL driver should not start the peripheral, when I add an address phase? I assumed this would be intended behaviour or the correct way to use the command struct?

Eventually the "address phase" problem could be solved by "Alternate Bytes" - that idea came up while I was typing this post. I have not yet tried that. But what are "alternate Bytes"?

发布评论

评论列表(0)

  1. 暂无评论