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.
 
 
 
 

124 lines
2.6 KiB

  1. #include "config.h"
  2. #include "adc.h"
  3. #include "adcext.h"
  4. #include "dac.h"
  5. #include "uart.h"
  6. #include "timer.h"
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include "scaling.h"
  10. #include "util.h"
  11. #include "mode.h"
  12. #include "zoom.h"
  13. int send_data = 0;
  14. uint16_t send_adc;
  15. uint16_t send_dac;
  16. int possible_overflow = 0;
  17. float dac_current;
  18. #define TIMER_RATE 8000 /* how often to read the ADC and update DAC */
  19. #define PC_RATE 8000 /* how often to send data to the PC */
  20. /* Run mode */
  21. void TISR_HANDLER(5)
  22. {
  23. static int count = 0;
  24. static uint16_t dac_cmd;
  25. int16_t v;
  26. float i;
  27. /* toggle A9 every time an interrupt occurs */
  28. LATAbits.LATA9 = 1;
  29. timer_clear_txif(5);
  30. /* Get most recent sample from 12-bit ADC. */
  31. v = adc_get();
  32. if (v < 0 || v >= 2047)
  33. possible_overflow = 1;
  34. /* Send data to PC at 1 Hz */
  35. if (++count >= (TIMER_RATE / PC_RATE)) {
  36. count = 0;
  37. /* Send most recent sample and old DAC value */
  38. send_adc = v;
  39. send_dac = dac_cmd;
  40. send_data = 1;
  41. }
  42. /* Convert ADC value to current */
  43. i = adc12_to_current(v);
  44. #if 0
  45. /* Adjust DAC to null this current to 0 */
  46. dac_current -= i;
  47. #else
  48. /* If this current exceeds +-1A, cancel it out at the DAC */
  49. if (i < -1.0 || i > 1.0)
  50. dac_current -= i;
  51. #endif
  52. if (dac_current < dac_current_min)
  53. dac_current = dac_current_min;
  54. if (dac_current > dac_current_max)
  55. dac_current = dac_current_max;
  56. /* Now send it out */
  57. dac_cmd = current_to_dac(dac_current);
  58. dac_write(dac_cmd);
  59. LATAbits.LATA9 = 0;
  60. }
  61. void send_to_pc(uint16_t adc, uint16_t dac)
  62. {
  63. /* Sent data format:
  64. 1Aaa aaaa 0aaa aaDd 0ddd dddd 0ddd dddd
  65. Aaaaaaaaaaaa = 12-bit ADC value (2s compliment signed)
  66. Dddddddddddddddd = 16-bit DAC command (unsigned)
  67. */
  68. uart1_put(0x80 | ((adc & 0x0FE0) >> 5));
  69. uart1_put(((adc & 0x001F) << 2) | ((dac & 0xC000) >> 14));
  70. uart1_put((dac & 0x3F80) >> 7);
  71. uart1_put((dac & 0x007F));
  72. }
  73. void run_normal(void)
  74. {
  75. uart1_init(500000);
  76. led_on();
  77. /* Assume startup current is 0 */
  78. dac_current = 0.0;
  79. dac_write(current_to_dac(dac_current));
  80. msleep(100);
  81. degauss();
  82. timer_setup_16bit(5, TIMER_RATE, 1);
  83. timer_set_priority(5, 6);
  84. while(1) {
  85. if (send_data) {
  86. /* There's data to send. Disable the ISR briefly
  87. while we grab it */
  88. uint16_t a, d;
  89. disable_int({
  90. if (possible_overflow) {
  91. /* Mark a possible overflow in the output
  92. by setting ADC to an unlikely value */
  93. possible_overflow = 0;
  94. a = 0x0800;
  95. } else {
  96. a = send_adc;
  97. }
  98. d = send_dac;
  99. send_data = 0;
  100. });
  101. send_to_pc(a, d);
  102. }
  103. }
  104. }