model.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #define _BSD_SOURCE
  2. #define _IPECAMERA_MODEL_C
  3. #include <sys/time.h>
  4. #include <unistd.h>
  5. #include <assert.h>
  6. #include "../tools.h"
  7. #include "../error.h"
  8. #include "model.h"
  9. #define ADDR_MASK 0x7F00
  10. #define WRITE_BIT 0x8000
  11. #define RETRIES 10
  12. //ToDo: check bot 1 and 2 bits for READY
  13. #define READ_READY_BIT 0x20000
  14. #define READ_ERROR_BIT 0x40000
  15. #define ipecamera_datacpy(dst, src, bank) pcilib_datacpy(dst, src, 4, 1, bank->raw_endianess)
  16. //#define IPECAMERA_SIMPLIFIED_READOUT
  17. #define IPECAMERA_MULTIREAD
  18. //static pcilib_register_value_t ipecamera_bit_mask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
  19. int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value) {
  20. uint32_t val, tmp[4];
  21. char *wr, *rd;
  22. struct timeval start, cur;
  23. int retries = RETRIES;
  24. assert(addr < 128);
  25. wr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr);
  26. rd = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr);
  27. if ((!rd)||(!wr)) {
  28. pcilib_error("Error resolving addresses of read & write registers");
  29. return PCILIB_ERROR_INVALID_ADDRESS;
  30. }
  31. //printf("%i %x %p %p\n", addr, val, wr, rd);
  32. /*
  33. #ifdef IPECAMERA_SIMPLIFIED_READOUT
  34. ipecamera_datacpy(tmp, rd, bank);
  35. #endif
  36. */
  37. retry:
  38. val = (addr << 8);
  39. ipecamera_datacpy(wr, &val, bank);
  40. #ifdef IPECAMERA_SIMPLIFIED_READOUT
  41. usleep(PCILIB_REGISTER_TIMEOUT);
  42. // ipecamera_datacpy(tmp, rd, bank);
  43. // usleep(PCILIB_REGISTER_TIMEOUT);
  44. ipecamera_datacpy(wr, &val, bank);
  45. usleep(PCILIB_REGISTER_TIMEOUT);
  46. // ipecamera_datacpy(tmp, rd, bank);
  47. // usleep(PCILIB_REGISTER_TIMEOUT);
  48. ipecamera_datacpy(wr, &val, bank);
  49. usleep(PCILIB_REGISTER_TIMEOUT);
  50. #endif /* IPECAMERA_SIMPLIFIED_READOUT */
  51. gettimeofday(&start, NULL);
  52. #ifdef IPECAMERA_MULTIREAD
  53. usleep(PCILIB_REGISTER_TIMEOUT);
  54. pcilib_datacpy(tmp, rd, 4, 4, bank->raw_endianess);
  55. val = tmp[0];
  56. #else /* IPECAMERA_MULTIREAD */
  57. ipecamera_datacpy(&val, rd, bank);
  58. while ((val & READ_READY_BIT) == 0) {
  59. gettimeofday(&cur, NULL);
  60. if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
  61. ipecamera_datacpy(&val, rd, bank);
  62. }
  63. #endif /* IPECAMERA_MULTIREAD */
  64. if ((val & READ_READY_BIT) == 0) {
  65. if (--retries > 0) {
  66. pcilib_warning("Timeout reading register value (CMOSIS %lu, status: %lx), retrying (try %i of %i)...", addr, val, RETRIES - retries, RETRIES);
  67. goto retry;
  68. }
  69. pcilib_error("Timeout reading register value (CMOSIS %lu, status: %lx)", addr, val);
  70. return PCILIB_ERROR_TIMEOUT;
  71. }
  72. if (val & READ_ERROR_BIT) {
  73. /* if (--retries > 0) {
  74. pcilib_warning("Error reading register (CMOSIS %lu, status: %lx), retrying (try %i of %i)...", addr, val, RETRIES - retries, RETRIES);
  75. goto retry;
  76. }*/
  77. pcilib_error("Error reading register value (CMOSIS %lu, status: %lx)", addr, val);
  78. return PCILIB_ERROR_FAILED;
  79. }
  80. if (((val&ADDR_MASK) >> 8) != addr) {
  81. if (--retries > 0) {
  82. pcilib_warning("Address verification failed during register read (CMOSIS %lu, status: %lx), retrying (try %i of %i)...", addr, val, RETRIES - retries, RETRIES);
  83. goto retry;
  84. }
  85. pcilib_error("Address verification failed during register read (CMOSIS %lu, status: %lx)", addr, val);
  86. return PCILIB_ERROR_VERIFY;
  87. }
  88. // *value = val&ipecamera_bit_mask[bits];
  89. *value = val&0xFF;
  90. return 0;
  91. }
  92. int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value) {
  93. uint32_t val, tmp[4];
  94. char *wr, *rd;
  95. struct timeval start, cur;
  96. int retries = RETRIES;
  97. assert(addr < 128);
  98. assert(value < 256);
  99. wr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr);
  100. rd = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr);
  101. if ((!rd)||(!wr)) {
  102. pcilib_error("Error resolving addresses of read & write registers");
  103. return PCILIB_ERROR_INVALID_ADDRESS;
  104. }
  105. //printf("%i %x %p %p\n", addr, val, wr, rd);
  106. /*
  107. #ifdef IPECAMERA_SIMPLIFIED_READOUT
  108. ipecamera_datacpy(tmp, rd, bank);
  109. #endif
  110. */
  111. retry:
  112. val = WRITE_BIT|(addr << 8)|(value&0xFF);
  113. ipecamera_datacpy(wr, &val, bank);
  114. #ifdef IPECAMERA_SIMPLIFIED_READOUT
  115. usleep(PCILIB_REGISTER_TIMEOUT);
  116. // ipecamera_datacpy(tmp, rd, bank);
  117. // usleep(PCILIB_REGISTER_TIMEOUT);
  118. ipecamera_datacpy(wr, &val, bank);
  119. usleep(PCILIB_REGISTER_TIMEOUT);
  120. // ipecamera_datacpy(tmp, rd, bank);
  121. // usleep(PCILIB_REGISTER_TIMEOUT);
  122. ipecamera_datacpy(wr, &val, bank);
  123. usleep(PCILIB_REGISTER_TIMEOUT);
  124. #endif /* IPECAMERA_SIMPLIFIED_READOUT */
  125. gettimeofday(&start, NULL);
  126. #ifdef IPECAMERA_MULTIREAD
  127. usleep(PCILIB_REGISTER_TIMEOUT);
  128. pcilib_datacpy(tmp, rd, 4, 4, bank->raw_endianess);
  129. val = tmp[0];
  130. #else /* IPECAMERA_MULTIREAD */
  131. ipecamera_datacpy(&val, rd, bank);
  132. while ((val & READ_READY_BIT) == 0) {
  133. gettimeofday(&cur, NULL);
  134. if (((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) > PCILIB_REGISTER_TIMEOUT) break;
  135. ipecamera_datacpy(&val, rd, bank);
  136. }
  137. #endif /* IPECAMERA_MULTIREAD */
  138. if ((val & READ_READY_BIT) == 0) {
  139. if (--retries > 0) {
  140. pcilib_warning("Timeout occured during register write (CMOSIS %lu, value: %lu, status: %lx), retrying (try %i of %i)...", addr, value, val, RETRIES - retries, RETRIES);
  141. goto retry;
  142. }
  143. pcilib_error("Timeout writting register value (CMOSIS %lu, value: %lu, status: %lx)", addr, value, val);
  144. return PCILIB_ERROR_TIMEOUT;
  145. }
  146. if (val & READ_ERROR_BIT) {
  147. /* if (--retries > 0) {
  148. pcilib_warning("Register write has failed (CMOSIS %lu, value: %lu, status: %lx), retrying (try %i of %i)...", addr, value, val, RETRIES - retries, RETRIES);
  149. goto retry;
  150. }*/
  151. pcilib_error("Error writting register value (CMOSIS %lu, value: %lu, status: %lx)", addr, value, val);
  152. return PCILIB_ERROR_FAILED;
  153. }
  154. if (((val&ADDR_MASK) >> 8) != addr) {
  155. if (--retries > 0) {
  156. pcilib_warning("Address verification failed during register write (CMOSIS %lu, value: %lu, status: %lx), retrying (try %i of %i)...", addr, value, val, RETRIES - retries, RETRIES);
  157. goto retry;
  158. }
  159. pcilib_error("Address verification failed during register write (CMOSIS %lu, value: %lu, status: %lx)", addr, value, val);
  160. return PCILIB_ERROR_VERIFY;
  161. }
  162. if ((val&0xFF/*&ipecamera_bit_mask[bits]*/) != value) {
  163. pcilib_error("Value verification failed during register read (CMOSIS %lu, value: %lu != %lu)", addr, val/*&ipecamera_bit_mask[bits]*/, value);
  164. return PCILIB_ERROR_VERIFY;
  165. }
  166. //printf("%i\n", val&ipecamera_bit_mask[bits]);
  167. return 0;
  168. }