Skip to content
Browse files

init

  • Loading branch information...
0 parents commit 08a24ccd784e69fa1aabc7499dacb6a3d85948bd @kiu committed Aug 10, 2012
3 errata.txt
@@ -0,0 +1,3 @@
+PCB
+ - USB connector footprint is missing two holes
+ - LED, C2 and ISP silkscreen missing orientation marker
11 firmware/lib/global.h
@@ -0,0 +1,11 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#ifndef cbi
+ #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
+#endif
+#ifndef sbi
+ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
+#endif
+
+#endif
285 firmware/lib/rfm12/rfm12.c
@@ -0,0 +1,285 @@
+#include <stdio.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+
+#include "rfm12_config.h"
+#include "rfm12.h"
+#include "../global.h"
+
+struct RFM12_stati {
+ unsigned char Rx:1;
+ unsigned char Tx:1;
+ unsigned char New:1;
+};
+
+struct RFM12_stati RFM12_status;
+volatile unsigned char RFM12_Index = 0;
+unsigned char RFM12_Data[RFM12_DATA_LENGTH + 10]; // +10 == paket overhead
+
+// -----------------------------------------------------------------------------
+
+unsigned int crcUpdate(unsigned int crc, unsigned char data) {
+ unsigned int tmp;
+ unsigned char i;
+
+ tmp = data << 8;
+ for (i=0; i<8; i++) {
+ if ((crc^tmp) & 0x8000) {
+ crc = (crc<<1) ^ 0x1021;
+ } else {
+ crc = crc << 1;
+ }
+ tmp = tmp << 1;
+ }
+ return crc;
+}
+
+ISR(RFM12_IRQ_VECT) {
+ if(RFM12_status.Rx) {
+ if(RFM12_Index < RFM12_DATA_LENGTH) {
+ unsigned char c = rfm12_trans(0xB000) & 0x00FF;
+ if (RFM12_Index == 0 && c > RFM12_DATA_LENGTH) {
+ c = RFM12_DATA_LENGTH;
+ }
+ RFM12_Data[RFM12_Index++] = c;
+ } else {
+ rfm12_trans(0x8208);
+ RFM12_status.Rx = 0;
+ }
+ if(RFM12_Index >= RFM12_Data[0] + 3) { //EOT
+ rfm12_trans(0x8208);
+ RFM12_status.Rx = 0;
+ RFM12_status.New = 1;
+ }
+ } else if(RFM12_status.Tx) {
+ rfm12_trans(0xB800 | RFM12_Data[RFM12_Index]);
+ if(!RFM12_Index) {
+ RFM12_status.Tx = 0;
+ rfm12_trans(0x8208); // TX off
+ } else {
+ RFM12_Index--;
+ }
+ } else {
+ rfm12_trans(0x0000); //dummy read
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+unsigned short rfm12_trans(unsigned short dataOut) {
+ unsigned char i;
+ unsigned short dataIn = 0;
+
+ cbi(RFM12_SPI_PORT, RFM12_SPI_CS);
+ for (i=0; i<16; i++) {
+ if (dataOut & 32768) {
+ sbi(RFM12_SPI_PORT, RFM12_SPI_SDI);
+ } else {
+ cbi(RFM12_SPI_PORT, RFM12_SPI_SDI);
+ }
+ dataIn<<=1;
+ if (RFM12_SPI_PIN & (1<<RFM12_SPI_SDO)) {
+ dataIn |= 1;
+ }
+ sbi(RFM12_SPI_PORT, RFM12_SPI_SCK);
+ dataOut <<= 1;
+ asm("nop");
+ cbi(RFM12_SPI_PORT, RFM12_SPI_SCK);
+ }
+ sbi(RFM12_SPI_PORT, RFM12_SPI_CS);
+
+ return dataIn;
+}
+
+// -----------------------------------------------------------------------------
+
+void rfm12_reset(void) {
+ sbi(RFM12_RESET_PORT, RFM12_RESET);
+ _delay_ms(200);
+
+ cbi(RFM12_RESET_PORT, RFM12_RESET);
+ _delay_ms(10);
+
+ sbi(RFM12_RESET_PORT, RFM12_RESET);
+ _delay_ms(200);
+}
+
+void rfm12_init(void) {
+ RFM12_RESET_DDR |= (1<<RFM12_RESET);
+
+ sbi(RFM12_SPI_DDR, RFM12_SPI_SDI);
+ sbi(RFM12_SPI_DDR, RFM12_SPI_SCK);
+ sbi(RFM12_SPI_DDR, RFM12_SPI_CS);
+ cbi(RFM12_SPI_DDR, RFM12_SPI_SDO);
+ sbi(RFM12_SPI_PORT, RFM12_SPI_CS);
+
+ cbi(RFM12_IRQ_DDR, RFM12_IRQ);
+
+ rfm12_reset();
+
+ rfm12_trans(0x0000);
+// rfm12_trans(0x80D8); // Enable FIFO
+
+ rfm12_trans(0xC0E0); // AVR CLK: 10MHz
+ rfm12_trans(0x80D7); // Enable FIFO
+ rfm12_trans(0xC2AB); // Data Filter: internal
+ rfm12_trans(0xCA81); // Set FIFO mode
+ rfm12_trans(0xE000); // disable wakeuptimer
+ rfm12_trans(0xC800); // disable low duty cycle
+ rfm12_trans(0xC4F7); // AFC settings: autotuning: -10kHz...+7,5kHz
+
+ rfm12_trans(0x0000);
+
+ RFM12_status.Rx = 0;
+ RFM12_status.Tx = 0;
+ RFM12_status.New = 0;
+
+ sbi(MCUCR, RFM12_IRQ_SENSE);
+ sbi(GICR, RFM12_IRQ_INT);
+}
+
+// -----------------------------------------------------------------------------
+
+void rfm12_setbandwidth(unsigned char bandwidth, unsigned char gain, unsigned char drssi) {
+ rfm12_trans(0x9400|((bandwidth&7)<<5)|((gain&3)<<3)|(drssi&7));
+}
+
+void rfm12_setfreq(unsigned short freq) {
+ if (freq<96) { // 430,2400MHz
+ freq=96;
+ }
+ if (freq>3903) { // 439,7575MHz
+ freq=3903;
+ }
+ rfm12_trans(0xA000|freq);
+}
+
+void rfm12_setbaud(unsigned short baud) {
+ if (baud<663) {
+ return;
+ }
+ if (baud<5400) { // Baudrate= 344827,58621/(R+1)/(1+CS*7)
+ rfm12_trans(0xC680|((43104/baud)-1));
+ } else {
+ rfm12_trans(0xC600|((344828UL/baud)-1));
+ }
+}
+
+void rfm12_setpower(unsigned char power, unsigned char mod) {
+ rfm12_trans(0x9800|(power&7)|((mod&15)<<4));
+}
+
+// -----------------------------------------------------------------------------
+
+unsigned char rfm12_rxstart(void) {
+ if(RFM12_status.New) {
+ return(1); // buffer not yet empty
+ }
+ if(RFM12_status.Tx) {
+ return(2); // tx in action
+ }
+ if(RFM12_status.Rx) {
+ return(3); // rx already in action
+ }
+
+ rfm12_trans(0x82C8); // RX on
+ rfm12_trans(0xCA81); // set FIFO mode
+ rfm12_trans(0xCA83); // enable FIFO
+
+ RFM12_Index = 0;
+ RFM12_status.Rx = 1;
+
+ return(0);
+}
+
+unsigned char rfm12_rxfinish(unsigned char *data) {
+ unsigned int crc, crc_chk = 0;
+ unsigned char i;
+
+ if(RFM12_status.Rx) {
+ return(255); // not finished yet
+ }
+ if(!RFM12_status.New) {
+ return(254); // old buffer
+ }
+
+ for(i=0; i<RFM12_Data[0] + 1; i++) {
+ crc_chk = crcUpdate(crc_chk, RFM12_Data[i]);
+ }
+
+ crc = RFM12_Data[i++];
+ crc |= RFM12_Data[i] << 8;
+
+ RFM12_status.New = 0;
+
+ if(crc != crc_chk) {
+ return(0); //crc err -or- strsize
+ }
+
+ for(i=0; i<RFM12_Data[0]; i++) {
+ data[i] = RFM12_Data[i+1];
+ }
+
+ return(RFM12_Data[0]); // strsize
+}
+
+// -----------------------------------------------------------------------------
+
+unsigned char rfm12_txstart(unsigned char *data, unsigned char size) {
+ unsigned char i, l;
+ unsigned int crc;
+
+ if(RFM12_status.Tx) {
+ return(2); // tx in action
+ }
+ if(RFM12_status.Rx) {
+ return(3); // rx already in action
+ }
+ if(size > RFM12_DATA_LENGTH) {
+ return(4); // str to big to transmit
+ }
+
+ RFM12_status.Tx = 1;
+ RFM12_Index = size + 9; // act -10
+
+ i = RFM12_Index;
+ RFM12_Data[i--] = 0xAA;
+ RFM12_Data[i--] = 0xAA;
+ RFM12_Data[i--] = 0xAA;
+ RFM12_Data[i--] = 0x2D;
+ RFM12_Data[i--] = 0xD4;
+ RFM12_Data[i--] = size;
+ crc = crcUpdate(0, size);
+ for(l=0; l<size; l++) {
+ RFM12_Data[i--] = data[l];
+ crc = crcUpdate(crc, data[l]);
+ }
+ RFM12_Data[i--] = (crc & 0x00FF);
+ RFM12_Data[i--] = (crc >> 8);
+ RFM12_Data[i--] = 0xAA;
+ RFM12_Data[i--] = 0xAA;
+
+ rfm12_trans(0x8238); // TX on
+
+ return(0);
+}
+
+unsigned char rfm12_txfinished(void) {
+ if(RFM12_status.Tx) {
+ return(255); // not yet finished
+ }
+ return(0);
+}
+
+// -----------------------------------------------------------------------------
+
+void rfm12_allstop(void) {
+ rfm12_trans(0x8208); // shutdown all
+ RFM12_status.Rx = 0;
+ RFM12_status.Tx = 0;
+ RFM12_status.New = 0;
+ rfm12_trans(0x0000); // dummy read
+}
+
+// -----------------------------------------------------------------------------
98 firmware/lib/rfm12/rfm12.h
@@ -0,0 +1,98 @@
+#ifndef RFM12_H
+#define RFM12_H
+
+#include "rfm12_config.h"
+
+#define RxBW400 1
+#define RxBW340 2
+#define RxBW270 3
+#define RxBW200 4
+#define RxBW134 5
+#define RxBW67 6
+
+#define TxBW15 0
+#define TxBW30 1
+#define TxBW45 2
+#define TxBW60 3
+#define TxBW75 4
+#define TxBW90 5
+#define TxBW105 6
+#define TxBW120 7
+
+#define LNA_0 0
+#define LNA_6 1
+#define LNA_14 2
+#define LNA_20 3
+
+#define RSSI_103 0
+#define RSSI_97 1
+#define RSSI_91 2
+#define RSSI_85 3
+#define RSSI_79 4
+#define RSSI_73 5
+#define RSSI_67 6
+#define RSSI_61 7
+
+#define PWRdB_0 0
+#define PWRdB_3 1
+#define PWRdB_6 2
+#define PWRdB_9 3
+#define PWRdB_12 4
+#define PWRdB_15 5
+#define PWRdB_18 6
+#define PWRdB_21 7
+
+#define RFM12_TxBDW(kfrq) ((unsigned char)(kfrq/15)-1)
+#define RFM12_FREQ(freq) ((freq-430.0)/0.0025)
+
+// -----------------------------------------------------------------------------
+
+// reset module
+void rfm12_reset(void);
+
+// initialize module
+void rfm12_init(void);
+
+// -----------------------------------------------------------------------------
+
+// transfer 1 word to/from module
+unsigned short rfm12_trans(unsigned short data);
+
+// -----------------------------------------------------------------------------
+
+// set center frequency
+void rfm12_setfreq(unsigned short freq);
+
+// set baudrate
+void rfm12_setbaud(unsigned short baud);
+
+// set transmission settings
+void rfm12_setpower(unsigned char power, unsigned char mod);
+
+// set receiver settings
+void rfm12_setbandwidth(unsigned char bandwidth, unsigned char gain, unsigned char drssi);
+
+// -----------------------------------------------------------------------------
+
+// start receiving a package
+unsigned char rfm12_rxstart(void);
+
+// readout the package, if one arrived
+unsigned char rfm12_rxfinish(unsigned char *data);
+
+// -----------------------------------------------------------------------------
+
+// start transmitting a package of size size
+unsigned char rfm12_txstart(unsigned char *data, unsigned char size);
+
+// check whether the package is already transmitted
+unsigned char rfm12_txfinished(void);
+
+// -----------------------------------------------------------------------------
+
+// stop all Rx and Tx operations
+void rfm12_allstop(void);
+
+// -----------------------------------------------------------------------------
+
+#endif
25 firmware/lib/rfm12/rfm12_config.h
@@ -0,0 +1,25 @@
+#ifndef __RFM12_CONFIG_H
+#define __RFM12_CONFIG_H
+
+#define RFM12_DATA_LENGTH 244 // Max 254 - 10
+
+#define RFM12_SPI_PORT PORTB
+#define RFM12_SPI_PIN PINB
+#define RFM12_SPI_DDR DDRB
+#define RFM12_SPI_SDI 3
+#define RFM12_SPI_SCK 5
+#define RFM12_SPI_CS 2
+#define RFM12_SPI_SDO 4
+
+#define RFM12_RESET_PORT PORTD
+#define RFM12_RESET_DDR DDRD
+#define RFM12_RESET PD3
+
+#define RFM12_IRQ_PORT PORTD
+#define RFM12_IRQ_DDR DDRD
+#define RFM12_IRQ 2
+#define RFM12_IRQ_INT INT0
+#define RFM12_IRQ_VECT INT0_vect
+#define RFM12_IRQ_SENSE ISC01 // falling edge
+
+#endif
651 firmware/lib/uart/uart.c
@@ -0,0 +1,651 @@
+/*************************************************************************
+Title: Interrupt UART library with receive/transmit circular buffers
+Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
+File: $Id: uart.c,v 1.6.2.1 2007/07/01 11:14:38 peter Exp $
+Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
+Hardware: any AVR with built-in UART,
+License: GNU General Public License
+
+DESCRIPTION:
+ An interrupt is generated when the UART has finished transmitting or
+ receiving a byte. The interrupt handling routines use circular buffers
+ for buffering received and transmitted data.
+
+ The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
+ the buffer size in bytes. Note that these variables must be a
+ power of 2.
+
+USAGE:
+ Refere to the header file uart.h for a description of the routines.
+ See also example test_uart.c.
+
+NOTES:
+ Based on Atmel Application Note AVR306
+
+LICENSE:
+ Copyright (C) 2006 Peter Fleury
+
+ 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
+ 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.
+
+*************************************************************************/
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include "uart.h"
+
+
+/*
+ * constants and macros
+ */
+
+/* size of RX/TX buffers */
+#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
+#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
+
+#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
+#error RX buffer size is not a power of 2
+#endif
+#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
+#error TX buffer size is not a power of 2
+#endif
+
+#if defined(__AVR_AT90S2313__) \
+ || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
+ || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
+ || defined(__AVR_ATmega103__)
+ /* old AVR classic or ATmega103 with one UART */
+ #define AT90_UART
+ #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
+ #define UART0_STATUS USR
+ #define UART0_CONTROL UCR
+ #define UART0_DATA UDR
+ #define UART0_UDRIE UDRIE
+#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
+ /* old AVR classic with one UART */
+ #define AT90_UART
+ #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
+ #define UART0_STATUS UCSRA
+ #define UART0_CONTROL UCSRB
+ #define UART0_DATA UDR
+ #define UART0_UDRIE UDRIE
+#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
+ || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
+ || defined(__AVR_ATmega323__)
+ /* ATmega with one USART */
+ #define ATMEGA_USART
+ #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
+ #define UART0_STATUS UCSRA
+ #define UART0_CONTROL UCSRB
+ #define UART0_DATA UDR
+ #define UART0_UDRIE UDRIE
+#elif defined(__AVR_ATmega163__)
+ /* ATmega163 with one UART */
+ #define ATMEGA_UART
+ #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
+ #define UART0_STATUS UCSRA
+ #define UART0_CONTROL UCSRB
+ #define UART0_DATA UDR
+ #define UART0_UDRIE UDRIE
+#elif defined(__AVR_ATmega162__)
+ /* ATmega with two USART */
+ #define ATMEGA_USART0
+ #define ATMEGA_USART1
+ #define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV
+ #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA
+ #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
+ #define UART0_STATUS UCSR0A
+ #define UART0_CONTROL UCSR0B
+ #define UART0_DATA UDR0
+ #define UART0_UDRIE UDRIE0
+ #define UART1_STATUS UCSR1A
+ #define UART1_CONTROL UCSR1B
+ #define UART1_DATA UDR1
+ #define UART1_UDRIE UDRIE1
+#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
+ /* ATmega with two USART */
+ #define ATMEGA_USART0
+ #define ATMEGA_USART1
+ #define UART0_RECEIVE_INTERRUPT SIG_UART0_RECV
+ #define UART1_RECEIVE_INTERRUPT SIG_UART1_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_UART0_DATA
+ #define UART1_TRANSMIT_INTERRUPT SIG_UART1_DATA
+ #define UART0_STATUS UCSR0A
+ #define UART0_CONTROL UCSR0B
+ #define UART0_DATA UDR0
+ #define UART0_UDRIE UDRIE0
+ #define UART1_STATUS UCSR1A
+ #define UART1_CONTROL UCSR1B
+ #define UART1_DATA UDR1
+ #define UART1_UDRIE UDRIE1
+#elif defined(__AVR_ATmega161__)
+ /* ATmega with UART */
+ #error "AVR ATmega161 currently not supported by this libaray !"
+#elif defined(__AVR_ATmega169__)
+ /* ATmega with one USART */
+ #define ATMEGA_USART
+ #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
+ #define UART0_STATUS UCSRA
+ #define UART0_CONTROL UCSRB
+ #define UART0_DATA UDR
+ #define UART0_UDRIE UDRIE
+#elif defined(__AVR_ATmega48__) ||defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
+ /* ATmega with one USART */
+ #define ATMEGA_USART0
+ #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
+ #define UART0_STATUS UCSR0A
+ #define UART0_CONTROL UCSR0B
+ #define UART0_DATA UDR0
+ #define UART0_UDRIE UDRIE0
+#elif defined(__AVR_ATtiny2313__)
+ #define ATMEGA_USART
+ #define UART0_RECEIVE_INTERRUPT SIG_USART0_RX
+ #define UART0_TRANSMIT_INTERRUPT SIG_USART0_UDRE
+ #define UART0_STATUS UCSRA
+ #define UART0_CONTROL UCSRB
+ #define UART0_DATA UDR
+ #define UART0_UDRIE UDRIE
+#elif defined(__AVR_ATmega329__) ||defined(__AVR_ATmega3290__) ||\
+ defined(__AVR_ATmega649__) ||defined(__AVR_ATmega6490__) ||\
+ defined(__AVR_ATmega325__) ||defined(__AVR_ATmega3250__) ||\
+ defined(__AVR_ATmega645__) ||defined(__AVR_ATmega6450__)
+ /* ATmega with one USART */
+ #define ATMEGA_USART0
+ #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
+ #define UART0_STATUS UCSR0A
+ #define UART0_CONTROL UCSR0B
+ #define UART0_DATA UDR0
+ #define UART0_UDRIE UDRIE0
+#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega640__)
+/* ATmega with two USART */
+ #define ATMEGA_USART0
+ #define ATMEGA_USART1
+ #define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV
+ #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA
+ #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
+ #define UART0_STATUS UCSR0A
+ #define UART0_CONTROL UCSR0B
+ #define UART0_DATA UDR0
+ #define UART0_UDRIE UDRIE0
+ #define UART1_STATUS UCSR1A
+ #define UART1_CONTROL UCSR1B
+ #define UART1_DATA UDR1
+ #define UART1_UDRIE UDRIE1
+#elif defined(__AVR_ATmega644__)
+ /* ATmega with one USART */
+ #define ATMEGA_USART0
+ #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
+ #define UART0_STATUS UCSR0A
+ #define UART0_CONTROL UCSR0B
+ #define UART0_DATA UDR0
+ #define UART0_UDRIE UDRIE0
+#elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
+ /* ATmega with two USART */
+ #define ATMEGA_USART0
+ #define ATMEGA_USART1
+ #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
+ #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
+ #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
+ #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
+ #define UART0_STATUS UCSR0A
+ #define UART0_CONTROL UCSR0B
+ #define UART0_DATA UDR0
+ #define UART0_UDRIE UDRIE0
+ #define UART1_STATUS UCSR1A
+ #define UART1_CONTROL UCSR1B
+ #define UART1_DATA UDR1
+ #define UART1_UDRIE UDRIE1
+#else
+ #error "no UART definition for MCU available"
+#endif
+
+
+/*
+ * module global variables
+ */
+static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
+static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
+static volatile unsigned char UART_TxHead;
+static volatile unsigned char UART_TxTail;
+static volatile unsigned char UART_RxHead;
+static volatile unsigned char UART_RxTail;
+static volatile unsigned char UART_LastRxError;
+
+#if defined( ATMEGA_USART1 )
+static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
+static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
+static volatile unsigned char UART1_TxHead;
+static volatile unsigned char UART1_TxTail;
+static volatile unsigned char UART1_RxHead;
+static volatile unsigned char UART1_RxTail;
+static volatile unsigned char UART1_LastRxError;
+#endif
+
+
+
+SIGNAL(UART0_RECEIVE_INTERRUPT)
+/*************************************************************************
+Function: UART Receive Complete interrupt
+Purpose: called when the UART has received a character
+**************************************************************************/
+{
+ unsigned char tmphead;
+ unsigned char data;
+ unsigned char usr;
+ unsigned char lastRxError;
+
+
+ /* read UART status register and UART data register */
+ usr = UART0_STATUS;
+ data = UART0_DATA;
+
+ /* */
+#if defined( AT90_UART )
+ lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
+#elif defined( ATMEGA_USART )
+ lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
+#elif defined( ATMEGA_USART0 )
+ lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
+#elif defined ( ATMEGA_UART )
+ lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
+#endif
+
+ /* calculate buffer index */
+ tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
+
+ if ( tmphead == UART_RxTail ) {
+ /* error: receive buffer overflow */
+ lastRxError = UART_BUFFER_OVERFLOW >> 8;
+ }else{
+ /* store new index */
+ UART_RxHead = tmphead;
+ /* store received data in buffer */
+ UART_RxBuf[tmphead] = data;
+ }
+ UART_LastRxError = lastRxError;
+}
+
+
+SIGNAL(UART0_TRANSMIT_INTERRUPT)
+/*************************************************************************
+Function: UART Data Register Empty interrupt
+Purpose: called when the UART is ready to transmit the next byte
+**************************************************************************/
+{
+ unsigned char tmptail;
+
+
+ if ( UART_TxHead != UART_TxTail) {
+ /* calculate and store new buffer index */
+ tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
+ UART_TxTail = tmptail;
+ /* get one byte from buffer and write it to UART */
+ UART0_DATA = UART_TxBuf[tmptail]; /* start transmission */
+ }else{
+ /* tx buffer empty, disable UDRE interrupt */
+ UART0_CONTROL &= ~_BV(UART0_UDRIE);
+ }
+}
+
+
+/*************************************************************************
+Function: uart_init()
+Purpose: initialize UART and set baudrate
+Input: baudrate using macro UART_BAUD_SELECT()
+Returns: none
+**************************************************************************/
+void uart_init(unsigned int baudrate)
+{
+ UART_TxHead = 0;
+ UART_TxTail = 0;
+ UART_RxHead = 0;
+ UART_RxTail = 0;
+
+#if defined( AT90_UART )
+ /* set baud rate */
+ UBRR = (unsigned char)baudrate;
+
+ /* enable UART receiver and transmmitter and receive complete interrupt */
+ UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
+
+#elif defined (ATMEGA_USART)
+ /* Set baud rate */
+ if ( baudrate & 0x8000 )
+ {
+ UART0_STATUS = (1<<U2X); //Enable 2x speed
+ baudrate &= ~0x8000;
+ }
+ UBRRH = (unsigned char)(baudrate>>8);
+ UBRRL = (unsigned char) baudrate;
+
+ /* Enable USART receiver and transmitter and receive complete interrupt */
+ UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
+
+ /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
+ #ifdef URSEL
+ UCSRC = (1<<URSEL)|(3<<UCSZ0);
+ #else
+ UCSRC = (3<<UCSZ0);
+ #endif
+
+#elif defined (ATMEGA_USART0 )
+ /* Set baud rate */
+ if ( baudrate & 0x8000 )
+ {
+ UART0_STATUS = (1<<U2X0); //Enable 2x speed
+ baudrate &= ~0x8000;
+ }
+ UBRR0H = (unsigned char)(baudrate>>8);
+ UBRR0L = (unsigned char) baudrate;
+
+ /* Enable USART receiver and transmitter and receive complete interrupt */
+ UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
+
+ /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
+ #ifdef URSEL0
+ UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
+ #else
+ UCSR0C = (3<<UCSZ00);
+ #endif
+
+#elif defined ( ATMEGA_UART )
+ /* set baud rate */
+ if ( baudrate & 0x8000 )
+ {
+ UART0_STATUS = (1<<U2X); //Enable 2x speed
+ baudrate &= ~0x8000;
+ }
+ UBRRHI = (unsigned char)(baudrate>>8);
+ UBRR = (unsigned char) baudrate;
+
+ /* Enable UART receiver and transmitter and receive complete interrupt */
+ UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
+
+#endif
+
+}/* uart_init */
+
+
+/*************************************************************************
+Function: uart_getc()
+Purpose: return byte from ringbuffer
+Returns: lower byte: received byte from ringbuffer
+ higher byte: last receive error
+**************************************************************************/
+unsigned int uart_getc(void)
+{
+ unsigned char tmptail;
+ unsigned char data;
+
+
+ if ( UART_RxHead == UART_RxTail ) {
+ return UART_NO_DATA; /* no data available */
+ }
+
+ /* calculate /store buffer index */
+ tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
+ UART_RxTail = tmptail;
+
+ /* get data from receive buffer */
+ data = UART_RxBuf[tmptail];
+
+ return (UART_LastRxError << 8) + data;
+
+}/* uart_getc */
+
+
+/*************************************************************************
+Function: uart_putc()
+Purpose: write byte to ringbuffer for transmitting via UART
+Input: byte to be transmitted
+Returns: none
+**************************************************************************/
+void uart_putc(unsigned char data)
+{
+ unsigned char tmphead;
+
+
+ tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
+
+ while ( tmphead == UART_TxTail ){
+ ;/* wait for free space in buffer */
+ }
+
+ UART_TxBuf[tmphead] = data;
+ UART_TxHead = tmphead;
+
+ /* enable UDRE interrupt */
+ UART0_CONTROL |= _BV(UART0_UDRIE);
+
+}/* uart_putc */
+
+
+/*************************************************************************
+Function: uart_puts()
+Purpose: transmit string to UART
+Input: string to be transmitted
+Returns: none
+**************************************************************************/
+void uart_puts(const char *s )
+{
+ while (*s)
+ uart_putc(*s++);
+
+}/* uart_puts */
+
+
+/*************************************************************************
+Function: uart_puts_p()
+Purpose: transmit string from program memory to UART
+Input: program memory string to be transmitted
+Returns: none
+**************************************************************************/
+void uart_puts_p(const char *progmem_s )
+{
+ register char c;
+
+ while ( (c = pgm_read_byte(progmem_s++)) )
+ uart_putc(c);
+
+}/* uart_puts_p */
+
+
+/*
+ * these functions are only for ATmegas with two USART
+ */
+#if defined( ATMEGA_USART1 )
+
+SIGNAL(UART1_RECEIVE_INTERRUPT)
+/*************************************************************************
+Function: UART1 Receive Complete interrupt
+Purpose: called when the UART1 has received a character
+**************************************************************************/
+{
+ unsigned char tmphead;
+ unsigned char data;
+ unsigned char usr;
+ unsigned char lastRxError;
+
+
+ /* read UART status register and UART data register */
+ usr = UART1_STATUS;
+ data = UART1_DATA;
+
+ /* */
+ lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
+
+ /* calculate buffer index */
+ tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
+
+ if ( tmphead == UART1_RxTail ) {
+ /* error: receive buffer overflow */
+ lastRxError = UART_BUFFER_OVERFLOW >> 8;
+ }else{
+ /* store new index */
+ UART1_RxHead = tmphead;
+ /* store received data in buffer */
+ UART1_RxBuf[tmphead] = data;
+ }
+ UART1_LastRxError = lastRxError;
+}
+
+
+SIGNAL(UART1_TRANSMIT_INTERRUPT)
+/*************************************************************************
+Function: UART1 Data Register Empty interrupt
+Purpose: called when the UART1 is ready to transmit the next byte
+**************************************************************************/
+{
+ unsigned char tmptail;
+
+
+ if ( UART1_TxHead != UART1_TxTail) {
+ /* calculate and store new buffer index */
+ tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
+ UART1_TxTail = tmptail;
+ /* get one byte from buffer and write it to UART */
+ UART1_DATA = UART1_TxBuf[tmptail]; /* start transmission */
+ }else{
+ /* tx buffer empty, disable UDRE interrupt */
+ UART1_CONTROL &= ~_BV(UART1_UDRIE);
+ }
+}
+
+
+/*************************************************************************
+Function: uart1_init()
+Purpose: initialize UART1 and set baudrate
+Input: baudrate using macro UART_BAUD_SELECT()
+Returns: none
+**************************************************************************/
+void uart1_init(unsigned int baudrate)
+{
+ UART1_TxHead = 0;
+ UART1_TxTail = 0;
+ UART1_RxHead = 0;
+ UART1_RxTail = 0;
+
+
+ /* Set baud rate */
+ if ( baudrate & 0x8000 )
+ {
+ UART1_STATUS = (1<<U2X1); //Enable 2x speed
+ baudrate &= ~0x8000;
+ }
+ UBRR1H = (unsigned char)(baudrate>>8);
+ UBRR1L = (unsigned char) baudrate;
+
+ /* Enable USART receiver and transmitter and receive complete interrupt */
+ UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
+
+ /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
+ #ifdef URSEL1
+ UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
+ #else
+ UCSR1C = (3<<UCSZ10);
+ #endif
+}/* uart_init */
+
+
+/*************************************************************************
+Function: uart1_getc()
+Purpose: return byte from ringbuffer
+Returns: lower byte: received byte from ringbuffer
+ higher byte: last receive error
+**************************************************************************/
+unsigned int uart1_getc(void)
+{
+ unsigned char tmptail;
+ unsigned char data;
+
+
+ if ( UART1_RxHead == UART1_RxTail ) {
+ return UART_NO_DATA; /* no data available */
+ }
+
+ /* calculate /store buffer index */
+ tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
+ UART1_RxTail = tmptail;
+
+ /* get data from receive buffer */
+ data = UART1_RxBuf[tmptail];
+
+ return (UART1_LastRxError << 8) + data;
+
+}/* uart1_getc */
+
+
+/*************************************************************************
+Function: uart1_putc()
+Purpose: write byte to ringbuffer for transmitting via UART
+Input: byte to be transmitted
+Returns: none
+**************************************************************************/
+void uart1_putc(unsigned char data)
+{
+ unsigned char tmphead;
+
+
+ tmphead = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
+
+ while ( tmphead == UART1_TxTail ){
+ ;/* wait for free space in buffer */
+ }
+
+ UART1_TxBuf[tmphead] = data;
+ UART1_TxHead = tmphead;
+
+ /* enable UDRE interrupt */
+ UART1_CONTROL |= _BV(UART1_UDRIE);
+
+}/* uart1_putc */
+
+
+/*************************************************************************
+Function: uart1_puts()
+Purpose: transmit string to UART1
+Input: string to be transmitted
+Returns: none
+**************************************************************************/
+void uart1_puts(const char *s )
+{
+ while (*s)
+ uart1_putc(*s++);
+
+}/* uart1_puts */
+
+
+/*************************************************************************
+Function: uart1_puts_p()
+Purpose: transmit string from program memory to UART1
+Input: program memory string to be transmitted
+Returns: none
+**************************************************************************/
+void uart1_puts_p(const char *progmem_s )
+{
+ register char c;
+
+ while ( (c = pgm_read_byte(progmem_s++)) )
+ uart1_putc(c);
+
+}/* uart1_puts_p */
+
+
+#endif
194 firmware/lib/uart/uart.h
@@ -0,0 +1,194 @@
+#ifndef UART_H
+#define UART_H
+/************************************************************************
+Title: Interrupt UART library with receive/transmit circular buffers
+Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
+File: $Id: uart.h,v 1.8.2.1 2007/07/01 11:14:38 peter Exp $
+Software: AVR-GCC 4.1, AVR Libc 1.4
+Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz
+License: GNU General Public License
+Usage: see Doxygen manual
+
+LICENSE:
+ Copyright (C) 2006 Peter Fleury
+
+ 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
+ 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.
+
+************************************************************************/
+
+/**
+ * @defgroup pfleury_uart UART Library
+ * @code #include <uart.h> @endcode
+ *
+ * @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers.
+ *
+ * This library can be used to transmit and receive data through the built in UART.
+ *
+ * An interrupt is generated when the UART has finished transmitting or
+ * receiving a byte. The interrupt handling routines use circular buffers
+ * for buffering received and transmitted data.
+ *
+ * The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE constants define
+ * the size of the circular buffers in bytes. Note that these constants must be a power of 2.
+ * You may need to adapt this constants to your target and your application by adding
+ * CDEFS += -DUART_RX_BUFFER_SIZE=nn -DUART_RX_BUFFER_SIZE=nn to your Makefile.
+ *
+ * @note Based on Atmel Application Note AVR306
+ * @author Peter Fleury pfleury@gmx.ch http://jump.to/fleury
+ */
+
+/**@{*/
+
+
+#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
+#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
+#endif
+
+
+/*
+** constants and macros
+*/
+
+/** @brief UART Baudrate Expression
+ * @param xtalcpu system clock in Mhz, e.g. 4000000L for 4Mhz
+ * @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
+ */
+#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
+
+/** @brief UART Baudrate Expression for ATmega double speed mode
+ * @param xtalcpu system clock in Mhz, e.g. 4000000L for 4Mhz
+ * @param baudrate baudrate in bps, e.g. 1200, 2400, 9600
+ */
+#define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) (((xtalCpu)/((baudRate)*8l)-1)|0x8000)
+
+
+/** Size of the circular receive buffer, must be power of 2 */
+#ifndef UART_RX_BUFFER_SIZE
+#define UART_RX_BUFFER_SIZE 64
+#endif
+/** Size of the circular transmit buffer, must be power of 2 */
+#ifndef UART_TX_BUFFER_SIZE
+#define UART_TX_BUFFER_SIZE 64
+#endif
+
+/* test if the size of the circular buffers fits into SRAM */
+#if ( (UART_RX_BUFFER_SIZE+UART_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) )
+#error "size of UART_RX_BUFFER_SIZE + UART_TX_BUFFER_SIZE larger than size of SRAM"
+#endif
+
+/*
+** high byte error return code of uart_getc()
+*/
+#define UART_FRAME_ERROR 0x0800 /* Framing Error by UART */
+#define UART_OVERRUN_ERROR 0x0400 /* Overrun condition by UART */
+#define UART_BUFFER_OVERFLOW 0x0200 /* receive ringbuffer overflow */
+#define UART_NO_DATA 0x0100 /* no receive data available */
+
+
+/*
+** function prototypes
+*/
+
+/**
+ @brief Initialize UART and set baudrate
+ @param baudrate Specify baudrate using macro UART_BAUD_SELECT()
+ @return none
+*/
+extern void uart_init(unsigned int baudrate);
+
+
+/**
+ * @brief Get received byte from ringbuffer
+ *
+ * Returns in the lower byte the received character and in the
+ * higher byte the last receive error.
+ * UART_NO_DATA is returned when no data is available.
+ *
+ * @param void
+ * @return lower byte: received byte from ringbuffer
+ * @return higher byte: last receive status
+ * - \b 0 successfully received data from UART
+ * - \b UART_NO_DATA
+ * <br>no receive data available
+ * - \b UART_BUFFER_OVERFLOW
+ * <br>Receive ringbuffer overflow.
+ * We are not reading the receive buffer fast enough,
+ * one or more received character have been dropped
+ * - \b UART_OVERRUN_ERROR
+ * <br>Overrun condition by UART.
+ * A character already present in the UART UDR register was
+ * not read by the interrupt handler before the next character arrived,
+ * one or more received characters have been dropped.
+ * - \b UART_FRAME_ERROR
+ * <br>Framing Error by UART
+ */
+extern unsigned int uart_getc(void);
+
+
+/**
+ * @brief Put byte to ringbuffer for transmitting via UART
+ * @param data byte to be transmitted
+ * @return none
+ */
+extern void uart_putc(unsigned char data);
+
+
+/**
+ * @brief Put string to ringbuffer for transmitting via UART
+ *
+ * The string is buffered by the uart library in a circular buffer
+ * and one character at a time is transmitted to the UART using interrupts.
+ * Blocks if it can not write the whole string into the circular buffer.
+ *
+ * @param s string to be transmitted
+ * @return none
+ */
+extern void uart_puts(const char *s );
+
+
+/**
+ * @brief Put string from program memory to ringbuffer for transmitting via UART.
+ *
+ * The string is buffered by the uart library in a circular buffer
+ * and one character at a time is transmitted to the UART using interrupts.
+ * Blocks if it can not write the whole string into the circular buffer.
+ *
+ * @param s program memory string to be transmitted
+ * @return none
+ * @see uart_puts_P
+ */
+extern void uart_puts_p(const char *s );
+
+/**
+ * @brief Macro to automatically put a string constant into program memory
+ */
+#define uart_puts_P(__s) uart_puts_p(PSTR(__s))
+
+
+
+/** @brief Initialize USART1 (only available on selected ATmegas) @see uart_init */
+extern void uart1_init(unsigned int baudrate);
+/** @brief Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */
+extern unsigned int uart1_getc(void);
+/** @brief Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */
+extern void uart1_putc(unsigned char data);
+/** @brief Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */
+extern void uart1_puts(const char *s );
+/** @brief Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */
+extern void uart1_puts_p(const char *s );
+/** @brief Macro to automatically put a string constant into program memory */
+#define uart1_puts_P(__s) uart1_puts_p(PSTR(__s))
+
+/**@}*/
+
+
+#endif // UART_H
+
636 firmware/makefile
@@ -0,0 +1,636 @@
+# Hey Emacs, this is a -*- makefile -*-
+#----------------------------------------------------------------------------
+# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
+#
+# Released to the Public Domain
+#
+# Additional material for this makefile was written by:
+# Peter Fleury
+# Tim Henigan
+# Colin O'Flynn
+# Reiner Patommel
+# Markus Pfaff
+# Sander Pool
+# Frederik Rouleau
+# Carlos Lamas
+#
+#----------------------------------------------------------------------------
+# 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 = atmega8
+# 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.
+# Typical values are:
+# F_CPU = 1000000
+# F_CPU = 1843200
+# F_CPU = 2000000
+# F_CPU = 3686400
+# F_CPU = 4000000
+# F_CPU = 7372800
+# F_CPU = 8000000
+# F_CPU = 11059200
+ F_CPU = 12000000
+# F_CPU = 14745600
+# F_CPU = 16000000
+# F_CPU = 18432000
+# F_CPU = 20000000
+
+
+
+# Output format. (can be srec, ihex, binary)
+FORMAT = ihex
+
+
+# Target file name (without extension).
+TARGET = rfm12trx
+
+
+# Object files directory
+# To put object files in current directory, use a dot (.), do NOT make
+# this an empty or blank macro!
+OBJDIR = .
+
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC = $(TARGET).c lib/uart/uart.c lib/rfm12/rfm12.c
+
+
+# List C++ source files here. (C dependencies are automatically generated.)
+CPPSRC =
+
+
+# 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 = 2
+
+
+# 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 = stabs
+
+
+# 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 for C sources
+CDEFS = -DF_CPU=$(F_CPU)UL
+#CDEFS += -DRF_PORT=PORTC
+#CDEFS += -DRF_DDR=DDRC
+#CDEFS += -DRF_PIN=PINC
+#CDEFS += -DSDI=0
+#CDEFS += -DSCK=1
+#CDEFS += -DCS=2
+#CDEFS += -DSDO=3
+#CDEFS += -DRF12DEBUG
+#CDEFS += -DRF12DEBUGBIN
+
+#CDEFS += -DRF_IRQDDR=DDRD
+#CDEFS += -DRF_IRQPIN=PIND
+#CDEFS += -DRF_IRQPORT=PORTD
+#CDEFS += -DIRQ=2
+
+
+# Place -D or -U options here for C++ sources
+CPPDEFS = -DF_CPU=$(F_CPU)UL
+#CPPDEFS += -D__STDC_LIMIT_MACROS
+#CPPDEFS += -D__STDC_CONSTANT_MACROS
+
+
+
+#---------------- Compiler Options C ----------------
+# -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)
+CFLAGS += -O$(OPT)
+CFLAGS += -funsigned-char
+CFLAGS += -funsigned-bitfields
+CFLAGS += -fpack-struct
+CFLAGS += -fshort-enums
+CFLAGS += -Wall
+CFLAGS += -Wstrict-prototypes
+#CFLAGS += -mshort-calls
+#CFLAGS += -fno-unit-at-a-time
+#CFLAGS += -Wundef
+#CFLAGS += -Wunreachable-code
+#CFLAGS += -Wsign-compare
+CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+CFLAGS += $(CSTANDARD)
+
+
+#---------------- Compiler Options C++ ----------------
+# -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
+CPPFLAGS = -g$(DEBUG)
+CPPFLAGS += $(CPPDEFS)
+CPPFLAGS += -O$(OPT)
+CPPFLAGS += -funsigned-char
+CPPFLAGS += -funsigned-bitfields
+CPPFLAGS += -fpack-struct
+CPPFLAGS += -fshort-enums
+CPPFLAGS += -fno-exceptions
+CPPFLAGS += -Wall
+CFLAGS += -Wundef
+#CPPFLAGS += -mshort-calls
+#CPPFLAGS += -fno-unit-at-a-time
+#CPPFLAGS += -Wstrict-prototypes
+#CPPFLAGS += -Wunreachable-code
+#CPPFLAGS += -Wsign-compare
+CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
+CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
+#CPPFLAGS += $(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]
+# -listing-cont-lines: Sets the maximum number of continuation lines of hex
+# dump that will be displayed for a given single line of source input.
+ASFLAGS = -Wa,-adhlns=$(<:.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
+
+
+#---------------- 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
+
+
+# List any extra directories to look for libraries 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.
+EXTRALIBDIRS =
+
+
+
+#---------------- 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,--section-start,.data=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 += $(patsubst %,-L%,$(EXTRALIBDIRS))
+LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
+#LDFLAGS += -T linker_script.x
+
+
+
+#---------------- 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 = avrispv2
+AVRDUDE_PROGRAMMER = avr910
+# com1 = serial port. Use lpt1 to connect to parallel port.
+AVRDUDE_PORT = /dev/ttyUSB0
+
+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)
+
+#AVRDUDE_HFUSE_FLAGS = -U hfuse:w:0xd9:m
+#AVRDUDE_LFUSE_FLAGS = -U lfuse:w:0xe0:m
+AVRDUDE_HFUSE_FLAGS = -U hfuse:w:0xd9:m
+AVRDUDE_LFUSE_FLAGS = -U lfuse:w:0xe0:m
+
+#---------------- 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
+AR = avr-ar rcs
+NM = avr-nm
+AVRDUDE = avrdude
+REMOVE = rm -f
+REMOVEDIR = rm -rf
+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 C:
+MSG_COMPILING_CPP = Compiling C++:
+MSG_ASSEMBLING = Assembling:
+MSG_CLEANING = Cleaning project:
+MSG_CREATING_LIBRARY = Creating library:
+
+
+
+
+# Define all object files.
+OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
+
+# Define all listing files.
+LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
+
+
+# Compiler flags to generate dependency files.
+GENDEPFLAGS = -MMD -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_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+
+
+
+# Default target.
+all: begin gccversion sizebefore build sizeafter end
+
+# Change the build target to build a HEX file or a library.
+build: elf hex eep lss sym
+#build: lib
+
+
+elf: $(TARGET).elf
+hex: $(TARGET).hex
+eep: $(TARGET).eep
+lss: $(TARGET).lss
+sym: $(TARGET).sym
+LIBNAME=lib$(TARGET).a
+lib: $(LIBNAME)
+
+
+
+# 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) --format=avr $(TARGET).elf
+ELFSIZE = $(SIZE) $(TARGET).elf
+sizebefore:
+ @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
+ 2>/dev/null; echo; fi
+
+sizeafter:
+ @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
+ 2>/dev/null; echo; fi
+
+
+
+# Display compiler version information.
+gccversion :
+ @$(CC) --version
+
+fuse:
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_HFUSE_FLAGS)
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_LFUSE_FLAGS)
+
+
+# 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
+COFFCONVERT += --change-section-address .data-0x800000
+COFFCONVERT += --change-section-address .bss-0x800000
+COFFCONVERT += --change-section-address .noinit-0x800000
+COFFCONVERT += --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 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
+
+# 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 $< > $@
+
+
+
+# Create library from object files.
+.SECONDARY : $(TARGET).a
+.PRECIOUS : $(OBJ)
+%.a: $(OBJ)
+ @echo
+ @echo $(MSG_CREATING_LIBRARY) $@
+ $(AR) $@ $(OBJ)
+
+
+# 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.
+$(OBJDIR)/%.o : %.c
+ @echo
+ @echo $(MSG_COMPILING) $<
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create object files from C++ source files.
+$(OBJDIR)/%.o : %.cpp
+ @echo
+ @echo $(MSG_COMPILING_CPP) $<
+ $(CC) -c $(ALL_CPPFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+%.s : %.c
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C++ source files.
+%.s : %.cpp
+ $(CC) -S $(ALL_CPPFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+$(OBJDIR)/%.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) $(SRC:%.c=$(OBJDIR)/%.o)
+ $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
+ $(REMOVE) $(SRC:.c=.s)
+ $(REMOVE) $(SRC:.c=.d)
+ $(REMOVE) $(SRC:.c=.i)
+ $(REMOVEDIR) .dep
+
+
+# Create object files directory
+$(shell mkdir $(OBJDIR) 2>/dev/null)
+
+
+# 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
+
+
161 firmware/rfm12trx.c
@@ -0,0 +1,161 @@
+/*
+ * rfm12trx http://schoar.de/tinkering/rfm12trx
+*/
+
+#include "rfm12trx.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/sleep.h>
+#include <util/delay.h>
+
+#include "lib/global.h"
+#include "lib/uart/uart.h"
+#include "lib/rfm12/rfm12.h"
+
+unsigned char tx_buf[RFM12_DATA_LENGTH];
+uint8_t tx_pos = 0;
+
+uint8_t tx_high;
+uint8_t tx_low;
+uint8_t tx_toggle;
+
+uint8_t tx_ready = 0;
+
+uint8_t hexconvert(uint8_t ascii) {
+ if (ascii >= '0' && ascii <= '9') {
+ return ascii - 48;
+ }
+
+ if (ascii >= 'A' && ascii <= 'F') {
+ return ascii - 55;
+ }
+
+ if (ascii >= 'a' && ascii <= 'f') {
+ return ascii - 87;
+ }
+
+ return 255;
+}
+
+void read(void) {
+ if (tx_ready == 1) {
+ return;
+ }
+
+ while(1) {
+
+ unsigned int ci = uart_getc();
+
+ if (ci & UART_NO_DATA) {
+ return;
+ }
+
+ uint8_t cc = (uint8_t)ci;
+
+ if (hexconvert(cc) != 255) {
+ if (tx_toggle == 0) {
+ tx_high = hexconvert(cc);
+ } else {
+ tx_low = hexconvert(cc);
+ tx_buf[tx_pos++] = tx_high * 16 + tx_low;
+ }
+ tx_toggle ^= 1;
+ }
+
+ if (cc == '\r' || cc == '\n' || tx_pos >= sizeof(tx_buf) - 1) {
+ tx_ready = 1;
+ tx_toggle = 0;
+ return;
+ }
+
+ }
+}
+
+void rx(void) {
+ uint8_t state;
+
+ state = rfm12_rxstart();
+
+ unsigned char tmp[RFM12_DATA_LENGTH];
+ state = rfm12_rxfinish(tmp);
+ if (state == 0) {
+ return;
+ }
+ if (state == 255) {
+ return;
+ }
+ if (state == 254) {
+ rfm12_allstop();
+ return;
+ }
+
+ char out[16];
+ sprintf(out, "RX: [%02x] ", state);
+ uart_puts(out);
+ for (uint8_t i=0; i < state; i++) {
+ sprintf(out,"%02x", tmp[i]);
+ uart_puts(out);
+ }
+ uart_puts("\r\n");
+}
+
+void tx(void) {
+ if (tx_ready == 0) {
+ return;
+ }
+ tx_ready = 0;
+
+ uint8_t len = tx_pos;
+ tx_pos = 0;
+ if (len == 0) {
+ return;
+ }
+
+ rfm12_allstop();
+ if (rfm12_txstart(tx_buf, len) != 0) {
+ return;
+ }
+
+ while (rfm12_txfinished() != 0) {
+ }
+
+ char out[16];
+ sprintf(out, "TX: [%02x] ", len);
+ uart_puts(out);
+ for (uint8_t i=0; i < len; i++) {
+ sprintf(out,"%02x", tx_buf[i]);
+ uart_puts(out);
+ }
+ uart_puts("\r\n");
+}
+
+int main (void) {
+
+ _delay_ms(2000);
+
+ sei();
+
+ uart_init(UART_BAUD_SELECT_DOUBLE_SPEED(UART_BAUD_RATE, F_CPU));
+ uart_puts("\r\nrfm12trx http://schoar.de/tinkering/rfm12trx\r\n");
+
+ rfm12_init();
+
+ rfm12_setfreq(RFM12_FREQ(434.32));
+ rfm12_setbandwidth(RxBW200, LNA_6, RSSI_79);
+ rfm12_setbaud(19200);
+ rfm12_setpower(PWRdB_0, TxBW105);
+
+ while(1) {
+ read();
+
+ if (tx_ready != 0) {
+ tx();
+ } else {
+ rx();
+ }
+ }
+
+}
7 firmware/rfm12trx.h
@@ -0,0 +1,7 @@
+#ifndef RFM12TRX_H
+#define RFM12TRX_H
+
+#define F_CPU 12000000UL
+#define UART_BAUD_RATE 115200
+
+#endif
BIN firmware/rfm12trx_ftprog.xml
Binary file not shown.
5 license.txt
@@ -0,0 +1,5 @@
+Creative Commons Attribution 3.0 Unported (CC BY 3.0)
+https://creativecommons.org/licenses/by/3.0/
+
+@kiu112
+simon@schoar.de
9 pcb/gerber/readme.txt
@@ -0,0 +1,9 @@
+Order: 54018
+
+QTY: 10
+Layer: 2
+PCB Thickness: 1.6mm
+PCB Dimension: 50x50mm (22x48mm)
+PCB Color: red
+Surface: Hasl
+E-Test: 50%
2,301 pcb/gerber/rfm12trx.GBL
@@ -0,0 +1,2301 @@
+G75*
+G70*
+%OFA0B0*%
+%FSLAX24Y24*%
+%IPPOS*%
+%LPD*%
+%AMOC8*
+5,1,8,0,0,1.08239X$1,22.5*
+%
+%ADD10C,0.0000*%
+%ADD11OC8,0.0600*%
+%ADD12R,0.0433X0.0394*%
+%ADD13R,0.0220X0.0500*%
+%ADD14R,0.0500X0.0220*%
+%ADD15R,0.0394X0.0433*%
+%ADD16R,0.0472X0.0472*%
+%ADD17OC8,0.1250*%
+%ADD18C,0.0160*%
+%ADD19OC8,0.0356*%
+D10*
+X000574Y000574D02*
+X000574Y019471D01*
+X009235Y019471D01*
+X009235Y000574D01*
+X000574Y000574D01*
+X001125Y001755D02*
+X001127Y001805D01*
+X001133Y001855D01*
+X001143Y001904D01*
+X001157Y001952D01*
+X001174Y001999D01*
+X001195Y002044D01*
+X001220Y002088D01*
+X001248Y002129D01*
+X001280Y002168D01*
+X001314Y002205D01*
+X001351Y002239D01*
+X001391Y002269D01*
+X001433Y002296D01*
+X001477Y002320D01*
+X001523Y002341D01*
+X001570Y002357D01*
+X001618Y002370D01*
+X001668Y002379D01*
+X001717Y002384D01*
+X001768Y002385D01*
+X001818Y002382D01*
+X001867Y002375D01*
+X001916Y002364D01*
+X001964Y002349D01*
+X002010Y002331D01*
+X002055Y002309D01*
+X002098Y002283D01*
+X002139Y002254D01*
+X002178Y002222D01*
+X002214Y002187D01*
+X002246Y002149D01*
+X002276Y002109D01*
+X002303Y002066D01*
+X002326Y002022D01*
+X002345Y001976D01*
+X002361Y001928D01*
+X002373Y001879D01*
+X002381Y001830D01*
+X002385Y001780D01*
+X002385Y001730D01*
+X002381Y001680D01*
+X002373Y001631D01*
+X002361Y001582D01*
+X002345Y001534D01*
+X002326Y001488D01*
+X002303Y001444D01*
+X002276Y001401D01*
+X002246Y001361D01*
+X002214Y001323D01*
+X002178Y001288D01*
+X002139Y001256D01*
+X002098Y001227D01*
+X002055Y001201D01*
+X002010Y001179D01*
+X001964Y001161D01*
+X001916Y001146D01*
+X001867Y001135D01*
+X001818Y001128D01*
+X001768Y001125D01*
+X001717Y001126D01*
+X001668Y001131D01*
+X001618Y001140D01*
+X001570Y001153D01*
+X001523Y001169D01*
+X001477Y001190D01*
+X001433Y001214D01*
+X001391Y001241D01*
+X001351Y001271D01*
+X001314Y001305D01*
+X001280Y001342D01*
+X001248Y001381D01*
+X001220Y001422D01*
+X001195Y001466D01*
+X001174Y001511D01*
+X001157Y001558D01*
+X001143Y001606D01*
+X001133Y001655D01*
+X001127Y001705D01*
+X001125Y001755D01*
+X007424Y001755D02*
+X007426Y001805D01*
+X007432Y001855D01*
+X007442Y001904D01*
+X007456Y001952D01*
+X007473Y001999D01*
+X007494Y002044D01*
+X007519Y002088D01*
+X007547Y002129D01*
+X007579Y002168D01*
+X007613Y002205D01*
+X007650Y002239D01*
+X007690Y002269D01*
+X007732Y002296D01*
+X007776Y002320D01*
+X007822Y002341D01*
+X007869Y002357D01*
+X007917Y002370D01*
+X007967Y002379D01*
+X008016Y002384D01*
+X008067Y002385D01*
+X008117Y002382D01*
+X008166Y002375D01*
+X008215Y002364D01*
+X008263Y002349D01*
+X008309Y002331D01*
+X008354Y002309D01*
+X008397Y002283D01*
+X008438Y002254D01*
+X008477Y002222D01*
+X008513Y002187D01*
+X008545Y002149D01*
+X008575Y002109D01*
+X008602Y002066D01*
+X008625Y002022D01*
+X008644Y001976D01*
+X008660Y001928D01*
+X008672Y001879D01*
+X008680Y001830D01*
+X008684Y001780D01*
+X008684Y001730D01*
+X008680Y001680D01*
+X008672Y001631D01*
+X008660Y001582D01*
+X008644Y001534D01*
+X008625Y001488D01*
+X008602Y001444D01*
+X008575Y001401D01*
+X008545Y001361D01*
+X008513Y001323D01*
+X008477Y001288D01*
+X008438Y001256D01*
+X008397Y001227D01*
+X008354Y001201D01*
+X008309Y001179D01*
+X008263Y001161D01*
+X008215Y001146D01*
+X008166Y001135D01*
+X008117Y001128D01*
+X008067Y001125D01*
+X008016Y001126D01*
+X007967Y001131D01*
+X007917Y001140D01*
+X007869Y001153D01*
+X007822Y001169D01*
+X007776Y001190D01*
+X007732Y001214D01*
+X007690Y001241D01*
+X007650Y001271D01*
+X007613Y001305D01*
+X007579Y001342D01*
+X007547Y001381D01*
+X007519Y001422D01*
+X007494Y001466D01*
+X007473Y001511D01*
+X007456Y001558D01*
+X007442Y001606D01*
+X007432Y001655D01*
+X007426Y001705D01*
+X007424Y001755D01*
+X007424Y018290D02*
+X007426Y018340D01*
+X007432Y018390D01*
+X007442Y018439D01*
+X007456Y018487D01*
+X007473Y018534D01*
+X007494Y018579D01*
+X007519Y018623D01*
+X007547Y018664D01*
+X007579Y018703D01*
+X007613Y018740D01*
+X007650Y018774D01*
+X007690Y018804D01*
+X007732Y018831D01*
+X007776Y018855D01*
+X007822Y018876D01*
+X007869Y018892D01*
+X007917Y018905D01*
+X007967Y018914D01*
+X008016Y018919D01*
+X008067Y018920D01*
+X008117Y018917D01*
+X008166Y018910D01*
+X008215Y018899D01*
+X008263Y018884D01*
+X008309Y018866D01*
+X008354Y018844D01*
+X008397Y018818D01*
+X008438Y018789D01*
+X008477Y018757D01*
+X008513Y018722D01*
+X008545Y018684D01*
+X008575Y018644D01*
+X008602Y018601D01*
+X008625Y018557D01*
+X008644Y018511D01*
+X008660Y018463D01*
+X008672Y018414D01*
+X008680Y018365D01*
+X008684Y018315D01*
+X008684Y018265D01*
+X008680Y018215D01*
+X008672Y018166D01*
+X008660Y018117D01*
+X008644Y018069D01*
+X008625Y018023D01*
+X008602Y017979D01*
+X008575Y017936D01*
+X008545Y017896D01*
+X008513Y017858D01*
+X008477Y017823D01*
+X008438Y017791D01*
+X008397Y017762D01*
+X008354Y017736D01*
+X008309Y017714D01*
+X008263Y017696D01*
+X008215Y017681D01*
+X008166Y017670D01*
+X008117Y017663D01*
+X008067Y017660D01*
+X008016Y017661D01*
+X007967Y017666D01*
+X007917Y017675D01*
+X007869Y017688D01*
+X007822Y017704D01*
+X007776Y017725D01*
+X007732Y017749D01*
+X007690Y017776D01*
+X007650Y017806D01*
+X007613Y017840D01*
+X007579Y017877D01*
+X007547Y017916D01*
+X007519Y017957D01*
+X007494Y018001D01*
+X007473Y018046D01*
+X007456Y018093D01*
+X007442Y018141D01*
+X007432Y018190D01*
+X007426Y018240D01*
+X007424Y018290D01*
+X001125Y018290D02*
+X001127Y018340D01*
+X001133Y018390D01*
+X001143Y018439D01*
+X001157Y018487D01*
+X001174Y018534D01*
+X001195Y018579D01*
+X001220Y018623D01*
+X001248Y018664D01*
+X001280Y018703D01*
+X001314Y018740D01*
+X001351Y018774D01*
+X001391Y018804D01*
+X001433Y018831D01*
+X001477Y018855D01*
+X001523Y018876D01*
+X001570Y018892D01*
+X001618Y018905D01*
+X001668Y018914D01*
+X001717Y018919D01*
+X001768Y018920D01*
+X001818Y018917D01*
+X001867Y018910D01*
+X001916Y018899D01*
+X001964Y018884D01*
+X002010Y018866D01*
+X002055Y018844D01*
+X002098Y018818D01*
+X002139Y018789D01*
+X002178Y018757D01*
+X002214Y018722D01*
+X002246Y018684D01*
+X002276Y018644D01*
+X002303Y018601D01*
+X002326Y018557D01*
+X002345Y018511D01*
+X002361Y018463D01*
+X002373Y018414D01*
+X002381Y018365D01*
+X002385Y018315D01*
+X002385Y018265D01*
+X002381Y018215D01*
+X002373Y018166D01*
+X002361Y018117D01*
+X002345Y018069D01*
+X002326Y018023D01*
+X002303Y017979D01*
+X002276Y017936D01*
+X002246Y017896D01*
+X002214Y017858D01*
+X002178Y017823D01*
+X002139Y017791D01*
+X002098Y017762D01*
+X002055Y017736D01*
+X002010Y017714D01*
+X001964Y017696D01*
+X001916Y017681D01*
+X001867Y017670D01*
+X001818Y017663D01*
+X001768Y017660D01*
+X001717Y017661D01*
+X001668Y017666D01*
+X001618Y017675D01*
+X001570Y017688D01*
+X001523Y017704D01*
+X001477Y017725D01*
+X001433Y017749D01*
+X001391Y017776D01*
+X001351Y017806D01*
+X001314Y017840D01*
+X001280Y017877D01*
+X001248Y017916D01*
+X001220Y017957D01*
+X001195Y018001D01*
+X001174Y018046D01*
+X001157Y018093D01*
+X001143Y018141D01*
+X001133Y018190D01*
+X001127Y018240D01*
+X001125Y018290D01*
+D11*
+X003904Y009341D03*
+X003904Y008341D03*
+X004904Y008341D03*
+X004904Y009341D03*
+X005904Y009341D03*
+X005904Y008341D03*
+D12*
+X005239Y001361D03*
+X004570Y001361D03*
+X002149Y007326D03*
+X002149Y007995D03*
+X003389Y015534D03*
+X004058Y015534D03*
+D13*
+X004117Y006594D03*
+X003802Y006594D03*
+X004432Y006594D03*
+X004747Y006594D03*
+X005062Y006594D03*
+X005377Y006594D03*
+X005692Y006594D03*
+X006007Y006594D03*
+X006007Y003214D03*
+X005692Y003214D03*
+X005377Y003214D03*
+X005062Y003214D03*
+X004747Y003214D03*
+X004432Y003214D03*
+X004117Y003214D03*
+X003802Y003214D03*
+D14*
+X003214Y003802D03*
+X003214Y004117D03*
+X003214Y004432D03*
+X003214Y004747D03*
+X003214Y005062D03*
+X003214Y005377D03*
+X003214Y005692D03*
+X003214Y006007D03*
+X006594Y006007D03*
+X006594Y005692D03*
+X006594Y005377D03*
+X006594Y005062D03*
+X006594Y004747D03*
+X006594Y004432D03*
+X006594Y004117D03*
+X006594Y003802D03*
+D15*
+X007326Y008448D03*
+X007995Y008448D03*
+X006420Y013172D03*
+X005751Y013172D03*
+X005751Y015534D03*
+X006420Y015534D03*
+X004058Y011597D03*
+X003389Y011597D03*
+D16*
+X002149Y009649D03*
+X002149Y008822D03*
+D17*
+X004904Y018290D03*
+D18*
+X004425Y019118D02*
+X000754Y019118D01*
+X000754Y018960D02*
+X001279Y018960D01*
+X001296Y018977D02*
+X001068Y018749D01*
+X000945Y018451D01*
+X000945Y018129D01*
+X001068Y017831D01*
+X001296Y017604D01*
+X001594Y017480D01*
+X001916Y017480D01*
+X002214Y017604D01*
+X002441Y017831D01*
+X002565Y018129D01*
+X002565Y018451D01*
+X002441Y018749D01*
+X002214Y018977D01*
+X001916Y019100D01*
+X001594Y019100D01*
+X001296Y018977D01*
+X001120Y018801D02*
+X000754Y018801D01*
+X000754Y018643D02*
+X001024Y018643D01*
+X000959Y018484D02*
+X000754Y018484D01*
+X000754Y018326D02*
+X000945Y018326D01*
+X000945Y018167D02*
+X000754Y018167D01*
+X000754Y018009D02*
+X000995Y018009D01*
+X001060Y017850D02*
+X000754Y017850D01*
+X000754Y017692D02*
+X001208Y017692D01*
+X001466Y017533D02*
+X000754Y017533D01*
+X000754Y017375D02*
+X003169Y017375D01*
+X003327Y017533D02*
+X002044Y017533D01*
+X002302Y017692D02*
+X003486Y017692D01*
+X003644Y017850D02*
+X002449Y017850D01*
+X002515Y018009D02*
+X003803Y018009D01*
+X003956Y018162D02*
+X003931Y018290D01*
+X004005Y018663D01*
+X004216Y018979D01*
+X004532Y019190D01*
+X004904Y019264D01*
+X005277Y019190D01*
+X005593Y018979D01*
+X005804Y018663D01*
+X005878Y018290D01*
+X005804Y017918D01*
+X005593Y017602D01*
+X005277Y017391D01*
+X004904Y017317D01*
+X004776Y017342D01*
+X003306Y015871D01*
+X003663Y015871D01*
+X003696Y015839D01*
+X003697Y015842D01*
+X003731Y015875D01*
+X003772Y015899D01*
+X003818Y015911D01*
+X004040Y015911D01*
+X004040Y015553D01*
+X004076Y015553D01*