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"?