cmosis.c 6.9 KB

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