Microchip® Advanced Software Framework

mega_remorse_example.c File Reference
#include <stddef.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <asf.h>
#include <conf_usart.h>

Data Structures

struct  RING
 Ring Buffer Structure. More...
 

Macros

#define BAUD_PRESCALE   (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
 
#define DOT_TIME_IN_MS   (DOT_TIME_IN_TICKS * 10.0)
 
#define DOT_TIME_IN_TICKS   (25)
 
#define min(a, b)
 
#define MORSE_RX_BUF_SIZE   (32)
 
#define REMORSE_CLK_HZ   (100)
 
#define REMORSE_RESTART   (400)
 
#define REMORSE_TIMEOUT   (1000)
 

Typedefs

typedef RINGRING_ID
 

Functions

static int bsp_morse_getchar (FILE *stream)
 Decode morse code input from button. More...
 
static int bsp_morse_putchar (char c, FILE *stream)
 Flash out morse code for character on led. More...
 
static int bsp_tty_getchar (FILE *stream)
 Fetch a character from uart receiver. More...
 
static int bsp_tty_putchar (char c, FILE *stream)
 Push a character out uart transmitter. More...
 
 ISR (TIMER1_COMPA_vect)
 Interrupt Service Routines. More...
 
int main (void)
 Entry point for morse code example. More...
 
static void morse_fmtchar (char rc)
 Print out character as ASCII morse code (. More...
 
static char morse_parse (uint8_t pattern, int len)
 Parse morse code pattern into ASCII character. More...
 
static void morse_poll (void)
 Poll button for debounced conversion to Morse code. More...
 
static void remorse_instructions (void)
 Print out remorse instructions. More...
 
static int rng_buf_get (RING_ID rng_id, char *buffer, int maxbytes)
 
  • get characters from a ring buffer
More...
 
static int rng_buf_put (RING_ID rng_id, char *buffer, int nbytes)
 
  • put bytes into a ring buffer
More...
 
static void rng_flush (RING_ID ring_id)
 make a ring buffer empty More...
 
static int rng_free_bytes (RING_ID ring_id)
 
  • determine the number of free bytes in a ring buffer
More...
 
static RING_ID rng_init (RING *p_ring, int nbytes, char *buffer)
 Ring Utility Functions. More...
 
static bool rng_is_empty (RING_ID ring_id)
 
  • test if a ring buffer is empty
More...
 
static bool rng_is_full (RING_ID ring_id)
 
  • test if a ring buffer is full (no more room)
More...
 
void rng_move_ahead (RING_ID ring_id, int n)
 
  • advance a ring pointer by <n> bytes
More...
 
static int rng_nBytes (RING_ID ring_id)
 rng_nBytes - determine the number of bytes in a ring buffer More...
 
void rng_put_ahead (RING_ID ring_id, char byte, int offset)
 
  • put a byte ahead in a ring buffer without moving ring pointers
More...
 

Variables

const uint8_t morse_ascii_tbl [][2]
 
static char morse_rx_buf [MORSE_RX_BUF_SIZE+1]
 
static RING morse_rx_ring
 
static RING_ID morse_rx_ring_id
 
static volatile bool remorse_restart
 
static volatile uint32_t remorse_tick_cnt
 
static volatile uint32_t remorse_wd_cnt
 
static FILE tty_console = FDEV_SETUP_STREAM(bsp_tty_putchar, bsp_tty_getchar, _FDEV_SETUP_RW)
 
static FILE tty_morse = FDEV_SETUP_STREAM(bsp_morse_putchar, bsp_morse_getchar, _FDEV_SETUP_RW)
 
static bool user_input = false
 

#define BAUD_PRESCALE   (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define DOT_TIME_IN_MS   (DOT_TIME_IN_TICKS * 10.0)

Referenced by bsp_morse_putchar().

#define DOT_TIME_IN_TICKS   (25)

Referenced by morse_poll().

#define min (   a,
 
)
Value:
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })

Referenced by rng_buf_get(), and rng_buf_put().

#define MORSE_RX_BUF_SIZE   (32)

Referenced by main().

#define REMORSE_CLK_HZ   (100)
#define REMORSE_RESTART   (400)

Referenced by morse_poll().

#define REMORSE_TIMEOUT   (1000)

Referenced by ISR().

typedef RING* RING_ID

static int bsp_morse_getchar ( FILE *  stream)
static

Decode morse code input from button.

If we have any decoded morse code we return it or _FDEV_ERR if none.

References rng_buf_get().

static int bsp_morse_putchar ( char  c,
FILE *  stream 
)
static

Flash out morse code for character on led.

Polling version of character write. We spin here until character can be placed in transmit register.

References DOT_TIME_IN_MS, LED0, LED_Off, LED_On, and morse_ascii_tbl.

static int bsp_tty_getchar ( FILE *  stream)
static

Fetch a character from uart receiver.

Polling version of a character read. We spin here until receive buffer has something to read.

References USART0, usart_get(), usart_rx_is_complete(), and user_input.

static int bsp_tty_putchar ( char  c,
FILE *  stream 
)
static

Push a character out uart transmitter.

Polling version of character write. We spin here until character can be placed in transmit register.

References USART0, usart_data_register_is_empty(), and usart_put().

ISR ( TIMER1_COMPA_vect  )

Interrupt Service Routines.

Remorse clock interrupt routine

This routine is called at interrupt level on each clock interrupt.

References morse_poll(), remorse_restart, remorse_tick_cnt, REMORSE_TIMEOUT, and remorse_wd_cnt.

int main ( void  )

Entry point for morse code example.

Main function.

The SAM3X_EK, SAM3X Arduino board and SAM4C_EK use two bytes length internal address EEPROM.

References usart_rs232_options::baudrate, board_init(), LED0, LED_Off, morse_fmtchar(), morse_rx_buf, MORSE_RX_BUF_SIZE, remorse_instructions(), remorse_restart, remorse_wd_cnt, rng_init(), tty_console, tty_morse, USART0, and usart_init_rs232().

static void morse_fmtchar ( char  rc)
static

Print out character as ASCII morse code (.

and -)

References morse_ascii_tbl.

Referenced by main(), and remorse_instructions().

static char morse_parse ( uint8_t  pattern,
int  len 
)
static

Parse morse code pattern into ASCII character.

Parameters
[in]patternmorse code pattern to match
[in]lenmorse code patter length
Returns
the ASCII character that matches the mores code patter

References morse_ascii_tbl.

Referenced by morse_poll().

static void morse_poll ( void  )
static

Poll button for debounced conversion to Morse code.

References DOT_TIME_IN_TICKS, ioport_get_pin_level(), LED0, LED_Off, LED_On, morse_parse(), REMORSE_RESTART, remorse_restart, remorse_tick_cnt, rng_buf_put(), rng_flush(), and user_input.

Referenced by ISR().

static void remorse_instructions ( void  )
static

Print out remorse instructions.

References morse_fmtchar(), tty_morse, and user_input.

Referenced by main().

int rng_buf_get ( RING_ID  rng_id,
char *  buffer,
int  maxbytes 
)
static

  • get characters from a ring buffer

This routine copies bytes from the ring buffer <rng_id> into <buffer>. It copies as many bytes as are available in the ring, up to <maxbytes>. The bytes copied will be removed from the ring.

param[in] ring_id ring buffer to get data from param[in] buffer pointer to buffer to receive data param[in] maxbytes maximum number of bytes to get

Returns
The number of bytes actually received from the ring buffer; it may be zero if the ring buffer is empty at the time of the call.

References RING::buf, RING::buf_size, min, RING::p_from_buf, and RING::p_to_buf.

Referenced by bsp_morse_getchar().

int rng_buf_put ( RING_ID  rng_id,
char *  buffer,
int  nbytes 
)
static

  • put bytes into a ring buffer

This routine puts bytes from <buffer> into ring buffer <ring_id>. The specified number of bytes will be put into the ring, up to the number of bytes available in the ring.

Parameters
[in]rng_idring buffer to put data into
[in]bufferbuffer to get data from
[in]nbytesnumber of bytes to try to put
Returns
The number of bytes actually put into the ring buffer; it may be less than number requested, even zero, if there is insufficient room in the ring buffer at the time of the call.

References RING::buf, RING::buf_size, min, RING::p_from_buf, and RING::p_to_buf.

Referenced by morse_poll().

void rng_flush ( RING_ID  ring_id)
static

make a ring buffer empty

This routine initializes a specified ring buffer to be empty. Any data currently in the buffer will be lost.

Parameters
[in]ring_idring buffer to initialize

References RING::p_from_buf, and RING::p_to_buf.

Referenced by morse_poll(), and rng_init().

int rng_free_bytes ( RING_ID  ring_id)
static

  • determine the number of free bytes in a ring buffer

This routine determines the number of bytes currently unused in a specified ring buffer.

Parameters
[in]rng_idring buffer to examine
Returns
The number of unused bytes in the ring buffer.

References RING::buf_size, RING::p_from_buf, and RING::p_to_buf.

RING_ID rng_init ( RING p_ring,
int  nbytes,
char *  buffer 
)
static

Ring Utility Functions.

initialize an empty ring buffer

This routine initializes a ring buffer of size "nbytes". The buffer must be one byte larger than nBytes since the algorithm always leaves at least one empty byte in the buffer.

Parameters
[in]p_ringpointer to a RING struct
[in]nbytesnumber of bytes in ring buffer
[in]bufferpointer to RING buffer of size nBytes + 1
Returns
ID of the ring buffer, or NULL if init fails

References RING::buf, RING::buf_size, and rng_flush().

Referenced by main().

bool rng_is_empty ( RING_ID  ring_id)
static

  • test if a ring buffer is empty

This routine determines if a specified ring buffer is empty.

Parameters
[in]rng_idring buffer to test
Returns
TRUE if empty, FALSE if not.

References RING::p_from_buf, and RING::p_to_buf.

bool rng_is_full ( RING_ID  ring_id)
static

  • test if a ring buffer is full (no more room)

This routine determines if a specified ring buffer is completely full.

Parameters
[in]rng_idring buffer to test
Returns
TRUE if full, FALSE if not.

References RING::buf_size, RING::p_from_buf, and RING::p_to_buf.

void rng_move_ahead ( RING_ID  ring_id,
int  n 
)

  • advance a ring pointer by <n> bytes

This routine advances the ring buffer input pointer by <n> bytes. This makes <n> bytes available in the ring buffer, after having been written ahead in the ring buffer with rng_put_ahead().

Parameters
[in]ring_idring buffer to be advanced
[in]nnumber of bytes ahead to move input pointer

References RING::buf_size, and RING::p_to_buf.

int rng_nBytes ( RING_ID  ring_id)
static

rng_nBytes - determine the number of bytes in a ring buffer

This routine determines the number of bytes currently in a specified ring buffer.

Parameters
[in]rng_idring buffer to be enumerated
Returns
The number of bytes filled in the ring buffer.

References RING::buf_size, RING::p_from_buf, and RING::p_to_buf.

void rng_put_ahead ( RING_ID  ring_id,
char  byte,
int  offset 
)

  • put a byte ahead in a ring buffer without moving ring pointers

This routine writes a byte into the ring, but does not move the ring buffer pointers. Thus the byte will not yet be available to rng_buf_get() calls. The byte is written <offset> bytes ahead of the next input location in the ring. Thus, an offset of 0 puts the byte in the same position as would RNG_ELEM_PUT would put a byte, except that the input pointer is not updated.

Bytes written ahead in the ring buffer with this routine can be made available all at once by subsequently moving the ring buffer pointers with the routine rng_move_ahead().

Before calling nng_put_ahead(), the caller must verify that at least <offset> + 1 bytes are available in the ring buffer.

Parameters
[in]ring_idring buffer to put byte in
[in]bytebyte to be put in ring
[in]offsetoffset beyond next input byte where to put byte

References RING::buf, RING::buf_size, and RING::p_to_buf.

const uint8_t morse_ascii_tbl[][2]
char morse_rx_buf[MORSE_RX_BUF_SIZE+1]
static

Referenced by main().

RING morse_rx_ring
static
RING_ID morse_rx_ring_id
static
volatile bool remorse_restart
static

Referenced by ISR(), main(), and morse_poll().

volatile uint32_t remorse_tick_cnt
static

Referenced by ISR(), and morse_poll().

volatile uint32_t remorse_wd_cnt
static

Referenced by ISR(), and main().

FILE tty_console = FDEV_SETUP_STREAM(bsp_tty_putchar, bsp_tty_getchar, _FDEV_SETUP_RW)
static

Referenced by main().

FILE tty_morse = FDEV_SETUP_STREAM(bsp_morse_putchar, bsp_morse_getchar, _FDEV_SETUP_RW)
static

Referenced by main(), and remorse_instructions().

bool user_input = false
static