Atmega8 SPI init?

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

I want to Init ATmega8 SPI port to MASTER. What's the matter whit this code? (SPI doesnt transmit, SS pin is configured as output)

sbi MOSI_PORT,MOSI
sbi MOSI_DIR,MOSI

sbi MISO_PORT,MISO
cbi MISO_DIR,MISO

sbi SCLK_PORT,SCLK
sbi SCLK_DIR,SCLK

ldi R16,0b01011100
out SPCR,R16

ldi R16,0b00000000
out SPSR,R16

in R16,SPSR
in R16,SPDR ;Clear SPIF & WCOL bits

I try transmit a byte

ldi R16,SomeData
out SPDR,R16

VFX.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is one of my init routine.

;Set up SPI, LSB first, Master, clock idle high, phase=1, clock fck/64
ldi r17,(1<<SPE)|(1<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0)|(1<<SPR1)

out SPCR,r17

You will need to change the parameters according to your requirements.

This is my SPI output routine. spireg can be changed to r16.

spi_out:
; Start transmission of data (spireg)
cbi portb,SS ;Clear /SS pin
out SPDR,spireg
; Wait for transmission complete
Wait4spif:
sbis SPSR,SPIF
rjmp Wait4spif
sbi portb,SS ;Set /SS pin
ret

admin's test signature
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thx, this is same as my init rutin. I tried a lot of commbination, but SPI doesnt transmit. Now I use SW SPI, not HW.

VFX.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hummmm... works OK in the southern hemisphere :-))

admin's test signature
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Its looks like Budapest is too far from southern hemisphere :)) Not works. :(((((((

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are all the ports defined to the correct address port B? Also just check again that the SS pin is infact an output (don't see it set up in the above), and the last point the pins for the SPI are different in say the mega8 and the 8535. I'm using the mega8's SPI without hiccups (of course just check that the chip is ok just in case some pins are blown)

All assigned to portb.
MOSI_PORT, MOSI_DIR, MISO_PORT, MISO_DIR, SCLK_PORT, SCLK_DIR

admin's test signature
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

.EQU YellowLED_DIR = DDRB ;Yellow LED
.EQU YellowLED_PORT= PORTB
.EQU YellowLED = 2

.equ MOSI_DIR = DDRB
.equ MOSI_PORT = PORTB
.equ MOSI = 3

.equ MISO_DIR = DDRB
.equ MISO_PORT = PORTB
.equ MISO_PIN = PINB
.equ MISO = 4

.equ SCLK_DIR = DDRB
.equ SCLK_PORT = PORTB
.equ SCLK = 5

....

SBI YellowLED_PORT,YellowLED ;LED
SBI YellowLED_DIR,YellowLED ;LED -> Output

sbi MOSI_PORT,MOSI
sbi MOSI_DIR,MOSI

sbi MISO_PORT,MISO
cbi MISO_DIR,MISO

sbi SCLK_PORT,SCLK
sbi SCLK_DIR,SCLK

HW SPI not work, but I use SW (at same pins) is wokrs well (I made a TouchScreen controller and a would like to send measured positon to an ATmega128):

SPISendByte:
ldi R17,8 ;8 bitet kuldunk
SPISb1: sbrc R18,7 ;kimarad ha bit7 = 0
sbi MOSI_PORT,MOSI
sbrs R18,7 ;kimarad ha bit7 = 1
cbi MOSI_PORT,MOSI
cbi SCLK_PORT,SCLK ;CLK=L
nop
nop
nop
nop
nop
sbic MISO_PIN,MISO ;kimarad ha MISO = L
sec
sbis MISO_PIN,MISO ;kimarad ha MISO = H
clc

rol R18 ;kovetkezo bit beleptet

sbi SCLK_PORT,SCLK ;CLK=H
dec R17
brne SPISb1
ret

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's a cut and paste version of the important stuff I've used with sucess to communicate with a SEEPROM on the SPI bus with the Mega8 as the Master.

; **** SPI Control Register ****
ldi TEMP,0b01011111
out SPCR,TEMP

; **** PORT B Data Directon Register ****
ldi TEMP,0b11101111
out DDRB,TEMP
ldi TEMP,0b11111111
out PORTB,TEMP

; Send byte to SEEPROM

cbi PORTB,CS_SEEP ;Select SEEPROM
ldi TEMP,SEEPREAD ;Setup for SEEPROM Read Instruction
out SPDR,TEMP ;Send instruction on SPI bus to device

then just do a 'sbis SPSR,SPIF' instruction waiting for the byte to be fully sent and that's it!!.

Do you have a scope to see that there is actually data being sent on the SPI bus and maybe the SPI setup doesn't match between devices?

admin's test signature
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Data path: ATmega8 -> CPLD -> ATmega128

I can debug CPLD. ATmega8 SCLK pin isn't pulsed (always Low).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry to point this out again but the SS pin is not initiliased above(VFX post). If the SS pin is configured as an input and it is low or goes low during transmission, the SPI will not transmit or will abort transmission.
Also you say "ATmega8 SCLK pin isn't pulsed (always Low)" that's strange because it is set up for normally high, active low. From you post:
ldi R16,0b01011100
out SPCR,R16 So both cpol and cpha are set for 1 or mode 3. Well if you are happy with the software SPI don't pursue this any further :-)

admin's test signature
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Also you say "ATmega8 SCLK pin isn't pulsed (always Low)" that's strange because it is set up for normally high, active low. From you post:"

As you pointed out /SS is not initialized as an output, this can cause the same behaviour on SCK as well.

If /SS is sensed LOW, the SPI hardware will override the DDRx settings for all SPI input pins, except SS. And when SS is low, all SPI pins are inputs except MISO and /SS. When master the only required input is MOSI.

The result is that the chip may think it's addressed as a slave, consequentially SCK is set as input. Remember that it's the master that drives the SCK line. And in this case the actual master, may believe it's being addressed as a slave, thus never asserting SCK.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thx all for help!

I used SS pin as output (drives a yellow led):

.EQU YellowLED_DIR = DDRB ;Yellow LED
.EQU YellowLED_PORT= PORTB
.EQU YellowLED = 2

SBI YellowLED_PORT,YellowLED ;LED
SBI YellowLED_DIR,YellowLED ;LED -> Output

SW SPI is works well. This is good for me, but I wondering, that HW SPI doesnt work.

Thanx
best regards
VFX

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

try setting the DDRx register after setting up the SPCR, as the init of SPCR perform some configuration, or some other code has inadvertantly set the bits to something else.

I use the following code order. This method has worked on all AVR's with SPI that I have Tried. Note that this code was designed for multiple masters, as such I only enable SPI for the duration of a transaction.

Startup-init
All SPI Pins as inputs, except /SS
Set SPSR (SPI2X=0)
Set SPCR (MSTR=1, SPIEN=0, CPOL=1, CPHA=1, SPIR=Fosc/4)

; to acquire SPI bus
Set SPCR (MSTR=1, SPIEN=1, CPOL=1, CPHA=1, SPIR=Fosc/4)
Set SPIPORT (SCL=1, MOSI=1, MISO=0, [SS=1])
Set SPIDDR (SCL=1, MOSI=1, MISO=0, [SS=1])

; to send/receive a byte
Write SPDR
wait for SPSR.SPIF=1
Read SPDR
; repeat transfers as necessary for entire transaction

; release SPI for other devices
Set SPCR (MSTR=1, SPIEN=0, CPOL=1, CPHA=1, SPIR=Fosc/4)
Set SPIPORT (SCL=0, MOSI=0, MISO=0, [SS=1])
Set SPIDDR (SCL=0, MOSI=0, MISO=0, [SS=1])

The above method was used to share a dataflash with 4 AVR's.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.