1 | /*##############################################################################
|
2 | Name : USI TWI Slave driver - I2C/TWI-EEPROM
|
3 | Version : 1.3 - Stable
|
4 | autor : Martin Junghans jtronics@gmx.de
|
5 | page : www.jtronics.de
|
6 | License : GNU General Public License
|
7 |
|
8 | Created from Atmel source files for Application Note AVR312:
|
9 | Using the USI Module as an I2C slave like a I2C-EEPROM.
|
10 | //############################################################################*/
|
11 |
|
12 | #include <stdlib.h>
|
13 | #include <avr/io.h>
|
14 | #include <avr/interrupt.h>
|
15 | #include <avr/pgmspace.h>
|
16 |
|
17 | //################################################################## USI-TWI-I2C
|
18 |
|
19 | #include "usiTwiSlave.h"
|
20 |
|
21 | // Note: The LSB is the I2C r/w flag and must not be used for addressing!
|
22 | #define SLAVE_ADDR_ATTINY 0x52 // 0b00110100
|
23 |
|
24 | #ifndef F_CPU
|
25 | #define F_CPU 16000000UL
|
26 | #endif
|
27 |
|
28 | //####################################################################### Macros
|
29 |
|
30 | #define uniq(LOW,HEIGHT) ((HEIGHT << 8)|LOW) // Create 16 bit number from two bytes
|
31 | #define LOW_BYTE(x) (x & 0xff) // Get low byte from 16 bit number
|
32 | #define HIGH_BYTE(x) ((x >> 8) & 0xff) // Get high byte from 16 bit number
|
33 |
|
34 | #define sbi(ADDRESS,BIT) ((ADDRESS) |= (1<<(BIT))) // Set bit
|
35 | #define cbi(ADDRESS,BIT) ((ADDRESS) &= ~(1<<(BIT)))// Clear bit
|
36 | #define toggle(ADDRESS,BIT) ((ADDRESS) ^= (1<<BIT)) // Toggle bit
|
37 |
|
38 | #define bis(ADDRESS,BIT) (ADDRESS & (1<<BIT)) // Is bit set?
|
39 | #define bic(ADDRESS,BIT) (!(ADDRESS & (1<<BIT))) // Is bit clear?
|
40 |
|
41 | //#################################################################### Variables
|
42 |
|
43 | uint16_t word=0; // Counter
|
44 | uint8_t byte1, byte2;
|
45 | uint16_t buffer;
|
46 | uint8_t high,low = 0; // Variables used with uniq (high and low byte)
|
47 |
|
48 | //################################################################# Main routine
|
49 | int main(void)
|
50 | {
|
51 | cli(); // Disable interrupts
|
52 |
|
53 | usiTwiSlaveInit(SLAVE_ADDR_ATTINY); // TWI slave init
|
54 |
|
55 | sei(); // Re-enable interrupts
|
56 |
|
57 | for (int i = 0; i < 10; i++) // Fill buffers with arbitrary data
|
58 | txbuffer[i] = i + 10;
|
59 |
|
60 | for (int i = 0; i < 4; i++)
|
61 | rxbuffer[i] = i + 20;
|
62 |
|
63 | while(1)
|
64 | {
|
65 | //############################################ Read data from reception buffer
|
66 | // 8 bit variables
|
67 | byte1 = rxbuffer[0];
|
68 | byte2 = rxbuffer[1];
|
69 |
|
70 | // 2 8 bit variables converted into a 16 bit number
|
71 | low = rxbuffer[2];
|
72 | high = rxbuffer[3];
|
73 | word = uniq(low,high);
|
74 |
|
75 | //########################################## Write data to transmission buffer
|
76 | // 8 bit variables
|
77 | txbuffer[0]= byte1;
|
78 | txbuffer[1]= byte2;
|
79 |
|
80 | // 16 bit variable broken up into its high and low byte
|
81 | buffer = word;
|
82 | txbuffer[2] = LOW_BYTE(buffer);
|
83 | txbuffer[3] = HIGH_BYTE(buffer);
|
84 |
|
85 | //############################################################################
|
86 |
|
87 | } //end.while
|
88 | } //end.main
|