Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

SPI on an ATmega not quite working

SPI on an ATmega not quite working

2004-02-03 by Brian Dean

Hi,

This is my first time using the hardware SPI on an ATmega, although
I've bit banged SPI plenty of times.  I want to use the hardware SPI
since all the shifting happens in the background.

What I've found is that while the data seems to be being shifted out
and the clock generated OK, nothing seems to be being sensed on the
MISO input of the master.  I.e., I send commands, but responses all
come back as 0x00 or 0xff depending on whether I have the internal
pull-up enabled on the MISO pin.

Is this normal for the hardware SPI?  While the data sheet is not
perfectly clear to me, it seems to imply that when you write data to
the SPDR register, the clock begins and the data is shifted out.  Once
shifting is complete as signaled by the SPIF flag in the SPSR
register, you are then supposed to read the SPDR register which should
contain the previous response from the slave device.  Is this correct?

Just to double check the slave, I implemented a simple bit bang SPI
using the same pins that are used by the hardware SPI and I then get
the expected responses from the slave.  Perhaps I've misconfigured the
SPI for what I want to do?  Can anyone offer a suggestion?

Here's my setup and byte transfer code for an ATmega128:

void spi_init(void)
{
  DDRB   = 0x07;  /* /SS, CLK, & MOSI are outputs */
  PORTB |= 0x01;  /* deselect slave */
  PORTB |= 0x08;  /* enable MISO pull-up */

  /*
   * set up for master, lsb first, clock idle high, sample on trailing
   * edge, freq=fosc/128 (125,000 bps @ 16 MHz)
   */
  SPCR = BV(SPE)|BV(MSTR)|BV(DORD)|BV(CPOL)|BV(CPHA)|BV(SPR1)|BV(SPR0);
}


uint8_t spi_tx_rx(uint8_t c)
{
  uint8_t b;

  SPDR = c;
  while (!(SPSR & BV(SPIF)))
    ;

  b = SPDR;

  return b;
}

For sanity's sake, I've tried all variations of DORD, CPOL, and CPHA,
with no affect.  All received data comes back as 0xff.

Any ideas?

Thanks,
-Brian
-- 
Brian Dean, bsd@bdmicro.com
BDMICRO - Maker of the MAVRIC ATmega128 Dev Board
http://www.bdmicro.com/

Re: [AVR-Chat] SPI on an ATmega not quite working

2004-02-03 by Brian Dean

On Mon, Feb 02, 2004 at 10:13:53PM -0500, Dave VanHorn wrote:

> The MISO pin is defined as input in DDR, right?

Yep.  On the ATmega128, MISO is bit 3 of PORTB (mask 0x08).  I
initialize DDRB to 0x07 which sets /SS, SCK, and MOSI to outputs and
MISO as an input.

-Brian
-- 
Brian Dean, bsd@bdmicro.com
BDMICRO - Maker of the MAVRIC ATmega128 Dev Board
http://www.bdmicro.com/

Re: [AVR-Chat] SPI on an ATmega not quite working

2004-02-03 by Brian Dean

After hooking up a scope and taking some measurements, I think the
problem might be that the hardware SPI on the ATmega128 is too fast
for the device I'm hooking up.  At the largest prescale for the
hardware SPI, I measure the SPI clock at around 116 KHz.  This is
close to what the datasheet says which at my crystal freq of 16 MHz,
SPI clock should be fosc/128 = 125 KHz which is in the ballpark.

When I switch over to my manual bit banging, I needed to insert a
small delay to slow down the clock toggling for reliable
communication.  Right at the border for when it works and when it
doesn't work, the clock is at around 36 KHz - significantly slower
than the slowest I can make the hardware SPI clock run.

So it looks like the problem is that the slave device is too slow to
keep up, and that I cannot prescale the hardware SPI clock down
enough.  Bummer.

The device I'm hooking up, BTW, is a Sony PS/2 gamepad.

It's still possible I'm doing something wrong.  I'd really like to use
the hardware SPI if possible, it seems much more elegant than bit
banging it.  But whatever works, I guess.

-Brian
-- 
Brian Dean, bsd@bdmicro.com
BDMICRO - Maker of the MAVRIC ATmega128 Dev Board
http://www.bdmicro.com/

Re: [AVR-Chat] SPI on an ATmega not quite working

2004-02-03 by Dave VanHorn

At 11:53 PM 2/2/2004 -0500, Brian Dean wrote:
>After hooking up a scope and taking some measurements, I think the
>problem might be that the hardware SPI on the ATmega128 is too fast
>for the device I'm hooking up.  At the largest prescale for the
>hardware SPI, I measure the SPI clock at around 116 KHz.  This is
>close to what the datasheet says which at my crystal freq of 16 MHz,
>SPI clock should be fosc/128 = 125 KHz which is in the ballpark.

<VBG>
My current project is running 4 MHz SPI, and at that, I have two pushpops 
waiting for the byte to clear. :)
If I could get the SPI on the M8, with internal RC osc, up to 6 MHz, then I 
wouldn't have to wait.

It's only bugging me because it's too fast to go interrupt driven, but I 
don't have enough waste cycles to do anything useful.

I'm also taking data from the host at 800kbits/sec, and doing a fun pixel 
count.
I have to count, in a 104 byte string, how many total black bits, and how 
many under each of 0x88, 0x44, 0x22, and 0x11 masks.
Then I do compensated burn time calculations for either four burns masked 
like that, or two masked as 0xAA,0x55
I also have to load the head either two or four times per burn line.
Tonights test gives 33 lines/sec print speed, roughly 1.5x the 
competition's top of the line machine..

I had a different problem though. I asked them to put resistors in series 
with the SPI clock and data leads, to keep EMI down..
They put in values 50 TIMES larger than I asked for..
Input is a sharp square wave, output looks like wiggling a rope..

>When I switch over to my manual bit banging, I needed to insert a
>small delay to slow down the clock toggling for reliable
>communication.  Right at the border for when it works and when it
>doesn't work, the clock is at around 36 KHz - significantly slower
>than the slowest I can make the hardware SPI clock run.

check that the polarity is right, it might be loosing it in setup time.

>So it looks like the problem is that the slave device is too slow to
>keep up, and that I cannot prescale the hardware SPI clock down
>enough.  Bummer.

My first version of the printer was software driven, no spi.
I was so pushed for speed, that I didn't loop the byte, or the line routines.
104 straightlined calls to a straightlined byte output engine.
Ouch.


>The device I'm hooking up, BTW, is a Sony PS/2 gamepad.
>
>It's still possible I'm doing something wrong.  I'd really like to use
>the hardware SPI if possible, it seems much more elegant than bit
>banging it.  But whatever works, I guess.

Well, you can always underclock, or use the FDIV register.

Re: [AVR-Chat] SPI on an ATmega not quite working

2004-02-03 by Brian Dean

On Tue, Feb 03, 2004 at 12:06:26AM -0500, Dave VanHorn wrote:

> Tonights test gives 33 lines/sec print speed, roughly 1.5x the
> competition's top of the line machine..

Sounds very cool!  My application is nothing so time critical - it is
part of the operator interface for a robot rover.  On the operator
side sits a radio modem, MAVRIC-II, and Sony PS/2 controller.  On the
robot sits the other radio modem.  I've used the second serial port on
the MAVRIC-II to act as a pass-thru so that I can hook up a laptop for
a command interface.  When that is not in use, I have the game
controller to send commands to control various aspects of the robot.

On the robot I've got another MAVRIC-II and am using the on-board
RS-485 interface to control a pair of dual h-bridge motor controllers.
I had these made which incorporate an ATmega8 w/RS-485 which drives a
pair of LMD18200's.  The Mega8 generates the PWM, senses the encoders,
motor current, and thermal shutdown of each of the h-bridges.  I also
implemented a built-in PID algorithm on the controllers to maintain
constant velocity so it is set and forget.  Communication between
these smart motor controllers and the MAVRIC-II is with a packet
protocol over the RS-485 bus.

So the MAVRIC-II on the robot is free to control other stuff.  I'm
currently working on collision avoidance sensors (combination of bump,
IR, and motor stall detection) and a pan/tilt camera mount for remote
video.

The base is powerful - I need to be careful because it is strong
enough to push heavy object aside with ease, climb over anything it's
tires can get a grip on, damage walls, furniture, etc.  I'm intending
it to mostly live outside.

-Brian
-- 
Brian Dean, bsd@bdmicro.com
BDMICRO - Maker of the MAVRIC ATmega128 Dev Board
http://www.bdmicro.com/

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.