[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-chat] Strange ET-Base ATmega-128 Behavior
From: |
tomdean |
Subject: |
[avr-chat] Strange ET-Base ATmega-128 Behavior |
Date: |
Mon, 14 May 2012 17:35:21 -0700 |
User-agent: |
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20120428 Thunderbird/12.0.1 |
I have several ET-Base ATmega 128 boards that behave strangely on power
cycle or reset.
On random trials, the device will not restart. Frequently, this
alternates Ok, fail, Ok, fail...
I changed wall adapters, even went to battery operation.
The +5 is clean and at 5.1 volts.
I tried three ET-BASE ATmega 128 boards - same.
I built and programmed with AVR Studio and on FreeBSD with avr-gcc+avrdude.
The only connection to the board is a TDS-2014 to look at a port pin.
The code (below) is a simple SPI application - send 10 bytes in a loop
with a 10msec delay.
In the failure mode, the code waits for the spi to complete sending 10
bytes,
while (spi_done ==0) sleep_mode();
I changed this to while (1) if (spi_done) break;
I disconnected power, shorted the power connector, reconnected power.
Every other time , (mostly) it works than fails.
Same behavior with the reset button.
The code does not write to fuses, eeprom, or flash!
Any ideas?
Tom Dean
/*
* uM_FPU.c
*
* Created: 5/14/2012 1:10:48 PM
* Author: tomdean
*/
/////////////////////////////////////////////////////////
// includes
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <uM_FPU.h>
/////////////////////////////////////////////////////////
// initialize
void initialize() {
TRACE_INIT;
timer_init();
spi_init();
DDRB = 0xf7; // MISO in all others out
PORTB |= _BV(4); // de-select the uM-FPU
set_sleep_mode(SLEEP_MODE_IDLE );
}
/////////////////////////////////////////////////////////
// main
int main(void) {
initialize();
sei();
while(1) {
TRACE_ON(0);
spi_count = 10;
spi_idx = 1;
spi_done = 0;
PORTB &= ~_BV(4); // select uM-FPU
SPDR = spi_buf[0];
//while (spi_done == 0) sleep_mode();
while (1) if (spi_done == 1) break;
PORTB |= _BV(4); // de-select uM-FPU
TRACE_OFF(0);
timer_wait_ms(10);
}
}
// timer.c - timer for uM_FPU
////////////////////////////////////////////////
// includes
#include <avr/io.h> // port definitions
#include <avr/interrupt.h> // sei
#include <uM_FPU.h>
volatile unsigned long timer_ms;
//////////////////////////////////////////////////////////////
// initialize
void timer_init(void) {
TCNT0 = 0;
// CTC, F_CPU/64
TCCR0 = _BV(WGM01) | _BV(CS02);// | _BV(CS00);
// every 250 TCNT0 clocks generate an interrupt and clear the counter
OCR0 = 249; // tuned w/ TDS-2014
// compare match interrupt enable
TIMSK |= _BV(OCIE0);
// clear the timer count
timer_ms = 0UL;
// enable interrupts
//sei();
}
//////////////////////////////////////////////////////////////
// clear
void timer_clear() {
timer_ms = 0UL;
}
//////////////////////////////////////////////////////////////
// get current time in ms since last clear
unsigned long timer_current() {
return timer_ms;
}
//////////////////////////////////////////////////////////////
// timer has elapsed
uint8_t timer_has_elapsed(unsigned long start, unsigned int ms_wait) {
return timer_ms - start > ms_wait;
}
//////////////////////////////////////////////////////////////
// wait ms
void timer_wait_ms(unsigned int ms_wait) {
unsigned long start = timer_ms;
while (timer_ms - start < (unsigned long)ms_wait);
}
//////////////////////////////////////////////////////////////
// wait us
void timer_wait_us(unsigned int us_wait) {
cli();
while (us_wait--) {
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
sei();
}
//////////////////////////////////////////////////////////////
//
ISR(TIMER0_COMP_vect) {
TRACE_TOGGLE(7);
timer_ms++;
}
ISR(TIMER0_OVF_vect) {
TRACE_TOGGLE(6);
}
// spi.c - spi implementation
#include <avr/io.h>
#include <avr/interrupt.h>
#include <uM_FPU.h>
volatile uint8_t spi_buf[100];
volatile uint8_t spi_done;
volatile uint8_t spi_idx;
volatile uint8_t spi_count;
void spi_init() {
//DDR_SPI = _BV(MOSI) | _BV(SCK);
SPSR = 0; // make sure no pending interrupt
SPCR = _BV(SPIE) | _BV(SPE) | _BV(MSTR) | _BV(SPR0);
spi_done = spi_idx = spi_count = 0;
}
ISR(SPI_STC_vect) {
TRACE_ON(5);
SPCR |= _BV(MSTR);
if (spi_idx == spi_count) spi_done = 1;
else SPDR = spi_buf[spi_idx++];
TRACE_OFF(5);
}
/*
* IncFile1.h
*
* Created: 5/14/2012 1:17:36 PM
* Author: tomdean
*/
#ifndef INC_UM_FPU_H
#define INC_UM_FPU_H
/////////////////////////////////////////////
// trace
#define TRACE_PORT PORTC
#define TRACE_DDR DDRC
#define TRACE_ON(n) TRACE_PORT |= _BV(n)
#define TRACE_OFF(n) TRACE_PORT &= ~_BV(n)
#define TRACE_TOGGLE(n) TRACE_PORT ^= _BV(n)
#define TRACE_INIT \
TRACE_DDR = 0xff; \
TRACE_PORT = 0
/////////////////////////////////////////////
// spi
#define DDR_SPI DDRB
#define SCK 1
#define MOSI 2
extern volatile uint8_t spi_buf[100];
extern volatile uint8_t spi_done;
extern volatile uint8_t spi_idx;
extern volatile uint8_t spi_count;
/////////////////////////////////////////////
// prototypes
void timer_init(void);
void timer_clear(void);
unsigned long timer_current(void);
uint8_t timer_has_elapsed(unsigned long, unsigned int);
void timer_wait_ms(unsigned int);
void timer_wait_us(unsigned int);
void spi_init(void);
void initialize(void);
#endif
- [avr-chat] Strange ET-Base ATmega-128 Behavior,
tomdean <=