Community
cancel
Showing results for 
Search instead for 
Did you mean: 
JSchi7
Novice
1,274 Views

How to use qm_uart_irq_read() ?

Hi,

I want to use qm_uart_irq_read() as an interrupt driven serial I/O driver so I can be executing non-interrupt code while receiving serial data. This requires copying the data from the xfer structure serial buffer to a circular buffer that is accessed by both the code in the UART RX callback and reading it out in the non-interrupt code. Normally when I do this I need a semaphore or mutex to lock the circular buffer while the non-interrupt side accesses it.

Is there such an instruction in the D2000 or is there some other way of doing this ?

I have a structure like this to support this operation:

# define RX_SIZE 32

# define FIFO_SIZE 64

typedef struct {

int uart;

qm_uart_transfer_t xfer;

int psn;

int count;

uint8_t rx_buffer[RX_SIZE];

int head;

int tail;

int size;

uint8_t fifo[FIFO_SIZE];

} PORT_HANDLE;

PORT_HANDLE phy;

And it is set up like this:

/* Setup a non-blocking IRQ RX transfer. */

phy.xfer.data = phy.rx_buffer;

phy.xfer.data_len = RX_SIZE;

phy.xfer.fin_callback = uart_0_rx_callback;

phy.xfer.err_callback = uart_0_error_callback;

qm_irq_request(QM_IRQ_UART_0, qm_uart_0_isr);

phy.uart = QM_UART_0;

// Init FIFO

phy.head = 0;

phy.tail = 0;

phy.size = 0;

In the IRQ RX routine I do this:

void uart_0_rx_callback(uint32_t id, uint32_t len)

{

int i;

switch (id)

{

case 1:

// Trans from rx_buffer to FIFO overwrite head

if( len > 0 )

{

for( i=0; i<(<span style="color: # 0433ff;">int)len; i++ )

{

phy.fifo[phy.head++] = phy.rx_buffer[i];

if( phy.head >= FIFO_SIZE )

phy.head = 0;

}

}

break;

default:

break;

}

}

Thanks for the help

--jim schimpf

0 Kudos
4 Replies
JSchi7
Novice
102 Views

Slight error in the code (above):

the setup:

phy.xfer.fin_callback = uart_0_rx_callback;

phy.xfer.err_callback = uart_0_error_callback;

qm_irq_request(QM_IRQ_UART_0, qm_uart_0_isr);

should be

phy.xfer.fin_callback = uart_0_rx_callback;

phy.xfer.err_callback = uart_0_error_callback;

qm_uart_irq_read(QM_UART_0, &(phy.xfer)); <-- Fixed this line.

HOW TO USE IT:

Found out how to use qm_uart_irq_read(). (1) Set up the xfer structure so it can get data. (2) Set up an irq routine to catch the data. (3) Call qm_uart_irq_read() with the UART # and the xfer struct in the setup. Now it will call the IRQ routine when the buffer is FULL, not before so make the buffer small so it calls the irq say on every char. (4) In the IRQ routine call qm_uart_irq_read() after emptying the buffer so it runs AGAIN.

Sergio_A_Intel
Employee
102 Views

Hi

Have you managed to solve your issue and use qm_uart_irq_read()? Is there anything else we can assist you with in this thread? Remember if you found the solution to your question you can mark the answer as "Correct Answer"

Sergio

JSchi7
Novice
102 Views

Not quite.

Working with the UART sample project I modified it to (1) have a loop at the end so it never exits main (i.e. runs forever) (2) modified the BIG_NUMBER from 50 to 1 so I get an interrupt/character. But when I transferred this code to my application it would not generate an interrupt on serial in. I then when back to the UART project and found if I didn't do the TX interrupt setup and output, no RX interrupts would be generated. So I put that back in and RX interrupts worked. Why would this be the case particularly since the xfer structure is used for the TX then re-used for the RX ? Here is the UART main.c that generates an interrupt call on each serial character. I marked the modifications.

# include "qm_pinmux.h"

# include "qm_uart.h"

# include "qm_interrupt.h"

# include "qm_scss.h"

# define BANNER_STR ("Hello, world! QMSI echo application, Pol'd message.\n\n")

# define BANNER_IRQ_ID (1)

# define BANNER_IRQ ("Hello, world! QMSI echo application, IRQ'd message.\n\n")

# define BANNER_IRQ_COMPLETE ("IRQ Transfer completed.\n")

# define RX_STR ("Data received.\n")

# define ERR_STR ("Transmission error.\n")

# define CLR_SCREEN ("\033[2J\033[;H")

static void uart_0_example_tx_callback(uint32_t id, uint32_t len);

static void uart_0_example_rx_callback(uint32_t id, uint32_t len);

static void uart_0_example_error_callback(uint32_t id, qm_uart_status_t status);

# define BIG_NUMBER_RX (1) /* <<<<<<<<<<<<<<<<<<<<< Set for 1 character interrupt */

static uint8_t rx_buffer[BIG_NUMBER_RX];

qm_uart_transfer_t xfer;

/* Sample UART0 QMSI application. */

int main(void)

{

qm_uart_config_t cfg, rd_cfg;

qm_uart_status_t ret __attribute__((unused));

/* Set divisors to yield 115200bps baud rate. */

/* Sysclk is set by boot ROM to hybrid osc in crystal mode (32MHz),

* peripheral clock divisor set to 1.

*/

cfg.baud_divisor = QM_UART_CFG_BAUD_DL_PACK(0, 17, 6);

cfg.line_control = QM_UART_LC_8N1;

cfg.hw_fc = false;

/* Mux out UART0 tx/rx pins and enable input for rx. */

# if (QUARK_SE)

qm_pmux_select(QM_PIN_ID_18, QM_PMUX_FN_0);

qm_pmux_select(QM_PIN_ID_19, QM_PMUX_FN_0);

qm_pmux_input_en(QM_PIN_ID_18, true);

# elif(QUARK_D2000)

qm_pmux_select(QM_PIN_ID_12, QM_PMUX_FN_2);

qm_pmux_select(QM_PIN_ID_13, QM_PMUX_FN_2);

qm_pmux_input_en(QM_PIN_ID_13, true);

# else

# error("Unsupported / unspecified processor detected.")

# endif

clk_periph_enable(CLK_PERIPH_CLK | CLK_PERIPH_UART...

JSchi7
Novice
102 Views

This code works: You call init_phy to set it up then put_phy() to write data, stat_phy() to check for data and get_phy() to get data. Runs at 115200 as I didn't want to try to figure out QM_UART_CFG_BAUD_DL_PACK(0, 17, 6); at this point.

--jim schimpf

# include "qm_pinmux.h"

# include "qm_uart.h"

# include "qm_interrupt.h"

# include "qm_scss.h"

# include "phy.h"

# if 0

# pragma mark -

# pragma mark -- Data --

# endif

static void uart_0_error_callback(uint32_t id, qm_uart_status_t status);

static void uart_0_rx_callback(uint32_t id, uint32_t len);

static void uart_0_tx_callback(uint32_t id, uint32_t len);

# define RX_SIZE 1 // Small so lots of int/char

# define FIFO_SIZE 64

# define FIRENET_DWELL 100

typedef struct {

int uart;

qm_uart_transfer_t xfer; // Int rec struct

uint8_t rx_buffer[RX_SIZE]; // Int rec buffer 1 byte

// FIFO for foreground operations

int head;

int tail;

uint8_t fifo[FIFO_SIZE];

} PORT_HANDLE;

PORT_HANDLE phy;

# ifndef false

# define false 0

# define true 1

# define EOF -1

# endif

// FOR TX interrupt

# define BANNER_IRQ_ID (1)

# define BANNER_IRQ ("\r\n----\r\n")

# define BANNER_IRQ_COMPLETE ("\r\n****\r\n")

# if 0

# pragma mark -

# pragma mark -- External API --

# endif

//*************************************************************************

/*

* void *init_phy( char *port ) - Initialize Phy layer

*

* INPUT: port - Serial port used (number in list)

* baud - Baud rate used (ignored) - 115200 used

*

* OUTPUT: Return port handle if opened, -1 if problem

*

* This is called by each node to get the port used for I/O

*/

//************************************************************************

void *init_phy( char</s...

Reply