I have recently finished building up a board for a nanovoltmeter (
https://github.com/curtisseizert/Nanovoltmeter) that uses an AD4032-34 as the core ADC to perform conversions, which gives the option for clocking data out over one, two, or four lines. I have attached a timing diagram for the a read over four lines. It is very simple - pull the NCS low and start clocking out the data. The MCU is an STM32U575. I had planned to use the octospi bus to perform data reads from the converter, being somewhat familiar with configuration of quadspi on the F446. My plan was to simply skip all the phases except the data phase, but this does not appear to work on the STM32U575. I can get the frame to look right on the scope using a board that was only populated with the MCU and associated oscillators, but when I move to a fully populated board, it becomes clear that the octospi IO pins remain low impedance during the transfer, with IO3 pulling high and the others pulling low. The setup code is below.
static void OCTOSPIMInit(void)
{
OCTOSPIM->PCR[0] |= (3U << OCTOSPIM_PCR_IOHSRC_Pos)
| (1U << OCTOSPIM_PCR_IOLSRC_Pos)
| OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_NCSEN
| OCTOSPIM_PCR_CLKEN;
OCTOSPIM->PCR[0] &= ~(OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_DQSEN);
OCTOSPIM->PCR[1] &= ~(OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOLEN
| OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_DQSEN);
}
/**
* @brief Configures OCTOSPI for indirect reads
* @param none
* @retvalue none
*/
void OCTOSPIInit(void)
{
OCTOSPIGPIOInit();
OCTOSPIMInit();
// Setup data length register
OCTOSPI1->DLR = OCTOSPI_DATA_SIZE;
// Setup CCR
OCTOSPI1->CCR = OCTOSPI_FOUR_LINES;
// Setup Alternate bytes register
OCTOSPI1->ABR = 0;
// Setup Address Register
OCTOSPI1->AR = 0;
// Setup Device Control Register
OCTOSPI1->DCR1 = (OCTOSPI_MTYP << OCTOSPI_DCR1_MTYP_Pos) | // MTYPE 02 (Standard)
(1U << OCTOSPI_DCR1_DEVSIZE_Pos); // Devsize = 4 bytes
OCTOSPI1->DCR2 = (OCTOSPI_PRESCALER << OCTOSPI_DCR2_PRESCALER_Pos);
// Setup control register
OCTOSPI1->CR = (OCTOSPI_FMODE_IR << OCTOSPI_CR_FMODE_Pos) | // Indirect read
(OCTOSPI_FIFO_THRESHOLD << OCTOSPI_CR_FTHRES_Pos); // Set FIFO Threshold
While I was attempting to debug this, I found this line in the U5 reference manual: "Any of these phases can be configured to be skipped but, in case of single-phase command, the only use case supported is instruction-phase-only." This is not the case with quadspi on F4, which mentions only that you need to keep at least one of the phases. Is it possible to use octospi to do simple four-lane data transfers that are otherwise equivalent to a SPI read, or is it not possible to use the octospi bus to interface with this peripheral? I have been able to use SPI to get data from the ADC fast enough for this to work at 500 kSPS, but I would have preferred to use octospi to be able to reduce the amount of time needed for the transfer and potentially run the MCU at a lower clock rate or use an AD4030-24 at a faster sampling rate.