2018-05-28 12:05 AM
Im trying to catch data from the unknown device, this device has data and clock. I decided to make my stm32 as spi slave and catch the data as recevier.And im struggling with it. I have this data flow which i want to catch:
Clock is yellow and green is data.
I need only 16bytes from it, when data line goes low, we can see this 16bytes:
And there is the speed of the clock, as you can see its around 1.5us each clock pulse. So what i have to do is configure spi with HAL, i toolk SPI1(PA5 - CLOCK, PA7- DATA) cuz it has more powerful MHZ, chose spi mode ''RECEIVE ONLY SLAVE'', HARDWARE NSS SIGNAL: DISABLED. And here is my spi1 config:
static void MX_SPI1_Init(void)
{/* SPI1 parameter configuration*/
hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_SLAVE; hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.FirstBit = SPI_FIRSTBIT_LSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
What im doing in main.c, as oscilo's pictures says we need to catch the moment when data goes low and then try to read a data, im trying to catch first pulse then wait until data goes high then low and only they read spi, at least only first byte - it should be 0.
int main(void)
{ /* USER CODE BEGIN 1 */ /* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init(); MX_DMA_Init(); MX_USB_DEVICE_Init(); MX_SPI1_Init(); /* USER CODE BEGIN 2 *//* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */ uint8_t collect_bits = 0; char string_array[21] = {0}; uint8_t spi_buffer[16] ={0} ; spi_buffer[0] = 5; // while (1) // { // HAL_Delay(10000); while (HAL_GPIO_ReadPin (GPIOA,GPIO_PIN_7) == 0){} // wait until GPIOC 9 goes high while (HAL_GPIO_ReadPin (GPIOA,GPIO_PIN_7) == 1){} // wait until GPIOC 9 goes high while (HAL_GPIO_ReadPin (GPIOA,GPIO_PIN_7) == 0){} // wait until GPIOC 9 goes high while (HAL_GPIO_ReadPin (GPIOA,GPIO_PIN_7) == 1){} // wait until GPIOC 9 goes high HAL_SPI_Receive(&hspi1, (uint8_t*)spi_buffer, 16,0); /* USER CODE END WHILE *//* USER CODE BEGIN 3 */
// }
/* USER CODE END 3 */}
And i catch nothing at all, my spi buffer all 16 bytes are 0. I tried SPI_DMA it changed only first byte on 0XFF. What am i doing wrong? Thanks
#stm32f4-spi #receive Note: this post was migrated and contained many threaded conversations, some content may be missing.Solved! Go to Solution.
2018-05-29 04:05 AM
are you sending and receiving from the same buffer ?
I would suggest:
uint8_t spi_Rxbuffer[16] ={0}
uint8_t spi_Txbuffer[16] ={0}
there will be a flag to say HAL_SPI_TransmitReceive has completed. but its difficult to manage HAL sometimes.
I would use the register level coding style, I guess along these lines;
// initialise table
char RxTable[16];
char RxCounter=0;
// clear RxSPI buffers // not sure if its double buffered or not.
while ((hspi1.Instance->SR & SPI_FLAG_RXNE))
RxSPI = hspi1.Instance->DR & 0xFF; // dump old bytes in bufferwhile(1){
while(RxCounter <16){
while (!(hspi1.Instance->SR & SPI_FLAG_RXNE))
;
RxSPI = hspi1.Instance->DR;// now you have 8 SPI clock cycles to do something with the data
RxTable[RxCounter++] = RxSPI;
}
RxCounter =0;
// Process data within 8 SPI clock cycles or start losing bytes
}
// after thought:
// now consider that you may have lost coherency:
0xFE0010
is your stringif ((RxSPI == 0xFE) && ( RxState =0)) RxState =1;
else if ((RxSPI == 0x00) && ( RxState =1)) RxState =2;
else if ((RxSPI == 0x01) && ( RxState =2))){
// check if we have been here before, that means we already have a complete set of data
if( RxCounter ==15)
; // we have complete data set in bytes RxTable[0..12]
// have start position.. start recording data
RxCounter =0;
RxState =0; // reset state machine
}
else RxState =0;
2018-05-28 12:37 AM
Better use scope which can analyse/decode/log simple serial bus such as I2C or SPI.
2018-05-28 02:47 AM
Well, my scope can do that. But the point that i need my stm32 catch this 16bytes data and then output it on PC
2018-05-28 02:51 AM
Btw the images above is from my oscilo it catched the data and decode it, with chosen spi protocol on it.
2018-05-28 02:58 AM
IMO the Cube/HAL code wouldn't manipulate SSI for the slave+softNSS case, so it will either start receiving as soon as enabled or never.
I don't Cube.
JW
2018-05-28 05:41 AM
,
,
Thanks for reply, what should i use then? Periph? CMSIS? Btw you said:
>,>,>, SSI for the slave+softNSS case, so it will either start receiving as
soon as enabled or never.
i puted NSS as hardware and pulled it down. So spi slave should start
receving
immediatly after it got first clocks. Why it doesnt happen?
2018-05-28 19:59 GMT+10:00 waclawek.jan <,st-microelectronics@jiveon.com>,:
STMicroelectronics Community
<,https://community.st.com/?et=watches.email.thread>,
Re: STM32f407 as SPI slave[HAL]
reply from waclawek.jan
<,
MCUs Forum* - View the full discussion
<,https://community.st.com/0D70X000006Sjw0SAC
2018-05-28 07:57 AM
i puted NSS as hardware and pulled it down. So spi slave should start
receving
immediatly after it got first clocks. Why it doesnt happen?
I don't know. Read out and check/post the content of SPI and relevant GPIO registers.
JW
2018-05-28 08:06 AM
You said that HAL is a bad idea for this task. What should i use instead?
StdPeriph?
2018-05-28 22:58 GMT+10:00 waclawek.jan <st-microelectronics@jiveon.com>:
STMicroelectronics Community
<https://community.st.com/?et=watches.email.thread>
Re: STM32f407 as SPI slave[HAL]
reply from waclawek.jan
<
MCUs Forum* - View the full discussion
<https://community.st.com/0D70X000006SxywSAC
2018-05-28 10:32 AM
I try not to make recommendations in this regard.
My personal opinion is that any 'library' of this kind becomes a nuisance as soon as the task gets beyond usual or trivial, so it's better avoid them right away. I simply use the mcu's registers. But that view is here seen as extreme, and partially results from the nature of the work I do. Your may be different.
JW
2018-05-28 01:07 PM
'
You said that HAL is a bad idea for this task.'
any approach is a compromise of sort. that means anyone of them can be bad for at least one application. whether it is bad or not to your application is up to you.
I use both SPL (and liked it) and direct register access. because that has worked for me. hal is buggy and hard to think through vs. the datasheet.
others have found the opposite, however.
end of the day, use whatever that floats your boat.