129 lines
3.7 KiB
C
129 lines
3.7 KiB
C
#include "dac_drv_if.h"
|
|
|
|
#include "elite_pin_ctrl.h"
|
|
#include "nrf_log.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
|
|
#define MAX5136_NOP_MODE (0x00 << 0)
|
|
#define MAX5136_LDAC_MODE (0x01 << 0)
|
|
#define MAX5136_CLR_MODE (0x02 << 0)
|
|
#define MAX5136_PWR_CTRL_MODE (0x03 << 0)
|
|
#define MAX5136_LINEARITY_MODE (0x05 << 0)
|
|
#define MAX5136_WRITE_MODE (0x01 << 4)
|
|
#define MAX5136_WRITE_THROUGH_MODE (0x03 << 4)
|
|
|
|
#define MAX5136_LINEARITY_SET (0b1000000000)
|
|
#define MAX5136_LINEARITY_CLR (0b0000000000)
|
|
|
|
typedef struct __PACKED
|
|
{
|
|
uint8_t ctrl_bits;
|
|
uint16_t data_bits;
|
|
} max5136_opcode_t;
|
|
|
|
static int max5136_ldac_mode(uint32_t channel_mask)
|
|
{
|
|
/*
|
|
Move contents of input to DAC registers indicated by 1's.
|
|
No effect on registers indicated by 0's.
|
|
*/
|
|
max5136_opcode_t op_code = {
|
|
.ctrl_bits = MAX5136_LDAC_MODE,
|
|
.data_bits = __REVSH((channel_mask & 0b1111) << 8),
|
|
};
|
|
spi2_write(CS_DAC_PIN, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
|
return 0;
|
|
}
|
|
|
|
static int max5136_power_control_mode(uint32_t channel_mask, uint32_t ready_enable)
|
|
{
|
|
/*
|
|
Power down DACs indicated by 1's.
|
|
Set READY_EN = 1 to enable READY.
|
|
*/
|
|
max5136_opcode_t op_code = {
|
|
.ctrl_bits = MAX5136_PWR_CTRL_MODE | (channel_mask & 0b1111),
|
|
.data_bits = __REVSH(((channel_mask & 0b1111) << 8) | (ready_enable == 0 ? 0 : 1)),
|
|
};
|
|
spi2_write(CS_DAC_PIN, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
|
return 0;
|
|
}
|
|
|
|
static int max5136_write_mode(uint32_t channel_mask, int32_t dac_val)
|
|
{
|
|
/*
|
|
Write to selected input registers (DAC output not affected).
|
|
*/
|
|
max5136_opcode_t op_code = {
|
|
.ctrl_bits = MAX5136_WRITE_MODE | (channel_mask & 0b1111),
|
|
.data_bits = __REVSH(dac_val),
|
|
};
|
|
spi2_write(CS_DAC_PIN, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
|
return 0;
|
|
}
|
|
|
|
static int max5136_write_through_mode(uint32_t channel_mask, int32_t dac_val)
|
|
{
|
|
/*
|
|
Write to selected input and DAC registers, DAC outputs updated (writethrough).
|
|
*/
|
|
max5136_opcode_t op_code = {
|
|
.ctrl_bits = MAX5136_WRITE_THROUGH_MODE | (channel_mask & 0b1111),
|
|
.data_bits = __REVSH(dac_val),
|
|
};
|
|
spi2_write(CS_DAC_PIN, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
|
return 0;
|
|
}
|
|
|
|
static void max5136_linearity(void)
|
|
{
|
|
/*
|
|
To guarantee DAC linearity, wait until the supplies have
|
|
settled. Set the LIN bit in the DAC linearity register; wait
|
|
10ms, and clear the LIN bit.
|
|
*/
|
|
max5136_opcode_t op_code = { .ctrl_bits = MAX5136_LINEARITY_MODE };
|
|
|
|
op_code.data_bits = __REVSH(MAX5136_LINEARITY_SET);
|
|
spi2_write(CS_DAC_PIN, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
|
|
op_code.data_bits = __REVSH(MAX5136_LINEARITY_CLR);
|
|
spi2_write(CS_DAC_PIN, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
|
}
|
|
|
|
static int max5136_soft_reset(void)
|
|
{
|
|
/*
|
|
The software clear command acts as a software POR,
|
|
erasing the contents of all registers. All outputs
|
|
return to the state determined by the M/Z input.
|
|
*/
|
|
|
|
max5136_opcode_t op_code = {
|
|
.ctrl_bits = MAX5136_CLR_MODE,
|
|
.data_bits = 0,
|
|
};
|
|
spi2_write(CS_DAC_PIN, (uint8_t *)&op_code, sizeof(op_code), NULL, 0);
|
|
return 0;
|
|
}
|
|
|
|
static int max5136_init(void)
|
|
{
|
|
max5136_soft_reset();
|
|
max5136_linearity();
|
|
return 0;
|
|
}
|
|
|
|
dac_drv_if_t max5316_drv = {
|
|
.init = max5136_init,
|
|
.ldac_mode = max5136_ldac_mode,
|
|
.reset = max5136_soft_reset,
|
|
.power_control_mode = max5136_power_control_mode,
|
|
.write_mode = max5136_write_mode,
|
|
.write_through_mode = max5136_write_through_mode,
|
|
};
|