avr-chat
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]