I am using a custom devBoard with a single STM32L071 chip. Using debug mode (System Workbench), I can see the TDR register of USART2, and the data I want to transmit is there, but there is no signal coming from the pins on the board.
There is no hardware issue, I had the board checked.
I found the GPIO configuration online, and the USART configuration is what I need.
My main function:
HAL_Init();
GPIO_Config();
Configure_USART();
char message[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x55 };
HAL_UART_Transmit(&g_meterUart, (uint8_t*)message, sizeof(message), 0xFFFF);
GPIO configure
__HAL_RCC_GPIOA_CLK_ENABLE()
;
GPIO_InitTypeDef USART_GPIO_InitStruct;
USART_GPIO_InitStruct.Pull = GPIO_NOPULL;
USART_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
USART_GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
USART_GPIO_InitStruct.Pin = GPIO_PIN_2;
USART_GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOA, &USART_GPIO_InitStruct);
USART_GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
USART_GPIO_InitStruct.Pin = GPIO_PIN_3;
HAL_GPIO_Init(GPIOA, &USART_GPIO_InitStruct);
Configuring USART
__USART2_CLK_ENABLE();
g_meterUart.Instance = USART2;
g_meterUart.Init.BaudRate = 9600;
g_meterUart.Init.WordLength = UART_WORDLENGTH_8B;
g_meterUart.Init.StopBits = UART_STOPBITS_1;
g_meterUart.Init.Parity = UART_PARITY_NONE;
g_meterUart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
g_meterUart.Init.Mode = UART_MODE_TX_RX;
g_meterUart.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_DeInit(&g_meterUart) != HAL_OK) {
}
if (HAL_UART_Init(&g_meterUart) != HAL_OK) {
};
Here are a couple suspicious issues I found with a quick review of the STM32L071 datasheet. According to Table 16, page 49:
PA2 is USART2_TX but you have configured GPIO_PIN_2 for GPIO_MODE_INPUT. Do you have the direction of PA2 and PA3 reversed?
The USART2 functions of PA2 and PA3 are selected with Alternate Function 4 but you have specified LL_GPIO_AF_7.
Related
I am working with a STM32F3DISCOVERY board and I'm trying to dive a bit deeper into the abstractions of the HAL. I made a simple version of a function that transmits data over SPI, sadly it does not work (at least the DAC I'm sending it to does not change state) and I'm not sure what I am missing there. Maybe there's also something in the initialization code that doesn't work with my simple version. I'd be happy for any guidance or references I could check. Thank you!
#include <stm32f3xx_hal.h>
#define PINS_SPI GPIO_PIN_5 | GPIO_PIN_7
#define GPIO_PORT GPIOA
/* This is the simplest function I could come up with to do the transfer but I'm clearly missing something here */
uint8_t SPI_SendReceive(SPI_HandleTypeDef *hspi, uint8_t data) {
/* Loop while DR register in not empty */
while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET) {
}
/* Send data through the SPI1 peripheral */
hspi->Instance->DR = data;
/* Wait to receive data */
while ((hspi->Instance->SR & SPI_FLAG_RXNE) == RESET) {
}
return hspi->Instance->DR;
}
int main() {
HAL_Init();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
static SPI_HandleTypeDef spi = {.Instance = SPI1};
spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
spi.Init.Direction = SPI_DIRECTION_2LINES;
spi.Init.CLKPhase = SPI_PHASE_1EDGE;
spi.Init.CLKPolarity = SPI_POLARITY_LOW;
spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi.Init.DataSize = SPI_DATASIZE_8BIT;
spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
spi.Init.NSS = SPI_NSS_HARD_OUTPUT;
spi.Init.TIMode = SPI_TIMODE_DISABLE;
spi.Init.Mode = SPI_MODE_MASTER;
HAL_SPI_Init(&spi);
__HAL_SPI_ENABLE(&spi);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = PINS_SPI;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* TI 8564 DAC Settings */
uint8_t cmd1 = 0b00010000;
/* DAC output value (16-bit) */
uint16_t cmd23 = 0;
uint8_t cmd2 = cmd23 >> 8;
uint8_t cmd3 = cmd23 & 0xff;
uint8_t command[3] = {cmd1, cmd2, cmd3};
while (true) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
/* This does not work :( */
SPI_SendReceive(&spi, command[0]);
SPI_SendReceive(&spi, command[1]);
SPI_SendReceive(&spi, command[2]);
/* This works! When commenting in the lines above and commenting this out */
/* HAL_SPI_Transmit(&spi, command, 3, HAL_MAX_DELAY); */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(1000);
}
}
Check the contents of HAL_SPI_Init. Most likely this function calls another function which is supposed to do the low-level initialization, and you're responsible to provide this function yourself. To make it more complex, this alleged second function already has a "dummy" weak alias defined, so the toolchain doesn't return any error but just builds a code unable to do anything.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I am working with an Analog Devices Waveform generator (AD5930) and am trying to program it using the spi peripheral on a STM32f767 Eval board. The waveform generator is to be programmed by loading data, in the form of 16bit words, into the devices registers using the serial clock of the SPI. The data words include register address, first 4 bits, and commands, the last twelve bits. Connections from the STM32 to the AD5930 are properly placed and when checking the lines with an oscilloscope I am can see the data, clock and control all come off the board.
As of right now I'm trying to send 8 16bit command words using the HAL_SPI_Transmit command. Here is whats included in my main.c:
`
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();`
`HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(5); `
spiData[0] = 0x0E83;
spiData[1] = 0x13E8;
spiData[2] = 0x2000;
spiData[3] = 0x3800;
spiData[4] = 0x63E8;
spiData[5] = 0xC0C5;
spiData[6] = 0xD002;
spiData[7] = 0xA3E8;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
if((HAL_SPI_Transmit(&hspi1,(uint8_t*)&spiData,8,5)) ==HAL_TIMEOUT){
HAL_Delay(100);
}
while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
HAL_Delay(1);`
Below are my initialization specifications:
`
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 192;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LD3_Pin|LD2_Pin|GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Pin PB8 is used as a control trigger to begin waveform generation after registers are programmed, PIN PA5 is used for SPI Clock, PD7 as SPI data or MOSI, and pin PA4 is used as Chip Select.
What I observe on the oscilloscope(when viewing clock + data) is data being clocked in, what seems to be correct but hanging high when the clk has stopped. I dont get HAL TIMEOUT error so my assumption is the data was formatted correctly for transmission. When the program continues to run, and the trigger(Pin PB8) transitions I don't see a waveform in the output. What about my configuration may be preventing me from communicating correctly with the AD5930?
HAL_SPI_Transmit third parameter is the number of bytes to transmit. Your data buffer contains 16 bytes (8 * sizeof(uint16) = 8 * 2 bytes), but you only send 8.
When ch = 0x80, on PC I receive 0x00,
When ch = 0x40, on PC I receive 0x80,
When ch = 0x20, on PC I receive 0x60,
When ch = 0x10, on PC I receive 0x10,
When ch = 0x08, on PC I receive 0x08,
When ch = 0x04, on PC I receive 0x04,
When ch = 0x02, on PC I receive 0x02,
When ch = 0x01, on PC I receive 0x01,
Can't figure what is going on here... I am attaching USART Initialization, Transmit Function and Main. I should be software issue, already tested the hardware and it's ok. MCU = STM32L011
void InitUSART(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
USARTx_CLK_ENABLE();
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
//UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_ENABLE;
HAL_UART_Init(&UartHandle);
/* Transmit Configuration */
USARTx_TX_GPIO_CLK_ENABLE();
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
/* Receive Configuration */
USARTx_RX_GPIO_CLK_ENABLE();
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USARTx_IRQn);
}
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint16_t* tmp;
uint32_t tickstart = 0;
/* Check that a Tx process is not already ongoing */
if(huart->gState == HAL_UART_STATE_READY)
{
if((pData == NULL ) || (Size == 0U))
{
return HAL_ERROR;
}
/* In case of 9bits/No Parity transfer, pData buffer provided as input paramter
should be aligned on a u16 frontier, as data to be filled into TDR will be
handled through a u16 cast. */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
if((((uint32_t)pData)&1) != 0)
{
return HAL_ERROR;
}
}
/* Process Locked */
__HAL_LOCK(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Init tickstart for timeout managment*/
tickstart = HAL_GetTick();
huart->TxXferSize = Size;
huart->TxXferCount = Size;
while(huart->TxXferCount > 0U)
{
huart->TxXferCount--;
if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
tmp = (uint16_t*) pData;
huart->Instance->TDR = (*tmp & (uint16_t)0x01FFU);
pData += 2U;
}
else
{
huart->Instance->TDR = (*pData++ & (uint8_t)0xFFU);
}
}
if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
/* At end of Tx process, restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
int main(void)
{
/* STM32L0xx HAL library initialization:
- Configure the Flash prefetch, Flash preread and Buffer caches
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock to 32 MHz */
SystemClock_Config();
InitUSART();
//Transmit(txBuffer, 2);
extern UART_HandleTypeDef UartHandle;
uint16_t ch = 0x80;
TransmitEnable();
while(1){
HAL_UART_Transmit(&UartHandle, &ch, 1, 0xFF);
HAL_Delay(5);
}
}
Looks like it was a clock issue after all. I was using internal 16 MHz oscillator (HSI) multiplied up to 32 MHz with PLL. Single baud width on 9600 baudrate was 110us. Now I switched to 4 MHz (internal MSI) and I am getting 104us per baud. Communication is flawless now.
RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0)!= HAL_OK)
{
while(1);
}
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
__HAL_RCC_PWR_CLK_DISABLE();
Acording your sent source file, you programmed the usart as "8 bits", but this STM HAL routine compute data_bits+parity_bit=8bits(your selection). For standard text transmission, for this STM HAL should be: 9 bits (8_data_bits+one_parity_bit).
I have been trying to implement spi on STM32F407 discovery mode in DMA mode. I got the data, but the problem is that, I have 112 bits of data via Pulse Position Modulation, and the frequency of data is 1MHz. Since this info signal is arbitrary, I've configured my board as a slave (although there is no real master) and I make SCK from board itself via PWM. The thing is, that I am receiving data, but I get the whole 112 bits in 42 pulses. I am not sure of how the SPI is triggered by the SCK, since the durrations do not match.
There is configuration of my SPI:
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}}
My msp.c file
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA4 ------> SPI1_NSS
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
PB3 ------> SPI1_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI1 DMA Init */
/* SPI1_RX Init */
hdma_spi1_rx.Instance = DMA2_Stream0;
hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx);
/* SPI1 interrupt Init */
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}}
I start SPI via:
HAL_SPI_Receive_DMA(&hspi1, data, 14); //data is array uint8_t
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); //NSS out which is shortened with real NSS of Slave
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); /clock
After I got the data I use this in SPI handler:
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
In memory I got all of the 112 (14 bytes)
Data
And there is the oscilogram
Oscilogram
Any ideas?
I have used CubeMX as a base of my code
I am currently working on the STM32L476RG Nucleo board and I am trying to communicate with the SPI2 bus.
It seems that I am sending data with the MOSI pin but I don't have anything on the SCK pin.
Here are my initialisation code and sending data code:
In the main.c:
/Function that initializes the SPI/
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLED;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLED;
HAL_SPI_Init(&hspi2);
}
/Function that sends data via SPI to the slave/
void ADAS1000_SetRegisterValue(unsigned char regAddress,
unsigned long regVal)
{
unsigned char writeCmd[4] = {0, 0, 0, 0};
writeCmd[0] = 0x80 + regAddress; // Write bit and register address.
writeCmd[1] = (unsigned char)((regVal & 0xFF0000) >> 16);
writeCmd[2] = (unsigned char)((regVal & 0x00FF00) >> 8);
writeCmd[3] = (unsigned char)((regVal & 0x0000FF) >> 0);
HAL_SPI_Transmit(&hspi2, &(writeCmd[0]), (uint16_t) sizeof(writeCmd[0]), 50);
HAL_Delay(500);
HAL_SPI_Transmit(&hspi2, &(writeCmd[1]), (uint16_t) sizeof(writeCmd[1]), 50);
HAL_Delay(500);
HAL_SPI_Transmit(&hspi2, &(writeCmd[2]), (uint16_t) sizeof(writeCmd[2]), 50);
HAL_Delay(500);
HAL_SPI_Transmit(&hspi2, &(writeCmd[3]), (uint16_t) sizeof(writeCmd[3]), 50);
HAL_Delay(500);
}
In the hal_msp.c :
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI2)
{
/* Peripheral clock enable */
__SPI2_CLK_ENABLE();
/**SPI2 GPIO Configuration
PC2 ------> SPI2_MISO
PC3 ------> SPI2_MOSI
PB10 ------> SPI2_SCK
PB12 ------> SPI2_NSS
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
If you have any ideas or advice, thanks for helping!
EDIT
void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__GPIOC_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
}
This might be the problem:
// [...]
hspi2.Init.NSS = SPI_NSS_SOFT;
// [...]
Without checking the definition of your HAL macros, I believe that this configures the SPI not to drive NSS - but to have this done by software. This means that you are responsible to assert the NSS pin manually before putting data into the SPI peripheral.
This in turn may cause the SPI slave side not to respond, which may appear like the SCK signals weren't reaching the slave at all.