View previous topic :: View next topic |
Author |
Message |
syndetic1
Joined: 02 Jan 2007 Posts: 76
|
Posted: Thu Dec 02, 2021 11:23 pm Post subject: XMEGA I2C |
|
|
Hi guys,
I am stuck getting the I2C to work on a XMEGA128A1
I cant get it to work with either Hardware or Software I2C (Code below).
It's gets stuck on the I2C start. So whatever I am doing it's pretty fundamental. By stuck, I mean the program hangs.
It does not matter what I2C address I use. I do have a AT30TS74 I2C temperature sensor connected but I would have thought that the code should run even if there is nothing on the bus?
I put a CRO on the SCL line and with the hardware version of the code, get not clock pulses and with the software version, I get 1 clock pulse.
So Whatever I am doing is pretty basic.
SOFTWARE VERSION
Code: |
'*******************************************************************************
' FILENAME: ATXMEGA128A1 ADC Test x.bas
'
' PROCESSOR: ATXMEGA128A1
' CLOCK: 16Mhz XTAL
' TITLE:
' BOARD: 0420-04 and 0420-01
' MODIFIED: 3-DEC-2021
' AUTHOR: Frank Thomson
' Based on example https://avrhelp.mcselec.com/index.html?using_the_i2c_protocol.htm
'*******************************************************************************
$regfile = "xm128A1Udef.dat" '"xm128A1Udef.dat" ' "C:\MCS\BASCAVR2082\DAT\xm128A1Udef.dat"
$framesize = 200 ' After global variables then after unused SRAM, grows bottom up, string conversion routines (PRINT, LCD, INPUT) require a buffer in SRAM
$swstack = 200 ' ISR routine parameters and grow top down
$hwstack = 200 ' Return address after routine call (SUB, FUNCTION, GOSUB) and grow top down
$crystal = 16000000
'Config Osc = Enabled , 32mhzosc = Enabled ' enable 2 MHz and 32 MHz internal oscillators
'Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
Config osc = enabled , EXTOSC = enabled , 32KHZOSC =DISABLED, pllosc = enabled , range = 12MHZ_16MHZ , startup = XTAL_16KCLK , pllsource = extclock , pllmul = 1
Config Sysclock = PLL , Prescalea = 1 , Prescalebc = 1_1
Disable Jtag
'--------{INITIALSE SOFT I2C}----------------------------------
$FORCESOFTI2C
Config I2cdelay = 10
$lib "i2c.lbx" ' Software I2C
'----{ INITIALIZE HARDWARE}------------------------------------
' PORTS A,B, C, D, E, F, H, J, K, Q Default to ALL INPUTS on Reset
' Port D which has a LED
'PORT D.0 - 0 0 LED SPARE 2
' D.1 - 0 0 LED SPARE 1
' D.2 - 0 0 LED FAIL
' D.3 - 0 0 LED STATUS
' D.4 - 0 0 LED TESTING
' D.5 - 0 0 LED DEVICE
' D.6 - 0 0 Reserved for USB N
' D.7 - 0 0 Reserved for USB N
' 76543210
Config PortD = &B00000011
PortD = &B00000000
' F
'PORT F.0 - 0 0 I2C SDA Temperature Sensor
' F.1 - 0 0 I2C SCL Temperature Sensor
' F.2 - 0 0 USART F0 RXD Goes to the GPS
' F.3 - 0 0 USART F0 TXD GPS
' F.4 - 0 0 Shaker
' F.5 - 0 0 Electromagnet
' F.6 - 0 0 USART F1 RXD
' F.7 - 0 0 USART F1 TXD Auxillary AVR
' 76543210
Config PortF = &B00000000
PortF = &B00000000
'---{I2C}--------------------------------
'Config TWI & TWI1 are for ATMEGA. TWIC, TWID, TWIE, TWIF for XMEGA
' Hardware I2C initialise
'Open "TWIF" For Binary As #4 ' or use TWID,TWIE oR TWIF
'Config TWIF = 100000 ' 100kHz
'I2cinit #4
'--{SOFTWARE I2C}-------------------------
config sda = portF.0
Config SCL = PortF.1
I2cinit
'---- INITIALISE COMMS ---------------------------------------------------------------------
Config Com5 = 9600 , mode = ASYNCHRONEOUS, Parity = None , Stopbits = 1 , Databits = 8
Open "COM5:" For Binary As # 6
Config Serialin6 = Buffered , Size = 10
'--{VARIABLES}-------------------------
Dim LEDcounter as word
Dim B as byte
B =&b10011110 ' Address of AT30TS74 temperature sensor
'-----MAIN PROGRAM START---------------------------------------------------------------------
portd.0 = 1 ' LED SPARE 2 ON
Print # 6 ,
print # 6, "AT X Mega 128A1U I2C Test Program"
print # 6, "Software I2C Version"
loopforever :
Print # 6, "I2C START"
I2Cstart
Print # 6, "Start Error : " ; Err ' show error
I2CWBYTE B
Print # 6, "Write Error : " ; Err ' show error
I2cstop
Print # 6, "Stop Error : " ; Err ' show error
' Heartbeat LED
LEDcounter = LEDcounter + 1
if LEDcounter >= 60000 then
toggle portd.1 'FAIL LED ON OFF
LEDcounter = 0
end if
goto loopforever
|
HARDWARE VERSION
Code: |
'*******************************************************************************
' FILENAME: ATXMEGA128A1 ADC Test x.bas
'
' PROCESSOR: ATXMEGA128A1
' CLOCK: 16Mhz XTAL
' TITLE:
' BOARD: 0420-04 and 0420-01
' MODIFIED: 3-DEC-2021
' AUTHOR: Frank Thomson
' Based on example https://avrhelp.mcselec.com/index.html?using_the_i2c_protocol.htm
'*******************************************************************************
$regfile = "xm128A1Udef.dat" '"xm128A1Udef.dat" ' "C:\MCS\BASCAVR2082\DAT\xm128A1Udef.dat"
$framesize = 200 ' After global variables then after unused SRAM, grows bottom up, string conversion routines (PRINT, LCD, INPUT) require a buffer in SRAM
$swstack = 200 ' ISR routine parameters and grow top down
$hwstack = 200 ' Return address after routine call (SUB, FUNCTION, GOSUB) and grow top down
$crystal = 16000000
'Config Osc = Enabled , 32mhzosc = Enabled ' enable 2 MHz and 32 MHz internal oscillators
'Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
Config osc = enabled , EXTOSC = enabled , 32KHZOSC =DISABLED, pllosc = enabled , range = 12MHZ_16MHZ , startup = XTAL_16KCLK , pllsource = extclock , pllmul = 1
Config Sysclock = PLL , Prescalea = 1 , Prescalebc = 1_1
Disable Jtag
'--------{INITIALSE SOFT I2C}----------------------------------
'$FORCESOFTI2C
'Config I2cdelay = 10
'$lib "i2c.lbx" ' Software I2C
'----{ INITIALIZE HARDWARE}------------------------------------
' PORTS A,B, C, D, E, F, H, J, K, Q Default to ALL INPUTS on Reset
' Port D which has a LED
'PORT D.0 - 0 0 LED SPARE 2
' D.1 - 0 0 LED SPARE 1
' D.2 - 0 0 LED FAIL
' D.3 - 0 0 LED STATUS
' D.4 - 0 0 LED TESTING
' D.5 - 0 0 LED DEVICE
' D.6 - 0 0 Reserved for USB N
' D.7 - 0 0 Reserved for USB N
' 76543210
Config PortD = &B00000011
PortD = &B00000000
' F
'PORT F.0 - 0 0 I2C SDA Temperature Sensor
' F.1 - 0 0 I2C SCL Temperature Sensor
' F.2 - 0 0 USART F0 RXD Goes to the GPS
' F.3 - 0 0 USART F0 TXD GPS
' F.4 - 0 0 Shaker
' F.5 - 0 0 Electromagnet
' F.6 - 0 0 USART F1 RXD
' F.7 - 0 0 USART F1 TXD Auxillary AVR
' 76543210
Config PortF = &B00000000
PortF = &B00000000
'---{I2C}--------------------------------
'Config TWI & TWI1 are for ATMEGA. TWIC, TWID, TWIE, TWIF for XMEGA
' Hardware I2C initialise
Open "TWIF" For Binary As # 4 ' or use TWID,TWIE oR TWIF
Config TWIF = 100000 ' 100kHz
I2cinit # 4
'--{SOFTWARE I2C}-------------------------
'config sda = portF.0
'Config SCL = PortF.1
'I2cinit
'---- INITIALISE COMMS ---------------------------------------------------------------------
Config Com5 = 9600 , mode = ASYNCHRONEOUS, Parity = None , Stopbits = 1 , Databits = 8
Open "COM5:" For Binary As # 6
Config Serialin6 = Buffered , Size = 10
'--{VARIABLES}-------------------------
Dim LEDcounter as word
Dim B as byte
B =&b10011110 ' Address of AT30TS74 temperature sensor
Dim TWI_START as Byte ' Required by Bascom TWI Library code
'-----MAIN PROGRAM START---------------------------------------------------------------------
portd.0 = 1 ' LED SPARE 2 ON
Print # 6 ,
print # 6, "AT X Mega 128A1U I2C Test Program"
print # 6, "HARDWARE I2C Version"
loopforever :
Print # 6, "I2C START"
I2Cstart # 4
Print # 6, "Start Error : " ; Err ' show error <--- Never gets to here
I2CWBYTE B , # 4
Print # 6, "Write Error : " ; Err ' show error
I2cstop # 4
Print # 6, "Stop Error : " ; Err ' show error
' Heartbeat LED
LEDcounter = LEDcounter + 1
if LEDcounter >= 60000 then
toggle portd.1 'FAIL LED ON OFF
LEDcounter = 0
end if
goto loopforever
|
(BASCOM-AVR version : 2.0.8.4 ) |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Dec 03, 2021 2:02 am Post subject: |
|
|
Your code addressing the I2C device seems incomplete.
Usually it goes:
Start
Send R or W address
Restart
Send command or register address to access
Do reads or further writes
Stop
The read or write address requires to include the rightmost R/W bit, read address of the device is &h91, write is &h90, provided A0..2 = 0. |
|
Back to top |
|
|
Tiny
Joined: 10 Nov 2010 Posts: 101 Location: The Netherlands
|
Posted: Fri Dec 03, 2021 8:09 am Post subject: |
|
|
Hello,
the first thing to test is that the scl and sda pin are a logic "1" in idle state before you are going to communicate over the i2c bus.
then do a i2c bus scan see the example "xmega-scanner.bas" that comes with Bascom to ensure that the slave device is responding
Regards,
Tiny |
|
Back to top |
|
|
syndetic1
Joined: 02 Jan 2007 Posts: 76
|
Posted: Sun Dec 05, 2021 6:34 am Post subject: Still Stuck |
|
|
I copied xmega-scaner.bas and made minimum modifications to suit may hardware.
Basically I am using UART5 for my serial comms.
and I am using the U version of the chip
The program sends the I2cstart and comes back
but never comes back from I2cwbyte
It just hangs
Also I tried simulating the original xmega-scanner.bas and it get's stuck at exactly the same place.
Code: |
'------------------------------------------------------------------
' (c) 1995-2020 MCS
' xmega-scanner.bas
'purpose : scan all i2c addresses to find slave chips
'Micro: Xmega128A1
'
' Changed 5-DEC-2021 Frank Thomson
'
'------------------------------------------------------------------
'---{CHANGES FROM THE ORIGINAL}------------------------------------
'1. .def file changed from xM128a1def.dat to xm128A1Udef.dat
'2. Com5 used for serial Note open as #6
'------------------------------------------------------------------
$regfile = "xm128A1Udef.dat" ' the used chip {We are using a U}
$crystal = 32000000 ' frequency used
$hwstack = 40
$swstack = 40
$framesize = 40
'first enable the osc of your choice
Config Osc = Enabled , 32mhzosc = Enabled
'configure the systemclock
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
'Config Com1 = 19200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
'Config Serialin = Buffered , Size = 50
'---- INITIALISE COMMS ---------------------------------------------------------------------
Config Com5 = 9600 , mode = ASYNCHRONEOUS, Parity = None , Stopbits = 1 , Databits = 8
Open "COM5:" For Binary As #6
Config Serialin6 = Buffered , Size = 10
'------------------------------------------------------------------------------------------
Config Twic = 100000 'CONFIG TWI will ENABLE the TWI master interface - We are using F
'Enable Interrupts
'Open "COM1:" For Binary As #1
I2cinit
Dim Twi_start As Byte , B As Byte
Print #6, "Scan start"
For B = 0 To 254 Step 2 'for all odd addresses
I2cstart : Print #6, "I2C Started" 'send start
I2cwbyte B : Print #6, "I2cwbyte B -> "; B 'send address <---- HANGS HERE-------
If Err = 0 Then 'we got an ack
Print #6, "Slave at : " ; B ; " hex : " ; Hex(b) ; " bin : " ; Bin(b)
End If
I2cstop 'free bus
Next
Print #6, "End Scan"
End
|
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Dec 05, 2021 1:13 pm Post subject: |
|
|
Power supply for AT30TS74 is 3.3 or 5.0V?
Pull-ups to SCL/SDA are installed?
Pulling to 3.3 or 5.0V? |
|
Back to top |
|
|
syndetic1
Joined: 02 Jan 2007 Posts: 76
|
Posted: Sun Dec 05, 2021 10:43 pm Post subject: |
|
|
MWS wrote: | Power supply for AT30TS74 is 3.3 or 5.0V?
Pull-ups to SCL/SDA are installed?
Pulling to 3.3 or 5.0V? |
Everything is 3V3
Pullups installed.
I am also confused that xmega-scanner.bas when run in the simulator gets stuck at exactly the same point.
If there are zero devices on the I2C bus, I would have thought xmega-scanner.bas should still run and yet not find any devices. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Dec 05, 2021 11:18 pm Post subject: |
|
|
syndetic1 wrote: | I am also confused that xmega-scanner.bas when run in the simulator gets stuck at exactly the same point. |
I think simulation-detail goes not that far to simulate the hardware I2C unit, means the code is looping for a bit to set or clear and gets stuck. Which may happen on real hardware too, but out of different reasons.
Quote: | If there are zero devices on the I2C bus, I would have thought xmega-scanner.bas should still run and yet not find any devices. |
As long the code is executed on real hardware, I'd expect that too.
Hardware is double checked? Try out the scanner example with as little modifications as possible.
Try another TWI-unit, TWIE/F if possible. |
|
Back to top |
|
|
syndetic1
Joined: 02 Jan 2007 Posts: 76
|
Posted: Mon Dec 06, 2021 12:04 am Post subject: |
|
|
I have attached the schematic that applies to the original post. This has one I2C temperature sensor on the Port F I2C. The program hangs. It hangs irrespective of whether I configure for hardware or software I2C.
On my PCB, The Port C I2C is not connected to any I2C hardware but it is not damaged by configuring it for I2C. The original xmega-scanner.bas is written for Port C and it hangs too. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Mon Dec 06, 2021 12:49 am Post subject: |
|
|
R101/102 are harmful, remove them, R103/104 are factor 10 too high, 4k7 is more appropriate.
I2CInit enables internal pullips on the pins, these are in the range of 15k to 20k.
All together this creates a voltage divider, where no one is desired and it slurs the signals edges, confuses the controller. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Tue Dec 07, 2021 12:06 pm Post subject: Re: Still Stuck |
|
|
syndetic1 wrote: | Code: | Config Twic = 100000 'CONFIG TWI will ENABLE the TWI master interface - We are using F |
|
In your schematic you use port F, you need to write:
Code: | Config Twif = 100000 |
EDIT:
Try this, simulated as far as possible and checked that every I2C-command works on the right bus.
If the "inactive bus timeout" disturbs the scanner's function, remove it, this option is for bus-recovery.
Code: | $regfile = "xm128A1Udef.dat"
$crystal = 32000000
$hwstack = 40
$swstack = 40
$framesize = 40
'$sim
Config Osc = Enabled , 32mhzosc = Enabled
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
'---- INITIALISE COMMS ---------------------------------------------------------------------
#IF _SIM = 0
Config Com5 = 9600 , mode = ASYNCHRONEOUS, Parity = None , Stopbits = 1 , Databits = 8
Open "COM5:" For Binary As #6
#ENDIF
'------------------------------------------------------------------------------------------
Open "twif" For Binary As #4
Config Twif = 100000
Set TWIF_MASTER_CTRLB.2 ' sets Inactive Bus timeout to 50µs
I2cinit #4
Dim Twi_start As Byte , B As Byte
#IF _SIM = 0
Print #6, "Scan start"
#ENDIF
For B = 0 To 254 Step 2
I2cstart #4
#IF _SIM = 0
Print #6, "I2C Started"
#ENDIF
I2cwbyte B, #4
#IF _SIM = 0
Print #6, "I2cwbyte B -> "; B
#ENDIF
#IF _SIM = 0
If Err = 0 Then 'we got an ack
Print #6, "Slave at : " ; B ; " hex : " ; Hex(b) ; " bin : " ; Bin(b)
End If
#ENDIF
I2cstop #4 'free bus
Next
#IF _SIM = 0
Print #6, "End Scan"
#ENDIF
End |
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5921 Location: Holland
|
Posted: Tue Dec 07, 2021 2:46 pm Post subject: |
|
|
when using $FORCESOFTI2C
you should not include the lib for the normal AVR : $lib "i2c.lbx" ' Software I2C
for the rest i agree with MWS comment about the resistors. and also config twic/twif
it seems the scl is kept low (clock stretching).
so you best check with a scope what is keeping this line low.
i would get rid of all the R's and the i2c chip as well. maybe your board is bad?
also see if you can manipulate the pins with normal code. _________________ Mark |
|
Back to top |
|
|
syndetic1
Joined: 02 Jan 2007 Posts: 76
|
Posted: Tue Dec 07, 2021 9:10 pm Post subject: |
|
|
Thanks guys. The code posted by MWS on Tue Dec 07, 2021 12:06 pm was very helpful. It ran on my hardware.
Thanks again all. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|