i2c.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <util/delay.h>
  2. #include <avr/io.h>
  3. #include "i2c.h"
  4. void scl_toggle(void) __attribute__ ((noinline));
  5. void istart(void) __attribute__ ((noinline));
  6. void istop(void) __attribute__ ((noinline));
  7. void i2c_delay(void){
  8. _delay_us(10);
  9. }
  10. void scl_toggle(void){
  11. i2c_delay();
  12. SCLDDR &= ~SCL;
  13. i2c_delay();
  14. SCLDDR |= SCL;
  15. }
  16. void istart(void){
  17. SDADDR |= SDA;
  18. i2c_delay();
  19. SCLDDR |= SCL;
  20. i2c_delay();
  21. }
  22. void istop(void){
  23. i2c_delay();
  24. SCLDDR &= ~SCL;
  25. i2c_delay();
  26. SDADDR &= ~SDA;
  27. i2c_delay();
  28. }
  29. unsigned char i2cPutbyte(unsigned char b){
  30. signed char a;
  31. for(a=7;a>=0;a--){
  32. if(b&_BV(a)) SDADDR &= ~SDA; else SDADDR |= SDA;
  33. scl_toggle();
  34. }
  35. SDADDR &= ~SDA; // leave SDL HI
  36. i2c_delay();
  37. SCLDDR &= ~SCL;
  38. i2c_delay();
  39. while(!(SCLPIN&SCL));
  40. i2c_delay(); // clock back up
  41. b = (SDAPIN & SDA); // get the ACK bit
  42. //_delay_us(15);
  43. SCLDDR |= SCL; // not really ??
  44. return (b == 0); // return ACK value
  45. }
  46. unsigned char i2cGetbyte(unsigned char notlast){
  47. signed char a;
  48. unsigned char ret=0;
  49. SDADDR &= ~SDA; // make sure pullups are ativated
  50. for(a=7;a>=0;a--){
  51. i2c_delay();
  52. SCLDDR &= ~SCL;
  53. i2c_delay();
  54. if(SDAPIN&SDA) ret |= _BV(a);
  55. SCLDDR |= SCL;
  56. }
  57. i2c_delay();
  58. if(notlast) SDADDR |= SDA; else SDADDR &= ~SDA;
  59. scl_toggle(); // clock pulse
  60. SDADDR &= ~SDA; // leave with SDL HI
  61. return ret;
  62. }
  63. /*
  64. void i2cInit(void){
  65. set_bit( SDADDR, SDA); // set SDA as output
  66. set_bit( SCLDDR, SCL); // set SCL as output
  67. SDADDR &= ~SDA; // set I/O state and pull-ups
  68. SCLDDR &= ~SDA; // set I/O state and pull-ups
  69. }*/
  70. void i2cSend(unsigned char reg, unsigned char length, unsigned char *data, unsigned char device){ // x24/23 x22/21 20/19
  71. unsigned char i;
  72. istart(); // do start transition
  73. i2cPutbyte(device); // send DEVICE address
  74. i2cPutbyte(reg);
  75. for(i=0;i<length;i++){
  76. i2cPutbyte(data[i]);
  77. }
  78. SDADDR |= SDA; // clear data line and
  79. istop(); // send STOP transition
  80. }
  81. void i2cReceive(unsigned char reg, unsigned char length, unsigned char *data, unsigned char device){ // x24/23 x22/21 20/19
  82. unsigned char i;
  83. istart(); // do start transition
  84. i2cPutbyte(device); // send DEVICE address
  85. i2cPutbyte(reg);
  86. i2c_delay();
  87. SCLDDR &= ~SCL;
  88. i2c_delay();// do a repeated START
  89. istart(); // transition
  90. i2cPutbyte(device | READ); // resend DEVICE, with READ bit set
  91. for(i=0;i<length;i++){
  92. data[i] = i2cGetbyte((i==length-1)?0:1);
  93. }
  94. SDADDR |= SDA; // clear data line and
  95. istop(); // send STOP transition
  96. }