Si115X.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include <Arduino.h>
  2. #include "Si115X.h"
  3. // Si115X::Si115X() {
  4. // //empty constructor
  5. // }
  6. /**
  7. * Configures a channel at a given index
  8. */
  9. void Si115X::config_channel(uint8_t index, uint8_t *conf){
  10. int len = sizeof(conf);
  11. if(len != 4 || index < 0 || index > 5)
  12. return;
  13. int inc = index * len;
  14. param_set(Si115X::ADCCONFIG_0 + inc, conf[0]);
  15. param_set(Si115X::ADCSENS_0 + inc, conf[1]);
  16. param_set(Si115X::ADCPOST_0 + inc, conf[2]);
  17. param_set(Si115X::MEASCONFIG_0 + inc, conf[3]);
  18. }
  19. /**
  20. * Writes data over i2c
  21. */
  22. void Si115X::write_data(uint8_t addr, uint8_t *data, size_t len){
  23. Wire.beginTransmission(addr);
  24. Wire.write(data, len);
  25. Wire.endTransmission();
  26. }
  27. /**
  28. * Reads data from a register over i2c
  29. */
  30. int Si115X::read_register(uint8_t addr, uint8_t reg, int bytesOfData){
  31. int val = -1;
  32. Si115X::write_data(addr, &reg, sizeof(reg));
  33. Wire.requestFrom(addr, bytesOfData);
  34. if(Wire.available())
  35. val = Wire.read();
  36. return val;
  37. }
  38. /**
  39. * param set as shown in the datasheet
  40. */
  41. void Si115X::param_set(uint8_t loc, uint8_t val){
  42. uint8_t packet[2];
  43. int r;
  44. int cmmnd_ctr;
  45. do {
  46. cmmnd_ctr = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
  47. packet[0] = Si115X::HOSTIN_0;
  48. packet[1] = val;
  49. Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
  50. packet[0] = Si115X::COMMAND;
  51. packet[1] = loc | (0B10 << 6);
  52. Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
  53. r = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
  54. } while(r > cmmnd_ctr);
  55. }
  56. /**
  57. * param query as shown in the datasheet
  58. */
  59. int Si115X::param_query(uint8_t loc){
  60. int result = -1;
  61. uint8_t packet[2];
  62. int r;
  63. int cmmnd_ctr;
  64. do {
  65. cmmnd_ctr = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
  66. packet[0] = Si115X::COMMAND;
  67. packet[1] = loc | (0B01 << 6);
  68. Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
  69. r = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
  70. } while(r > cmmnd_ctr);
  71. result = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_1, 1);
  72. return result;
  73. }
  74. /**
  75. * Sends command to the command register
  76. */
  77. void Si115X::send_command(uint8_t code){
  78. uint8_t packet[2];
  79. int r;
  80. int cmmnd_ctr;
  81. do {
  82. cmmnd_ctr = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
  83. packet[0] = Si115X::COMMAND;
  84. packet[1] = code;
  85. Si115X::write_data(Si115X::DEVICE_ADDRESS, packet, sizeof(packet));
  86. r = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::RESPONSE_0, 1);
  87. } while(r > cmmnd_ctr);
  88. }
  89. /**
  90. * Returns int given a byte array
  91. */
  92. int Si115X::get_int_from_bytes(uint8_t *data, size_t len){
  93. int result = 0;
  94. int shift = 8 * len;
  95. for(int i = 0; i < len; i++){
  96. shift -= 8;
  97. result |= ((data[i] << shift) & (0xFF << shift));
  98. }
  99. return result;
  100. }
  101. bool Si115X::Begin(void){
  102. Wire.begin();
  103. if (ReadByte(0x00) != 0x51) {
  104. return false;
  105. }
  106. Si115X::send_command(Si115X::START);
  107. Si115X::param_set(Si115X::CHAN_LIST, 0B000010);
  108. Si115X::param_set(Si115X::MEASRATE_H, 0);
  109. Si115X::param_set(Si115X::MEASRATE_L, 1); // 1 for a base period of 800 us
  110. Si115X::param_set(Si115X::MEASCOUNT_0, 5);
  111. Si115X::param_set(Si115X::MEASCOUNT_1, 10);
  112. Si115X::param_set(Si115X::MEASCOUNT_2, 10);
  113. Si115X::param_set(Si115X::THRESHOLD0_L, 200);
  114. Si115X::param_set(Si115X::THRESHOLD0_H, 0);
  115. Wire.beginTransmission(Si115X::DEVICE_ADDRESS);
  116. Wire.write(Si115X::IRQ_ENABLE);
  117. Wire.write(0B000010);
  118. Wire.endTransmission();
  119. uint8_t conf[4];
  120. conf[0] = 0B00000000;
  121. conf[1] = 0B00000010,
  122. conf[2] = 0B00000001;
  123. conf[3] = 0B11000001;
  124. Si115X::config_channel(1, conf);
  125. conf[0] = 0B00000000;
  126. conf[1] = 0B00000010,
  127. conf[2] = 0B00000001;
  128. conf[3] = 0B11000001;
  129. Si115X::config_channel(3, conf);
  130. return true;
  131. }
  132. uint16_t Si115X::ReadHalfWord(void) {
  133. Si115X::send_command(Si115X::FORCE);
  134. uint8_t data[3];
  135. data[0] = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::HOSTOUT_0, 1);
  136. data[1] = Si115X::read_register(Si115X::DEVICE_ADDRESS, Si115X::HOSTOUT_1, 1);
  137. // Si115X::send_command(Si115X::PAUSE);
  138. // data[3] = data[0] * 256 + data[1];
  139. return data[0] * 256 + data[1]; //* 256 + data[1];
  140. }
  141. uint8_t Si115X::ReadByte(uint8_t Reg) {
  142. Wire.beginTransmission(Si115X::DEVICE_ADDRESS);
  143. Wire.write(Reg);
  144. Wire.endTransmission();
  145. Wire.requestFrom(Si115X::DEVICE_ADDRESS, 1);
  146. return Wire.read();
  147. }