BrickUp API Service for Docker version.

i2c.h 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // This library provides the high-level functions needed to use the I2C
  2. // serial interface supported by the hardware of several AVR processors.
  3. /* 2010 Copyright (c) Seeed Technology Inc. All right reserved.
  4. Original Author: LG
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #include <avr/io.h>
  18. #include <avr/interrupt.h>
  19. #include "types.h"
  20. #include "defs.h"
  21. // TWSR values (not bits)
  22. // (taken from avr-libc twi.h - thank you Marek Michalkiewicz)
  23. // Master
  24. #define TW_START 0x08
  25. #define TW_REP_START 0x10
  26. // Master Transmitter
  27. #define TW_MT_SLA_ACK 0x18
  28. #define TW_MT_SLA_NACK 0x20
  29. #define TW_MT_DATA_ACK 0x28
  30. #define TW_MT_DATA_NACK 0x30
  31. #define TW_MT_ARB_LOST 0x38
  32. // Master Receiver
  33. #define TW_MR_ARB_LOST 0x38
  34. #define TW_MR_SLA_ACK 0x40
  35. #define TW_MR_SLA_NACK 0x48
  36. #define TW_MR_DATA_ACK 0x50
  37. #define TW_MR_DATA_NACK 0x58
  38. // Slave Transmitter
  39. #define TW_ST_SLA_ACK 0xA8
  40. #define TW_ST_ARB_LOST_SLA_ACK 0xB0
  41. #define TW_ST_DATA_ACK 0xB8
  42. #define TW_ST_DATA_NACK 0xC0
  43. #define TW_ST_LAST_DATA 0xC8
  44. // Slave Receiver
  45. #define TW_SR_SLA_ACK 0x60
  46. #define TW_SR_ARB_LOST_SLA_ACK 0x68
  47. #define TW_SR_GCALL_ACK 0x70
  48. #define TW_SR_ARB_LOST_GCALL_ACK 0x78
  49. #define TW_SR_DATA_ACK 0x80
  50. #define TW_SR_DATA_NACK 0x88
  51. #define TW_SR_GCALL_DATA_ACK 0x90
  52. #define TW_SR_GCALL_DATA_NACK 0x98
  53. #define TW_SR_STOP 0xA0
  54. // Misc
  55. #define TW_NO_INFO 0xF8
  56. #define TW_BUS_ERROR 0x00
  57. // defines and constants
  58. #define TWCR_CMD_MASK 0x0F
  59. #define TWSR_STATUS_MASK 0xF8
  60. // return values
  61. #define I2C_OK 0x00
  62. #define I2C_ERROR_NODEV 0x01
  63. #define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
  64. #define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))
  65. #define WRITE_sda() DDRC = DDRC | 0b00010000 //SDA must be output when writing
  66. #define READ_sda() DDRC = DDRC & 0b11101111 //SDA must be input when reading - don't forget the resistor on SDA!!
  67. // functions
  68. //! Initialize I2C (TWI) interface
  69. void i2cInit(void);
  70. //! Set the I2C transaction bitrate (in KHz)
  71. void i2cSetBitrate(unsigned short bitrateKHz);
  72. // Low-level I2C transaction commands
  73. //! Send an I2C start condition in Master mode
  74. void i2cSendStart(void);
  75. //! Send an I2C stop condition in Master mode
  76. void i2cSendStop(void);
  77. //! Wait for current I2C operation to complete
  78. void i2cWaitForComplete(void);
  79. //! Send an (address|R/W) combination or a data byte over I2C
  80. void i2cSendByte(unsigned char data);
  81. //! Receive a data byte over I2C
  82. // ackFlag = TRUE if recevied data should be ACK'ed
  83. // ackFlag = FALSE if recevied data should be NACK'ed
  84. void i2cReceiveByte(unsigned char ackFlag);
  85. //! Pick up the data that was received with i2cReceiveByte()
  86. unsigned char i2cGetReceivedByte(void);
  87. //! Get current I2c bus status from TWSR
  88. unsigned char i2cGetStatus(void);
  89. void delay_ms(uint16_t x);
  90. // high-level I2C transaction commands
  91. //! send I2C data to a device on the bus (non-interrupt based)
  92. unsigned char i2cMasterSendNI(unsigned char deviceAddr, unsigned char length, unsigned char* data);
  93. //! receive I2C data from a device on the bus (non-interrupt based)
  94. unsigned char i2cMasterReceiveNI(unsigned char deviceAddr, unsigned char length, unsigned char *data);
  95. /*********************
  96. ****I2C Functions****
  97. *********************/
  98. void i2cInit(void)
  99. {
  100. // set i2c bit rate to 40KHz
  101. i2cSetBitrate(100);
  102. // enable TWI (two-wire interface)
  103. sbi(TWCR, TWEN); // Enable TWI
  104. }
  105. void i2cSetBitrate(unsigned short bitrateKHz)
  106. {
  107. unsigned char bitrate_div;
  108. // set i2c bitrate
  109. // SCL freq = F_CPU/(16+2*TWBR))
  110. cbi(TWSR, TWPS0);
  111. cbi(TWSR, TWPS1);
  112. //calculate bitrate division
  113. bitrate_div = ((F_CPU/4000l)/bitrateKHz);
  114. if(bitrate_div >= 16)
  115. bitrate_div = (bitrate_div-16)/2;
  116. outb(TWBR, bitrate_div);
  117. }
  118. void i2cSendStart(void)
  119. {
  120. WRITE_sda();
  121. // send start condition
  122. TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  123. }
  124. void i2cSendStop(void)
  125. {
  126. // transmit stop condition
  127. TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
  128. }
  129. void i2cWaitForComplete(void)
  130. {
  131. int i = 0; //time out variable
  132. // wait for i2c interface to complete operation
  133. while ((!(TWCR & (1<<TWINT))) && (i < 90))
  134. i++;
  135. }
  136. void i2cSendByte(unsigned char data)
  137. {
  138. delay_ms(1);
  139. //printf("sending 0x%x\n", data);
  140. WRITE_sda();
  141. // save data to the TWDR
  142. TWDR = data;
  143. // begin send
  144. TWCR = (1<<TWINT)|(1<<TWEN);
  145. }
  146. void i2cReceiveByte(unsigned char ackFlag)
  147. {
  148. // begin receive over i2c
  149. if( ackFlag )
  150. {
  151. // ackFlag = TRUE: ACK the recevied data
  152. outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
  153. }
  154. else
  155. {
  156. // ackFlag = FALSE: NACK the recevied data
  157. outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
  158. }
  159. }
  160. unsigned char i2cGetReceivedByte(void)
  161. {
  162. // retieve received data byte from i2c TWDR
  163. return( inb(TWDR) );
  164. }
  165. unsigned char i2cGetStatus(void)
  166. {
  167. // retieve current i2c status from i2c TWSR
  168. return( inb(TWSR) );
  169. }
  170. void delay_ms(uint16_t x)
  171. {
  172. uint8_t y, z;
  173. for ( ; x > 0 ; x--){
  174. for ( y = 0 ; y < 90 ; y++){
  175. for ( z = 0 ; z < 6 ; z++){
  176. asm volatile ("nop");
  177. }
  178. }
  179. }
  180. }