USART(Serial) interrupt

Post your cool example code here.
miki
Posts: 30
Joined: Wed May 18, 2016 10:22 pm

USART(Serial) interrupt

Postby miki » Wed Jun 01, 2016 3:05 am

I read somewhere there is serial interrupt implemented in libmaple.
May somebody share on how to use it?
I need to process a serial frame,in interrupt on RX .

User avatar
RogerClark
Posts: 5465
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: USART(Serial) interrupt

Postby RogerClark » Wed Jun 01, 2016 9:43 am

I think the libmaple uses the uses interrupts to read the USART when an incoming character is received, and puts it into the input ring buffer

So if you want to call your own function as well as the character going into the ring buffer, you would need to modify the code in cores\maple\libmaple\usart_f1

e.g.

Code: Select all

void __irq_usart1(void) {
    usart_irq(&usart1_rb, USART1_BASE);
}


and insert some other code

Note.
I have not looked at precisely how the serial interrupt stuff works, and I can't see how the handler is getting configured in into the NVIC. But I don't think you would need to change the NVIC setup, you would just need to patch into the existing ISR

miki
Posts: 30
Joined: Wed May 18, 2016 10:22 pm

Re: USART(Serial) interrupt

Postby miki » Wed Jun 01, 2016 12:13 pm

The interrupt handler is called automatically as soon as a character is received and the appropriate flag is set.
So this function is the interrupt handler? It is fired automatically?

User avatar
RogerClark
Posts: 5465
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: USART(Serial) interrupt

Postby RogerClark » Wed Jun 01, 2016 9:14 pm

@miki

I presume it is fired straight away, but the best option is for you to write some code and do some research, or to read the master programming manual for the F103

miki
Posts: 30
Joined: Wed May 18, 2016 10:22 pm

Re: USART(Serial) interrupt

Postby miki » Thu Jun 02, 2016 4:01 pm

I tried some code on Serial3 and I saw it is nod defined. I used Generic F103C series
Serial and Serial2 are compiling.
I want to use USART3 because it is 5V tolerant.USAR2 is not,and I keep USART1 for debugging.
Or maybe Serial2 it is USART3 ?Confusing.Yes I see that in boards.cpp for generic,

User avatar
mrburnette
Posts: 1766
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: USART(Serial) interrupt

Postby mrburnette » Thu Jun 02, 2016 5:39 pm

miki wrote:I tried some code on Serial3 and I saw it is nod defined. I used Generic F103C series
Serial and Serial2 are compiling.
I want to use USART3 because it is 5V tolerant.USAR2 is not,and I keep USART1 for debugging.
Or maybe Serial2 it is USART3 ?Confusing.Yes I see that in boards.cpp for generic,



No.
It is not confusing, the forum was built on the Maple Mini clone first. Other boards came a weebit later.
With MM:
Serial == USBserial
Serial1 == Serial 1
Serial2 == Serial 2

Read more: http://www.stm32duino.com/viewtopic.php?t=3

Ray

miki
Posts: 30
Joined: Wed May 18, 2016 10:22 pm

Re: USART(Serial) interrupt

Postby miki » Thu Jun 02, 2016 7:53 pm

I want to bypass maple handler and use mine inside the arduino sketch to have better control and more checks
I don'T know how to proceed.I can replace __irq_usart3() in usart_f1.c but it seems too complicated and too personalized with declaring specific variables used only inside my sketch.I need to process data in the interrupt and have more control.
How can I use the original STM32 USART interrupt handlers?.
I read reference manual but did not find what I'm looking for.On avr it is simple you know the name of the vector and you call it inside the sketch.I want to do the same.

User avatar
mrburnette
Posts: 1766
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: USART(Serial) interrupt

Postby mrburnette » Thu Jun 02, 2016 8:22 pm

miki wrote:I want to bypass maple handler and use mine inside the arduino sketch to have better control and more checks
I don'T know how to proceed.
<...>


And we are suppose to do a virtual Vulcan Mind Meld with you?

Respectfully,
You need to work up to being a bit more self-sufficient with coding.
When you can articulate what control you need and why you need it and
can show a good-faith example of your attempt to solve your problem;
well then maybe we can help you climb the wall.

Ray

miki
Posts: 30
Joined: Wed May 18, 2016 10:22 pm

Re: USART(Serial) interrupt

Postby miki » Thu Jun 02, 2016 9:04 pm

Respectfully,

I need to insert something similar on my sketch.I need my handle override default handler from maple.


Code: Select all

uint16_t x;
uint16_t index;
#define BUFFER_SIZE

void USART_3 interrupt handler() {//?????

if((USART3_BASE->SR &0x0F)==0)   // Check overrun, noise error,framing ,parity error
{
if(index==0){
if((USART3_BASE->DR&0xff)==x){
index++;
start a timer for 5ooous;
interrupt on timer output compare;
}
}
else{
buffer[(index++)-1]=USART3_BASE->DR&0xff;
if(index>BUFFER_SIZE){
disable timer interrrupt;
index=0;
}
}
}
else
index=0;
}
Last edited by miki on Sat Jun 04, 2016 1:16 am, edited 2 times in total.

User avatar
mrburnette
Posts: 1766
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: USART(Serial) interrupt

Postby mrburnette » Fri Jun 03, 2016 1:53 pm

miki wrote:Respectfully,

I need to insert something similar on my sketch.I need my handle override default handler from maple.
<...>


Well, this seems to be another instance where my smart-mouth has gotten me into hot water. :oops:

Just to level-set: I am not the forum's resident expert on USART core implementation... maybe one will chime in.
I did however spend a quality amount of time last evening digging into this inquiry. The existing Arduino "core" code provides API's for Serial1, Serial2, and Serial3. These USARTS are represented in libmaple documentation which is used in the STM32duino core.
https://github.com/leaflabs/leaflabs-docs
Unfortunately, many of the links are 'dead', so details are often lost outside the code proper:
https://github.com/leaflabs/libmaple

USART1 sits on one internal bus(APB2) and USART2 and USART3 sit on the second internal bus(APB1.) For your purposes, you may find it more attractive to take #1 for your purposes and leave 2/3 as is. Just a thought as the clock tree shows that each bus can be independently clocked.
The libmaple USART header file for 1/2/3: here
The libmaple CPP file for 1/2/3: here

The .c sets up the ring buffer and interrupt for all three USARTS:

Code: Select all

#include <libmaple/usart.h>
#include <libmaple/gpio.h>
#include "usart_private.h"

/*
 * Devices
 */

static ring_buffer usart1_rb;
static usart_dev usart1 = {
    .regs     = USART1_BASE,
    .rb       = &usart1_rb,
    .max_baud = 4500000UL,
    .clk_id   = RCC_USART1,
    .irq_num  = NVIC_USART1,
};
/** USART1 device */
usart_dev *USART1 = &usart1;

static ring_buffer usart2_rb;
static usart_dev usart2 = {
    .regs     = USART2_BASE,
    .rb       = &usart2_rb,
    .max_baud = 2250000UL,
    .clk_id   = RCC_USART2,
    .irq_num  = NVIC_USART2,
};
/** USART2 device */
usart_dev *USART2 = &usart2;

static ring_buffer usart3_rb;
static usart_dev usart3 = {
    .regs     = USART3_BASE,
    .rb       = &usart3_rb,
    .max_baud = 2250000UL,
    .clk_id   = RCC_USART3,
    .irq_num  = NVIC_USART3,
};
/** USART3 device */
usart_dev *USART3 = &usart3;

#if defined(STM32_HIGH_DENSITY) || defined(STM32_XL_DENSITY)
static ring_buffer uart4_rb;
static usart_dev uart4 = {
    .regs     = UART4_BASE,
    .rb       = &uart4_rb,
    .max_baud = 2250000UL,
    .clk_id   = RCC_UART4,
    .irq_num  = NVIC_UART4,
};
/** UART4 device */
usart_dev *UART4 = &uart4;

static ring_buffer uart5_rb;
static usart_dev uart5 = {
    .regs     = UART5_BASE,
    .rb       = &uart5_rb,
    .max_baud = 2250000UL,
    .clk_id   = RCC_UART5,
    .irq_num  = NVIC_UART5,
};
/** UART5 device */
usart_dev *UART5 = &uart5;
#endif

/*
 * Routines
 */

void usart_config_gpios_async(usart_dev *udev,
                              gpio_dev *rx_dev, uint8 rx,
                              gpio_dev *tx_dev, uint8 tx,
                              unsigned flags) {
    gpio_set_mode(rx_dev, rx, GPIO_INPUT_FLOATING);
    gpio_set_mode(tx_dev, tx, GPIO_AF_OUTPUT_PP);
}

void usart_set_baud_rate(usart_dev *dev, uint32 clock_speed, uint32 baud) {
    uint32 integer_part;
    uint32 fractional_part;
    uint32 tmp;

    /* Figure out the clock speed, if the user doesn't give one. */
    if (clock_speed == 0) {
        clock_speed = _usart_clock_freq(dev);
    }
    ASSERT(clock_speed);

    /* Convert desired baud rate to baud rate register setting. */
    integer_part = (25 * clock_speed) / (4 * baud);
    tmp = (integer_part / 100) << 4;
    fractional_part = integer_part - (100 * (tmp >> 4));
    tmp |= (((fractional_part * 16) + 50) / 100) & ((uint8)0x0F);

    dev->regs->BRR = (uint16)tmp;
}

/**
 * @brief Call a function on each USART.
 * @param fn Function to call.
 */
void usart_foreach(void (*fn)(usart_dev*)) {
    fn(USART1);
    fn(USART2);
    fn(USART3);
#ifdef STM32_HIGH_DENSITY
    fn(UART4);
    fn(UART5);
#endif
}

/*
 * Interrupt handlers.
 */

void __irq_usart1(void) {
    usart_irq(&usart1_rb, USART1_BASE);
}

void __irq_usart2(void) {
    usart_irq(&usart2_rb, USART2_BASE);
}

void __irq_usart3(void) {
    usart_irq(&usart3_rb, USART3_BASE);
}

#ifdef STM32_HIGH_DENSITY
void __irq_uart4(void) {
    usart_irq(&uart4_rb, UART4_BASE);
}

void __irq_uart5(void) {
    usart_irq(&uart5_rb, UART5_BASE);
}
#endif
Status API Training Shop Blog About


Now we can follow the libmaple .h & .c to the STM32F103 "duino" core code HardwareSerial.h and HardwareSerial.cpp

To have total control over any of the USARTS, my suggestion at this point is to create separate files for the USART you select to own. You will have to muck with the build system, but this should not be too complicated since you are just creating 2 new library files and 2 new core files and can use the existing files as a reference for the new entries.

The approach above is a bit convoluted but by isolating one of the USARTS you can easily test using existing sketch code. Once everything is working, you can add whatever new structure/control you wish for the isolated port.

Ray


Return to “Code snipplets”

Who is online

Users browsing this forum: No registered users and 3 guests