1-Wire bus search algorithm, new C implementation

main.c 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <stdbool.h>
  5. #include <inttypes.h>
  6. #include "ow_search.h"
  7. // ----------- DEMO -----------------
  8. int main(void)
  9. {
  10. // The search algorithm stores its internal state in a struct.
  11. // This allows calling it repeatedly if there are more devices
  12. // than could fit in the address buffer.
  13. struct ow_search_state search_state;
  14. ow_search_init(&search_state, 0xF0 /* SEARCH_ROM */, false /* checksums */);
  15. // Buffer for the found addresses - can have up to 65536 rows
  16. // Keep in mind that each address uses 8 bytes
  17. #define CODE_BUFFER_LEN 8
  18. ow_romcode_t addresses[CODE_BUFFER_LEN];
  19. // The algorithm stores its return value in the status field,
  20. // we can loop until it becomes OW_SEARCH_DONE or OW_SEARCH_FAILED
  21. while (search_state.status == OW_SEARCH_MORE) {
  22. // Perform a run of the algorithm
  23. uint16_t count = ow_search_run(&search_state, addresses, CODE_BUFFER_LEN);
  24. // Do something with the found addresses
  25. printf("Found %d addresses, status %d\n", count, search_state.status);
  26. for (int i = 0; i < count; i++) {
  27. printf("> ");
  28. for (int j = 0; j < 8; j++) {
  29. printf("%02x ", addresses[i][j]);
  30. }
  31. uint64_t numeric = ow_romcode_to_u64(addresses[i]);
  32. printf(" (0x%016"PRIx64")\n", numeric);
  33. }
  34. printf("\n");
  35. }
  36. return 0;
  37. }
  38. // ------------ SIMULATOR ---------------
  39. // A simple 1-wire bus simulation following the real behavior of bus devices
  40. // in the search operation.
  41. struct owunit {
  42. ow_romcode_t romcode;
  43. bool selected;
  44. uint8_t rompos;
  45. int state;
  46. };
  47. #define UNITS_COUNT 13
  48. struct owunit units[UNITS_COUNT] = {
  49. {.romcode = {0b00000000}},//00
  50. {.romcode = {0b00000001}},//01
  51. {.romcode = {0b00010001}},//11
  52. {.romcode = {0b00110001}},//31
  53. {.romcode = {0b00110101}},//35
  54. {.romcode = {0b01010001}},//51
  55. {.romcode = {0b10000000}},//80
  56. {.romcode = {0b10101010}},//aa
  57. {.romcode = {0b11110101}},//f5
  58. {.romcode = {0b11110111}},//f7
  59. {.romcode = {0xFF,0x00,0xFF,0x00,0x55,0x00,0xAA,0x00}},
  60. {.romcode = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}},
  61. {.romcode = {0x10,0x76,0xc7,0x04,0x01,0x08,0x00,0x71}}, // this is from a real 1-wire thermometer - checksum should be OK
  62. };
  63. void rom_device_reset(struct owunit *device)
  64. {
  65. device->rompos = 0;
  66. device->state = 0;
  67. device->selected = true;
  68. }
  69. bool rom_device_read(struct owunit *device)
  70. {
  71. if (!device->selected) return true;
  72. bool res = 0;
  73. if (device->state == 0) {
  74. device->state++;
  75. res = ow_code_getbit(device->romcode, device->rompos);
  76. return res;
  77. }
  78. if (device->state == 1) {
  79. device->state++;
  80. res = !ow_code_getbit(device->romcode, device->rompos);
  81. return res;
  82. }
  83. return res;
  84. }
  85. void rom_device_write(struct owunit *device, bool selectedbit)
  86. {
  87. if (!device->selected) return;
  88. if (ow_code_getbit(device->romcode, device->rompos) != selectedbit) {
  89. device->selected = false;
  90. }
  91. else {
  92. device->rompos++;
  93. device->state = 0;
  94. }
  95. }
  96. bool ow_reset(void)
  97. {
  98. for (int i = 0; i < UNITS_COUNT; ++i) {
  99. rom_device_reset(&units[i]);
  100. }
  101. return (UNITS_COUNT > 0);
  102. }
  103. bool ow_read_bit(void)
  104. {
  105. bool bus = 1;
  106. for (int i = 0; i < UNITS_COUNT; ++i) {
  107. bus &= rom_device_read(&units[i]);
  108. }
  109. return bus;
  110. }
  111. void ow_write_bit(bool value)
  112. {
  113. for (int i = 0; i < UNITS_COUNT; ++i) {
  114. rom_device_write(&units[i], value);
  115. }
  116. }
  117. void ow_write_u8(uint8_t value)
  118. {
  119. (void) value;
  120. // Dummy, do nothing
  121. }