Here is the code that is working for me. I am sending three bytes to the slave. In this example 10, 20 and 30. The slave adds 1 and sends back 11, 21 and 31.
Here is a snipit of the master portion.
Code:
I2Caddress = $0A
I2CWrite i2cdat,i2cclk,I2Caddress,[10,20,30],NoGo
pauseus 5
i2cread i2cdat,i2cclk,i2caddress,[tp_x, tp_y, tp_dp],NoGo2
pauseus 5
USBBuffer[0] = tp_x
USBBuffer[1] = tp_y
USBBuffer[2] = tp_dp
USBBuffer[3] = 0
gosub dousbout ' I am using USB as a debugger
pause 100
goto mainmenu
NoGo:
USBBuffer[0] = 1
USBBuffer[1] = 2
USBBuffer[2] = 3
USBBuffer[3] = 0
gosub dousbout
goto mainmenu
NoGo2:
USBBuffer[0] = 4
USBBuffer[1] = 5
USBBuffer[2] = 6
USBBuffer[3] = 0
gosub dousbout
goto mainmenu
Here is the full slave. Pic18F2620 @ 20Mhz
Code:
asm
__CONFIG _CONFIG1H, _OSC_HS_1H
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _PBADEN_OFF_3H
__CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
endasm
DEFINE OSC 20
'DEFINE ADC_BITS 10
'DEFINE ADC_CLOCK 3
'DEFINE ADC_SAMPLEUS 50
Define I2C_SLOW 1
DEFINE I2C_HOLD 1
'OSCCON = %01110001 '8mhz
'OSCTUNE.6 = 1 ' PLL selected 32mhz clock
' PicBasic Pro I2C slave program
' Alias pins
scl VAR PORTC.3 ' I2C clock input
sda VAR PORTC.4 ' I2C data input
'ADCON2.7=1
ADCON1 = $F '$B 'an1-an3 analog remainder digital
CMCON = 7 'PortA Digital
'
'---------------- Alias pins -----------------------------------
'SCLDIR var TRISC.3
'SDADIR var TRISC.4
'--------------- Define used register flags -------------------
SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag
SSPIE VAR PIE1.3
BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
R_W VAR SSPSTAT.2 ' SSP (I2C) Read/Write
D_A VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKP VAR SSPCON1.4 ' SSP (I2C) SCK Release Control
SSPEN VAR SSPCON1.5 ' SSP (I2C) Enable
SSPOV VAR SSPCON1.6 ' SSP (I2C) Receive Overflow Indicator
WCOL VAR SSPCON1.7 ' SSP (I2C) Write Collision Detect
STAT_BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
STAT_RW VAR SSPSTAT.2 ' SSP (I2C) Read/Write
STAT_DA VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKE VAR SSPSTAT.6 ' SSP (I2C) Data/Address
WrData var byte
j var byte
'------------------- Rx Buffer defintion --------------------
RxBufferLEN con 3
RxBuffer var byte[Rxbufferlen]
RxBufferIndex var byte
RxCnt var byte
rxcnt = 0
'------------------ Tx Buffer defintion ----------------------
TxBufferLEN con 3
TxBuffer var byte[txbufferlen]
TxBufferIndex var byte
TxCnt var byte
txcnt = 0
'------------------ Define constants ------------------------
rxinptr var byte
rxoutptr var byte
txinptr var byte
txoutptr var byte
rxinptr = 0
rxoutptr = 0
txinptr = 0
txoutptr = 0
I2Caddress CON $0A ' Make address = 2
' Allocate RAM
result VAR BYTE ' ADC result
DataIn VAR BYTE[8] ' Data in
DataOut VAR BYTE[8] ' Data out array
readcnt VAR BYTE ' I2C read count
readcnt = 0 ' Zero counter
'****************************************************************
' Variables used in the program.
'
'****************************************************************
transdata var byte
transbit7 var transdata.7
Tdata var word
txdata var word
tydata var word
txcomp var word
tycomp var word
tx var word
ty var word
tvalue var word
txcomp=0
tycomp=0
tx=0
ty=0
tvalue=0
PD var bit 'pen down flag
address var byte
' -------------- Initialize I2C slave mode ------------------------
'SCLDIR = 1 ' SCL must be an input before enabling interrupts
'SDADIR = 1
SSPADD = I2Caddress ' Set our address
SSPCON1 = $36 ' Set to I2C slave with 7-bit address
SSPCON2.0 = 1
SSPSTAT = 0
SSPIE = 1
SSPIF = 0
RxBufferIndex = 0
TxBufferIndex = 0
'LED1 var PORTC.1
' Interrupt definition
' ====================
' USB interrupt used to keep USB connection alive
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler SSP_INT, _I2C_Int, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
endasm
''----------------- Initialization Done! -----------------------------
@ INT_ENABLE SSP_INT ; Master Synchronous Serial Port Interrupt Flag bit. The transmission/reception is complete
txbuffer = 0
portc.1 = 1'high led1
goto Main
'*****************************************************************************
'------------------------- I2C subroutine --------------------------------
I2C_Int:
If R_W = 0 then 'Write from master
if D_A = 0 then ' It's address from master
address = SSPBUF ' do nothing
rxcnt = 1
rxinptr = 0
rxoutptr = 0
txinptr = 0
txoutptr = 0
else
WCOL = 0
sspov = 0
if bf = 1 then 'There is data in buffer
if rxcnt < rxbufferlen then
rxbuffer[rxinptr] = SSPBUF
rxinptr = rxinptr + 1
if rxinptr = rxbufferlen then rxinptr = 0
endif
rxcnt = rxcnt + 1
EndIF
endif
else ' Read by master
dataout = SSPBUF 'dummy read
if bf = 0 then ' if buffer is empty
if txcnt > 0 then ' Is there a byte to transfer
SSPBUF = txbuffer[txoutptr] 'get the byte abd send it
txoutptr = txoutptr + 1
if txoutptr = txbufferlen then txoutptr = 0
txcnt = txcnt - 1
else
'no byte to send
endif
endif
endif
sspif = 0
CKP = 1
@ INT_RETURN
' -------------------------end I2C subroutine --------------------------------
'--------------------[ main program loop]---------------------------------------
Main:
'SSPOV = 0
'WCOL = 0
'INTCON.7 = 0 'trrn off interrupt
if txcnt < txbufferlen then
TxBuffer[txinptr] = rxbuffer[txinptr] | %00000001 ' add "1" to the data in
txinptr = txinptr + 1
if txinptr = txbufferlen then txinptr = 0
txcnt = txcnt + 1
'INTCON.7 = 1 'turn on interrupt
endif
if rxcnt != 0 then
datain = rxbuffer[rxoutptr]
rxoutptr = rxoutptr + 1
if rxoutptr = rxbufferlen then
rxoutptr = 0
endif
rxcnt = rxcnt - 1
endif
WrData=0
goto main
end
Disregard all the extra stuff, I am using this slave a Touch Screen controller.
Thanks
Dave
Bookmarks