Reputation: 161
I am using QSPI not to connect memory, but a FTDI display. I used STM32CubeMX and Atollic TrueStudio. I included FreeRTOS, but I'm not using that, yet.
Using QuadSPI, I have trouble to read and write 1, 2 or 4 bytes, where I transmit a 3 byte memory address.
If I try to read an address like this, it times out at HAL_QSPI_Receive, and no signals are generated on the bus, if I configure
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
If I configure
s_command.AddressMode = QSPI_ADDRESS_NONE;
Signals are generated to read a byte, but the address is not send of course.
To send the address and receive bytes afterwards, I send the address in the Alternate bytes. But now the number of bytes can 1 or 2, but not 4, because I will get a time-out again.
My code pieces
uint8_t pData[4];
uint32_t address = REG_ID;
QspiReadData(address, 1, pData);
uint32_t v = 0x12345678;
pData[0] = v >> 24;
pData[1] = (v >> 16) & 0xff;
pData[2] = (v >> 8) & 0xff;
pData[3] = v & 0xff;
QspiWriteData(addr, 4, pData);
uint8_t QspiReadData(uint32_t address, uint32_t size, uint8_t* pData)
{
QSPI_CommandTypeDef s_command;
QSPI_AutoPollingTypeDef s_config;
/* Initialize the read command */
s_command.InstructionMode = QSPI_INSTRUCTION_NONE;
s_command.Instruction = 0;
s_command.AddressMode = QSPI_ADDRESS_1_LINE;
s_command.AddressSize = QSPI_ADDRESS_32_BITS;
s_command.Address = address;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.AlternateBytes = 0;
s_command.AlternateBytesSize = 0;
s_command.DataMode = QSPI_DATA_1_LINE; // QSPI_DATA_4_LINES
s_command.DummyCycles = 0;
s_command.NbData = size;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
printf("HAL_QSPI_Command\n");
if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n");
return HAL_ERROR;
}
/* Reception of the data */
printf("HAL_QSPI_Receive\n");
if (HAL_QSPI_Receive(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n"); // Timeout after 5000mS
return HAL_ERROR;
}
return HAL_OK;
}
/* QUADSPI init function */
void MX_QUADSPI_Init(void)
{
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 254; /* 4 QSPI Freq= 108 MHz / (1+4) = 21.6 MHz */
hqspi.Init.FifoThreshold = 1;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
hqspi.Init.FlashSize = 0;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_8_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0; // QSPI_CLOCK_MODE_0 Rising edge CPOL=0, QSPI_CLOCK_MODE_3 Falling edge CPOL=1
hqspi.Init.FlashID = QSPI_FLASH_ID_1;
hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
if (HAL_QSPI_Init(&hqspi) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
uint8_t QspiWriteData(uint32_t address, uint32_t size, uint8_t* pData)
{
QSPI_CommandTypeDef s_command;
printf("Ft813QspiReadData8(%ld, %d, pData)\n", address, size);
/* Initialize the read command */
s_command.InstructionMode = QSPI_INSTRUCTION_NONE;
s_command.Instruction = 0;
s_command.AddressMode = QSPI_ADDRESS_NONE;
s_command.AddressSize = QSPI_ADDRESS_24_BITS;
s_command.Address = 0;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_1_LINE;
s_command.AlternateBytes = address;
s_command.AlternateBytesSize = QSPI_ALTERNATE_BYTES_24_BITS;
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.DummyCycles = 0;
s_command.NbData = size;
s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
/* Configure the command */
printf("HAL_QSPI_Command\n");
if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n");
return HAL_ERROR;
}
/* Reception of the data */
printf("HAL_QSPI_Transmit\n");
if (HAL_QSPI_Transmit(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
printf("HAL_ERROR\n");
return HAL_ERROR;
}
return HAL_OK;
}
What can be the problem?
The GPIO pins were configured like this, in case it helps sombody else:
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* qspiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(qspiHandle->Instance==QUADSPI)
{
/* USER CODE BEGIN QUADSPI_MspInit 0 */
/* USER CODE END QUADSPI_MspInit 0 */
/* QUADSPI clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
/**QUADSPI GPIO Configuration
PF6 ------> QUADSPI_BK1_IO3
PF7 ------> QUADSPI_BK1_IO2
PF8 ------> QUADSPI_BK1_IO0
PF9 ------> QUADSPI_BK1_IO1
PF10 ------> QUADSPI_CLK
PB10 ------> QUADSPI_BK1_NCS
*/
GPIO_InitStruct.Pin = QUADSPI_BK1_IO3_Pin|QUADSPI_BK1_IO2_Pin|QUADSPI_CLK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = QUADSPI_BK1_IO0_Pin|QUADSPI_BK1_IO1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = QUADSPI_BK1_NCS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(QUADSPI_BK1_NCS_GPIO_Port, &GPIO_InitStruct);
/* QUADSPI DMA Init */
/* QUADSPI Init */
hdma_quadspi.Instance = DMA2_Stream2;
hdma_quadspi.Init.Channel = DMA_CHANNEL_11;
hdma_quadspi.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_quadspi.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_quadspi.Init.MemInc = DMA_MINC_ENABLE;
hdma_quadspi.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_quadspi.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_quadspi.Init.Mode = DMA_NORMAL;
hdma_quadspi.Init.Priority = DMA_PRIORITY_LOW;
hdma_quadspi.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_quadspi) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(qspiHandle,hdma,hdma_quadspi);
/* QUADSPI interrupt Init */
HAL_NVIC_SetPriority(QUADSPI_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
/* USER CODE BEGIN QUADSPI_MspInit 1 */
/* USER CODE END QUADSPI_MspInit 1 */
}
}
Upvotes: 1
Views: 5766
Reputation: 185
hqspi.Init.FlashSize = 0; is wrong. QuadSPI module needs to learn the memory of device which will write/read. Change it with 31. It will run.
Upvotes: 4