123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #include <util/delay.h>
- #include <avr/io.h>
- #include "i2c.h"
- void scl_toggle(void) __attribute__ ((noinline));
- void istart(void) __attribute__ ((noinline));
- void istop(void) __attribute__ ((noinline));
- void i2c_delay(void){
- _delay_us(10);
- }
- void scl_toggle(void){
- i2c_delay();
- SCLDDR &= ~SCL;
- i2c_delay();
- SCLDDR |= SCL;
- }
- void istart(void){
- SDADDR |= SDA;
- i2c_delay();
- SCLDDR |= SCL;
- i2c_delay();
- }
- void istop(void){
- i2c_delay();
- SCLDDR &= ~SCL;
- i2c_delay();
- SDADDR &= ~SDA;
- i2c_delay();
- }
- unsigned char i2cPutbyte(unsigned char b){
- signed char a;
- for(a=7;a>=0;a--){
- if(b&_BV(a)) SDADDR &= ~SDA; else SDADDR |= SDA;
- scl_toggle();
- }
- SDADDR &= ~SDA; // leave SDL HI
- i2c_delay();
- SCLDDR &= ~SCL;
- i2c_delay();
- while(!(SCLPIN&SCL));
- i2c_delay(); // clock back up
- b = (SDAPIN & SDA); // get the ACK bit
- //_delay_us(15);
- SCLDDR |= SCL; // not really ??
- return (b == 0); // return ACK value
- }
- unsigned char i2cGetbyte(unsigned char notlast){
- signed char a;
- unsigned char ret=0;
- SDADDR &= ~SDA; // make sure pullups are ativated
- for(a=7;a>=0;a--){
- i2c_delay();
- SCLDDR &= ~SCL;
- i2c_delay();
- if(SDAPIN&SDA) ret |= _BV(a);
- SCLDDR |= SCL;
- }
- i2c_delay();
- if(notlast) SDADDR |= SDA; else SDADDR &= ~SDA;
- scl_toggle(); // clock pulse
- SDADDR &= ~SDA; // leave with SDL HI
- return ret;
- }
- /*
- void i2cInit(void){
- set_bit( SDADDR, SDA); // set SDA as output
- set_bit( SCLDDR, SCL); // set SCL as output
- SDADDR &= ~SDA; // set I/O state and pull-ups
- SCLDDR &= ~SDA; // set I/O state and pull-ups
- }*/
- void i2cSend(unsigned char reg, unsigned char length, unsigned char *data, unsigned char device){ // x24/23 x22/21 20/19
- unsigned char i;
- istart(); // do start transition
- i2cPutbyte(device); // send DEVICE address
- i2cPutbyte(reg);
- for(i=0;i<length;i++){
- i2cPutbyte(data[i]);
- }
- SDADDR |= SDA; // clear data line and
- istop(); // send STOP transition
- }
- void i2cReceive(unsigned char reg, unsigned char length, unsigned char *data, unsigned char device){ // x24/23 x22/21 20/19
- unsigned char i;
- istart(); // do start transition
- i2cPutbyte(device); // send DEVICE address
- i2cPutbyte(reg);
- i2c_delay();
- SCLDDR &= ~SCL;
- i2c_delay();// do a repeated START
- istart(); // transition
- i2cPutbyte(device | READ); // resend DEVICE, with READ bit set
- for(i=0;i<length;i++){
- data[i] = i2cGetbyte((i==length-1)?0:1);
- }
- SDADDR |= SDA; // clear data line and
- istop(); // send STOP transition
- }
|