You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

132 lines
3.4 KiB

  1. #include "config.h"
  2. #include "adc.h"
  3. /* The ADC (AD7846) is tricky, as new conversions start
  4. automatically when the previous data read finishes.
  5. To allow more control over start/read, we stretch the
  6. read indefinitely by delaying the final SCK edge.
  7. This means we can't have the hardware do SPI for us. */
  8. /* External serial clock, 2-wire I/O -- tie /EXT low,
  9. tie ADC SDI for rate selection, tie /CS low, use BUSY for
  10. interrupt notification if desired */
  11. /* Since the ADC is 5v, ADC SDO must be on a digital-only pin.
  12. All exposed pins on B D and E are digital, so use SPI pins:
  13. ADC SDO = PIC SDI1 = RF7
  14. ADC SCK = PIC SCK1 = RF6
  15. */
  16. #define TRIS_SDO TRISFbits.TRISF7
  17. #define R_SDO PORTFbits.RF7
  18. #define TRIS_SCK TRISFbits.TRISF6
  19. #define LAT_SCK LATFbits.LATF6
  20. /* Short delays */
  21. #define wait_200ns() do { \
  22. nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); \
  23. } while(0)
  24. #define wait_25ns() nop()
  25. /* Initialize ADC */
  26. void adc_init(void)
  27. {
  28. int i;
  29. TRIS_SDO = 1;
  30. LAT_SCK = 0;
  31. TRIS_SCK = 0;
  32. /* Startup delay CS down to SCK high t4 = 5000ns */
  33. for (i = 0; i < 5000 / 25; i++)
  34. wait_25ns();
  35. /* Trigger a dummy read so we're prepared for the
  36. next conversion */
  37. (void) adc_read();
  38. }
  39. /* Start a conversion if it hasn't already been started.
  40. Wait for conversion to finish.
  41. Read the result and return the raw 32-bit value. */
  42. uint32_t adc_read(void)
  43. {
  44. uint32_t val;
  45. int i;
  46. /* Start conversion by completing previous read */
  47. LAT_SCK = 0;
  48. /* Wait tKQMAX for SCK down to SDO valid */
  49. wait_200ns();
  50. /* Wait for conversion to finish */
  51. while (R_SDO == 1)
  52. continue;
  53. /* Read it out */
  54. val = 0;
  55. for (i = 0; i < 32; i++) {
  56. /* SCK low tLESCK = 25ns */
  57. wait_25ns();
  58. LAT_SCK = 1;
  59. /* SCK high tHESCK = 25ns, but
  60. we also have SCK down to SDO valid tKQMAX = 200ns?
  61. Probably misspecified but wait tKQMAX anyway. */
  62. wait_200ns();
  63. val <<= 1;
  64. if (R_SDO)
  65. val |= 1;
  66. /* Leave SCK high on final bit to delay new conversion */
  67. if (i < 31)
  68. LAT_SCK = 0;
  69. }
  70. /* Done */
  71. return val;
  72. }
  73. /* Convert a raw 32-bit value into a signed 32-bit result.
  74. The return value is full int32 range but only the high
  75. 24 should be significant: low 3 will always be 0,
  76. and the next 5 will be sub-resolution (see datasheet). */
  77. int32_t adc_convert(uint32_t raw)
  78. {
  79. int sigmsb = (raw >> 28) & 3;
  80. /* If SIG & MSB, it is a positive overflow */
  81. if (sigmsb == 3)
  82. return (int32_t)0x7FFFFFFFL;
  83. /* If !SIG & !MSB, it is a negative overflow */
  84. if (sigmsb == 0)
  85. return (int32_t)0x80000000L;
  86. /* Shift over EOC,DMY,SIG and return */
  87. return ((int32_t)(raw << 3));
  88. }
  89. /* Start a new conversion. If a conversion was already started
  90. but the result was not read, this does nothing. */
  91. void adc_start_conversion(void)
  92. {
  93. /* If we had a previous conversion ready to read,
  94. read it out so we can start a new conversion instead */
  95. if (adc_is_conversion_ready())
  96. (void) adc_read();
  97. /* Start conversion by completing previous read */
  98. LAT_SCK = 0;
  99. /* Wait tKQMAX for SCK down to SDO valid in case we
  100. call adc_is_conversion_finished right away. */
  101. wait_200ns();
  102. }
  103. /* Return 1 if a conversion is finished and ready to be read, 0 otherwise */
  104. int adc_is_conversion_ready(void)
  105. {
  106. if (LAT_SCK == 0 && R_SDO == 0)
  107. return 1;
  108. return 0;
  109. }