cancel
Showing results for 
Search instead for 
Did you mean: 

NVIC with STM32F4

warren
Associate
Posted on June 19, 2014 at 00:56

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

static

uint8_t BUFFER[BUFFER_SIZE];

// FUNCTION DEFINITIONS

void

SPI_PORT_DMA_RX_IRQHandler(

void

);

static

void

init(

void

);

void

SPI_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

void

init(){

// 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));

return

1;

}

1 REPLY 1
warren
Associate
Posted on June 19, 2014 at 16:46

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;