<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.mcselec.com/bavr/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.mcselec.com/bavr/index.php?action=history&amp;feed=atom&amp;title=I2C_USI_SLAVE</id>
		<title>I2C USI SLAVE - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.mcselec.com/bavr/index.php?action=history&amp;feed=atom&amp;title=I2C_USI_SLAVE"/>
		<link rel="alternate" type="text/html" href="http://wiki.mcselec.com/bavr/index.php?title=I2C_USI_SLAVE&amp;action=history"/>
		<updated>2026-06-03T00:41:03Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.18.6</generator>

	<entry>
		<id>http://wiki.mcselec.com/bavr/index.php?title=I2C_USI_SLAVE&amp;diff=5245&amp;oldid=prev</id>
		<title>Admin: Created page with &quot;The I2C_USI_SLAVE library is a library that ships with the I2C slave add on package.  The purpose of the lib is to offer I2C/TWI slave support for processors that have an USI ...&quot;</title>
		<link rel="alternate" type="text/html" href="http://wiki.mcselec.com/bavr/index.php?title=I2C_USI_SLAVE&amp;diff=5245&amp;oldid=prev"/>
				<updated>2015-06-15T21:24:28Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;The I2C_USI_SLAVE library is a library that ships with the I2C slave add on package.  The purpose of the lib is to offer I2C/TWI slave support for processors that have an USI ...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;The I2C_USI_SLAVE library is a library that ships with the I2C slave add on package.&lt;br /&gt;
&lt;br /&gt;
The purpose of the lib is to offer I2C/TWI slave support for processors that have an USI interface.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
USI master support is bundled with the commercial version of Bascom. This library is named i2_USI.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
The USI has two interrupts. One to detect the START condition and one to detect a counter overflow.&lt;br /&gt;
&lt;br /&gt;
Unfortunately Atmel did not define an interrupt for STOP condition. This means that it is not possible to detect a STOP condition with an interrupt.&lt;br /&gt;
&lt;br /&gt;
You can read the STOP condition bit from the USISR register but no interrupt will fire as for the START condition.&lt;br /&gt;
&lt;br /&gt;
So in practice, the&amp;amp;nbsp;&amp;lt;span style=&amp;quot;font-weight: bold;&amp;quot;&amp;gt;Twi_stop_received&amp;lt;/span&amp;gt;&amp;amp;nbsp;label will be called just before the I2CSTART is called or when data is clocked by the master.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
The following example demonstrates how to receive multiple bytes. It emulates an I2c, EEPROM memory chip.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span class=&amp;quot;f_Header&amp;quot;&amp;gt;Example&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bascomavr&amp;quot;&amp;gt;&lt;br /&gt;
'-------------------------------------------------------------------------------&lt;br /&gt;
' (c) 2004-2015 MCS Electronics&lt;br /&gt;
' This demo demonstrates the USI I2C slave and emulates an EEPROM chip&lt;br /&gt;
' This is part of the I2C Slave library which is a commercial addon library&lt;br /&gt;
' Not all AVR chips have an USI !!!!&lt;br /&gt;
'-------------------------------------------------------------------------------&lt;br /&gt;
' This is a simple sample. the master sends the address of the slave, the WORD address&lt;br /&gt;
' of the memory location, and a byte to store or read&lt;br /&gt;
'------------------------------------------------------------------------------&lt;br /&gt;
' The matching master code to write&lt;br /&gt;
' i2cstart : i2cwbyte &amp;amp;H40 : i2cwbyte low(address) : i2cwbyte high(address) : i2cwbyte value : i2cstop&lt;br /&gt;
' The mathing master code to read&lt;br /&gt;
' i2cstart : i2cwbyte &amp;amp;H40 : i2cwbyte low(address) : i2cwbyte high(address) : i2crepstart : i2cwbyte &amp;amp;H41 : i2cRbyte value, nack : i2cstop&lt;br /&gt;
'See also the eeprom_master.bas&lt;br /&gt;
 &lt;br /&gt;
$regfile = &amp;quot;attiny2313.dat&amp;quot;&lt;br /&gt;
'$regfile = &amp;quot;attiny85.dat&amp;quot;&lt;br /&gt;
$crystal = 8000000&lt;br /&gt;
$hwstack = 44&lt;br /&gt;
$swstack = 16&lt;br /&gt;
$framesize = 28&lt;br /&gt;
config CLOCKDIV=1&lt;br /&gt;
'I2C pins on tiny2313 connected like :&lt;br /&gt;
'PB5 SDA&lt;br /&gt;
'PB7 SCL&lt;br /&gt;
 &lt;br /&gt;
'I2C pins on tiny85 connected like :&lt;br /&gt;
'PB0 SDA&lt;br /&gt;
'PB2 SCL&lt;br /&gt;
 &lt;br /&gt;
config BASE=0 'arrays start at address 0&lt;br /&gt;
 &lt;br /&gt;
Const Cprint = 0 'make 0 for chips that have NO UART, make 1 when the micro has a UART and you want to show data on the terminal&lt;br /&gt;
 &lt;br /&gt;
#if cPrint&lt;br /&gt;
 Config Com1 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0&lt;br /&gt;
 print &amp;quot;USI DEMO&amp;quot;&lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
config usi = twislave , address = &amp;amp;H40 'bascom uses 8 bit i2c address (7 bit shifted to the left with one bit)&lt;br /&gt;
 &lt;br /&gt;
dim epr(128) as Eram byte 'for easy access to the memory&lt;br /&gt;
dim wAdres as Word, bValue as Byte&lt;br /&gt;
dim bAdresL as Byte at Wadres overlay 'overlay with wAdres LSB&lt;br /&gt;
dim bAdresH as Byte at Wadres+1 overlay 'overlay with wAdres MSB&lt;br /&gt;
 &lt;br /&gt;
'do not forget to enable global interrupts since USI is used in interrupt mode&lt;br /&gt;
enable interrupts 'it is important you enable interrupts&lt;br /&gt;
 &lt;br /&gt;
do&lt;br /&gt;
 ! nop ; nothing to do here&lt;br /&gt;
loop&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
'The following labels are called from the library. You need to insert code in these subroutines&lt;br /&gt;
'Notice that the PRINT commands are remarked.&lt;br /&gt;
'You can unmark them and see what happens, but it will increase code size&lt;br /&gt;
'The idea is that you write your code in the called labels. And this code must execute in as little time&lt;br /&gt;
'as possible. So when you slave must read the A/D converter, you can best do it in the main program&lt;br /&gt;
'then the data is available when the master requires it, and you do not need to do the conversion which cost time.&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
'A master can send or receive bytes.&lt;br /&gt;
'A master protocol can also send some bytes, then receive some bytes&lt;br /&gt;
'The master and slave address must match.&lt;br /&gt;
 &lt;br /&gt;
'the following labels are called from the library when master send stop or start&lt;br /&gt;
Twi_start_received:&lt;br /&gt;
 #if cprint&lt;br /&gt;
 Print &amp;quot;Master sent start or repeated start&amp;quot;&lt;br /&gt;
 #endif&lt;br /&gt;
Return&lt;br /&gt;
 &lt;br /&gt;
Twi_stop_received:&lt;br /&gt;
 #if cprint&lt;br /&gt;
 Print &amp;quot;Master sent stop&amp;quot;&lt;br /&gt;
 #endif&lt;br /&gt;
Return&lt;br /&gt;
 &lt;br /&gt;
'master sent our slave address and will now send data&lt;br /&gt;
Twi_addressed_goread:&lt;br /&gt;
 #if cprint&lt;br /&gt;
 Print &amp;quot;We were addressed and master will send data&amp;quot;&lt;br /&gt;
 #endif&lt;br /&gt;
Return&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Twi_addressed_gowrite:&lt;br /&gt;
 #if cprint&lt;br /&gt;
 Print &amp;quot;We were addressed and master will read data&amp;quot;&lt;br /&gt;
 #endif&lt;br /&gt;
Return&lt;br /&gt;
 &lt;br /&gt;
'this label is called when the master sends data and the slave has received the byte&lt;br /&gt;
'the variable TWI holds the received value&lt;br /&gt;
Twi_gotdata:&lt;br /&gt;
 #if cprint&lt;br /&gt;
 Print &amp;quot;received : &amp;quot; ; Twi ; &amp;quot; byte no : &amp;quot; ; Twi_btw ; &amp;quot;-&amp;quot;; usidr&lt;br /&gt;
 #endif&lt;br /&gt;
 Select Case Twi_btw&lt;br /&gt;
 Case 1 : bAdresL=TWI 'first byte is LSB&lt;br /&gt;
 Case 2 : bAdresH=TWI 'second byte is MSB&lt;br /&gt;
 case 3 :&lt;br /&gt;
 #if cprint&lt;br /&gt;
 print &amp;quot;address:&amp;quot; ; wAdres&lt;br /&gt;
 #endif&lt;br /&gt;
 epr(wAdres)=twi 'write to eeprom in case we receive a third byte which should only happen when we write to the slave&lt;br /&gt;
 End Select&lt;br /&gt;
 &lt;br /&gt;
'if you want to auto inc wAdres, use this code instead:&lt;br /&gt;
' Select Case Twi_btw&lt;br /&gt;
' Case 1 : bAdresL=TWI 'first byte is LSB&lt;br /&gt;
' Case 2 : bAdresH=TWI 'second byte is MSB&lt;br /&gt;
' case else : epr(wAdres)=twi 'write to eeprom in case we receive a third byte which should only happen when we write to the slave&lt;br /&gt;
' incr wAdres&lt;br /&gt;
' End Select&lt;br /&gt;
Return&lt;br /&gt;
 &lt;br /&gt;
'this label is called when the master receives data and needs a byte&lt;br /&gt;
'the variable twi_btr is a byte variable that holds the index of the needed byte&lt;br /&gt;
'so when sending multiple bytes from an array, twi_btr can be used for the index&lt;br /&gt;
Twi_master_needs_byte:&lt;br /&gt;
 #if cprint&lt;br /&gt;
 Print &amp;quot;Master needs byte : &amp;quot; ; Twi_btr&lt;br /&gt;
 print &amp;quot;address:&amp;quot; ; wAdres&lt;br /&gt;
 #endif&lt;br /&gt;
 twi=epr(wAdres) 'return the data from EEPROM&lt;br /&gt;
 'when you want to support auto adres increase add this :&lt;br /&gt;
 'incr wAdres&lt;br /&gt;
Return&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= &amp;lt;span class=&amp;quot;f_Header&amp;quot;&amp;gt;Master Example&amp;lt;/span&amp;gt; =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bascomavr&amp;quot;&amp;gt;&lt;br /&gt;
'------------------------------------------------------------------------------&lt;br /&gt;
' eeprom_master.bas&lt;br /&gt;
' demo for USI eeprom slave&lt;br /&gt;
'&lt;br /&gt;
'&lt;br /&gt;
'------------------------------------------------------------------------------&lt;br /&gt;
$Regfile= &amp;quot;m88pdef.dat&amp;quot;&lt;br /&gt;
$crystal=8000000&lt;br /&gt;
$HWstack=40&lt;br /&gt;
$SWstack=50&lt;br /&gt;
$FrameSize=40&lt;br /&gt;
$baud=19200&lt;br /&gt;
$lib &amp;quot;i2c_twi.lbx&amp;quot; ' we do not use software emulated I2C but the TWI&lt;br /&gt;
 &lt;br /&gt;
config CLOCKDIV=1 ' no need to change fuse byte, we set the divider to 1&lt;br /&gt;
Config Sda = Portc.4 ' I2C Bus konfigurieren&lt;br /&gt;
Config Scl = Portc.5&lt;br /&gt;
 &lt;br /&gt;
Dim Address As Word&lt;br /&gt;
Dim Value As Byte&lt;br /&gt;
'!!!!!!!!!!!!!!!!!!!!&lt;br /&gt;
'osccal=46 'REMARK THIS LINE, THIS WAS REQUIRED for the test chip&lt;br /&gt;
'!!!!!!!!!!!!!!!!!!!!&lt;br /&gt;
 &lt;br /&gt;
Print &amp;quot;Start&amp;quot;&lt;br /&gt;
I2cinit ' init i2c&lt;br /&gt;
For Address = 0 To 10 ' just test a bit&lt;br /&gt;
 value=address+10&lt;br /&gt;
 print &amp;quot;write &amp;quot;; address ; &amp;quot;:&amp;quot;;value&lt;br /&gt;
 &lt;br /&gt;
 I2cstart : I2cwbyte &amp;amp;H40 'slave address&lt;br /&gt;
 I2cwbyte Low(address) 'LSB first&lt;br /&gt;
 I2cwbyte High(address) 'MSB&lt;br /&gt;
 I2cwbyte Value 'write value&lt;br /&gt;
 I2cstop&lt;br /&gt;
 Waitms 500&lt;br /&gt;
next&lt;br /&gt;
 &lt;br /&gt;
print &amp;quot;Read&amp;quot;&lt;br /&gt;
For Address = 0 To 10&lt;br /&gt;
 ' The mathing master code to read&lt;br /&gt;
 I2cstart : I2cwbyte &amp;amp;H40 'send slave WRITE address&lt;br /&gt;
 I2cwbyte Low(address) : I2cwbyte High(address) : 'send eeprom address&lt;br /&gt;
 I2crepstart 'repeated start&lt;br /&gt;
 I2cwbyte &amp;amp;H41 'write slave READ address&lt;br /&gt;
 I2crbyte Value , Nack 'read eeprom value&lt;br /&gt;
 I2cstop&lt;br /&gt;
 print address;&amp;quot;:&amp;quot;;value&lt;br /&gt;
Next Address ' increment address byte&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
 &lt;br /&gt;
'EXPECTED OUTPUT&lt;br /&gt;
'(&lt;br /&gt;
Start&lt;br /&gt;
write 0:10&lt;br /&gt;
write 1:11&lt;br /&gt;
write 2:12&lt;br /&gt;
write 3:13&lt;br /&gt;
write 4:14&lt;br /&gt;
write 5:15&lt;br /&gt;
write 6:16&lt;br /&gt;
write 7:17&lt;br /&gt;
write 8:18&lt;br /&gt;
write 9:19&lt;br /&gt;
write 10:20&lt;br /&gt;
Read&lt;br /&gt;
0:10&lt;br /&gt;
1:11&lt;br /&gt;
2:12&lt;br /&gt;
3:13&lt;br /&gt;
4:14&lt;br /&gt;
5:15&lt;br /&gt;
6:16&lt;br /&gt;
7:17&lt;br /&gt;
8:18&lt;br /&gt;
9:19&lt;br /&gt;
10:20&lt;br /&gt;
')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Languages}}&lt;br /&gt;
&lt;br /&gt;
[[Category:ASM Libraries and Add-Ons]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	</feed>