OpenCores
URL https://opencores.org/ocsvn/neo430/neo430/trunk

Subversion Repositories neo430

[/] [neo430/] [trunk/] [neo430/] [sw/] [example/] [uart_irq/] [main.c] - Rev 198

Compare with Previous | Blame | View Log

// #################################################################################################
// #  < UART interrupt example >                                                                   #
// # ********************************************************************************************* #
// # UART RECEIVE is conducted using the UART RX interrupt                                         #
// # UART TRANSMIT is conducted by using the timer interrupt                                       #
// # ********************************************************************************************* #
// # BSD 3-Clause License                                                                          #
// #                                                                                               #
// # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
// #                                                                                               #
// # Redistribution and use in source and binary forms, with or without modification, are          #
// # permitted provided that the following conditions are met:                                     #
// #                                                                                               #
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
// #    conditions and the following disclaimer.                                                   #
// #                                                                                               #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
// #    conditions and the following disclaimer in the documentation and/or other materials        #
// #    provided with the distribution.                                                            #
// #                                                                                               #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
// #    endorse or promote products derived from this software without specific prior written      #
// #    permission.                                                                                #
// #                                                                                               #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
// # ********************************************************************************************* #
// # The NEO430 Processor - https://github.com/stnolting/neo430                                    #
// #################################################################################################
 
 
// Libraries
#include <stdint.h>
#include <neo430.h>
 
// Configuration
#define BAUD_RATE 19200
#define UART_FIFO_SIZE 512 // must be a power of two!
#define UART_FIFO_MASK (UART_FIFO_SIZE-1)
 
// Types
struct uart_fifo {
  uint8_t data[UART_FIFO_SIZE];
  uint16_t get_pnt;
  uint16_t put_pnt;
};
 
// Global vars
volatile struct uart_fifo uart_rtx_fifo;
 
// Function prototypes
void __attribute__((__interrupt__)) uart_irq_handler(void);
void __attribute__((__interrupt__)) timer_irq_handler(void);
void __attribute__((__interrupt__)) gpio_irq_handler(void);
 
void fifo_put_string(volatile struct uart_fifo *fifo, char *s);
uint8_t fifo_put(volatile struct uart_fifo *fifo, uint8_t c);
uint8_t fifo_get(volatile struct uart_fifo *fifo, uint8_t *c);
 
/* ------------------------------------------------------------
 * INFO Main function
 * ------------------------------------------------------------ */
int main(void) {
 
  // setup UART
  neo430_uart_setup(BAUD_RATE);
 
 
  // init fifo
  uart_rtx_fifo.get_pnt = 0;
  uart_rtx_fifo.put_pnt = 0;
 
  // deactivate all LEDs
  GPIO_OUTPUT = 0;
 
  // set address of UART, TIMER and GPIO IRQ handlers
  IRQVEC_SERIAL = (uint16_t)(&uart_irq_handler);
  IRQVEC_TIMER  = (uint16_t)(&timer_irq_handler);
  IRQVEC_GPIO   = (uint16_t)(&gpio_irq_handler);
 
  // configure GPIO pin-change interrupt
  GPIO_IRQMASK = 0xFFFF; // use all input pins as trigger
 
  // configure UART RX interrupt
  UART_CT |= (1<<UART_CT_RX_IRQ);
 
  // configure TIMER period
  neo430_timer_disable();
  TMR_THRES = 1;
 
  // configure timer operation
  TMR_CT = (1<<TMR_CT_EN)   | // enable timer
           (1<<TMR_CT_ARST) | // auto reset on threshold match
           (1<<TMR_CT_IRQ)  | // enable IRQ
           (1<<TMR_CT_RUN)  | // make timer run
           (TMR_PRSC_4096<<TMR_CT_PRSC0);
 
 
  // write string to buffer
  fifo_put_string(&uart_rtx_fifo, "\r\nUART IRQ FIFO Echo Test\r\n");
 
  // enable global IRQs
  neo430_eint();
 
  while(1) {
    neo430_sleep();
  }
 
  return 0;
}
 
 
 
/* ------------------------------------------------------------
 * INFO UART interrupt handler
 * INFO Put received char into buffer
 * ------------------------------------------------------------ */
void __attribute__((__interrupt__)) uart_irq_handler(void) {
 
  fifo_put(&uart_rtx_fifo, (uint8_t)neo430_uart_char_read());
}
 
 
 
/* ------------------------------------------------------------
 * INFO Timer interrupt handler
 * INFO Send char from buffer if available
 * ------------------------------------------------------------ */
void __attribute__((__interrupt__)) timer_irq_handler(void) {
 
  uint8_t c;
 
  // UART transceiver idle?
  if ((UART_CT & (1<<UART_CT_TX_BUSY)) == 0) {
    // char in buffer available?
    if (fifo_get(&uart_rtx_fifo, &c) == 0) {
      UART_RTX = (uint16_t)c;
    }
  }
}
 
/* ------------------------------------------------------------
 * INFO Write string to buffer, blocking!
 * ------------------------------------------------------------ */
void fifo_put_string(volatile struct uart_fifo *fifo, char *s) {
 
  uint8_t c = 0;
  while ((c = (uint8_t)*s++))
    fifo_put(fifo, c);
}
 
 
/* ------------------------------------------------------------
 * INFO Write to buffer, return 0 if success
 * ------------------------------------------------------------ */
uint8_t fifo_put(volatile struct uart_fifo *fifo, uint8_t c) {
 
  uint16_t next = ((fifo->put_pnt + 1) & UART_FIFO_MASK);
 
  if (fifo->get_pnt == next)
    return 1; // fifo full
 
  fifo->data[fifo->put_pnt & UART_FIFO_MASK] = c;
  fifo->put_pnt = next;
 
  return 0;
}
 
 
/* ------------------------------------------------------------
 * INFO Read from buffer, returns 0 if success
 * ------------------------------------------------------------ */
uint8_t fifo_get(volatile struct uart_fifo *fifo, uint8_t *c) {
 
  if (fifo->get_pnt == fifo->put_pnt)
    return 1; // fifo empty
 
  *c = fifo->data[fifo->get_pnt];
 
  fifo->get_pnt = (fifo->get_pnt+1) & UART_FIFO_MASK;
 
  return 0;
}
 
 
 
/* ------------------------------------------------------------
 * INFO GPIO pin-change interrupt handler
 * ------------------------------------------------------------ */
void __attribute__((__interrupt__)) gpio_irq_handler(void) {
 
  GPIO_OUTPUT = (GPIO_OUTPUT + 1) & 0x00FF; // increment LED counter
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.