2014-06-18 03:56 PM
Hello all,
I am encountering some strange behaviour with my STM32F4 Discovery board; I am attempting to set up an transfer with another micro-controller via SPI and DMA, and have initialized the peripherals / handlers as follows. Before writing the code to do the actual transfer, I attempted to get my interrupt handler working, however here I find myself hung up. When I debug the NVIC register and step through my program (I'm using iar workbench), I find that the ISPR is not being set on the call to:NVIC_EnableIRQ(SPI_PORT_DMA_RX_IRQn);
despite the NVIC_EnableIRQ call successfully setting the NVIC->ISER[14] (DMA1_Stream3) register to 1. Additionally, (and frankly with NVIC_EnableIRQ not work I wouldn't expect this to), if I do begin transmitting SPI to the micro, even after the buffer fills up, it does not generate an interrupt (though it does encounter a bus fault..). I don't have very much experience with STM32; would anyone be able to set me on the right track for getting these interrupts firing? Cheers, Warren#include ''stm32f4xx.h''
#include ''stm32f4_discovery.h'' #include <string.h> #include <stdio.h> #define SPI_PORT SPI2 #define SPI_PORT_CLOCK RCC_APB1Periph_SPI2 #define SPI_SCK_PIN GPIO_Pin_13 #define SPI_SCK_GPIO_PORT GPIOB #define SPI_SCK_SOURCE GPIO_PinSource13 #define SPI_SCK_AF GPIO_AF_SPI2 #define SPI_MOSI_PIN GPIO_Pin_15 #define SPI_MOSI_GPIO_PORT GPIOB #define SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOB #define SPI_MOSI_SOURCE GPIO_PinSource15 #define SPI_MOSI_AF GPIO_AF_SPI2 #define SPI_PORT_DR_ADDRESS SPI_PORT->DR #define SPI_PORT_DMA DMA1 #define SPI_PORT_DMAx_CLK RCC_AHB1Periph_DMA1 #define SPI_PORT_RX_DMA_CHANNEL DMA_Channel_0 #define SPI_PORT_RX_DMA_STREAM DMA1_Stream3 #define SPI_PORT_RX_DMA_FLAG_TCIF DMA_FLAG_TCIF3 #define SPI_PORT_DMA_RX_IRQn DMA1_Stream3_IRQn #define SPI_PORT_DMA_RX_IRQHandler DMA1_Stream3_IRQHandler #define BUFFER_SIZE 600 // Globals staticuint8_t BUFFER[BUFFER_SIZE];
// FUNCTION DEFINITIONS voidSPI_PORT_DMA_RX_IRQHandler(
void);
static voidinit(
void);
voidSPI_PORT_DMA_RX_IRQHandler(){
if(DMA_GetITStatus(SPI_PORT_RX_DMA_STREAM, DMA_IT_TCIF3) == SET) {
DMA_Cmd(SPI_PORT_RX_DMA_STREAM, DISABLE); DMA_ClearITPendingBit(SPI_PORT_RX_DMA_STREAM, DMA_IT_TCIF3); } } static voidinit(){
// Configure the clocks for the various peripherals RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB1PeriphClockCmd(SPI_PORT_CLOCK, ENABLE); RCC_AHB1PeriphClockCmd(SPI_PORT_DMAx_CLK, ENABLE); RCC_AHB1PeriphClockCmd(SPI_MOSI_GPIO_CLK, ENABLE); DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Set up GPIO's GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_Init(GPIOA, &GPIO_InitStructure); // Connect SPI pins to AF5 GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_SOURCE, SPI_SCK_AF); GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_SOURCE, SPI_MOSI_AF); // Now configure the pins themselves, but the SPI pins use the alternate function GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN; GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN; GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); // Now we can set up the SPI peripheral // Assume the target is write only and we look after the chip select ourselves SPI_I2S_DeInit(SPI_PORT); SPI_StructInit(&SPI_InitStructure); SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; SPI_Init(SPI_PORT, &SPI_InitStructure); // Set up the DMA // Start with a blank DMA configuration DMA_DeInit(SPI_PORT_RX_DMA_STREAM); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_Channel = SPI_PORT_RX_DMA_CHANNEL; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_BufferSize = sizeof(message);
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & SPI_PORT_DR_ADDRESS; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) BUFFER; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_Init(SPI_PORT_RX_DMA_STREAM, &DMA_InitStructure); DMA_ITConfig(SPI_PORT_RX_DMA_STREAM, DMA_IT_TC, ENABLE); // Enable dma rx request. SPI_I2S_DMACmd(SPI_PORT, SPI_I2S_DMAReq_Rx, ENABLE); // Enable the SPI port SPI_Cmd(SPI_PORT, ENABLE); DMA_Cmd (SPI_PORT_RX_DMA_STREAM, ENABLE); // Ensure DMA is enabled before initiate the interrupt while(DMA_GetCmdStatus(SPI_PORT_RX_DMA_STREAM) != ENABLE)
__NOP(); // Will eventually put a timeout here// Enable the interrupt in the NVIC
NVIC_InitStructure.NVIC_IRQChannel = SPI_PORT_DMA_RX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } uint32_t main( void){
SystemInit(); __enable_irq(); init(); NVIC_EnableIRQ(SPI_PORT_DMA_RX_IRQn); NVIC_SetPendingIRQ(SPI_PORT_DMA_RX_IRQn); printf( ''%d\n'', NVIC_GetPendingIRQ (SPI_PORT_DMA_RX_IRQn));
return1;
}2014-06-19 07:46 AM
Apologies; missed the declaration of a struct.
typedef struct {
int8_t msg[40];
uint8_t values[30];
uint8_t offsets[8];
uint8_t flag;
} message;