PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

116 lines
2.9KB

  1. #include "EasyTransferI2C.h"
  2. //Captures address and size of struct
  3. void EasyTransferI2C::begin(uint8_t * ptr, uint8_t length, TwoWire *theSerial){
  4. address = ptr;
  5. size = length;
  6. _serial = theSerial;
  7. //dynamic creation of rx parsing buffer in RAM
  8. rx_buffer = (uint8_t*) malloc(size);
  9. }
  10. //Sends out struct in binary, with header, length info and checksum
  11. void EasyTransferI2C::sendData(uint8_t i2c_address){
  12. uint8_t CS = size;
  13. _serial->beginTransmission(i2c_address);
  14. #if ARDUINO >= 100
  15. _serial->write(0x06);
  16. _serial->write(0x85);
  17. _serial->write(size);
  18. #else
  19. _serial->send(0x06);
  20. _serial->send(0x85);
  21. _serial->send(size);
  22. #endif
  23. for(int i = 0; i<size; i++){
  24. CS^=*(address+i);
  25. #if ARDUINO >= 100
  26. _serial->write(*(address+i));
  27. #else
  28. _serial->send(*(address+i));
  29. #endif
  30. }
  31. #if ARDUINO >= 100
  32. _serial->write(CS);
  33. #else
  34. _serial->send(CS);
  35. #endif
  36. _serial->endTransmission();
  37. }
  38. boolean EasyTransferI2C::receiveData(){
  39. //start off by looking for the header bytes. If they were already found in a previous call, skip it.
  40. if(rx_len == 0){
  41. //this size check may be redundant due to the size check below, but for now I'll leave it the way it is.
  42. if(_serial->available() >= 3){
  43. //this will block until a 0x06 is found or buffer size becomes less then 3.
  44. #if ARDUINO >= 100
  45. while(_serial->read() != 0x06) {
  46. #else
  47. while(_serial->receive() != 0x06) {
  48. #endif
  49. //This will trash any preamble junk in the serial buffer
  50. //but we need to make sure there is enough in the buffer to process while we trash the rest
  51. //if the buffer becomes too empty, we will escape and try again on the next call
  52. if(_serial->available() < 3)
  53. return false;
  54. }
  55. #if ARDUINO >= 100
  56. if (_serial->read() == 0x85){
  57. rx_len = _serial->read();
  58. #else
  59. if (_serial->receive() == 0x85){
  60. rx_len = _serial->receive();
  61. #endif
  62. //make sure the binary structs on both Arduinos are the same size.
  63. if(rx_len != size){
  64. rx_len = 0;
  65. return false;
  66. }
  67. }
  68. }
  69. }
  70. //we get here if we already found the header bytes, the struct size matched what we know, and now we are byte aligned.
  71. if(rx_len != 0){
  72. while(_serial->available() && rx_array_inx <= rx_len){
  73. #if ARDUINO >= 100
  74. rx_buffer[rx_array_inx++] = _serial->read();
  75. #else
  76. rx_buffer[rx_array_inx++] = _serial->receive();
  77. #endif
  78. }
  79. if(rx_len == (rx_array_inx-1)){
  80. //seem to have got whole message
  81. //last uint8_t is CS
  82. calc_CS = rx_len;
  83. for (int i = 0; i<rx_len; i++){
  84. calc_CS^=rx_buffer[i];
  85. }
  86. if(calc_CS == rx_buffer[rx_array_inx-1]){//CS good
  87. memcpy(address,rx_buffer,size);
  88. rx_len = 0;
  89. rx_array_inx = 0;
  90. return true;
  91. }
  92. else{
  93. //failed checksum, need to clear this out anyway
  94. rx_len = 0;
  95. rx_array_inx = 0;
  96. return false;
  97. }
  98. }
  99. }
  100. return false;
  101. }