I have done some searching and found many questions, but am not coming to a correct conclusion. To start with the hardware design: the STM32 is a host MCU for a SI4362 RX only radio that uses spi for communication. i have hard coded all the radio power up commands, and as written in the API for the SI4362:
To apply a patch, the patch content has to be sent to the radio chip after POR but before issuing the POWER_UP command. ...The GPIO1 pin goes high when the radio is ready for receiving SPI commands. During the reset period, the radio cannot accept any SPI commands. ...Each line has to be sent to the chip as an eight byte long command. A CTS reply has to be read from the chip after each line.
i have created the patch into an array to be written through a for loop. in my example code i am using an LED flashing at different rates to determine my location where i am stuck.
Once the CTS value reads FFh then the read data is ready to be clocked out to the host MCU. The typical time for a valid FFh CTS reading is 20 μs.
So my code is getting stuck at the second for loop meaning my POR is working by sending the SDN pin low. This powers up the SI4362 and draws the GPIO1 high as the first CTS. then I go into the patch initialization that is 265 address array of 8 bytes per address. this is what it looks like higher up in declaration
...
uint8_t array_263[8] ={ 0xEF,0x7D,0x0D,0xB5,0xCF,0x00,0xC5,0x75 };
uint8_t array_264[8] ={ 0xE3,0xC6,0x0E,0x0B,0x10,0x44,0x10,0xEE };
uint8_t array_265[8] ={ 0x05,0x12,0x86,0x0D,0xC0,0xA5,0xF6,0x92 };
uint8_t *theArrays[] = {array_1,array_2,array_3,array_4,\
array_5,array_6,array_7,array_8,array_9,\
array_10,array_11,array_12,array_13,array_14,\
array_15,array_16,array_17,array_18,array_19,\
...
I then transmit the first line of 8 bytes followed by the loop that is stuck waiting on the CTS from the SPI that should return a 0xFF. i apoloogize if im not describing it well. i am just working on the prototype proof of concept and have not had good luck outsourcing on sites so far.
HAL_GPIO_WritePin(SDN_GPIO_Port, SDN_Pin, GPIO_PIN_RESET);
while (!HAL_GPIO_ReadPin(GPIOB, RX_DATA_Pin)) {
HAL_Delay(500);
for (int i = 0; i < 10; i )
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
HAL_Delay(30);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
HAL_Delay(30);
}
}
for (int i = 0; i < 265; i )
{
HAL_SPI_Transmit(&hspi1, theArrays[i],8, 50);
do {
HAL_SPI_Receive(&hspi1,reg_data,1,50);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
HAL_Delay(100);
}while(*reg_data != 0xff);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
HAL_Delay(30);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
HAL_Delay(30);
}
CodePudding user response:
Double checking a few datasheets it would seem that i wasnt getting the first SPI command input within the time recommended. here is updated code. now i need to verify what im sending and receiving, so i will have to figure out the USART now to make that work. i feel that it will require a different question altogether if i have one. thank you @nilsie for looking at the code and mentioning the CS pin (i assumed that because i included it in MX it would work automatically within the HAL_transmit call)
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
// CS pin should default high
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_SET);
uart_buf_len = sprintf(uart_buf, "SPI Test\r\n");
HAL_UART_Transmit(&huart1, (uint8_t *)uart_buf, uart_buf_len, 100);
HAL_GPIO_WritePin(SDN_GPIO_Port, SDN_Pin, GPIO_PIN_SET);
for (int i = 0; i < 10; i )
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
HAL_Delay(100);
}
HAL_GPIO_WritePin(SDN_GPIO_Port, SDN_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_RESET);
int count = 0;
while (!HAL_GPIO_ReadPin(GPIOB, RX_DATA_Pin) && count != 13) {
HAL_Delay(1);
count ;
}
count = 0;
for (int i = 0; i < 265; i )
{
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, theArrays[i],8, 50);
do {
HAL_SPI_Receive(&hspi1, (uint8_t *)spi_buf, 1, 100);
}while(*spi_buf != 0xFF);
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_SET);
}
for (int i = 0; i < 10; i )
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
HAL_Delay(20);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
HAL_Delay(20);
}
CodePudding user response:
First, regarding the CS pin - as you said, it can be controlled by the software or by the hardware through the SPI peripheral. In the case of the software control, before calling the transmit and/or receive functions, you need to pull the CS pin low. When the transmit/receive sequence is executed, you can pull the CS pin high, which marks the end of communication with that device on the SPI bus. You have done that correctly, assuming the SS is the chip select pin for SI4362.
Is there any other SPI device connected to the bus?
What is the data rate/frequency of the SPI peripheral? The maximum frequency that SI4362 operates at is 10 MHz according to the datasheet.
Also, another common pitfall of SPI communication can be different clock polarity and clock phase settings between the master and the slave. From the datasheet of SI4362:
The internal MCU will clock out the SDO data on the negative edge so the host MCU should process the SDO data on the rising edge of SCLK.
Can you please post the SPI initialization code, along with the SPI_HandleTypeDef structure and the clock configuration from the CubeMX?