-
Notifications
You must be signed in to change notification settings - Fork 40
Description
I tried to compile (STM32F103C8T6) but the first error that occurred seems to be relative to the interrupt register definition.
c:\arduino ide\arduino-1.8.10-windows-portable\portable\sketchbook\libraries\dyn_swi\dyn_swi.h:106:2: error: #error SWI_IRQ_NUM not defined (CMSIS)
#error SWI_IRQ_NUM not defined (CMSIS)
https://github.com/stm32duino/Arduino_Core_STM32
I found this post that might help someone identify that SPI port interrupt register:
https://os.mbed.com/forum/mbed/topic/26688/?page=1#comment-50909
Maybe it will be interesting for some MBED developers.
I explain how to extend the SPISlave class for use interrupts on STM32 MCU. With this solution we do not need to change anything in the basic SPISlave class.
First step is common and strighforward. We create instance of SPISlave class and do some configuration (format, frequency, ...). Next we setup SPI CR2 register to enable interrupts. Especially:
- TXEIE bit to enable 'Tx buffer empty' interrupt - RXNEIE bit to enable 'RX buffer not empty' interrupt
and at last we install own ISR routine for SPI interrupts.
Some explanaition.
Because SPI work in full duplex mode we must have 'filler' (empty) character. I use null byte as filler. Send or receive null byte means that there is nothing to send (or receive). As a consequence this protocol cant be used for binary data. Null bytes must be encoded/decoded on both side (escape sequence processing).
My ISR routine cooperate with two buffers and simple API: - saveInBuf save received characters in external buffer - char2send get next byte to send from transmit buffer
Local (static) buffer 'intBuf' is used in the case when main receive buffer is (temporarily) in use and received character can't be saved.
I run test program on Nucleo-STM32F103RB (64 MHz HSI) connected to Orange Pi Lite (Armbian Linux). On Orange Pi side I use two transmission buffers and Timer interrupt to check for pending transmission (once per 100 us). I configure SPI on both side in 8 bit mode and 16 Mhz frequency.
extern uint32_t Default_Handler;
SPI_TypeDef *cspi = SPI2;
bool blockReader, blockWriter;
void setIRQvector(IRQn_Type it, uint32_t fa)
{
uint32_t dh;
if(it >= 0)
{
if(!fa)
{
NVIC_DisableIRQ(it);
dh = (uint32_t) Default_Handler;
NVIC_SetVector(it, dh);
}
else
{
NVIC_SetVector(it, fa);
NVIC_EnableIRQ(it);
}
}
}
#define TXEIE_MASK 0x80
#define RXNEIE_MASK 0x40
void enableSPIinterrupt(bool enable)
{
uint32_t isr = 0;
if(enable)
{
isr = (uint32_t) rwSPIservice;
cspi->CR2 |= (TXEIE_MASK | RXNEIE_MASK);
}
else
cspi->CR2 &= ~(TXEIE_MASK | RXNEIE_MASK);
setIRQvector(SPI2_IRQn, isr);
}
#define RXNE_MASK 1
#define TXE_MASK 2
void rwSPIservice(void)
{
static char intBuf[16];
static uint16_t cInBuf;
int tc;
if(cspi->SR & RXNE_MASK && cInBuf < sizeof(intBuf))
{
tc = cspi->DR;
if(tc)
intBuf[cInBuf++] = tc;
}
if(cInBuf > 0 && !blockReader)
{
short saved = saveInBuf(intBuf, cInBuf);
if(saved > 0)
{
cInBuf -= saved;
if(cInBuf > 0)
memmove(intBuf, intBuf + saved, cInBuf);
}
}
if(cspi->SR & TXE_MASK)
{
tc = 0;
if(!blockWriter)
{
tc = char2send();
if(tc < 0)
tc = 0;
}
cspi->DR = tc;
}
}