|
|
@ -44,6 +44,25 @@ void AudioDac::Start(SampleRate sample_rate, BitDepth bit_depth) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Next, wait for the IC to boot up before we try configuring it.
|
|
|
|
|
|
|
|
bool is_booted = false; |
|
|
|
|
|
|
|
for (int i=0; i<10; i++) { |
|
|
|
|
|
|
|
uint8_t result = ReadPowerState(); |
|
|
|
|
|
|
|
is_booted = result >> 7;
|
|
|
|
|
|
|
|
if (is_booted) { |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ESP_LOGI(TAG, "Waiting for boot..."); |
|
|
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(1)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!is_booted) { |
|
|
|
|
|
|
|
// TODO: properly handle
|
|
|
|
|
|
|
|
ESP_LOGE(TAG, "Timed out waiting for boot!"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Now do all the math required to correctly set up the internal clocks.
|
|
|
|
// Now do all the math required to correctly set up the internal clocks.
|
|
|
|
int p, j, d, r; |
|
|
|
int p, j, d, r; |
|
|
|
int nmac, ndac, ncp, dosr, idac; |
|
|
|
int nmac, ndac, ncp, dosr, idac; |
|
|
@ -153,15 +172,36 @@ void AudioDac::Start(SampleRate sample_rate, BitDepth bit_depth) { |
|
|
|
|
|
|
|
|
|
|
|
i2c_master_stop(handle); |
|
|
|
i2c_master_stop(handle); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "Configuring DAC"); |
|
|
|
// TODO: Handle this gracefully.
|
|
|
|
// TODO: Handle this gracefully.
|
|
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, handle, 50)); |
|
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, handle, kPCM5122Timeout)); |
|
|
|
|
|
|
|
|
|
|
|
i2c_cmd_link_delete(handle); |
|
|
|
i2c_cmd_link_delete(handle); |
|
|
|
|
|
|
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10)); |
|
|
|
// The DAC takes a moment to reconfigure itself. Give it some time before we
|
|
|
|
|
|
|
|
// start asking for its state.
|
|
|
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(5)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: investigate why it's stuck waiting for CP voltage.
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
bool is_configured = false; |
|
|
|
|
|
|
|
for (int i=0; i<10; i++) { |
|
|
|
|
|
|
|
uint8_t result = ReadPowerState(); |
|
|
|
|
|
|
|
is_configured = (result & 0b1111) == 0b1001; |
|
|
|
|
|
|
|
if (is_configured) { |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ESP_LOGI(TAG, "Waiting for configure..."); |
|
|
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(1)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TODO: Handle this gracefully.
|
|
|
|
if (!is_configured) { |
|
|
|
assert(ReadPowerState() == 0x05); |
|
|
|
// TODO: properly handle
|
|
|
|
|
|
|
|
ESP_LOGE(TAG, "Timed out waiting for configure!"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint8_t AudioDac::ReadPowerState() { |
|
|
|
uint8_t AudioDac::ReadPowerState() { |
|
|
@ -176,10 +216,11 @@ uint8_t AudioDac::ReadPowerState() { |
|
|
|
i2c_master_write_byte(handle, (kPCM5122Address << 1 | I2C_MASTER_WRITE), true); |
|
|
|
i2c_master_write_byte(handle, (kPCM5122Address << 1 | I2C_MASTER_WRITE), true); |
|
|
|
i2c_master_write_byte(handle, DSP_BOOT_POWER_STATE, true); |
|
|
|
i2c_master_write_byte(handle, DSP_BOOT_POWER_STATE, true); |
|
|
|
i2c_master_start(handle); |
|
|
|
i2c_master_start(handle); |
|
|
|
|
|
|
|
i2c_master_write_byte(handle, (kPCM5122Address << 1 | I2C_MASTER_READ), true); |
|
|
|
i2c_master_read_byte(handle, &result, I2C_MASTER_NACK); |
|
|
|
i2c_master_read_byte(handle, &result, I2C_MASTER_NACK); |
|
|
|
i2c_master_stop(handle); |
|
|
|
i2c_master_stop(handle); |
|
|
|
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, handle, 50)); |
|
|
|
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, handle, kPCM5122Timeout)); |
|
|
|
|
|
|
|
|
|
|
|
i2c_cmd_link_delete(handle); |
|
|
|
i2c_cmd_link_delete(handle); |
|
|
|
|
|
|
|
|
|
|
|