I updated the MAX6675 test program after studying the SPI documentation in the GD32VF103 User Manual back and forth, and finally I can read values from the MAX6675 via SPI1, but only after switching to SPI software mode and by explicitly controlling the CS/NSS pin.
I couldn’t get it to work in “hardware mode”, so I would be interested if anybody could tell what was wrong with my attempts to configure SPI1 in hardware mode.
This is the setup, the Longan Nano being the master and the MA6675 being the slave (screen shot from the GD32VF103 User Manual):
I want to use the “MRU” hardware mode according to table “Table 18-2. SPI operating modes” in section “18.5.3. SPI operating modes” in the the GD32VF103 User Manual:
- Register configuration: MSTMOD = 1, RO = 1, BDEN = 0, BDOEN: Don’t care
- MOSI: Not used, MISO: Reception
Under “18.5.2. NSS function” it says:
If the application wants to use NSS line to control the SPI slave, NSS should be configured to hardware output mode (SWNSSEN=0, NSSDRV=1). NSS stays high after SPI is enabled and goes low when transmission or reception process begins. When SPI is disabled, the NSS goes high.
This is the configuration of SPI1 in my code, that should accomplish the configuration with SWNSSEN=0, NSSDRV=1:
spi_init_struct.trans_mode = SPI_TRANSMODE_RECEIVEONLY;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT;
spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
spi_init_struct.nss = SPI_NSS_HARD;
spi_init_struct.prescale = SPI_PSC_256;
spi_init_struct.endian = SPI_ENDIAN_MSB;
Inside a loop the program then does the following to receive the data from the MAX6675:
while (RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE));
uint16_t const data = spi_i2s_data_receive(SPI1);
First I retrieve the data from SPI1 to empty the buffer. Then SPI1 is enabled. Then the loop waits until there’s data available in the receive buffer. Then it reads the data and disables SPI1.
According to the documentation I would expect that NSS goes from high to low when spi_enable(SPI1) is called, but this is not happening. When I watch the signals with a logic analyzer, I can see a clock signal for exactly 16 cycles on the SCK pin, but the NSS pin stays high. Note that I’m setting the NSS pin to high explicitly in the GPIO configuration code, otherwise it would stay low forever.
This is the GPIO configuration for SPI1 that I used for hardware mode:
/* SPI1_SCK(PB13), SPI1_MISO(PB14) GPIO pin configuration */
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
/* SPI1_CS(PB12) GPIO pin configuration */
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
As the CS/NSS pin should be automatically controlled by the hardware, I configured GPIOB pin 12 as GPIO_MODE_AF_PP. Is this correct?