Shop OBEX P1 Docs P2 Docs Learn Events
I2C slave problem — Parallax Forums

I2C slave problem

edited 2010-03-13 23:09 in General Discussion
I'm trying to get an I2C slave module working on the SX, and I can't seem to get it right at all. I manually typed in the Guenther Daubach program and ran it, in Debug mode, and I got this message:

"Bit_Co is not a valid integer"

So, I just try to run the program in "Run" mode, and all that happens is the heat sink gets really hot. I have 4 LED's connected to PORTB's lower 4 bits so that I can see the counting up. But... nothing.

I also have a very minimal data analyzer hooked up, and I don't see anything going on.

Could someone please give me some tips?

I don't need any wires hooked up to SDA and SCL, do I? Besides the data analyzer, I mean. Are all my settings OK for it to
send data to itself? I'm still kind of unsure about DeviceType. It can only be a 1 or a 0, so if you are trying to prioritize which Master has priority on the bus, you're not getting much of a selection there.

Also, like I said, I have 4 LED's hooked up to portB, so I can see it work. Maybe I didn't put that data line in the right spot???

Thanks for any and all help.



[noparse][[/noparse]code];==================================
; Programming the SX Microcontroller
; App025.src
;=======================================

include "Setup28.inc"

;--Modify these definitions as needed
;
SELF_TEST equ 1
SCOPE equ 1

DEV_TYPE equ 1
DEV_ID equ 3
BIT_COUNT equ 16
WAIT_IDLE equ 4

REPEAT_SEND equ 5

I2C_PORT equ ra
SCL_BIT equ 0
SDA_BIT equ 1
I2C_BIT_MASK equ %11111100

INT_PERIOD equ 125



;

;-- Internal definitions

ifdef SELF_TEST
DEV_ADDR equ ((DEV_TYPE * 8) + DEV_ID) * 16
else
DEV_ADDR equ (((1-DEV_TYPE) * 8) + DEV_ID) * 16
endif
; DEV_ADDR equ 0xA0

TRIS equ 00fh
LVL equ 00dh
INT_ON equ %10011110 ;Enable RTCC interrupt
SCL equ I2C_PORT.SCL_BIT
SDA equ I2C_PORT.SDA_BIT

SDA_LOW macro
clrb TrisMask.SDA_BIT
endm

SDA_HIGH macro
setb TrisMask.SDA_BIT
endm

SCL_LOW macro
clrb TrisMask.SCL_BIT
endm

SCL_HIGH macro
setb TrisMask.SCL_BIT
endm

SkipIfNotSda macro
snb SDA
endm

SkipIfScl macro
sb SCL
endm

SkipIfNotScl macro
snb SCL
endm

StartTx macro
setb Flags.0
endm

StopTx macro
clrb Flags.0
endm

SkipIfTxNotBusy macro
snb Flags.0
endm

SetTxError macro
setb Flags.1
endm

ClrTxError macro
clrb Flags.1
endm

SkipIfNoTxError macro
snb Flags.1
endm

SetRxData macro
setb Flags.2
endm

ClrRxData macro
clrb Flags.2
endm

SkipIfNoRxData macro
snb Flags.2
endm

;-- Global Variables

org $08

Flags ds 1
DevAddr ds 1
Timer ds 3

;--Variables for the I2C master

org $50
I2C_Tx equ $

TxData ds 2
TxBuffer ds 2
TxState ds 1
TxSubState ds 1
TxRepeat ds 1
TxBitCount ds 1
TxTimer ds 1
TrisMask ds 1
TxTimeout ds 1

;--Varibles for the I2C slave

org $70
I2C_Rx equ $

RxData ds 2
RxBitCount ds 1
RxState ds 1
RxSubState ds 1
RxTimeout ds 1

;--ISR

org $00
call @I2CTX
call @I2CRX

bank I2C_Tx
and I2C_PORT, #I2C_BIT_MASK
mov !I2C_PORT, TrisMask

mov w, #-INT_PERIOD
retiw

;--Initialize the ports


InitPorts
mode TRIS
mov !rb, #%11110000

mode LVL
mov w, #%11111100
mov !I2C_PORT, w
mode TRIS

ifdef SCOPE
mov !rc, #%11111110
endif
ret

org $100

Start ;Mainline program

include "Clr2x.inc"

call InitPorts
mov DevAddr, #DEV_ADDR
bank I2C_Tx
mov TxData, DevAddr

mov TrisMask, #I2C_BIT_MASK
setb TrisMask.SCL_BIT
setb TrisMask.SDA_BIT
mov !I2C_PORT, TrisMask
mov !option, #INT_ON
mov Timer+1, #5

Main ;Main Program Loop
SkipIfNoRxData
;nop
;mov rb, RxData + 1

SkipIfTxNotBusy
jmp Main

[noparse]:D[/noparse]elay
decsz Timer
jmp [noparse]:D[/noparse]elay
StartTx
decsz Timer+1
jmp Main
add TxData+1, #1
addb TxData, c
and TxData, #$0f
or TxData, DevAddr


jmp Main

org $200
;--I2C master
bank I2C_Tx

ClockHigh
SCL_HIGH
inc TxSubState
retp

ClockLow
ifdef SCOPE
clrb rc.0
endif
SCL_LOW
inc TxSubState
retp

DataHigh
SDA_HIGH
inc TxSubState
retp

WaitClockHigh;
SkipIfNotScl
inc RxSubState
retp

I2CTX ;I2C Master
mov w, TxState
jmp pc + w
:TxIdle
jmp :Idle
:TxInit
jmp :InitSend
jmp :SetStart
jmp :SendData
jmp :GetAck
jmp :SetStop

:TxError
jmp :HandleError

:Idle
mov TxRepeat, #REPEAT_SEND+1
SDA_HIGH
SCL_HIGH
SkipIfTxNotBusy
inc TxState
retp

:InitSend
mov TxBuffer, TxData
mov TxBuffer+1, TxData+1
ifdef SCOPE
setb rc.0
endif
mov TxBitCount, #BIT_COUNT
ClrTxError
clr TxTimeout
clr TxSubState
inc TxState
retp

:SetStart
mov w, TxSubState
jmp pc+w
jmp :StartInit
jmp :WaitIdle

:StartInit
SCL_HIGH
SDA_HIGH
mov TxTimer, #WAIT_IDLE
inc TxSubState
retp

:WaitIdle
dec TxTimeout
snz
jmp :HandleError
sb SCL
jmp :NotIdle
sb SDA
jmp :NotIdle
dec TxTimer

sz
retp
clr TxTimeout
SDA_LOW
clr TxSubState
inc TxState
retp

:NotIdle
mov TxTimer, #4
retp

:SendData
mov w, TxSubState
jmp pc+w
jmp ClockLow
jmp :SetDataBit
jmp ClockHigh
jmp :CheckClockHigh

:SetDataBit
SDA_HIGH
sb TxBuffer.7
SDA_LOW

inc TxSubState
retp

:CheckClockHigh
dec TxTimeout
snz
jmp :HandleError
sb SCL
retp
sb TxBuffer.7
jmp :PrepareNext
SkipIfNotSda
jmp :PrepareNext
mov TxState, #(:TxError-:TxIdle)
retp

:PrepareNext
clr TxTimeout
rl TxBuffer + 1
rl TxBuffer
clr TxSubState
dec TxBitCount
sz
retp
inc TxState
retp

:GetAck
mov w, TxSubState
jmp pc+w
jmp ClockLow
jmp DataHigh
jmp ClockHigh
jmp :CheckClockHighAck

:CheckClockHighAck
dec TxTimeout
snz
jmp :HandleError
sb SCL
retp
inc TxState
clr TxSubState
SkipIfNotSda
SetTxError
retp

:SetStop
mov w, TxSubState
jmp pc+w
jmp ClockLow
jmp [noparse]:D[/noparse]ataLow
jmp ClockHigh
jmp DataHigh
jmp DataHigh
jmp :TxFinish

[noparse]:D[/noparse]ataLow
SDA_LOW
inc TxSubState
retp

:TxFinish
inc TxState
SkipIfNoTxError
retp
clr TxState
StopTx
retp

:HandleError
SCL_HIGH
SDA_HIGH
clr TxSubState
clr TxState
dec TxRepeat
mov w, #(:TxInit - :TxIdle)
sz
mov TxState, w
StopTx
SetTxError
retp

org $400

I2CRX

bank I2C_Rx
SkipIfNoRxData
retp
dec RxTimeout
snz
jmp :RxError

mov w, RxState
jmp pc+w
jmp :RxDetectStart
jmp :RxGetBits
jmp :RxSendAck

:RxDetectStart
mov w, RxSubState
jmp pc + w
jmp :WaitSdaHigh
jmp :WaitSdaLow

:WaitSdaHigh
SkipIfNotSda
inc RxSubState
retp

:WaitSdaLow
SkipIfNotSda
retp
SkipIfScl
jmp :RxError
mov RxBitCount, #BIT_COUNT
clr RxSubState
inc RxState
retp

:RxGetBits
mov w, RxSubState
jmp pc+w
jmp :WaitClockHigh
jmp :GetDataBit

:GetDataBit
clc
SkipIfNotSda
stc
rl RxData +1
rl RxData
decsz RxBitCount
jmp :SetupNext
clr RxSubState
inc RxState
retp

:SetupNext
dec RxSubState
retp

:RxSendAck
mov w, RxSubState
jmp pc+w
jmp :WaitClockLowAck
jmp :WaitClockHigh
jmp :WaitClockLow

:WaitClockLowAck
SkipIfNotScl
retp
mov w, RxData
ifndef SELF_TEST
xor w, #%10000000
endif
bank I2C_Tx
and w, #$f0
mov w, DevAddr-w
snz
SDA_LOW
bank I2C_Rx
inc RxSubState
retp

:WaitClockHigh
SkipIfNotScl
inc RxSubState
retp

:WaitClockLow
SkipIfNotScl
retp
ifndef SELF_TEST
bank I2C_Tx
SDA_HIGH
bank I2C_Rx
endif
SetRxData

:RxError
clr RxState
clr RxSubState
clr RxTimeout
retp


RESET Main

Comments

  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2010-03-12 19:12
    What heat sink are you talking about? Is this on one of the Parallax Protoboards for the SX28? Can you post a schematic and perhaps a picture of your setup?

    It sounds like the SX28 is supposed to be a slave device. What device is the master and what are you trying to send to it. How are they connected? Are you trying to send data to a pin configured as a output instead of an input?
  • edited 2010-03-12 20:18
    RobotWorkshop said...
    What heat sink are you talking about? Is this on one of the Parallax Protoboards for the SX28? Can you post a schematic and perhaps a picture of your setup?

    It sounds like the SX28 is supposed to be a slave device. What device is the master and what are you trying to send to it. How are they connected? Are you trying to send data to a pin configured as a output instead of an input?

    A schematic would only show a Parallax protoboard with 4 LED's coming out of port b with 4 4700 ohm resistors used to keep each LED from "letting the smoke out".

    The heatsink on the Parallax protoboard sold by Parallax. There's just 4 LED's connected to port b's lowest 4 bits, that's all right now. The program is supposed to be able to send a message to itself, according to the book by Mr. Daubach. Later on, after I get it talking to itself, I'll disable the Master I2C section, and just have the Slave part running. A PIC16F690 will be the Master. Later on, the SX will be the slave only, rather than a master and a slave at the same time.


    I've been fiddling around with this for a while, and before on a different setup, with it connected to the PIC16f690, I tried using the SXBasic software but that didn't work either. The PIC sent out a nice I2C wave packet, but when I hooked it up to the SX, it got all messy.

    I'd rather use the SX assembly I2C, because the rest of the program will be in assembly. Here's how the waveforms look using SXB, and the following very simple code:


    DEVICE         SX28, OSCXT2, TURBO, STACKX, OPTIONX
    FREQ         4_000_000
    ID         "I2C"
    
    SDA         PIN     RA.0 INPUT 
    SCL         PIN     RA.1 INPUT
    
                
    Ack         CON     0
    Nak         CON     1
    
    RxAddy         VAR     Byte
    
    
    WATCH RxAddy
    PROGRAM Start
    
    Start:
    TRIS_B = %11110000             ' make LED ports outputs
    Main:
      DO
    
       I2CRECV SDA, RxAddy, Ack
     
      RB = RxAddy
      
      LOOP
    



    Like I said, though, I'd rather do the whole program in SX assembly.

    Post Edited (Indisputable Attitude) : 3/12/2010 8:24:06 PM GMT
    648 x 436 - 71K
    643 x 437 - 61K
  • edited 2010-03-13 08:02
    I had a chance to fiddle around some more with this project. I have a clean signal going from the PIC to the SX, as determined by use of the PICKIT2's built-in data logger.

    I just don't know why the SX software doesn't grab the data packets. Does anyone have a copy of Guenther Daubach's program that is confirmed OK? Is it possible that the problem has something to do with the Debug error message?

    I don't get that either. Why would the Debug come up with an error, and then gray-out the Run button, but I can run the program no problem when I run it by hitting Control-A?

    Someone out there PLZ help.
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2010-03-13 12:58
    I had to ask about the schematic since people often have all sorts of configurations and many are hand wired on a breadboard. Since you are using one of the prebuilt protoboards that answers a lot about your setup. I have to question the use of 4700 ohm resistors for the LED's and I assume that was a typo and you probably meant 470 ohm resistors instead.

    A couple things come to mind regarding the debug issue. That is usually grayed out when ever the resonator is left in the circuit. If you are using a resonator it must be pulled out for debugging to work. For programming and normal operation it can be left in place. Are you using a 4Mhz resonator? If so are you leaving the SX-key plugged in after programming? Another question is if you are using the older Serial version of the SX-Key or the newer USB version.

    I went back and searched the SX forum and found some threads talking about I2C which may help:

    http://forums.parallax.com/forums/default.aspx?f=7&m=333732

    http://forums.parallax.com/forums/default.aspx?f=7&m=312895

    http://forums.parallax.com/forums/default.aspx?f=7&m=269425

    http://forums.parallax.com/forums/default.aspx?f=7&m=236034

    http://forums.parallax.com/forums/default.aspx?f=7&m=252244

    The SX/B code changed a bit with newer versions of the compiler. Depending upon what version you're using that may be a factor.
  • edited 2010-03-13 21:57
    I'm going to try that 4th link software that Zoot posted. It's also at the SXList site, just for future reference:
    http://www.sxlist.com/techref/scenix/lib/io/osi2/i2c/i2c_slave.src

    I really am using 4700 ohm resistors with the LED's. I can still see them just fine for testing purposes, and I know I'm way under the current maximum, even without having to do a calculation.

    I have an older 9-pin D-sub connector style SX-Key, that says, "Revision F" on it. I've run many programs on it without any problems. I've pulled the oscillator out, so that can't be the problem.

    Still, the program seems to be doing something when I use the I2C example in the "Programming the SX Microcontroller" book. I was hoping someone would find a line out of place.

    BTW... in the i2cs.src program, he allows you to choose whichever two port pins you want. But... isn't the SX hardware set up so that only PortB can trigger interrupts? So wouldn't that mean that I can't use PortA?

    Anyway, thanks for the tips and advice, please keep them coming. I'll post in this thread after I run the i2cs.src program.
  • Martin HodgeMartin Hodge Posts: 1,246
    edited 2010-03-13 23:09
    The author of that program may not be using hardware interrupts, opting instead to do polling in a software interrupt. That would allow any pin to be used.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -MH
Sign In or Register to comment.