Keyboard firmwares for Atmel AVR and Cortex-M
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <util/twi.h>
  2. #include <avr/io.h>
  3. #include <stdlib.h>
  4. #include <avr/interrupt.h>
  5. #include <util/twi.h>
  6. #include <stdbool.h>
  7. #include "i2c.h"
  8. #define I2C_READ 1
  9. #define I2C_WRITE 0
  10. #define I2C_ACK 1
  11. #define I2C_NACK 0
  12. // Limits the amount of we wait for any one i2c transaction.
  13. // Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
  14. // 9 bits, a single transaction will take around 90μs to complete.
  15. //
  16. // (F_CPU/SCL_CLOCK) => # of mcu cycles to transfer a bit
  17. // poll loop takes at least 8 clock cycles to execute
  18. #define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8
  19. #define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE)
  20. static volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE] = {0};
  21. static volatile uint8_t slave_buffer_pos;
  22. static volatile bool slave_has_register_set = false;
  23. static uint8_t i2c_start(uint8_t address);
  24. static void i2c_stop(void);
  25. static uint8_t i2c_write(uint8_t data);
  26. static uint8_t i2c_read(uint8_t ack);
  27. // Wait for an i2c operation to finish
  28. inline static
  29. void i2c_delay(void) {
  30. uint16_t lim = 0;
  31. while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT)
  32. lim++;
  33. // easier way, but will wait slightly longer
  34. // _delay_us(100);
  35. }
  36. // i2c_device_addr: the i2c device to communicate with
  37. // addr: the memory address to read from the i2c device
  38. // dest: pointer to where read data is saved
  39. // len: the number of bytes to read
  40. //
  41. // NOTE: on error, the data in dest may have been modified
  42. bool i2c_master_read(uint8_t i2c_device_addr, uint8_t addr, uint8_t *dest, uint8_t len) {
  43. bool err;
  44. if (len == 0) return 0;
  45. err = i2c_start(i2c_device_addr + I2C_WRITE);
  46. if (err) return err;
  47. err = i2c_write(addr);
  48. if (err) return err;
  49. err = i2c_start(i2c_device_addr + I2C_READ);
  50. if (err) return err;
  51. for (uint8_t i = 0; i < len-1; ++i) {
  52. dest[i] = i2c_read(I2C_ACK);
  53. }
  54. dest[len-1] = i2c_read(I2C_NACK);
  55. i2c_stop();
  56. return 0;
  57. }
  58. // i2c_device_addr: the i2c device to communicate with
  59. // addr: the memory address at which to write in the i2c device
  60. // data: the data to be written
  61. // len: the number of bytes to write
  62. bool i2c_master_write(uint8_t i2c_device_addr, uint8_t addr, uint8_t *data, uint8_t len) {
  63. bool err;
  64. if (len == 0) return 0;
  65. err = i2c_start(i2c_device_addr + I2C_WRITE);
  66. if (err) return err;
  67. err = i2c_write(addr);
  68. if (err) return err;
  69. for (uint8_t i = 0; i < len; ++i) {
  70. err = i2c_write(data[i]);
  71. if (err) return err;
  72. }
  73. i2c_stop();
  74. return 0;
  75. }
  76. void i2c_slave_write(uint8_t addr, uint8_t data) {
  77. i2c_slave_buffer[addr] = data;
  78. }
  79. uint8_t i2c_slave_read(uint8_t addr) {
  80. return i2c_slave_buffer[addr];
  81. }
  82. // Setup twi to run at 100kHz
  83. void i2c_master_init(void) {
  84. // no prescaler
  85. TWSR = 0;
  86. // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10.
  87. // Check datasheets for more info.
  88. TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
  89. }
  90. // Start a transaction with the given i2c slave address. The direction of the
  91. // transfer is set with I2C_READ and I2C_WRITE.
  92. // returns: 0 => success
  93. // 1 => error
  94. uint8_t i2c_start(uint8_t address) {
  95. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
  96. i2c_delay();
  97. // check that we started successfully
  98. if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
  99. return 1;
  100. TWDR = address;
  101. TWCR = (1<<TWINT) | (1<<TWEN);
  102. i2c_delay();
  103. if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) )
  104. return 1; // slave did not acknowledge
  105. else
  106. return 0; // success
  107. }
  108. // Finish the i2c transaction.
  109. void i2c_stop(void) {
  110. TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  111. uint16_t lim = 0;
  112. while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT)
  113. lim++;
  114. }
  115. // Write one byte to the i2c slave.
  116. // returns 0 => slave ACK
  117. // 1 => slave NACK
  118. uint8_t i2c_write(uint8_t data) {
  119. TWDR = data;
  120. TWCR = (1<<TWINT) | (1<<TWEN);
  121. i2c_delay();
  122. // check if the slave acknowledged us
  123. return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1;
  124. }
  125. // Read one byte from the i2c slave. If ack=1 the slave is acknowledged,
  126. // if ack=0 the acknowledge bit is not set.
  127. // returns: byte read from i2c device
  128. uint8_t i2c_read(uint8_t ack) {
  129. TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA);
  130. i2c_delay();
  131. return TWDR;
  132. }
  133. void i2c_slave_init(uint8_t address) {
  134. TWAR = address << 0; // slave i2c address
  135. // TWEN - twi enable
  136. // TWEA - enable address acknowledgement
  137. // TWINT - twi interrupt flag
  138. // TWIE - enable the twi interrupt
  139. TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
  140. }
  141. ISR(TWI_vect);
  142. ISR(TWI_vect) {
  143. uint8_t ack = 1;
  144. switch(TW_STATUS) {
  145. case TW_SR_SLA_ACK:
  146. // this device has been addressed as a slave receiver
  147. slave_has_register_set = false;
  148. break;
  149. case TW_SR_DATA_ACK:
  150. // this device has received data as a slave receiver
  151. // The first byte that we receive in this transaction sets the location
  152. // of the read/write location of the slaves memory that it exposes over
  153. // i2c. After that, bytes will be written at slave_buffer_pos, incrementing
  154. // slave_buffer_pos after each write.
  155. if(!slave_has_register_set) {
  156. slave_buffer_pos = TWDR;
  157. // don't acknowledge the master if this memory loctaion is out of bounds
  158. if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) {
  159. ack = 0;
  160. slave_buffer_pos = 0;
  161. }
  162. slave_has_register_set = true;
  163. } else {
  164. i2c_slave_buffer[slave_buffer_pos] = TWDR;
  165. BUFFER_POS_INC();
  166. }
  167. break;
  168. case TW_ST_SLA_ACK:
  169. case TW_ST_DATA_ACK:
  170. // master has addressed this device as a slave transmitter and is
  171. // requesting data.
  172. TWDR = i2c_slave_buffer[slave_buffer_pos];
  173. BUFFER_POS_INC();
  174. break;
  175. case TW_BUS_ERROR: // something went wrong, reset twi state
  176. TWCR = 0;
  177. default:
  178. break;
  179. }
  180. // Reset everything, so we are ready for the next TWI interrupt
  181. TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
  182. }