2015-10-17 02:07 AM
I am currently trying to make DMA periodically pull data from memory (array ''buffer'') and push it to spi. When I manually call the SPI_Transmit function, it transmits something, the clock line shows up on my oscilloscope. But when I use DMA; nothing happens.
This is my code:void
initSPI(
void
) {
__HAL_RCC_SPI1_CLK_ENABLE();
spi.Instance = SPI1;
spi.Init.Direction = SPI_DIRECTION_2LINES;
spi.Init.Mode = SPI_MODE_MASTER;
spi.Init.DataSize = SPI_DATASIZE_16BIT;
spi.Init.CLKPolarity = SPI_POLARITY_LOW;
spi.Init.CLKPhase = SPI_PHASE_1EDGE;
spi.Init.NSS = SPI_NSS_SOFT;
spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
spi.Init.TIMode = SPI_TIMODE_DISABLED;
spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
spi.Init.CRCPolynomial = 1;
HAL_SPI_Init(&spi);
__HAL_SPI_ENABLE(&spi);
__HAL_LINKDMA(&spi, hdmatx, dma2stream3);
}
void
initGPIO(
void
) {
__HAL_RCC_GPIOA_CLK_ENABLE()
;
__HAL_RCC_GPIOB_CLK_ENABLE()
;
__HAL_RCC_GPIOD_CLK_ENABLE()
;
GPIO_InitTypeDef gpio;
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pin = MOSI_Pin | SCK_Pin;
gpio.Alternate = GPIO_AF5_SPI1;
gpio.Speed = GPIO_SPEED_HIGH;
gpio.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA, &gpio);
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pin = LAT_Pin | OE_Pin;
HAL_GPIO_Init(GPIOA, &gpio);
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pin = RX_Pin | TX_Pin;
HAL_GPIO_Init(GPIOB, &gpio);
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
HAL_GPIO_Init(GPIOB, &gpio);
}
void
initDMA(
void
) {
__DMA1_CLK_ENABLE()
;
__DMA2_CLK_ENABLE()
;
dma1stream1.Instance = DMA1_Stream1;
dma1stream1.Init.Channel = DMA_CHANNEL_4;
dma1stream1.Init.Direction = DMA_PERIPH_TO_MEMORY;
dma1stream1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
dma1stream1.Init.MemBurst = DMA_MBURST_SINGLE;
dma1stream1.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
dma1stream1.Init.MemInc = DMA_MINC_ENABLE;
dma1stream1.Init.Mode = DMA_NORMAL;
dma1stream1.Init.PeriphBurst = DMA_PBURST_SINGLE;
dma1stream1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
dma1stream1.Init.PeriphInc = DMA_PINC_DISABLE;
dma1stream1.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&dma1stream1);
__HAL_DMA_ENABLE(&dma1stream1);
dma2stream3.Instance = DMA2_Stream3;
dma2stream3.Init.Channel = DMA_CHANNEL_3;
dma2stream3.Init.Direction = DMA_MEMORY_TO_PERIPH;
dma2stream3.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
dma2stream3.Init.MemBurst = DMA_MBURST_SINGLE;
dma2stream3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
dma2stream3.Init.MemInc = DMA_MINC_ENABLE;
dma2stream3.Init.Mode = DMA_NORMAL;
dma2stream3.Init.PeriphBurst = DMA_PBURST_SINGLE;
dma2stream3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
dma2stream3.Init.PeriphInc = DMA_PINC_DISABLE;
dma2stream3.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&dma2stream3);
__HAL_DMA_ENABLE(&dma2stream3);
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
HAL_DMA_Start_IT(&dma1stream1, (uint32_t) &(USART3->DR), (uint32_t) buffer, (16 * 16));
}
void
initTimers(
void
) {
__TIM2_CLK_ENABLE()
;
tim.Instance = TIM2;
tim.Init.Prescaler = multiplier - 1;
tim.Init.CounterMode = TIM_COUNTERMODE_UP;
tim.Init.Period = period - 1;
tim.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&tim);
HAL_TIM_Base_Start_IT(&tim);
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
}
void
TIM2_IRQHandler(
void
) {
if
(__HAL_TIM_GET_FLAG(&tim, TIM_FLAG_UPDATE) != RESET) {
if
(__HAL_TIM_GET_ITSTATUS(&tim, TIM_IT_UPDATE) != RESET) {
__HAL_TIM_CLEAR_FLAG(&tim, TIM_FLAG_UPDATE);
HAL_GPIO_WritePin(OE_Port, LAT_Pin, ENABLE);
HAL_GPIO_WritePin(LAT_Port, LAT_Pin, ENABLE);
HAL_GPIO_WritePin(LAT_Port, LAT_Pin, DISABLE);
LAYER_Port->ODR = ((LAYER_Port->ODR & ~(0xF)) | layer);
HAL_GPIO_WritePin(OE_Port, LAT_Pin, DISABLE);
layer++;
if
(layer > 7)
layer = 0;
HAL_DMA_Start(&dma2stream3, (uint32_t) buffer[currentBuffer][layer], (uint32_t) SPI1->DR, 16);
//HAL_SPI_Transmit_DMA(&spi, (uint8_t*) ''b'', 1);
}
}
}
int
main(
int
argc,
char
* argv[]) {
initGPIO();
initDMA();
initUART();
initSPI();
initTimers();
while
(1) {
}
return
0;
}
Some variable definitions:
TIM_HandleTypeDef tim;
DMA_HandleTypeDef dma1stream1, dma2stream3;
UART_HandleTypeDef uart3;
SPI_HandleTypeDef spi;
uint16_t buffer[2][16][16] = { { { 0 } } };
uint8_t currentBuffer = 0;
uint8_t bufferChanged = 0;
uint8_t layer = 0;
The timer is working properly, code in their get's called, printf has proven that to me. The only problem is SPI not outputting anything.
Do you find anything wrong with my code? I'm currently transitioning to HAL from std_lib^^
2015-10-22 01:18 PM