cancel
Showing results for 
Search instead for 
Did you mean: 

DISCOVERY BOARD SPI NO NSS

david2399
Associate II
Posted on September 01, 2014 at 06:25

Hello,

I have a Discovery board and am using the SPI master DMA example and SPI4. I set NSS as SPI_NSS_HARD_OUTPUT. What I get is CLK, and MOSI come out perfectly, but NSS is pinned low. I put a pullup on it, and it is pinned high now. The peripheral is in master mode. I am looking at PE4 for the NSS output.

Can anybody suggest what I might be overlooking here?
4 REPLIES 4
david2399
Associate II
Posted on September 01, 2014 at 06:58

Hello,

This may stem from the fact that the example does not look like it sets up the GPIO to alternate function mode in the example. I will try this tomorrow and report back.

Dave Bassett

david2399
Associate II
Posted on September 01, 2014 at 17:16

Hello,

As an update to this, I have added a HAL_GPIO_Init call for the NSS pin and filled in the GPIO.InitStruct parameters for it, and NSS is now activating (falling) a half a clock before the SPI clock does, which is very good. This code was added to the stm32f4xx_hal_msp.c file. There is still one issue I am dealing with, and that is NSS never goes back high after the 4 byte transmission.

Since DMA is enabled, I will check that hardware sees the end of programed transmission next and report on that. If somebody knows why NSS is not going back high, it would be nice to know.

David Bassett

 

david2399
Associate II
Posted on September 04, 2014 at 06:38

Hello,

Here is an update which brings the NSS signal high. I have included

__HAL_SPI_DISABLE(&SpiHandle); // stops SPI clock

 

and this worked. This has to be done AFTER

  while (HAL_SPI_GetState(&SpiHandle) != HAL_SPI_STATE_READY)

or it will not work. Presumably, this is after all flags get cleared and callbacks happen - at least this is what I stepped through.

My code implemented MOT mode 3, which has a continual NSS strobe for all 4 bytes I send, and NSS appears to go high 5uS after the last MOSI bit. My clock period is 2.875 uS, which puts this about 2 clocks after the last transmitted bit.

I have no idea how this port would work with MOT mode 0 or 2, which requires NSS to go high for ONE clock between bytes. If the clock rate is ~45MHz as advertised, there is NO WAY this will work. In addition, you would need at least a 2x clock to sample the SPI clk such that a timer would be able to raise NSS.

The second thing is having to disable the port to raise NSS counters logic that NSS should be coupled with each transmission (in my case, 4 bytes) so that NSS SHOULD fall 1/2 clock before SPI clk starts, and should go high 1/2 clock after the last bit. THEN you can stop the DMA channel, move the data out of the way, and stop the SPI port. I have used other CortexM3 micros from other vendors, and this is the way they all work - and I have logic analyzer traces showing this.

This appears to me to be a bug in the silicon, and there SHOULD be an errata explaining this and a workaround should be posted somewhere. There should be a display of all MOT modes running at the fastest speed allowed in the datasheet.

Dave Bassett

malcolm2
Associate II
Posted on September 04, 2014 at 11:07

Hi

I found that it was best to use SPI_NSS_SOFT.  You then have independent control of chip selection.  You will have to do this anyway if you have multiple devices on the SPI bus ( separate nss needed for each slave device).

    GPIO_InitStruct.Pin = LIS331_CS_PIN | L3GD20_CS_PIN | S25FL064_CS_PIN;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(SPI1_CS_PORT, &GPIO_InitStruct);

    HAL_GPIO_WritePin(SPI1_CS_PORT, LIS331_CS_PIN, GPIO_PIN_SET);

    HAL_GPIO_WritePin(SPI1_CS_PORT, L3GD20_CS_PIN, GPIO_PIN_SET);

    HAL_GPIO_WritePin(SPI1_CS_PORT, S25FL064_CS_PIN, GPIO_PIN_SET);

The above code sets up 3 pins for SPI chip select and works perfectly.  Each device (accelerometer, gyro of memory) is selected by issuing a GPIO_PIN_RESET for the relevant pin.