I had the same problem, STM32F411RE, Gnu Arm Eclipse HAL Lib 1.4.xx
However the problem wasn't enabling any Bits in the Control Registers...
1st I got a Timeout Error because my Baudratescaler was to small, I used 2 and got Timeouts, then I used 64 which was fine.
In the inital post his MISO PIN was declared Input, however all 3 PINS, MISO, MOSI, SCK need to be AF_PP in MODE, and AF5_SPIx in Alternate.
then use NSS as Software, and declare another random GPIO PIN as NSS and select the Slave via your own Code.
//GLOBAL VAR
SPI_HandleTypeDef SPI_Handle; // global fuer ISR
int
main(int argc, char* argv[])
{
// CLKs Enable
__HAL_RCC_SPI1_CLK_ENABLE(); // MUSS an sein, ist richtig
__HAL_RCC_GPIOA_CLK_ENABLE();
// SPI Config start
SPI_Handle.Instance = SPI1; // D13 bis D11
SPI_Handle.Init.Mode = SPI_MODE_MASTER;
SPI_Handle.Init.Direction = SPI_DIRECTION_2LINES; // transmit and receive
SPI_Handle.Init.DataSize = SPI_DATASIZE_8BIT; // 8 bit Packete
SPI_Handle.Init.CLKPolarity = SPI_POLARITY_LOW; // idle @ low state
SPI_Handle.Init.CLKPhase =SPI_PHASE_1EDGE; // Phase = 0, rising edge = sample
SPI_Handle.Init.NSS = SPI_NSS_SOFT;
SPI_Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
SPI_Handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPI_Handle.Init.TIMode = SPI_TIMODE_DISABLE; // Motorola standard verwenden
SPI_Handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SPI_Handle.Init.CRCPolynomial =0;
// SPI Config end
// SPI Init
if (HAL_SPI_Init(&SPI_Handle)!= HAL_OK)
{
printf("Fehler bei SPI Init\n");
}
// Interrupt enable
HAL_NVIC_SetPriority(SPI1_IRQn, 2,1);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
// GPIO Config start
// CLK,MISO,MOSI
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_9; // D8
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_5| GPIO_PIN_6 |GPIO_PIN_7; // D13 = CLK, A2 = NSS , D11 = MOSI, D12 = MISO
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // Push Pull
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
//GPIO Init
HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
//var
const uint32_t timeout = 100;
const uint16_t SIZE = 3; // Puffergroeße = 1 Byte
double temp;
HAL_StatusTypeDef HAL_Status; // 0 = ok, 1 = Error, 2 = Busy, 3 = timeout
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); // Slave sleep
while (1)
{
uint8_t transmit[3] = {0b00000110, 0b00000000, 0b00000000};
uint8_t receive [3] = {0,0,0};
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); // Slave wake up
if( (HAL_Status = HAL_SPI_TransmitReceive(&SPI_Handle,&transmit,&receive,SIZE,timeout)) != HAL_OK)
{
printf("1st TransmitReceive Error: %d\n", HAL_Status);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); // Slave sleep
//temp = (receive2 <<8) | receive3; // 12 BIT ADC Wert zusammenfuegen
printf("Receive: %d\t%d\n", receive[1], receive[2] ); // debug
printf("Transmit: %d\t%d\t %d\n", transmit[1],transmit[2],transmit[0] ); // debug
printf("Temp = %f\n", temp); // debug
printf("SIZE = %d\n", SIZE);
//temp = (temp *500.0)/4096; // 5 V Ref, 1°C pro 10mV => 500/2^12
//printf("Temp = %f\n", temp);
}
}
this codes makes the nucleo master, and uses the MCP3208 as Slave, which reads out a Temp sensor on Channel 0. The 1st Transfer Byte is the setup, the 2nd is the channel select, the 3rd is 0 to give the IC enough clocks. The 2nd and 3rd Receive Bytes are the result.