- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I have an SPI communication between my 1LD Wifi/BT module and another MCU.
This SPI use SPI5 hardware and works with DMA for Tx and Rx.
I want to use the chip select (pin 57, PB1, with external PullUp) configured as input pin with external interrupt.
I tried the follow configuration, but it never enter in the interrupt handler
Is the right use for configuration of external interrupt ?
Option 1 |
---|
void init_NssPin (void) { NssGpio.pin_number = 1; NssGpio.port = GPIOB; platform_gpio_init( &NssGpio, INPUT_HIGH_IMPEDANCE ); platform_result_t res; res = platform_gpio_irq_enable (&NssGpio, IRQ_TRIGGER_RISING_EDGE, ISR_SpiNss_handler, 0 ); WPRINT_APP_INFO( ( "result of NSS IRQ init = %d\n",res ) ); // note: result code give me 6010 which mean NO_EFFECT ... } void ISR_SpiNss_handler( void* arg ) { v_SetLedState(0,1); // debug: LED_INDEX_1 set to high } |
I aslo tried a second option with ExtInt functions and force the mapping of ISR function:
Option 2 |
---|
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource1); ExtIntSpiNss.EXTI_Line = EXTI_Line1; ExtIntSpiNss.EXTI_LineCmd = ENABLE; ExtIntSpiNss.EXTI_Mode = EXTI_Mode_Interrupt; ExtIntSpiNss.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_Init(&ExtIntSpiNss); /* Add IRQ vector to NVIC */ NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); WWD_RTOS_DEFINE_ISR ( ISR_SpiNss_handler ) { v_SetLedState(0,1); // debug: LED_INDEX_1 set to high } WWD_RTOS_MAP_ISR(ISR_SpiNss_handler, EXTI1_irq) |
But it also don't work.
Could you help me ?
Note: I use WICED v.6.2
- Labels:
-
Interrupts
-
WICED Studio
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello:
I have two questions about this thread:
1. What is the communication interface for wifi chip 1DL ? is it SDIO or SPI ?
2. Is the interrupt pin used to receive interrupt from Wifi chip ? like connecting with the OOB pin.
or you just test this SPI pin to see if it could work as an external INT pin .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1. The communication is SPI.
2. the interrupt is received by the 1LD modul. This interrupt is set on the Chip Select line of the SPI in order to detect the begin and the end of the SPI message.
Here is my code for initialisation of SPI and DMA used for Rx and Tx buffer of SPI.
static void configure_spi(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
SPI_InitTypeDef s_SPI_InitStruct;
// CLK + MOSI Pin Init
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF6_SPI5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF6_SPI5);
// NSS Pin Init
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed;
GPIO_Init(GPIOB, &GPIO_InitStruct);
v_SetLedState(0,0); // LED_INDEX_1 (TP618) set to low ///@debug
NssGpio.pin_number = 1;
NssGpio.port = GPIOB;
platform_gpio_init( &NssGpio, INPUT_HIGH_IMPEDANCE );
platform_result_t res;
res = platform_gpio_irq_enable (&NssGpio, IRQ_TRIGGER_RISING_EDGE, ISR_SpiNss_handler, 0 );
WPRINT_APP_INFO( ( "result of NSS IRQ init = %d\n",res ) );
// MISO Pin Init
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF6_SPI5);
s_SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
s_SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
s_SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
s_SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
s_SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
s_SPI_InitStruct.SPI_NSS = SPI_NSS_Hard;
s_SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
/* Be sure to clear Rx register */
if (SPI_I2S_GetFlagStatus(SPI5, SPI_I2S_FLAG_RXNE) == SET)
{
uint8_t dummy = SPI5->DR;
}
else{}
SPI_Init(SPI5, &s_SPI_InitStruct);
/* Init variables */
i8u_SPI_CmdRequestFlag.byte = 0x00;
}
static void configure_spi_dma(void)
{
uint8_t i = 0;
DMA_InitTypeDef dma_is;
RCC_APB2PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* init DMA buffer */
for(i=0; i<SPI_MSG_SIZE; i++)
{
dma_tx_buf=0x00;
dma_rx_buf=0x00;
}
/*** Rx DMA Stream ***/
dma_is.DMA_Channel = DMA_Channel_7;
dma_is.DMA_Memory0BaseAddr = (uint32_t)dma_rx_buf;
dma_is.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI5->DR));
dma_is.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma_is.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_is.DMA_DIR = DMA_DIR_PeripheralToMemory;
dma_is.DMA_Mode = DMA_Mode_Normal; // DMA_Mode_Circular;//DMA_Mode_Normal;
dma_is.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_is.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_is.DMA_BufferSize = SPI_MSG_SIZE;
dma_is.DMA_Priority = DMA_Priority_High;
dma_is.DMA_MemoryBurst = DMA_MemoryBurst_Single;
dma_is.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
dma_is.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_ClearFlag(DMA2_Stream5, DMA_FLAG_TCIF5 | DMA_FLAG_HTIF5 | DMA_FLAG_TEIF5 | DMA_FLAG_DMEIF5 | DMA_FLAG_FEIF5);
DMA_DeInit(DMA2_Stream5);
tx_thread_sleep(10);
DMA_Init(DMA2_Stream5, &dma_is);
DMA_ITConfig(DMA2_Stream5, DMA_IT_TC, DISABLE); //test interrupt on Chip Select pin instead of interrupt on DMA Rx buffer full // DMA_ITConfig(DMA2_Stream5, DMA_IT_TC, ENABLE);
DMA_SetCurrDataCounter(DMA2_Stream5, SPI_MSG_SIZE);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = DMA2_Stream5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
DMA_Cmd(DMA2_Stream5, ENABLE);
tx_thread_sleep(10);
/*** Tx DMA Stream ***/
dma_is.DMA_Channel = DMA_Channel_2;
dma_is.DMA_Memory0BaseAddr = (uint32_t)dma_tx_buf;
dma_is.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI5->DR));
dma_is.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma_is.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_is.DMA_DIR = DMA_DIR_MemoryToPeripheral;
dma_is.DMA_Mode = DMA_Mode_Normal; //DMA_Mode_Circular;//DMA_Mode_Normal;
dma_is.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_is.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma_is.DMA_BufferSize = SPI_MSG_SIZE;
dma_is.DMA_Priority = DMA_Priority_Medium;
dma_is.DMA_MemoryBurst = DMA_MemoryBurst_Single;
dma_is.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
dma_is.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_ClearFlag(DMA2_Stream4, DMA_FLAG_TCIF4 | DMA_FLAG_HTIF4 | DMA_FLAG_TEIF4 | DMA_FLAG_DMEIF4 | DMA_FLAG_FEIF4);
DMA_DeInit(DMA2_Stream4);
tx_thread_sleep(10);
DMA_Init(DMA2_Stream4, &dma_is);
DMA_SetCurrDataCounter(DMA2_Stream4, SPI_MSG_SIZE);
DMA_Cmd(DMA2_Stream4, ENABLE);
tx_thread_sleep(10);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
got it, I will try to find if we have same setting in the release.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello:
I think you already have the critical define in this thread, I just attach what I found in the release.
43xxx_Wi-Fi\WICED\platform\MCU\STM32F4xx
/* Setup DMA for SPI2 RX */ | ||
DMA_DeInit( DMA1_Stream3 ); | ||
dma_init_structure.DMA_Channel | = DMA_Channel_0; | |
dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t) &SPI2->DR; | ||
dma_init_structure.DMA_Memory0BaseAddr | = 0; |
below is to enable :
/* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */ | |
/* otherwise FreeRTOS will not be able to mask the interrupt */ | |
/* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */ | |
/* is the lowest priority */ | |
NVIC_EnableIRQ( SPI_BUS_TX_DMA_STREAM ); |
/* Enable DMA for TX */ | |
SPI_I2S_DMACmd( SPI2, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE ); |
in platform.c c
the struture describes the connections :
[WICED_SPI_2] = | ||
{ | ||
.port | = SPI2, | |
.gpio_af | = GPIO_AF_SPI2, | |
.peripheral_clock_reg = RCC_APB1Periph_SPI2, | ||
.peripheral_clock_func = RCC_APB2PeriphClockCmd, | ||
.pin_mosi | = &platform_gpio_pins[WICED_GPIO_31], | |
.pin_miso | = &platform_gpio_pins[WICED_GPIO_30], | |
.pin_clock | = &platform_gpio_pins[WICED_GPIO_29], | |
.tx_dma = | ||
{ | ||
.controller | = DMA1, | |
.stream | = DMA1_Stream4, | |
.channel | = DMA_Channel_0, | |
.irq_vector | = DMA1_Stream4_IRQn, | |
.complete_flags | = DMA_HISR_TCIF5, | |
.error_flags | = ( DMA_HISR_TEIF5 | DMA_HISR_FEIF5 | DMA_HISR_DMEIF5 ), | |
}, | ||
.rx_dma = | ||
{ | ||
.controller | = DMA1, | |
.stream | = DMA1_Stream3, | |
.channel | = DMA_Channel_0, | |
.irq_vector | = DMA1_Stream3_IRQn, | |
.complete_flags | = DMA_LISR_TCIF0, | |
.error_flags | = ( DMA_LISR_TEIF0 | DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 ), | |
}, | ||
} |
};
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am Ok with this configuration of DMA, but I don't see where you configure the Chip select pin of the SPI ?
So I don't understand the interrupt behavior:
=> does your Rx DMA interrupt will trig when the DMA buffer is full (no DMA size is defined in your example) ?
=> or does your Rx DMA interrupt will trig when the ChipSelect will be disable ?
I forgot to precise that in my case the 1LD module is the slave in this SPI communication.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
RCC_PCLK1Config( RCC_HCLK_Div2 ); /* Set clock to 18MHz (assuming 72MHz STM32 system clock) */ |
/* Enable SPI_SLAVE DMA clock */ | |
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA1, ENABLE ); |
/* Enable SPI_SLAVE Periph clock */ | |
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE ); |
/* Enable SYSCFG. Needed for selecting EXTI interrupt line */ | |
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG, ENABLE ); |
/* Setup the interrupt input for WLAN_IRQ */ |
#ifndef WWD_SPI_IRQ_FALLING_EDGE
platform_gpio_init( &wifi_spi_pins[WWD_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE ); | |
platform_gpio_irq_enable( &wifi_spi_pins[WWD_PIN_SPI_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 ); |
#else /* WWD_SPI_IRQ_FALLING_EDGE */
platform_gpio_init( &wifi_spi_pins[WWD_PIN_SPI_IRQ], INPUT_PULL_UP ); | |
platform_gpio_irq_enable( &wifi_spi_pins[WWD_PIN_SPI_IRQ], IRQ_TRIGGER_FALLING_EDGE, spi_irq_handler, 0 ); |
#endif /* WWD_SPI_IRQ_FALLING_EDGE */
/* Setup SPI slave select GPIOs */ | |
platform_gpio_init( &wifi_spi_pins[WWD_PIN_SPI_CS], OUTPUT_PUSH_PULL ); | |
platform_gpio_output_high( &wifi_spi_pins[WWD_PIN_SPI_CS] ); |
all the config include CS of SPI is here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I don't uderstand why you put the IRQ_PIN as interrupt and the CS pin as output ?
What is the hardware pin behind your PIN_SPI_IRQ ?
In case of SPI slave device, the CS should be set as input, no ?
and the interrupt activated on the CS pin.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hello:
I think in our code we set SPI2 as communication interface between F4xx and wifi chip.
and it is a master mode:
/* Setup SPI */
spi_init.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
spi_init.SPI_Mode = SPI_Mode_Master;
...................
/* Init SPI and enable it */
SPI_Init( SPI2, &spi_init );
then we use another pin acting as INT input from WLAN chip , didn't let CS pin multiplexed as DMA INT.
/* Setup the interrupt input for WLAN_IRQ */
platform_gpio_init( &wifi_spi_pins[WWD_PIN_SPI_IRQ], INPUT_HIGH_IMPEDANCE );
platform_gpio_irq_enable( &wifi_spi_pins[WWD_PIN_SPI_IRQ], IRQ_TRIGGER_RISING_EDGE, spi_irq_handler, 0 );
/* Wi-Fi gSPI bus pins. Used by WICED/platform/STM32F4xx/WWD/wwd_SPI.c */
const platform_gpio_t wifi_spi_pins[] =
{
[WWD_PIN_SPI_IRQ ] = { GPIOC, 9 },
[WWD_PIN_SPI_CS ] = { GPIOB, 12 },
[WWD_PIN_SPI_CLK ] = { GPIOB, 13 },
[WWD_PIN_SPI_MOSI] = { GPIOB, 15 },
[WWD_PIN_SPI_MISO] = { GPIOB, 14 },
};