Add F_CPU=0x800000 option with phase lock to external 32768 Hz crystal

Add MCU_CONF_LOW_WEAR option to avoid eeprom writes during development.
This commit is contained in:
David Kopf 2012-01-10 12:42:27 -05:00
parent 057398a6d1
commit 58298f59db
7 changed files with 95 additions and 5 deletions

View file

@ -93,6 +93,50 @@ ISR(AVR_OUTPUT_COMPARE_INT)
scount = 0;
seconds++;
}
#if F_CPU == 0x800000 && USE_32K_CRYSTAL
/* Special routine to phase lock CPU to 32768 watch crystal.
We are interrupting 128 times per second.
If RTIMER_ARCH_SECOND is a multiple of 128 we can use the residual modulo
128 to determine whether the clock is too fast or too slow.
E.g. for 8192 the phase should be constant modulo 0x40
OSCCAL is started in the lower range at 90, allowed to stabilize, then
rapidly raised or lowered based on the phase comparison.
It gives less phase noise to do this every tick and doesn't seem to hurt anything.
*/
#include "rtimer-arch.h"
{
volatile static uint8_t lockcount;
volatile static int16_t last_phase;
volatile static uint8_t osccalhigh,osccallow;
if (seconds < 60) { //give a minute to stabilize
if(++lockcount >= 8192UL*128/RTIMER_ARCH_SECOND) {
lockcount=0;
rtimer_phase = TCNT3 & 0x0fff;
if (seconds < 2) OSCCAL=100;
if (last_phase > rtimer_phase) osccalhigh=++OSCCAL; else osccallow=--OSCCAL;
last_phase = rtimer_phase;
}
} else {
#if TICK_MODULO
static uint8_t lock_clock;
if (++lock_clock>=TICK_MODULO) {
lock_clock=0;
#endif
uint8_t error = (TCNT3 - last_phase) & 0x3f;
if (error == 0) {
} else if (error<32) {
OSCCAL=osccallow-1;
} else {
OSCCAL=osccalhigh+1;
}
#if TICK_MODULO
}
#endif
}
}
#endif
#if RADIO_CONF_CALIBRATE_INTERVAL
if (++calibrate_interval==0) {
rf230_calibrate=1;
@ -198,6 +242,7 @@ clock_seconds(void)
}
#ifdef HANDLE_UNSUPPORTED_INTERRUPTS
/* Ignore unsupported interrupts, optionally hang for debugging */
/* BADISR is a gcc weak symbol that matches any undefined interrupt */
ISR(BADISR_vect) {
//static volatile uint8_t x;while (1) x++;
}

View file

@ -86,9 +86,23 @@
#define USART_BAUD_230400 1
#define USART_BAUD_250000 1
#define USART_BAUD_500000 0
#elif F_CPU == 0x800000UL
/* 8192 KHz with external 32768 crystal */
#define USART_BAUD_38400 12
#define USART_BAUD_57600 8
#define USART_BAUD_115200 4
#else
#error "Please define the baud rates for your CPU clock: ATmega128 handbook p. \
195-198 or set the rate in contiki-conf.h"
/* UBRR = F_CPU/(16*BAUD) - 1 */
#warning "Unusual CPU Clock Rate!!!!"
#warning "You may have to tune the UBRR regisgers for the correct baud rates"
#warning "See ATmega128 handbook p. 195-198 or set the rate in contiki-conf.h"
#ifndef USART_BAUD_38400
#define USART_BAUD_38400 F_CPU/(16*38400) - 1
#endif
#ifndef USART_BAUD_57600
#define USART_BAUD_57600 F_CPU/(16*57600) - 1
#endif
#endif

View file

@ -402,6 +402,10 @@
#define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS12 ) )
#define HAL_US_PER_SYMBOL ( 1 )
#define HAL_SYMBOL_MASK ( 0xFFFFffff )
#elif ( F_CPU == 0x800000UL )
#define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) )
#define HAL_US_PER_SYMBOL ( 2 )
#define HAL_SYMBOL_MASK ( 0x7FFFffff )
#elif ( F_CPU == 8000000UL )
#define HAL_TCCR1B_CONFIG ( ( 1 << ICES1 ) | ( 1 << CS11 ) | ( 1 << CS10 ) )
#define HAL_US_PER_SYMBOL ( 2 )

View file

@ -28,7 +28,6 @@
*
* This file is part of the Contiki operating system.
*
* $Id: rtimer-arch.h,v 1.5 2010/02/18 17:21:44 dak664 Exp $
*/
#ifndef __RTIMER_ARCH_H__
@ -42,6 +41,13 @@
* Setting RTIMER_ARCH_PRESCALER to 0 will leave Timers alone.
* rtimer_arch_now() will then return 0, likely hanging the cpu if used.
* Timer1 is used if Timer3 is not available.
*
* Note the rtimer tick to clock tick conversion will be nominally correct only
* when the same oscillator is used for both clocks.
* When an external 32768 watch crystal is used for clock ticks my raven CPU
* oscillator is 1% slow, 32768 counts on crystal = ~7738 rtimer ticks.
* For more accuracy define F_CPU to 0x800000 and optionally phase lock CPU
* clock to 32768 crystal. This gives RTIMER_ARCH_SECOND = 8192.
*/
#ifndef RTIMER_ARCH_PRESCALER
#define RTIMER_ARCH_PRESCALER 1024UL

View file

@ -49,6 +49,11 @@
#ifndef F_CPU
#define F_CPU 8000000UL
#endif
/* MCU_CONF_LOW_WEAR will remove the signature and eeprom from the .elf file */
/* This reduces reprogramming wear during development */
#define MCU_CONF_LOW_WEAR 0
#include <stdint.h>
typedef int32_t s32_t;
@ -76,6 +81,7 @@ unsigned long clock_seconds(void);
/* The 1284p can use TIMER2 with the external 32768Hz crystal to keep time. Else TIMER0 is used. */
/* The sleep timer in raven-lcd.c also uses the crystal and adds a TIMER2 interrupt routine if not already define by clock.c */
/* If F_CPU is 0x800000 the clock tick interrupt routine will (attempt to) keep the cpu clock phase locked to the crystal. */
#define AVR_CONF_USE32KCRYSTAL 1
/* Rtimer is implemented through the 16 bit Timer1, clocked at F_CPU through a 1024 prescaler. */

View file

@ -65,7 +65,6 @@ unsigned char debugflowsize,debugflow[DEBUGFLOWSIZE];
#include "loader/symbols-def.h"
#include "loader/symtab.h"
#include "params.h"
#if RF230BB //radio driver using contiki core mac
#include "radio/rf230bb/rf230bb.h"
#include "net/mac/frame802154.h"
@ -109,6 +108,8 @@ unsigned char debugflowsize,debugflow[DEBUGFLOWSIZE];
#include "net/rime.h"
#include "params.h"
/* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */
/* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */
/* STAMPS will print ENERGEST outputs if that is enabled. */
@ -143,8 +144,10 @@ SIGNATURE = {
};
#endif
#if !MCU_CONF_LOW_WEAR
/* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */
FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,};
#endif
/* Get a pseudo random number using the ADC */
uint8_t
@ -193,6 +196,10 @@ void initialize(void)
if(MCUSR & (1<<WDRF )) PRINTD("Watchdog reset!\n");
if(MCUSR & (1<<JTRF )) PRINTD("JTAG reset!\n");
MCUSR = 0;
PRINTD("CLOCK_SECOND %d\n",CLOCK_SECOND);
PRINTD("RTIMER_ARCH_SECOND %lu\n",RTIMER_ARCH_SECOND);
PRINTD("F_CPU %lu\n",F_CPU);
#if STACKMONITOR
/* Simple stack pointer highwater monitor. Checks for magic numbers in the main

View file

@ -6,7 +6,7 @@
* This allows parameter changes using a hardware programmer or custom application code.
* Corruption test is based on channel verify so get the channel before anything else!
* 2 Obtained from eeprom using the general settings manager and read from program flash if not present.
* Useful for for testing builds without wearing out flash memory.
* Useful for for testing builds without wearing out eeprom memory.
* 3 Obtained from eeprom using the settings manager and rewritten from flash if not present.
* This ensures all parameters are present in upper eeprom flash.
*
@ -21,10 +21,18 @@
//#define CONTIKI_CONF_RANDOM_MAC 1 //adds 78 bytes
#if CONTIKI_CONF_SETTINGS_MANAGER
#if MCU_CONF_LOW_WEAR
#define PARAMETER_STORAGE 2
#else
#define PARAMETER_STORAGE 3
#endif
#else
#if MCU_CONF_LOW_WEAR
#define PARAMETER_STORAGE 0
#else
#define PARAMETER_STORAGE 1
#endif
#endif
/* Include settings.h, then dummy out the write routines */
#include "settings.h"