avr: initial commit of v2 avr firmware test code
This commit is contained in:
parent
fcf5ed7d0e
commit
a5632ecb76
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// avrlibdefs.h : AVRlib global defines and macros include file
|
||||
//
|
||||
// Copyright (c) 2001-2002 Pascal Stang
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef AVRLIBDEFS_H
|
||||
#define AVRLIBDEFS_H
|
||||
|
||||
// Code compatibility to new AVR-libc
|
||||
// outb(), inb(), inw(), outw(), BV(), sbi(), cbi(), sei(), cli()
|
||||
#ifndef outb
|
||||
#define outb(addr, data) addr = (data)
|
||||
#endif
|
||||
#ifndef inb
|
||||
#define inb(addr) (addr)
|
||||
#endif
|
||||
#ifndef outw
|
||||
#define outw(addr, data) addr = (data)
|
||||
#endif
|
||||
#ifndef inw
|
||||
#define inw(addr) (addr)
|
||||
#endif
|
||||
#ifndef BV
|
||||
#define BV(bit) (1<<(bit))
|
||||
#endif
|
||||
#ifndef cbi
|
||||
#define cbi(reg,bit) reg &= ~(BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(reg,bit) reg |= (BV(bit))
|
||||
#endif
|
||||
#ifndef cli
|
||||
#define cli() __asm__ __volatile__ ("cli" ::)
|
||||
#endif
|
||||
#ifndef sei
|
||||
#define sei() __asm__ __volatile__ ("sei" ::)
|
||||
#endif
|
||||
|
||||
// support for individual port pin naming in the mega128
|
||||
// see port128.h for details
|
||||
#ifdef __AVR_ATmega128__
|
||||
// not currently necessary due to inclusion
|
||||
// of these defines in newest AVR-GCC
|
||||
// do a quick test to see if include is needed
|
||||
#ifndef PD0
|
||||
#include "port128.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// use this for packed structures
|
||||
// (this is seldom necessary on an 8-bit architecture like AVR,
|
||||
// but can assist in code portability to AVR)
|
||||
#define GNUC_PACKED __attribute__((packed))
|
||||
|
||||
// port address helpers
|
||||
#define DDR(x) ((x)-1) // address of data direction register of port x
|
||||
#define PIN(x) ((x)-2) // address of input register of port x
|
||||
|
||||
// MIN/MAX/ABS macros
|
||||
#define MIN(a,b) ((a<b)?(a):(b))
|
||||
#define MAX(a,b) ((a>b)?(a):(b))
|
||||
#define ABS(x) ((x>0)?(x):(-x))
|
||||
|
||||
// constants
|
||||
#define PI 3.14159265359
|
||||
|
||||
#endif
|
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// avrlibtypes.h : AVRlib global types and typedefines include file
|
||||
//
|
||||
// Copyright (c) 2001-2002 Pascal Stang
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef AVRLIBTYPES_H
|
||||
#define AVRLIBTYPES_H
|
||||
|
||||
#ifndef WIN32
|
||||
// true/false defines
|
||||
#define FALSE 0
|
||||
#define TRUE -1
|
||||
#endif
|
||||
|
||||
// datatype definitions macros
|
||||
typedef unsigned char u08;
|
||||
typedef signed char s08;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned long u32;
|
||||
typedef signed long s32;
|
||||
typedef unsigned long long u64;
|
||||
typedef signed long long s64;
|
||||
|
||||
/* use inttypes.h instead
|
||||
// C99 standard integer type definitions
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef signed short int16_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef signed long int32_t;
|
||||
typedef unsigned long uint64_t;
|
||||
typedef signed long int64_t;
|
||||
*/
|
||||
// maximum value that can be held
|
||||
// by unsigned data types (8,16,32bits)
|
||||
#define MAX_U08 255
|
||||
#define MAX_U16 65535
|
||||
#define MAX_U32 4294967295
|
||||
|
||||
// maximum values that can be held
|
||||
// by signed data types (8,16,32bits)
|
||||
#define MIN_S08 -128
|
||||
#define MAX_S08 127
|
||||
#define MIN_S16 -32768
|
||||
#define MAX_S16 32767
|
||||
#define MIN_S32 -2147483648
|
||||
#define MAX_S32 2147483647
|
||||
|
||||
#ifndef WIN32
|
||||
// more type redefinitions
|
||||
typedef unsigned char BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned int WORD;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
typedef char CHAR;
|
||||
typedef int INT;
|
||||
typedef long LONG;
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,173 @@
|
|||
//
|
||||
// basiciotest.c : test code for the io and buffer ops of the UART and SPI ports
|
||||
//
|
||||
// Copyright (c) 2010 flukso.net
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <avr/io.h> // include I/O definitions (port names, pin names, etc)
|
||||
#include <avr/interrupt.h> // include interrupt support
|
||||
|
||||
#include "uart.h" // include uart function library
|
||||
#include "spi.h"
|
||||
#include "ctrl.h"
|
||||
|
||||
|
||||
#define NO_OP_1 1
|
||||
#define NO_OP_2 2
|
||||
#define TRANSMIT 4
|
||||
#define HIGH_HEX 8
|
||||
#define TO_FROM_UART 16
|
||||
#define NEW_CTRL_MSG 32
|
||||
|
||||
#define SPI_END_OF_TX 0x00
|
||||
#define SPI_END_OF_MESSAGE ':'
|
||||
#define SPI_FORWARD_TO_UART_PORT 'u'
|
||||
#define SPI_FORWARD_TO_CTRL_PORT 'l'
|
||||
|
||||
|
||||
volatile uint8_t high_hex;
|
||||
volatile uint8_t spi_status;
|
||||
|
||||
uint8_t htoi(uint16_t hex) {
|
||||
uint8_t low_hex = (uint8_t) hex;
|
||||
uint8_t high_hex = (uint8_t) (hex >> 8);
|
||||
uint8_t byte;
|
||||
|
||||
byte = (high_hex > 0x40) ? (high_hex & 0x0F) + 9 : high_hex & 0x0F;
|
||||
byte = byte << 4;
|
||||
byte |= (low_hex > 0x40) ? (low_hex & 0x0F) + 9 : low_hex & 0x0F;
|
||||
return byte;
|
||||
}
|
||||
|
||||
uint16_t itoh(uint8_t byte) {
|
||||
uint8_t low_nibble = (byte & 0x0F);
|
||||
uint8_t high_nibble = (byte & 0xF0) >> 4;
|
||||
uint16_t hex;
|
||||
|
||||
hex = (high_nibble > 0x09) ? high_nibble - 9 + 0x60 : high_nibble + 0x30;
|
||||
hex = hex << 8;
|
||||
hex |= (low_nibble > 0x09) ? low_nibble - 9 + 0x60 : low_nibble + 0x30;
|
||||
return hex;
|
||||
}
|
||||
|
||||
|
||||
SIGNAL(SPI_STC_vect) {
|
||||
uint8_t spi_rx, spi_tx, uart_tx;
|
||||
|
||||
if (spi_status & (NO_OP_1 | NO_OP_2)) {
|
||||
spi_status--;
|
||||
return;
|
||||
}
|
||||
|
||||
// are we in transmit mode?
|
||||
if (spi_status & TRANSMIT) {
|
||||
if (spi_status & TO_FROM_UART) {
|
||||
|
||||
}
|
||||
else {
|
||||
if (ctrlGetFromTxBuffer(&spi_tx)) {
|
||||
received_from_spi(spi_tx);
|
||||
}
|
||||
else {
|
||||
received_from_spi(SPI_END_OF_TX);
|
||||
spi_status &= ~TRANSMIT;
|
||||
spi_status |= NO_OP_2;
|
||||
uartAddToTxBuffer('r'); //debugging
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// switch (spi_rx = received_from_spi(ctrlGetFromTxBuffer())) {
|
||||
switch (spi_rx = received_from_spi(0x00)) {
|
||||
case SPI_END_OF_TX:
|
||||
spi_status |= TRANSMIT;
|
||||
spi_status &= ~(HIGH_HEX | TO_FROM_UART);
|
||||
uartAddToTxBuffer('t'); //debugging
|
||||
break;
|
||||
case SPI_END_OF_MESSAGE:
|
||||
if (spi_status & TO_FROM_UART) {
|
||||
spi_status &= ~TO_FROM_UART;
|
||||
}
|
||||
else {
|
||||
ctrlAddToRxBuffer(spi_rx);
|
||||
spi_status |= NEW_CTRL_MSG;
|
||||
}
|
||||
break;
|
||||
case SPI_FORWARD_TO_UART_PORT:
|
||||
spi_status |= TO_FROM_UART;
|
||||
break;
|
||||
default:
|
||||
//check whether the incoming hex-encoded stream needs to be forwarded to the UART port
|
||||
if (spi_status & TO_FROM_UART) {
|
||||
if (spi_status & HIGH_HEX) {
|
||||
uart_tx = htoi(((uint16_t)high_hex << 8) + spi_rx);
|
||||
uartAddToTxBuffer(uart_tx);
|
||||
}
|
||||
else {
|
||||
high_hex = spi_rx;
|
||||
}
|
||||
// toggle to the HEX bit in spi_status
|
||||
spi_status ^= HIGH_HEX;
|
||||
}
|
||||
else {
|
||||
// forward to CTRL_RX buffer
|
||||
ctrlAddToRxBuffer(spi_rx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// initialize the CTRL buffers
|
||||
ctrlInit();
|
||||
|
||||
// initialize the UART buffers with a default UART baud rate of 4800
|
||||
uartInit();
|
||||
|
||||
// initialize the SPI in slave mode
|
||||
setup_spi(SPI_MODE_0, SPI_MSB, SPI_INTERRUPT, SPI_SLAVE);
|
||||
|
||||
uint8_t data;
|
||||
uint16_t send;
|
||||
|
||||
for(;;) {
|
||||
if (uartReceiveByte(&data)) {
|
||||
// check the HEX bit in spi_status
|
||||
if (spi_status & HIGH_HEX) {
|
||||
// loopback on the UART itf
|
||||
send = itoh(htoi(((uint16_t)high_hex << 8) + data));
|
||||
uartAddToTxBuffer((uint8_t)(send >> 8));
|
||||
uartAddToTxBuffer((uint8_t)(send));
|
||||
}
|
||||
else {
|
||||
high_hex = data;
|
||||
}
|
||||
// toggle to the HEX bit in spi_status
|
||||
spi_status ^= HIGH_HEX;
|
||||
|
||||
}
|
||||
|
||||
if (spi_status & NEW_CTRL_MSG) {
|
||||
ctrlLoop();
|
||||
spi_status &= ~NEW_CTRL_MSG;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
//
|
||||
// buffer.c : Multipurpose byte buffer structure and methods
|
||||
//
|
||||
// Copyright (c) 2001 Pascal Stang
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include "buffer.h"
|
||||
#include "global.h"
|
||||
#include "avr/io.h"
|
||||
|
||||
#ifndef CRITICAL_SECTION_START
|
||||
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli()
|
||||
#define CRITICAL_SECTION_END SREG = _sreg
|
||||
#endif
|
||||
|
||||
// global variables
|
||||
|
||||
// initialization
|
||||
|
||||
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size)
|
||||
{
|
||||
// begin critical section
|
||||
CRITICAL_SECTION_START;
|
||||
// set start pointer of the buffer
|
||||
buffer->dataptr = start;
|
||||
buffer->size = size;
|
||||
// initialize index and length
|
||||
buffer->dataindex = 0;
|
||||
buffer->datalength = 0;
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
// access routines
|
||||
unsigned char bufferGetFromFront(cBuffer* buffer)
|
||||
{
|
||||
unsigned char data = 0;
|
||||
// begin critical section
|
||||
CRITICAL_SECTION_START;
|
||||
// check to see if there's data in the buffer
|
||||
if(buffer->datalength)
|
||||
{
|
||||
// get the first character from buffer
|
||||
data = buffer->dataptr[buffer->dataindex];
|
||||
// move index down and decrement length
|
||||
buffer->dataindex++;
|
||||
if(buffer->dataindex >= buffer->size)
|
||||
{
|
||||
buffer->dataindex -= buffer->size;
|
||||
}
|
||||
buffer->datalength--;
|
||||
}
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
// return
|
||||
return data;
|
||||
}
|
||||
|
||||
void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes)
|
||||
{
|
||||
// begin critical section
|
||||
CRITICAL_SECTION_START;
|
||||
// dump numbytes from the front of the buffer
|
||||
// are we dumping less than the entire buffer?
|
||||
if(numbytes < buffer->datalength)
|
||||
{
|
||||
// move index down by numbytes and decrement length by numbytes
|
||||
buffer->dataindex += numbytes;
|
||||
if(buffer->dataindex >= buffer->size)
|
||||
{
|
||||
buffer->dataindex -= buffer->size;
|
||||
}
|
||||
buffer->datalength -= numbytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
// flush the whole buffer
|
||||
buffer->datalength = 0;
|
||||
}
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
||||
unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index)
|
||||
{
|
||||
// begin critical section
|
||||
CRITICAL_SECTION_START;
|
||||
// return character at index in buffer
|
||||
unsigned char data = buffer->dataptr[(buffer->dataindex+index)%(buffer->size)];
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
return data;
|
||||
}
|
||||
|
||||
unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data)
|
||||
{
|
||||
// begin critical section
|
||||
CRITICAL_SECTION_START;
|
||||
// make sure the buffer has room
|
||||
if(buffer->datalength < buffer->size)
|
||||
{
|
||||
// save data byte at end of buffer
|
||||
buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data;
|
||||
// increment the length
|
||||
buffer->datalength++;
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
// return success
|
||||
return -1;
|
||||
}
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
// return failure
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short bufferIsNotFull(cBuffer* buffer)
|
||||
{
|
||||
// begin critical section
|
||||
CRITICAL_SECTION_START;
|
||||
// check to see if the buffer has room
|
||||
// return true if there is room
|
||||
unsigned short bytesleft = (buffer->size - buffer->datalength);
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
return bytesleft;
|
||||
}
|
||||
|
||||
void bufferFlush(cBuffer* buffer)
|
||||
{
|
||||
// begin critical section
|
||||
CRITICAL_SECTION_START;
|
||||
// flush contents of the buffer
|
||||
buffer->datalength = 0;
|
||||
// end critical section
|
||||
CRITICAL_SECTION_END;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// buffer.h : Multipurpose byte buffer structure and methods
|
||||
//
|
||||
// This byte-buffer structure provides an easy and efficient way to store
|
||||
// and process a stream of bytes. You can create as many buffers as you
|
||||
// like (within memory limits), and then use this common set of functions to
|
||||
// access each buffer. The buffers are designed for FIFO operation (first
|
||||
// in, first out). This means that the first byte you put in the buffer
|
||||
// will be the first one you get when you read out the buffer. Supported
|
||||
// functions include buffer initialize, get byte from front of buffer, add
|
||||
// byte to end of buffer, check if buffer is full, and flush buffer. The
|
||||
// buffer uses a circular design so no copying of data is ever necessary.
|
||||
// This buffer is not dynamically allocated, it has a user-defined fixed
|
||||
// maximum size. This buffer is used in many places in the avrlib code.
|
||||
//
|
||||
// Copyright (c) 2001-2002 Pascal Stang
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef BUFFER_H
|
||||
#define BUFFER_H
|
||||
|
||||
// structure/typdefs
|
||||
|
||||
//! cBuffer structure
|
||||
typedef struct struct_cBuffer
|
||||
{
|
||||
unsigned char *dataptr; ///< the physical memory address where the buffer is stored
|
||||
unsigned short size; ///< the allocated size of the buffer
|
||||
unsigned short datalength; ///< the length of the data currently in the buffer
|
||||
unsigned short dataindex; ///< the index into the buffer where the data starts
|
||||
} cBuffer;
|
||||
|
||||
// function prototypes
|
||||
|
||||
//! initialize a buffer to start at a given address and have given size
|
||||
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size);
|
||||
|
||||
//! get the first byte from the front of the buffer
|
||||
unsigned char bufferGetFromFront(cBuffer* buffer);
|
||||
|
||||
//! dump (discard) the first numbytes from the front of the buffer
|
||||
void bufferDumpFromFront(cBuffer* buffer, unsigned short numbytes);
|
||||
|
||||
//! get a byte at the specified index in the buffer (kind of like array access)
|
||||
// ** note: this does not remove the byte that was read from the buffer
|
||||
unsigned char bufferGetAtIndex(cBuffer* buffer, unsigned short index);
|
||||
|
||||
//! add a byte to the end of the buffer
|
||||
unsigned char bufferAddToEnd(cBuffer* buffer, unsigned char data);
|
||||
|
||||
//! check if the buffer is full/not full (returns zero value if full)
|
||||
unsigned short bufferIsNotFull(cBuffer* buffer);
|
||||
|
||||
//! flush (clear) the contents of the buffer
|
||||
void bufferFlush(cBuffer* buffer);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// ctrl.c : AVR uC code for ctrl buffer initialisation and put/get ops
|
||||
//
|
||||
// Copyright (c) 2010 flukso.net
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include "global.h"
|
||||
#include "buffer.h"
|
||||
#include "ctrl.h"
|
||||
|
||||
cBuffer ctrlRxBuffer; // ctrl receive buffer
|
||||
cBuffer ctrlTxBuffer; // ctrl transmit buffer
|
||||
|
||||
static char ctrlRxData[CTRL_RX_BUFFER_SIZE];
|
||||
static char ctrlTxData[CTRL_TX_BUFFER_SIZE];
|
||||
|
||||
void ctrlInit(void) {
|
||||
// initialize the CTRL receive buffer
|
||||
bufferInit(&ctrlRxBuffer, (u08*) ctrlRxData, CTRL_RX_BUFFER_SIZE);
|
||||
// initialize the CTRL transmit buffer
|
||||
bufferInit(&ctrlTxBuffer, (u08*) ctrlTxData, CTRL_TX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
uint8_t ctrlAddToRxBuffer(uint8_t data) {
|
||||
return bufferAddToEnd(&ctrlRxBuffer, data);
|
||||
}
|
||||
|
||||
uint8_t ctrlGetFromTxBuffer(uint8_t* data) {
|
||||
// make sure we have data in the Tx buffer
|
||||
if(ctrlTxBuffer.datalength) {
|
||||
// get byte from beginning of buffer
|
||||
*data = bufferGetFromFront(&ctrlTxBuffer);
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
// no data
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ctrlAddToTxBuffer(uint8_t data) {
|
||||
return bufferAddToEnd(&ctrlTxBuffer, data);
|
||||
}
|
||||
|
||||
void ctrlLoop(void) {
|
||||
while (ctrlRxBuffer.datalength) {
|
||||
bufferAddToEnd(&ctrlTxBuffer, bufferGetFromFront(&ctrlRxBuffer));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// ctrl.h : AVR uC code for ctrl buffer initialisation and put/get ops
|
||||
//
|
||||
// Copyright (c) 2010 flukso.net
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef CTRL_H
|
||||
#define CTRL_H
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "buffer.h"
|
||||
|
||||
#ifndef CTRL_RX_BUFFER_SIZE
|
||||
#define CTRL_RX_BUFFER_SIZE 16
|
||||
#endif
|
||||
#ifndef CTRL_TX_BUFFER_SIZE
|
||||
#define CTRL_TX_BUFFER_SIZE 16
|
||||
#endif
|
||||
|
||||
void ctrlInit(void);
|
||||
|
||||
uint8_t ctrlAddToRxBuffer(uint8_t data);
|
||||
|
||||
uint8_t ctrlGetFromTxBuffer(uint8_t* data);
|
||||
|
||||
uint8_t ctrlAddToTxBuffer(uint8_t data);
|
||||
|
||||
void ctrlLoop(void);
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// global.h : AVR project global include
|
||||
//
|
||||
// Copyright (c) 2001-2002 Pascal Stang
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
// global AVRLIB defines
|
||||
#include "avrlibdefs.h"
|
||||
// global AVRLIB types definitions
|
||||
#include "avrlibtypes.h"
|
||||
|
||||
// project/system dependent defines
|
||||
|
||||
// CPU clock speed
|
||||
//#define F_CPU 16000000 // 16MHz processor
|
||||
//#define F_CPU 14745000 // 14.745MHz processor
|
||||
//#define F_CPU 8000000 // 8MHz processor
|
||||
//#define F_CPU 7372800 // 7.37MHz processor
|
||||
//#define F_CPU 4000000 // 4MHz processor
|
||||
//#define F_CPU 3686400 // 3.69MHz processor
|
||||
|
||||
#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond
|
||||
|
||||
#endif
|
|
@ -0,0 +1,524 @@
|
|||
#
|
||||
# makefile
|
||||
#
|
||||
# Copyright (c) Eric B. Weddington, Jörg Wunsch, et al.
|
||||
# Peter Fleury
|
||||
# Bart Van Der Meerssche
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# $Id$
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device, using avrdude.
|
||||
# Please customize the avrdude settings below first!
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# MCU name
|
||||
MCU = atmega48
|
||||
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
F_CPU = 1000000
|
||||
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = basiciotest
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = $(TARGET).c buffer.c uart.c spi.c ctrl.c
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC =
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
OPT = s
|
||||
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
||||
# AVR Studio 4.10 requires dwarf-2.
|
||||
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS =
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here
|
||||
CDEFS = -DF_CPU=$(F_CPU)UL
|
||||
|
||||
# uncomment and adapt these line if you want different UART library buffer size
|
||||
CDEFS += -DUART_RX_BUFFER_SIZE=32
|
||||
CDEFS += -DUART_TX_BUFFER_SIZE=32
|
||||
|
||||
CDEFS += -DUART_DEFAULT_BAUD_RATE=4800
|
||||
|
||||
# override default CTRL buffer sizes
|
||||
CDEFS += -DCTRL_RX_BUFFER_SIZE=16
|
||||
CDEFS += -DCTRL_TX_BUFFER_SIZE=16
|
||||
|
||||
# Place -I options here
|
||||
CINCS =
|
||||
|
||||
|
||||
|
||||
#---------------- Compiler Options ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS) $(CINCS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
CFLAGS += -Wall -Wstrict-prototypes
|
||||
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -ahlms: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||
|
||||
|
||||
#---------------- Library Options ----------------
|
||||
# Minimalistic printf version
|
||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
||||
|
||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard printf version.
|
||||
#PRINTF_LIB =
|
||||
PRINTF_LIB = $(PRINTF_LIB_MIN)
|
||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
||||
|
||||
|
||||
# Minimalistic scanf version
|
||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
||||
|
||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard scanf version.
|
||||
#SCANF_LIB =
|
||||
SCANF_LIB = $(SCANF_LIB_MIN)
|
||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
||||
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
|
||||
|
||||
#---------------- External Memory Options ----------------
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# used for variables (.data/.bss) and heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# only used for heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
EXTMEMOPTS =
|
||||
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += $(EXTMEMOPTS)
|
||||
#LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
||||
|
||||
|
||||
|
||||
#---------------- Programming Options (avrdude) ----------------
|
||||
|
||||
# Programming hardware: alf avr910 avrisp bascom bsd
|
||||
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
|
||||
#
|
||||
# Type: avrdude -c ?
|
||||
# to get a full listing.
|
||||
#
|
||||
AVRDUDE_PROGRAMMER = usbtiny
|
||||
|
||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||
AVRDUDE_PORT = /dev/ttyUSB* # programmer connected to serial device
|
||||
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
|
||||
|
||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||
# Note that this counter needs to be initialized first using -Yn,
|
||||
# see avrdude manual.
|
||||
#AVRDUDE_ERASE_COUNTER = -y
|
||||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level. Please use this when submitting bug
|
||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||
# to submit bug reports.
|
||||
#AVRDUDE_VERBOSE = -v -v
|
||||
|
||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||
|
||||
|
||||
|
||||
#---------------- Debugging Options ----------------
|
||||
|
||||
# For simulavr only - target MCU frequency.
|
||||
DEBUG_MFREQ = $(F_CPU)
|
||||
|
||||
# Set the DEBUG_UI to either gdb or insight.
|
||||
# DEBUG_UI = gdb
|
||||
DEBUG_UI = insight
|
||||
|
||||
# Set the debugging back-end to either avarice, simulavr.
|
||||
DEBUG_BACKEND = avarice
|
||||
#DEBUG_BACKEND = simulavr
|
||||
|
||||
# GDB Init Filename.
|
||||
GDBINIT_FILE = __avr_gdbinit
|
||||
|
||||
# When using avarice settings for the JTAG
|
||||
JTAG_DEV = /dev/com1
|
||||
|
||||
# Debugging port used to communicate between GDB / avarice / simulavr.
|
||||
DEBUG_PORT = 4242
|
||||
|
||||
# Debugging host used to communicate between GDB / avarice / simulavr, normally
|
||||
# just set to localhost unless doing some sort of crazy debugging when
|
||||
# avarice is running on a different computer.
|
||||
DEBUG_HOST = localhost
|
||||
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
NM = avr-nm
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
COPY = cp
|
||||
WINSHELL = cmd
|
||||
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_ERRORS_NONE = Errors: none
|
||||
MSG_BEGIN = -------- begin --------
|
||||
MSG_END = -------- end --------
|
||||
MSG_SIZE_BEFORE = Size before:
|
||||
MSG_SIZE_AFTER = Size after:
|
||||
MSG_COFF = Converting to AVR COFF:
|
||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
||||
MSG_FLASH = Creating load file for Flash:
|
||||
MSG_EEPROM = Creating load file for EEPROM:
|
||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
|
||||
|
||||
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(SRC:.c=.lst) $(ASRC:.S=.lst)
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: begin gccversion sizebefore build sizeafter end
|
||||
|
||||
build: elf hex eep lss sym
|
||||
|
||||
elf: $(TARGET).elf
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
|
||||
|
||||
|
||||
# Eye candy.
|
||||
# AVR Studio 3.x does not check make's exit code but relies on
|
||||
# the following magic strings to be generated by the compile job.
|
||||
begin:
|
||||
@echo
|
||||
@echo $(MSG_BEGIN)
|
||||
|
||||
end:
|
||||
@echo $(MSG_END)
|
||||
@echo
|
||||
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) -A $(TARGET).elf
|
||||
AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)
|
||||
|
||||
sizebefore:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
|
||||
$(AVRMEM) 2>/dev/null; echo; fi
|
||||
|
||||
sizeafter:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
|
||||
$(AVRMEM) 2>/dev/null; echo; fi
|
||||
|
||||
|
||||
|
||||
# Display compiler version information.
|
||||
gccversion :
|
||||
@$(CC) --version
|
||||
|
||||
|
||||
|
||||
# Program the device.
|
||||
program: $(TARGET).hex $(TARGET).eep
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
||||
|
||||
|
||||
# Generate avr-gdb config/init file which does the following:
|
||||
# define the reset signal, load the target file, connect to target, and set
|
||||
# a breakpoint at main().
|
||||
gdb-config:
|
||||
@$(REMOVE) $(GDBINIT_FILE)
|
||||
@echo define reset >> $(GDBINIT_FILE)
|
||||
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
|
||||
@echo end >> $(GDBINIT_FILE)
|
||||
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
|
||||
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
|
||||
ifeq ($(DEBUG_BACKEND),simulavr)
|
||||
@echo load >> $(GDBINIT_FILE)
|
||||
endif
|
||||
@echo break main >> $(GDBINIT_FILE)
|
||||
|
||||
debug: gdb-config $(TARGET).elf
|
||||
ifeq ($(DEBUG_BACKEND), avarice)
|
||||
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
|
||||
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
|
||||
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
|
||||
@$(WINSHELL) /c pause
|
||||
|
||||
else
|
||||
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
|
||||
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
|
||||
endif
|
||||
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
|
||||
|
||||
|
||||
|
||||
|
||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
||||
COFFCONVERT=$(OBJCOPY) --debugging \
|
||||
--change-section-address .data-0x800000 \
|
||||
--change-section-address .bss-0x800000 \
|
||||
--change-section-address .noinit-0x800000 \
|
||||
--change-section-address .eeprom-0x810000
|
||||
|
||||
|
||||
coff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
extcoff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
|
||||
# Create final output files (.hex, .eep) from ELF output file.
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EEPROM) $@
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.elf: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_LINKING) $@
|
||||
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
%.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
%.s : %.c
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
%.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
%.i : %.c
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
@echo
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) $(TARGET).hex
|
||||
$(REMOVE) $(TARGET).eep
|
||||
$(REMOVE) $(TARGET).cof
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(OBJ)
|
||||
$(REMOVE) $(LST)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) $(SRC:.c=.d)
|
||||
$(REMOVE) .dep/*
|
||||
|
||||
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
||||
build elf hex eep lss sym coff extcoff \
|
||||
clean clean_list program debug gdb-config
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <spi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#ifdef __ARDUINO__
|
||||
#include <wiring.h>
|
||||
#endif
|
||||
|
||||
void setup_spi(uint8_t mode, int dord, int interrupt, uint8_t clock)
|
||||
{
|
||||
// specify pin directions for SPI pins on port B
|
||||
if (clock == SPI_SLAVE) { // if slave SS and SCK is input
|
||||
DDRB &= ~(1<<SPI_MOSI_PIN); // input
|
||||
DDRB |= (1<<SPI_MISO_PIN); // output
|
||||
DDRB &= ~(1<<SPI_SS_PIN); // input
|
||||
DDRB &= ~(1<<SPI_SCK_PIN);// input
|
||||
} else {
|
||||
DDRB |= (1<<SPI_MOSI_PIN); // output
|
||||
DDRB &= ~(1<<SPI_MISO_PIN); // input
|
||||
DDRB |= (1<<SPI_SCK_PIN);// output
|
||||
DDRB |= (1<<SPI_SS_PIN);// output
|
||||
}
|
||||
SPCR = ((interrupt ? 1 : 0)<<SPIE) // interrupt enabled
|
||||
| (1<<SPE) // enable SPI
|
||||
| (dord<<DORD) // LSB or MSB
|
||||
| (((clock != SPI_SLAVE) ? 1 : 0) <<MSTR) // Slave or Master
|
||||
| (((mode & 0x02) == 2) << CPOL) // clock timing mode CPOL
|
||||
| (((mode & 0x01)) << CPHA) // clock timing mode CPHA
|
||||
| (((clock & 0x02) == 2) << SPR1) // cpu clock divisor SPR1
|
||||
| ((clock & 0x01) << SPR0); // cpu clock divisor SPR0
|
||||
SPSR = (((clock & 0x04) == 4) << SPI2X); // clock divisor SPI2X
|
||||
}
|
||||
|
||||
void disable_spi()
|
||||
{
|
||||
SPCR = 0;
|
||||
}
|
||||
|
||||
uint8_t send_spi(uint8_t out)
|
||||
{
|
||||
SPDR = out;
|
||||
while (!(SPSR & (1<<SPIF)));
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
uint8_t received_from_spi(uint8_t data)
|
||||
{
|
||||
SPDR = data;
|
||||
return SPDR;
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Andrew Smallbone <andrew@rocketnumbernine.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef _spi_h__
|
||||
#define _spi_h__
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
// create alias for the different SPI chip pins - code assumes all on port B
|
||||
#if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__))
|
||||
#define SPI_SS_PIN PORTB0
|
||||
#define SPI_SCK_PIN PORTB1
|
||||
#define SPI_MOSI_PIN PORTB2
|
||||
#define SPI_MISO_PIN PORTB3
|
||||
#elif (defined(__AVR_ATmega48__) || defined(_AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__))
|
||||
#define SPI_SS_PIN PORTB2
|
||||
#define SPI_SCK_PIN PORTB5
|
||||
#define SPI_MOSI_PIN PORTB3
|
||||
#define SPI_MISO_PIN PORTB4
|
||||
#else
|
||||
#error unknown processor - add to spi.h
|
||||
#endif
|
||||
|
||||
// SPI clock modes
|
||||
#define SPI_MODE_0 0x00 /* Sample (Rising) Setup (Falling) CPOL=0, CPHA=0 */
|
||||
#define SPI_MODE_1 0x01 /* Setup (Rising) Sample (Falling) CPOL=0, CPHA=1 */
|
||||
#define SPI_MODE_2 0x02 /* Sample (Falling) Setup (Rising) CPOL=1, CPHA=0 */
|
||||
#define SPI_MODE_3 0x03 /* Setup (Falling) Sample (Rising) CPOL=1, CPHA=1 */
|
||||
|
||||
// data direction
|
||||
#define SPI_LSB 1 /* send least significant bit (bit 0) first */
|
||||
#define SPI_MSB 0 /* send most significant bit (bit 7) first */
|
||||
|
||||
// whether to raise interrupt when data received (SPIF bit received)
|
||||
#define SPI_NO_INTERRUPT 0
|
||||
#define SPI_INTERRUPT 1
|
||||
|
||||
// slave or master with clock diviser
|
||||
#define SPI_SLAVE 0xF0
|
||||
#define SPI_MSTR_CLK4 0x00 /* chip clock/4 */
|
||||
#define SPI_MSTR_CLK16 0x01 /* chip clock/16 */
|
||||
#define SPI_MSTR_CLK64 0x02 /* chip clock/64 */
|
||||
#define SPI_MSTR_CLK128 0x03 /* chip clock/128 */
|
||||
#define SPI_MSTR_CLK2 0x04 /* chip clock/2 */
|
||||
#define SPI_MSTR_CLK8 0x05 /* chip clock/8 */
|
||||
#define SPI_MSTR_CLK32 0x06 /* chip clock/32 */
|
||||
|
||||
|
||||
|
||||
// setup spi
|
||||
void setup_spi(uint8_t mode, // timing mode SPI_MODE[0-4]
|
||||
int dord, // data direction SPI_LSB|SPI_MSB
|
||||
int interrupt, // whether to raise interrupt on recieve
|
||||
uint8_t clock); // clock diviser
|
||||
|
||||
// disable spi
|
||||
void disable_spi(void);
|
||||
|
||||
// send and receive a byte of data (master mode)
|
||||
uint8_t send_spi(uint8_t out);
|
||||
|
||||
// receive the byte of data waiting on the SPI buffer and
|
||||
// set the next byte to transfer - for use in slave mode
|
||||
// when interrupts are enabled.
|
||||
uint8_t received_from_spi(uint8_t out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
//
|
||||
// uart.c : UART driver with buffer support
|
||||
//
|
||||
// Copyright (c) 2000-2002 Pascal Stang
|
||||
// 2010 flukso.net
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "buffer.h"
|
||||
#include "uart.h"
|
||||
|
||||
// UART global variables
|
||||
// flag variables
|
||||
volatile u08 uartReadyTx; ///< uartReadyTx flag
|
||||
volatile u08 uartBufferedTx; ///< uartBufferedTx flag
|
||||
// receive and transmit buffers
|
||||
cBuffer uartRxBuffer; ///< uart receive buffer
|
||||
cBuffer uartTxBuffer; ///< uart transmit buffer
|
||||
unsigned short uartRxOverflow; ///< receive overflow counter
|
||||
|
||||
#ifndef UART_BUFFERS_EXTERNAL_RAM
|
||||
// using internal ram,
|
||||
// automatically allocate space in ram for each buffer
|
||||
static char uartRxData[UART_RX_BUFFER_SIZE];
|
||||
static char uartTxData[UART_TX_BUFFER_SIZE];
|
||||
#endif
|
||||
|
||||
typedef void (*voidFuncPtru08)(unsigned char);
|
||||
volatile static voidFuncPtru08 UartRxFunc;
|
||||
|
||||
// enable and initialize the uart
|
||||
void uartInit(void)
|
||||
{
|
||||
// initialize the buffers
|
||||
uartInitBuffers();
|
||||
// initialize user receive handler
|
||||
UartRxFunc = 0;
|
||||
|
||||
// enable RxD/TxD and interrupts
|
||||
outb(UCR, BV(RXCIE)|BV(RXEN)|BV(TXEN));
|
||||
|
||||
// set default baud rate
|
||||
uartSetBaudRate(UART_DEFAULT_BAUD_RATE);
|
||||
// initialize states
|
||||
uartReadyTx = TRUE;
|
||||
uartBufferedTx = FALSE;
|
||||
// clear overflow count
|
||||
uartRxOverflow = 0;
|
||||
// enable interrupts
|
||||
sei();
|
||||
}
|
||||
|
||||
// create and initialize the uart transmit and receive buffers
|
||||
void uartInitBuffers(void)
|
||||
{
|
||||
#ifndef UART_BUFFERS_EXTERNAL_RAM
|
||||
// initialize the UART receive buffer
|
||||
bufferInit(&uartRxBuffer, (u08*) uartRxData, UART_RX_BUFFER_SIZE);
|
||||
// initialize the UART transmit buffer
|
||||
bufferInit(&uartTxBuffer, (u08*) uartTxData, UART_TX_BUFFER_SIZE);
|
||||
#else
|
||||
// initialize the UART receive buffer
|
||||
bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE);
|
||||
// initialize the UART transmit buffer
|
||||
bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// redirects received data to a user function
|
||||
void uartSetRxHandler(void (*rx_func)(unsigned char c))
|
||||
{
|
||||
// set the receive interrupt to run the supplied user function
|
||||
UartRxFunc = rx_func;
|
||||
}
|
||||
|
||||
// set the uart baud rate
|
||||
void uartSetBaudRate(u32 baudrate)
|
||||
{
|
||||
// calculate division factor for requested baud rate, and set it
|
||||
u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
|
||||
outb(UBRRL, bauddiv);
|
||||
#ifdef UBRRH
|
||||
outb(UBRRH, bauddiv>>8);
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns the receive buffer structure
|
||||
cBuffer* uartGetRxBuffer(void)
|
||||
{
|
||||
// return rx buffer pointer
|
||||
return &uartRxBuffer;
|
||||
}
|
||||
|
||||
// returns the transmit buffer structure
|
||||
cBuffer* uartGetTxBuffer(void)
|
||||
{
|
||||
// return tx buffer pointer
|
||||
return &uartTxBuffer;
|
||||
}
|
||||
|
||||
// transmits a byte over the uart
|
||||
void uartSendByte(u08 txData)
|
||||
{
|
||||
// wait for the transmitter to be ready
|
||||
while(!uartReadyTx);
|
||||
// send byte
|
||||
outb(UDR, txData);
|
||||
// set ready state to FALSE
|
||||
uartReadyTx = FALSE;
|
||||
}
|
||||
|
||||
// gets a single byte from the uart receive buffer (getchar-style)
|
||||
int uartGetByte(void)
|
||||
{
|
||||
u08 c;
|
||||
if(uartReceiveByte(&c))
|
||||
return c;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// gets a byte (if available) from the uart receive buffer
|
||||
u08 uartReceiveByte(u08* rxData)
|
||||
{
|
||||
// make sure we have a receive buffer
|
||||
if(uartRxBuffer.size)
|
||||
{
|
||||
// make sure we have data
|
||||
if(uartRxBuffer.datalength)
|
||||
{
|
||||
// get byte from beginning of buffer
|
||||
*rxData = bufferGetFromFront(&uartRxBuffer);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no data
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no buffer
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// flush all data out of the receive buffer
|
||||
void uartFlushReceiveBuffer(void)
|
||||
{
|
||||
// flush all data from receive buffer
|
||||
//bufferFlush(&uartRxBuffer);
|
||||
// same effect as above
|
||||
uartRxBuffer.datalength = 0;
|
||||
}
|
||||
|
||||
// return true if uart receive buffer is empty
|
||||
u08 uartReceiveBufferIsEmpty(void)
|
||||
{
|
||||
if(uartRxBuffer.datalength == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// add byte to end of uart Tx buffer
|
||||
u08 uartAddToTxBuffer(u08 data)
|
||||
{
|
||||
u08 status;
|
||||
// add data byte to the end of the tx buffer
|
||||
status = bufferAddToEnd(&uartTxBuffer, data);
|
||||
// turn on buffered transmit
|
||||
uartBufferedTx = TRUE;
|
||||
// enable UDRIE0 interrupt
|
||||
UCR |= 1<<UDRIE0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// start transmission of the current uart Tx buffer contents
|
||||
void uartSendTxBuffer(void)
|
||||
{
|
||||
// turn on buffered transmit
|
||||
uartBufferedTx = TRUE;
|
||||
// send the first byte to get things going by interrupts
|
||||
uartSendByte(bufferGetFromFront(&uartTxBuffer));
|
||||
}
|
||||
/*
|
||||
// transmit nBytes from buffer out the uart
|
||||
u08 uartSendBuffer(char *buffer, u16 nBytes)
|
||||
{
|
||||
register u08 first;
|
||||
register u16 i;
|
||||
|
||||
// check if there's space (and that we have any bytes to send at all)
|
||||
if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
|
||||
{
|
||||
// grab first character
|
||||
first = *buffer++;
|
||||
// copy user buffer to uart transmit buffer
|
||||
for(i = 0; i < nBytes-1; i++)
|
||||
{
|
||||
// put data bytes at end of buffer
|
||||
bufferAddToEnd(&uartTxBuffer, *buffer++);
|
||||
}
|
||||
|
||||
// send the first byte to get things going by interrupts
|
||||
uartBufferedTx = TRUE;
|
||||
uartSendByte(first);
|
||||
// return success
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return failure
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// UART Transmit Complete Interrupt Handler
|
||||
UART_INTERRUPT_HANDLER(SIG_UART_DATA)
|
||||
{
|
||||
// check if buffered tx is enabled
|
||||
if(uartBufferedTx)
|
||||
{
|
||||
// check if there's data left in the buffer
|
||||
if(uartTxBuffer.datalength)
|
||||
{
|
||||
// send byte from top of buffer
|
||||
outb(UDR, bufferGetFromFront(&uartTxBuffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
// no data left
|
||||
uartBufferedTx = FALSE;
|
||||
// return to ready state
|
||||
uartReadyTx = TRUE;
|
||||
// disable TXCIE0 interrupt
|
||||
UCR &= ~(1<<UDRIE0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we're using single-byte tx mode
|
||||
// indicate transmit complete, back to ready
|
||||
uartReadyTx = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// UART Receive Complete Interrupt Handler
|
||||
UART_INTERRUPT_HANDLER(SIG_UART_RECV)
|
||||
{
|
||||
u08 c;
|
||||
|
||||
// get received char
|
||||
c = inb(UDR);
|
||||
|
||||
// if there's a user function to handle this receive event
|
||||
if(UartRxFunc)
|
||||
{
|
||||
// call it and pass the received data
|
||||
UartRxFunc(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise do default processing
|
||||
// put received char in buffer
|
||||
// check if there's space
|
||||
if( !bufferAddToEnd(&uartRxBuffer, c) )
|
||||
{
|
||||
// no space in buffer
|
||||
// count overflow
|
||||
uartRxOverflow++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,231 @@
|
|||
//
|
||||
// uart.h : UART driver with buffer support
|
||||
//
|
||||
// This library provides both buffered and unbuffered transmit and receive
|
||||
// functions for the AVR processor UART.<2E> Buffered access means that the
|
||||
// UART can transmit and receive data in the "background", while your code
|
||||
// continues executing.<2E> Also included are functions to initialize the
|
||||
// UART, set the baud rate, flush the buffers, and check buffer status.
|
||||
//
|
||||
// For full text output functionality, you may wish to use the rprintf
|
||||
// functions along with this driver.
|
||||
//
|
||||
// Most Atmel AVR-series processors contain one or more hardware UARTs
|
||||
// (aka, serial ports). UART serial ports can communicate with other
|
||||
// serial ports of the same type, like those used on PCs. In general,
|
||||
// UARTs are used to communicate with devices that are RS-232 compatible
|
||||
// (RS-232 is a certain kind of serial port).
|
||||
//
|
||||
// By far, the most common use for serial communications on AVR processors
|
||||
// is for sending information and data to a PC running a terminal program.
|
||||
// Here is an exmaple:
|
||||
// uartInit(); // initialize UART (serial port)
|
||||
// uartSetBaudRate(9600); // set UART speed to 9600 baud
|
||||
// rprintfInit(uartSendByte); // configure rprintf to use UART for output
|
||||
// rprintf("Hello World\r\n"); // send "hello world" message via serial port
|
||||
//
|
||||
// The CPU frequency (F_CPU) must be set correctly in \c global.h
|
||||
// for the UART library to calculate correct baud rates. Furthermore,
|
||||
// certain CPU frequencies will not produce exact baud rates due to
|
||||
// integer frequency division round-off. See your AVR processor's
|
||||
// datasheet for full details.
|
||||
//
|
||||
// Copyright (c) 2000-2002 Pascal Stang
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
#include "global.h"
|
||||
#include "buffer.h"
|
||||
|
||||
//! Default uart baud rate.
|
||||
/// This is the default speed after a uartInit() command,
|
||||
/// and can be changed by using uartSetBaudRate().
|
||||
#ifndef UART_DEFAULT_BAUD_RATE
|
||||
#define UART_DEFAULT_BAUD_RATE 9600
|
||||
#endif
|
||||
|
||||
// buffer memory allocation defines
|
||||
// buffer sizes
|
||||
#ifndef UART_TX_BUFFER_SIZE
|
||||
//! Number of bytes for uart transmit buffer.
|
||||
/// Do not change this value in uart.h, but rather override
|
||||
/// it with the desired value defined in your project's global.h
|
||||
#define UART_TX_BUFFER_SIZE 0x0040
|
||||
#endif
|
||||
#ifndef UART_RX_BUFFER_SIZE
|
||||
//! Number of bytes for uart receive buffer.
|
||||
/// Do not change this value in uart.h, but rather override
|
||||
/// it with the desired value defined in your project's global.h
|
||||
#define UART_RX_BUFFER_SIZE 0x0040
|
||||
#endif
|
||||
|
||||
// define this key if you wish to use
|
||||
// external RAM for the UART buffers
|
||||
//#define UART_BUFFER_EXTERNAL_RAM
|
||||
#ifdef UART_BUFFER_EXTERNAL_RAM
|
||||
// absolute address of uart buffers
|
||||
#define UART_TX_BUFFER_ADDR 0x1000
|
||||
#define UART_RX_BUFFER_ADDR 0x1100
|
||||
#endif
|
||||
|
||||
//! Type of interrupt handler to use for uart interrupts.
|
||||
/// Value may be SIGNAL or INTERRUPT.
|
||||
/// \warning Do not change unless you know what you're doing.
|
||||
#ifndef UART_INTERRUPT_HANDLER
|
||||
#define UART_INTERRUPT_HANDLER SIGNAL
|
||||
#endif
|
||||
|
||||
// compatibility with most newer processors
|
||||
#ifdef UCSRB
|
||||
#define UCR UCSRB
|
||||
#endif
|
||||
// compatibility with old Mega processors
|
||||
#if defined(UBRR) && !defined(UBRRL)
|
||||
#define UBRRL UBRR
|
||||
#endif
|
||||
// compatibility with megaXX8 processors
|
||||
#if defined(__AVR_ATmega48__) || \
|
||||
defined(__AVR_ATmega88__) || \
|
||||
defined(__AVR_ATmega168__) || \
|
||||
defined(__AVR_ATmega644__)
|
||||
#define UDR UDR0
|
||||
#define UCR UCSR0B
|
||||
#define RXCIE RXCIE0
|
||||
#define TXCIE TXCIE0
|
||||
#define RXC RXC0
|
||||
#define TXC TXC0
|
||||
#define RXEN RXEN0
|
||||
#define TXEN TXEN0
|
||||
#define UBRRL UBRR0L
|
||||
#define UBRRH UBRR0H
|
||||
#define SIG_UART_TRANS SIG_USART_TRANS
|
||||
#define SIG_UART_RECV SIG_USART_RECV
|
||||
#define SIG_UART_DATA SIG_USART_DATA
|
||||
#endif
|
||||
// compatibility with mega169 processors
|
||||
#if defined(__AVR_ATmega169__)
|
||||
#define SIG_UART_TRANS SIG_USART_TRANS
|
||||
#define SIG_UART_RECV SIG_USART_RECV
|
||||
#define SIG_UART_DATA SIG_USART_DATA
|
||||
#endif
|
||||
// compatibility with dual-uart processors
|
||||
// (if you need to use both uarts, please use the uart2 library)
|
||||
#if defined(__AVR_ATmega161__)
|
||||
#define UDR UDR0
|
||||
#define UCR UCSR0B
|
||||
#define UBRRL UBRR0
|
||||
#define SIG_UART_TRANS SIG_UART0_TRANS
|
||||
#define SIG_UART_RECV SIG_UART0_RECV
|
||||
#define SIG_UART_DATA SIG_UART0_DATA
|
||||
#endif
|
||||
#if defined(__AVR_ATmega128__)
|
||||
#ifdef UART_USE_UART1
|
||||
#define UDR UDR1
|
||||
#define UCR UCSR1B
|
||||
#define UBRRL UBRR1L
|
||||
#define UBRRH UBRR1H
|
||||
#define SIG_UART_TRANS SIG_UART1_TRANS
|
||||
#define SIG_UART_RECV SIG_UART1_RECV
|
||||
#define SIG_UART_DATA SIG_UART1_DATA
|
||||
#else
|
||||
#define UDR UDR0
|
||||
#define UCR UCSR0B
|
||||
#define UBRRL UBRR0L
|
||||
#define UBRRH UBRR0H
|
||||
#define SIG_UART_TRANS SIG_UART0_TRANS
|
||||
#define SIG_UART_RECV SIG_UART0_RECV
|
||||
#define SIG_UART_DATA SIG_UART0_DATA
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// functions
|
||||
|
||||
//! Initializes uart.
|
||||
/// \note After running this init function, the processor
|
||||
/// I/O pins that used for uart communications (RXD, TXD)
|
||||
/// are no long available for general purpose I/O.
|
||||
void uartInit(void);
|
||||
|
||||
//! Initializes transmit and receive buffers.
|
||||
/// Automatically called from uartInit()
|
||||
void uartInitBuffers(void);
|
||||
|
||||
//! Redirects received data to a user function.
|
||||
///
|
||||
void uartSetRxHandler(void (*rx_func)(unsigned char c));
|
||||
|
||||
//! Sets the uart baud rate.
|
||||
/// Argument should be in bits-per-second, like \c uartSetBaudRate(9600);
|
||||
void uartSetBaudRate(u32 baudrate);
|
||||
|
||||
//! Returns pointer to the receive buffer structure.
|
||||
///
|
||||
cBuffer* uartGetRxBuffer(void);
|
||||
|
||||
//! Returns pointer to the transmit buffer structure.
|
||||
///
|
||||
cBuffer* uartGetTxBuffer(void);
|
||||
|
||||
//! Sends a single byte over the uart.
|
||||
/// \note This function waits for the uart to be ready,
|
||||
/// therefore, consecutive calls to uartSendByte() will
|
||||
/// go only as fast as the data can be sent over the
|
||||
/// serial port.
|
||||
void uartSendByte(u08 data);
|
||||
|
||||
//! Gets a single byte from the uart receive buffer.
|
||||
/// Returns the byte, or -1 if no byte is available (getchar-style).
|
||||
int uartGetByte(void);
|
||||
|
||||
//! Gets a single byte from the uart receive buffer.
|
||||
/// Function returns TRUE if data was available, FALSE if not.
|
||||
/// Actual data is returned in variable pointed to by "data".
|
||||
/// Example usage:
|
||||
/// \code
|
||||
/// char myReceivedByte;
|
||||
/// uartReceiveByte( &myReceivedByte );
|
||||
/// \endcode
|
||||
u08 uartReceiveByte(u08* data);
|
||||
|
||||
//! Returns TRUE/FALSE if receive buffer is empty/not-empty.
|
||||
///
|
||||
u08 uartReceiveBufferIsEmpty(void);
|
||||
|
||||
//! Flushes (deletes) all data from receive buffer.
|
||||
///
|
||||
void uartFlushReceiveBuffer(void);
|
||||
|
||||
//! Add byte to end of uart Tx buffer.
|
||||
/// Returns TRUE if successful, FALSE if failed (no room left in buffer).
|
||||
u08 uartAddToTxBuffer(u08 data);
|
||||
|
||||
//! Begins transmission of the transmit buffer under interrupt control.
|
||||
///
|
||||
void uartSendTxBuffer(void);
|
||||
|
||||
//! Sends a block of data via the uart using interrupt control.
|
||||
/// \param buffer pointer to data to be sent
|
||||
/// \param nBytes length of data (number of bytes to sent)
|
||||
u08 uartSendBuffer(char *buffer, u16 nBytes);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue