#ifndef DAC_H
#define DAC_H

#include "config.h"

#define DAC_TYPE 2

#if DAC_TYPE == 0
  /* AD5542, normal 16-bit range */
  #define DAC_BITS 16
  #define __dac_to_spi_cmd(x) (x)
  #define __dac_to_16bit_equiv(x) (x)
#elif DAC_TYPE == 1
  /* AD5542, fake 10-bit range using random lower bits */
  #define DAC_BITS 10
  #define __dac_to_spi_cmd(x) (dac_lookup[(x)&1023])
  #define __dac_to_16bit_equiv(x) (dac_lookup[(x)&1023])
#elif DAC_TYPE == 2
  /* MAX504, true 10-bit DAC */
  #define DAC_BITS 10
  #define __dac_to_spi_cmd(x) ((x) << 2)
  #define __dac_to_16bit_equiv(x) ((x) << 6)
#else
  #error Unknown DAC type
#endif

#define DAC_LOW 0
#define DAC_HIGH ((uint16_t)(((uint32_t)1 << DAC_BITS) - 1))
#define DAC_MID ((uint16_t)((DAC_LOW + DAC_HIGH + (uint32_t)1) / 2))
#define DAC_RANGE (DAC_HIGH - DAC_LOW + 1)

/* Initialize DAC (AD5542) */
void dac_init(void);

/* Write raw value to DAC:
   DAC_HIGH 4.9998v
   DAC_MID  0v
   DAC_LOW  -5v
 */
void dac_write(uint16_t val);

/* Given a DAC command between DAC_LOW and DAC_HIGH,
   get the actual expected output voltage as a 16-bit value, where:
     0xffff = 4.9998v
     0x8000 = 0v
     0x0000 = -5v
*/
uint16_t dac_get_actual_16bit(uint16_t val);

/* Given a DAC command between DAC_LOW and DAC_HIGH,
   get the actual expected output voltage as a FLOAT, where:
     DAC_HIGH = 4.9998v
     DAC_MID  = 0v
     DAC_LOW  = -5v
   Example: for 10-bit DAC, convert integer command 123 into
   the more accurate 123.45 using known lower bits.
*/
float dac_get_actual_float(uint16_t val);

#endif
