Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider replacing DAC8568C with DAC8568A #7

Open
westlicht opened this issue Nov 22, 2017 · 5 comments
Open

Consider replacing DAC8568C with DAC8568A #7

westlicht opened this issue Nov 22, 2017 · 5 comments
Assignees

Comments

@westlicht
Copy link
Owner

westlicht commented Nov 22, 2017

The C grade have 5V full scale output, but due to VCC at 3.3V we only use half range at 2.5V and loose 1 bit of accuracy. We could replace with DAC8568A which has full range at 2.5V, so this would allow us to use all bits, however, we loose some accuracy due to lower grade of internal reference.

@westlicht westlicht self-assigned this Nov 22, 2017
@btomwhitehead
Copy link

btomwhitehead commented Jan 29, 2020

Resurrecting an old issue here but thought I its a pertinent place to raise it. If you dont think so, Im happy to delete my comment.

I made the mistake of getting a DAC8568B, which like A, doesn't have the 2x output gain. I am not worried about the initialisation value being at midpoint given the firmware appears to init the Dac to 0v regardless.

So the two options are:

  • Replace the DAC (and there will be an effective 15bit resolution)
  • Update firmware to reflect the reduced output gain by doubling D_IN.

Screen Shot 2020-01-29 at 8 09 27 PM

From my understanding of this issue and the effective output in the datasheet, it seems that the leading bit is irrelevant because the VCC is less than the 5v range. My thought it then that the gain can be made up with writing double the DATA value to the DAC. If this is true, if we reduce the right data bitwise shifts in the Dac write by 1, we can effectively make up the range:

void Dac::writeDac(uint8_t command, uint8_t address, uint16_t data, uint8_t function) {
    uint8_t b1 = command;
    uint8_t b2 = (address << 4) | (data >> 12);
    uint8_t b3 = data >> 4;
    uint8_t b4 = (data & 0xf) << 4 | function;
  ...

to

void Dac::writeDac(uint8_t command, uint8_t address, uint16_t data, uint8_t function) {
    uint8_t b1 = command;
    uint8_t b2 = (address << 4) | (data >> 11);
    uint8_t b3 = data >> 3;
    uint8_t b4 = ((data << 1) & 0xf) << 4 | function;
  ...

Do you think this could work? I am going to give it a test in the coming days. Or do you know a better place (this is no doubt a hack) to make such a change?

It seems like the scale values defined in src/apps/sequencer/model/Scale.cpp correspond to https://westlicht.github.io/performer/manual/#appendix-scales however I am not entirely sure how the octave int is converted to the dac volt output or how to fix the LFO scaling. So I dont really know how to address it at the app level.

🙏 🙏 🙏

edit:

I have tested the above and for several tracks (on which I tested it) and in cases C0 reads 0V, C5 reads 5V and C-5 reads -5V! So this appears to have worked!

I'd try comment on your precision questions regarding the worse internal 2.5v ref but my meter isnt isn't accurate enough to conclude. @westlicht If you are interested in determining the accuracy of this, I can source a higher quality meter and scope to perform whatever tests you like.

@westlicht
Copy link
Owner Author

Hey, I only saw this comment now. I think the change you did is valid, shifting the output by one bit. I might consider adding that to the hardware config so people can actually use the cheaper DAC if the wish to. I haven't measured the difference in accuracy, would have to first make a performer with the A grade DAC.

@btomwhitehead
Copy link

Great!

Yeah, I have been using it since without any complaints or noticeable drift.

Thanks for the response.

@Timnuge
Copy link

Timnuge commented Apr 10, 2020

Hello!

My Performer is built with DAC8568A🤔 A way to switch would make my life easy or, could you please share with me update file? Any help would be greatly appreciated!

@btomwhitehead
Copy link

btomwhitehead commented Apr 10, 2020

@Timnuge as per above notes, heres the changes I made to src/platform/stm32/drivers/Dac.cpp:

--- a/src/platform/stm32/drivers/Dac.cpp
+++ b/src/platform/stm32/drivers/Dac.cpp
@@ -72,9 +72,9 @@ void Dac::write() {

 void Dac::writeDac(uint8_t command, uint8_t address, uint16_t data, uint8_t function) {
     uint8_t b1 = command;
-    uint8_t b2 = (address << 4) | (data >> 12);
-    uint8_t b3 = data >> 4;
-    uint8_t b4 = (data & 0xf) << 4 | function;
+    uint8_t b2 = (address << 4) | (data >> 11);
+    uint8_t b3 = data >> 3;
+    uint8_t b4 = ((data << 1) & 0xf) << 4 | function;

     gpio_clear(DAC_PORT, DAC_SYNC);--- a/src/platform/stm32/drivers/Dac.cpp

Would have pushed a custom branch to the main repo but (very sensibly) I don't have the requisite permissions.

Theres probably a better way to express ((data << 1) & 0xf) << 4 but this works on a 8568B which has the same gain range as the A.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants