mirror of
https://github.com/jhbruhn/eurorack.git
synced 2025-03-15 02:55:49 +00:00
Fix bugs in AD57X4 driver implemenation
This commit is contained in:
parent
30a86fbdd9
commit
3da627830d
4 changed files with 47 additions and 22 deletions
|
@ -1,8 +1,8 @@
|
|||
#include "ad57x4.h"
|
||||
#include "peripherals.h"
|
||||
#include "spi_mode.h"
|
||||
#include <stm32f3xx_hal.h>
|
||||
#include <math.h>
|
||||
#include <stm32f3xx_hal.h>
|
||||
|
||||
static const uint32_t kPinEnable = GPIO_PIN_5;
|
||||
|
||||
|
@ -16,26 +16,34 @@ void AD57X4::Init()
|
|||
HAL_GPIO_Init(GPIOB, &init);
|
||||
|
||||
HAL_GPIO_WritePin(GPIOB, kPinEnable, GPIO_PIN_SET);
|
||||
|
||||
this->Write(REGISTER_CONTROL, 1, 0b100);
|
||||
}
|
||||
|
||||
void AD57X4::WriteVoltage(uint8_t dac, float voltage) {
|
||||
void AD57X4::WriteVoltage(uint8_t dac, float voltage)
|
||||
{
|
||||
CONSTRAIN(voltage, -10.799f, 10.799f);
|
||||
VoltageRange range = VOLTAGE_RANGE_FIVE_VOLTS;
|
||||
if(fabs(voltage) > 5) range = VOLTAGE_RANGE_TEN_VOLTS;
|
||||
if(fabs(voltage) > 10) range = VOLTAGE_RANGE_TEN_EIGHT_VOLTS;
|
||||
if (fabs(voltage) > 5)
|
||||
range = VOLTAGE_RANGE_TEN_VOLTS;
|
||||
if (fabs(voltage) > 10)
|
||||
range = VOLTAGE_RANGE_TEN_EIGHT_VOLTS;
|
||||
|
||||
float multiplier = 2.0f;
|
||||
if(range == VOLTAGE_RANGE_TEN_VOLTS) multiplier = 4.0f;
|
||||
if(range == VOLTAGE_RANGE_TEN_EIGHT_VOLTS) multiplier = 4.32f;
|
||||
if (range == VOLTAGE_RANGE_TEN_VOLTS)
|
||||
multiplier = 4.0f;
|
||||
if (range == VOLTAGE_RANGE_TEN_EIGHT_VOLTS)
|
||||
multiplier = 4.32f;
|
||||
float refin = 2.5f;
|
||||
|
||||
if (voltage < 0) {
|
||||
// convert to signed value
|
||||
int16_t value = (voltage / (multiplier * refin)) * (65535.0f);
|
||||
int16_t value = (32768.0f * voltage) / (multiplier * refin);
|
||||
|
||||
this->WriteDacBipolar(dac, range, value);
|
||||
} else {
|
||||
// convert to unsigned value
|
||||
uint16_t value = (voltage / (multiplier * refin)) * (65535.0f);
|
||||
uint16_t value = (65536.0f * voltage) / (multiplier * refin);
|
||||
|
||||
this->WriteDacUnipolar(dac, range, value);
|
||||
}
|
||||
|
@ -47,17 +55,25 @@ void AD57X4::EnableAndSetRange(uint8_t dac, VoltageRange range, bool bipolar)
|
|||
// power on dac
|
||||
this->dacPower |= 1 << dac;
|
||||
this->Write(REGISTER_POWER_CONTROL, 0, this->dacPower);
|
||||
for (int i = 0; i < 10000; i++)
|
||||
asm("nop");
|
||||
}
|
||||
if (this->dacRange[dac] != range) {
|
||||
if (this->dacRange[dac] != range || this->dacBipolar[dac] != bipolar) {
|
||||
this->Write(REGISTER_OUTPUT_RANGE, dac, range + (bipolar ? 3 : 0));
|
||||
this->dacRange[dac] = range;
|
||||
this->dacBipolar[dac] = bipolar;
|
||||
}
|
||||
}
|
||||
|
||||
void AD57X4::WriteDac(uint8_t dac, VoltageRange range, uint16_t value, bool bipolar) {
|
||||
EnableAndSetRange(dac, range, bipolar);
|
||||
this->Write(REGISTER_DAC, dac, value);
|
||||
this->Write(REGISTER_CONTROL, 0b101, 0); // LOAD command in Control Register
|
||||
}
|
||||
|
||||
void AD57X4::WriteDacUnipolar(uint8_t dac, VoltageRange range, uint16_t value)
|
||||
{
|
||||
EnableAndSetRange(dac, range, false);
|
||||
this->Write(REGISTER_DAC, dac, value);
|
||||
WriteDac(dac, range, value, false);
|
||||
}
|
||||
|
||||
void AD57X4::WriteDacBipolar(uint8_t dac, VoltageRange range, int16_t value)
|
||||
|
@ -66,9 +82,7 @@ void AD57X4::WriteDacBipolar(uint8_t dac, VoltageRange range, int16_t value)
|
|||
if (value < 0) {
|
||||
twosComplement = ~(-value) + 1;
|
||||
}
|
||||
|
||||
EnableAndSetRange(dac, range, true);
|
||||
this->Write(REGISTER_DAC, dac, twosComplement);
|
||||
WriteDac(dac, range, twosComplement, true);
|
||||
}
|
||||
|
||||
void AD57X4::Write(Register reg, uint8_t address, uint16_t data)
|
||||
|
@ -82,6 +96,7 @@ void AD57X4::Write(Register reg, uint8_t address, uint16_t data)
|
|||
|
||||
HAL_GPIO_WritePin(GPIOB, kPinEnable, GPIO_PIN_RESET);
|
||||
HAL_SPI_Transmit(&hspi2, &first, 1, HAL_MAX_DELAY); // write data
|
||||
HAL_SPI_Transmit(&hspi2, reinterpret_cast<uint8_t*>(&data), 2, HAL_MAX_DELAY);
|
||||
HAL_SPI_Transmit(&hspi2, reinterpret_cast<uint8_t*>(&data) + 1, 1, HAL_MAX_DELAY);
|
||||
HAL_SPI_Transmit(&hspi2, reinterpret_cast<uint8_t*>(&data), 1, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(GPIOB, kPinEnable, GPIO_PIN_SET);
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ enum VoltageRange {
|
|||
enum Register {
|
||||
REGISTER_DAC = 0,
|
||||
REGISTER_OUTPUT_RANGE = 1,
|
||||
REGISTER_CONTROL = 2,
|
||||
REGISTER_POWER_CONTROL = 3
|
||||
REGISTER_CONTROL = 3,
|
||||
REGISTER_POWER_CONTROL = 2
|
||||
};
|
||||
|
||||
class AD57X4 {
|
||||
|
@ -34,6 +34,8 @@ class AD57X4 {
|
|||
private:
|
||||
uint8_t dacPower = 0;
|
||||
VoltageRange dacRange[4];
|
||||
bool dacBipolar[4];
|
||||
void WriteDac(uint8_t dac, VoltageRange range, uint16_t value, bool bipolar);
|
||||
void EnableAndSetRange(uint8_t dac, VoltageRange range, bool bipolar);
|
||||
void Write(Register reg, uint8_t address, uint16_t data);
|
||||
DISALLOW_COPY_AND_ASSIGN(AD57X4);
|
||||
|
|
|
@ -45,7 +45,7 @@ void InitSPIAD5754(void)
|
|||
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi2.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
|
||||
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi2.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
|
|
|
@ -112,7 +112,7 @@ void SysTick_Handler(void)
|
|||
system_clock.Tick();
|
||||
}
|
||||
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) // called with 1kHz (OPTIMIZE!) the display should get its own spi bus
|
||||
{
|
||||
if (htim != &htim2) {
|
||||
return;
|
||||
|
@ -120,12 +120,19 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
|
|||
|
||||
static uint16_t count = 0;
|
||||
count++;
|
||||
if (count % (8000L / 20) == 0) {
|
||||
if (count % (1000L / 20) == 0) {
|
||||
// refresh display with 20fps
|
||||
ui.Flush();
|
||||
count = 0;
|
||||
}
|
||||
|
||||
static float v = 0;
|
||||
dac1.WriteVoltage(0, v+= 0.1f);
|
||||
dac1.WriteVoltage(1, v*3);
|
||||
dac1.WriteVoltage(2, v*5);
|
||||
dac1.WriteVoltage(3, v*10);
|
||||
if(v > 1) v = -1;
|
||||
|
||||
// write audiodac1
|
||||
// write audiodac2
|
||||
// write audiodac3
|
||||
|
@ -136,7 +143,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
|
|||
void InitTimers(void)
|
||||
{
|
||||
__HAL_RCC_TIM2_CLK_ENABLE();
|
||||
htim2.Init.Period = F_CPU / (8000 * 1) - 1;
|
||||
htim2.Init.Period = F_CPU / (1000 * 1) - 1;
|
||||
htim2.Init.Prescaler = 0;
|
||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
|
@ -161,6 +168,7 @@ void Init(void)
|
|||
//IWDG_Enable();
|
||||
display.Init();
|
||||
encoder.Init();
|
||||
dac1.Init();
|
||||
InitTimers();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue