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.
 
 
 
 

78 lines
1.7 KiB

  1. #include "config.h"
  2. #include "dac.h"
  3. /* Initialize DAC (AD5542) */
  4. void dac_init(void)
  5. {
  6. /* SPI2 */
  7. IEC2bits.SPI2IE = 0;
  8. SPI2CON1bits.DISSCK = 0;
  9. SPI2CON1bits.DISSDO = 0;
  10. SPI2CON1bits.MODE16 = 1;
  11. SPI2CON1bits.SMP = 0;
  12. SPI2CON1bits.CKE = 0;
  13. SPI2CON1bits.SSEN = 0;
  14. SPI2CON1bits.CKP = IO_HIGH;
  15. SPI2CON1bits.MSTEN = 1;
  16. SPI2CON1bits.SPRE = 4;
  17. SPI2CON1bits.PPRE = 3;
  18. /* There's no framed mode that does the normal
  19. "chip select" behavior, so control /SS2 manually */
  20. SPI2CON2bits.FRMEN = 0;
  21. LATGbits.LATG9 = IO_HIGH;
  22. TRISGbits.TRISG9 = 0;
  23. SPI2STATbits.SPISIDL = 0;
  24. SPI2STATbits.SPIEN = 1;
  25. dac_write(0x0000);
  26. }
  27. static const uint16_t dac_lookup[1024] = {
  28. #include "lookup.inc"
  29. };
  30. /* Write raw 16-bit desired value to DAC:
  31. DAC_HIGH 4.9998v
  32. DAC_MID 0v
  33. DAC_LOW -5v
  34. */
  35. void dac_write(uint16_t val)
  36. {
  37. LATGbits.LATG9 = IO_LOW;
  38. if (IO_HIGH == 1)
  39. SPI2BUF = __dac_to_spi_cmd(val);
  40. else
  41. SPI2BUF = ~__dac_to_spi_cmd(val);
  42. while (!SPI2STATbits.SPIRBF)
  43. continue;
  44. (void) SPI2BUF;
  45. LATGbits.LATG9 = IO_HIGH;
  46. }
  47. /* Given a DAC command between DAC_LOW and DAC_HIGH,
  48. get the actual expected output voltage as a 16-bit value, where:
  49. 0xffff = 4.9998v
  50. 0x8000 = 0v
  51. 0x0000 = -5v
  52. */
  53. uint16_t dac_get_actual_16bit(uint16_t val)
  54. {
  55. return __dac_to_16bit_equiv(val);
  56. }
  57. /* Given a DAC command between DAC_LOW and DAC_HIGH,
  58. get the actual expected output voltage as a FLOAT, where:
  59. DAC_HIGH = 4.9998v
  60. DAC_MID = 0v
  61. DAC_LOW = -5v
  62. Example: for 10-bit DAC, convert integer command 123 into
  63. the more accurate 123.45 using known lower bits.
  64. */
  65. float dac_get_actual_float(uint16_t val)
  66. {
  67. return __dac_to_16bit_equiv(val) * (DAC_RANGE / 65536.0);
  68. }