Waveform Generator (Two DAC examples)

Post your cool example code here.
User avatar
Vassilis
Posts: 313
Joined: Thu May 21, 2015 6:42 am
Location: Thessaloniki, Greece
Contact:

Waveform Generator (Two DAC examples)

Post by Vassilis » Mon Aug 17, 2015 5:37 pm

Today I received my new STM32F103VET board and I tried to test the DAC feature.
I did a quick search on this forum but I didn't find any simple DAC example. So, I created two ;)

The DAC examples are not compatible with the Arduino due DAC library but I think is the first step for us to make them have the same syntax as Arduino Due has.

Any comment is appreciated.

[Example 1] Sawtooth waveform on both DAC channels

Code: Select all

/**
 *  Example of using  the two DAC channels of the STM32F103VET micro-controller. 
 *  The STM32F103VET creates a Sawtooth waveform on pin PA4 (DAC Channel 1) and PA5 (DAC Channel 2) 
 *  
 *  (c) 17 August 2015 by Vassilis Serasidis 
 *  
 */
 
#include "libmaple/dac.h"

int i;

void setup() {
  dac_init(DAC, DAC_CH1 | DAC_CH2);   // Enable both DAC channels (Channel 1 and Channel 2).
  pinMode(PA4, OUTPUT); // DAC_CH1 shares the same pin with SPI1_NSS pin (PA4). So it has to be initialized again, as output. 

}

void loop() {
  //Create a sawtooth waveform on pins PA4 (DAC Channel 1) and PA5 (DAC Channel 2)
  for(i=0;i<4096;i++){
    dac_write_channel(DAC, DAC_CH1, i); //DAC, Channel, value
    dac_write_channel(DAC, DAC_CH2, i); //DAC, Channel, value
  }
}

[Example 2] Sine waveform on Channel 1, Triangle waveform on Channel 2

Code: Select all

/**
 *  Example of using  the two DAC channels of the STM32F103VET micro-controller. 
 *  The STM32F103VET creates a Sine waveform on pin PA4 (DAC Channel 1)
 *  and a triangular waveform on PA5 (DAC Channel 2) 
 *  
 *  (c) 17 August 2015 by Vassilis Serasidis 
 *  
 */
 
#include "libmaple/dac.h"

#define waveformLength 120


int i;

// Sine wave
static int sineWave[waveformLength] {
    0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
    0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
    0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
    0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
    0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
    0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
    0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
    0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
    0x112, 0x0df, 0x0b1, 0x087, 0x064, 0x045, 0x02c, 0x019, 0x00b, 0x002,
    0x000, 0x002, 0x00b, 0x019, 0x02c, 0x045, 0x064, 0x087, 0x0b1, 0x0df,
    0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
    0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
};

// Triangular wave
static int triangularWave[waveformLength] {
    0x044, 0x088, 0x0cc, 0x110, 0x154, 0x198, 0x1dc, 0x220, 0x264, 0x2a8,
    0x2ec, 0x330, 0x374, 0x3b8, 0x3fc, 0x440, 0x484, 0x4c8, 0x50c, 0x550,
    0x594, 0x5d8, 0x61c, 0x660, 0x6a4, 0x6e8, 0x72c, 0x770, 0x7b4, 0x7f8,
    0x83c, 0x880, 0x8c4, 0x908, 0x94c, 0x990, 0x9d4, 0xa18, 0xa5c, 0xaa0,
    0xae4, 0xb28, 0xb6c, 0xbb0, 0xbf4, 0xc38, 0xc7c, 0xcc0, 0xd04, 0xd48,
    0xd8c, 0xdd0, 0xe14, 0xe58, 0xe9c, 0xee0, 0xf24, 0xf68, 0xfac, 0xff0,
    0xfac, 0xf68, 0xf24, 0xee0, 0xe9c, 0xe58, 0xe14, 0xdd0, 0xd8c, 0xd48,
    0xd04, 0xcc0, 0xc7c, 0xc38, 0xbf4, 0xbb0, 0xb6c, 0xb28, 0xae4, 0xaa0,
    0xa5c, 0xa18, 0x9d4, 0x990, 0x94c, 0x908, 0x8c4, 0x880, 0x83c, 0x7f8,
    0x7b4, 0x770, 0x72c, 0x6e8, 0x6a4, 0x660, 0x61c, 0x5d8, 0x594, 0x550,
    0x50c, 0x4c8, 0x484, 0x440, 0x3fc, 0x3b8, 0x374, 0x330, 0x2ec, 0x2a8,
    0x264, 0x220, 0x1dc, 0x198, 0x154, 0x110, 0x0cc, 0x088, 0x044, 0x000
};


void setup() {
  dac_init(DAC, DAC_CH1 | DAC_CH2);   // Enable both DAC channels (Channel 1 and Channel 2).
  pinMode(PA4, OUTPUT); // DAC_CH1 shares the same pin with SPI1_NSS pin (PA4). So it has to be initialized again, as output. 
}

void loop() {
  //Create a Sine waveform on pin PA4 (DAC Channel 1) and a  triangular waveform on PA5 (DAC Channel 2)
  for(i=0;i<waveformLength;i++){
    dac_write_channel(DAC, DAC_CH1, sineWave[i]);  // write the selected waveform on DAC1
    dac_write_channel(DAC, DAC_CH2, triangularWave[i]);  // write the selected waveform on DAC2 
    delayMicroseconds(100);
  } 
}
I hope you like the examples :D

EDIT
I uploaded some screen-shots for the Example 2, taken from my DSO203 oscilloscope.
Attachments
TriangleWave.jpg
TriangleWave.jpg (41.17 KiB) Viewed 6532 times
SineWave.jpg
SineWave.jpg (40.96 KiB) Viewed 6532 times
Last edited by Vassilis on Sun Aug 23, 2015 9:16 am, edited 2 times in total.

User avatar
ahull
Posts: 1596
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: Waveform Generator (Two DAC examples)

Post by ahull » Mon Aug 17, 2015 10:10 pm

Looks good, I don't have a board to hand to try it with, but when I get a moment I'll connect one up to the scope. It compiles fine for the STM32F103RCT6, so I'll dig out that board.

The only issue I spotted is that you have used...

Code: Select all

#include "libmaple\dac.h"
... which is not portable across Windows and Linux/Mac - try...

Code: Select all

#include "libmaple/dac.h"
.. which should work for all platforms.
- Andy Hull -

User avatar
Vassilis
Posts: 313
Joined: Thu May 21, 2015 6:42 am
Location: Thessaloniki, Greece
Contact:

Re: Waveform Generator (Two DAC examples)

Post by Vassilis » Sun Aug 23, 2015 9:15 am

I uploaded two <Example 2> screen-shots on the first post. The screen-shots are taken from my DSO203 oscilloscope.

@Andy I did your backslash recommendation.

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: Waveform Generator (Two DAC examples)

Post by madias » Tue Aug 25, 2015 12:48 pm

Thank you for this little example. Works flawlessly :)
Vassilis: You don't have any clue how to port a working I2S code to our STM32F103xxx boards (like the RCT6 or VET6)?

User avatar
Vassilis
Posts: 313
Joined: Thu May 21, 2015 6:42 am
Location: Thessaloniki, Greece
Contact:

Re: Waveform Generator (Two DAC examples)

Post by Vassilis » Tue Aug 25, 2015 1:16 pm

madias wrote:Thank you for this little example. Works flawlessly :)
Vassilis: You don't have any clue how to port a working I2S code to our STM32F103xxx boards (like the RCT6 or VET6)?
If I understand the question, you want to run a I2S sketch example (for example) on STM32F103C8T6 by using an external I2S chip such as TDA1543.

Am I right?

EDIT
Or do you want an example sketch that uses the internal I2S feature of the VET6 mcu's

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: Waveform Generator (Two DAC examples)

Post by madias » Tue Aug 25, 2015 2:15 pm

You are totally right! I just wanna use the sketch with an external DAC like TDA1543 or those PT8211 just as a simple test, the fine tuning is no problem (sample rate, data format....). I use my PIC32MX250 with the PT8211 DAC's and they are really easy to setup, but with libmaple I have no clue how to begin, because it's simple not implemented.
internal I2S feature of the VET6 mcu's
Interesting thing, didn't heard about such a feature :) have to google for it....

User avatar
Vassilis
Posts: 313
Joined: Thu May 21, 2015 6:42 am
Location: Thessaloniki, Greece
Contact:

Re: Waveform Generator (Two DAC examples)

Post by Vassilis » Tue Aug 25, 2015 2:27 pm

The VET6 have two I2S interfaces multiplexed with SPI2 and SPI3. The I2S and the SPI data flow is almost the same. One small difference is that the I2S needs one more pin ( in case of using an external I2S chip) to select the left or the right audio channel.

I will try the VET6 internal (hardware) I2S tomorrow.

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: Waveform Generator (Two DAC examples)

Post by madias » Tue Aug 25, 2015 5:26 pm

Ok, there was a little misunderstood:
I mean F103 devices with the hardware I2S as an build in option. (I first thought, that the VET6 has I2S DAC's onboard...)
So in particular boards like the VET6, RCT6 and so on (I assume that all boards with the 12bit-2-channel-DAC's also have the I2S possibility)

The problem is, that only in the spi.h (lower caps!) file/s there are some register entries for I2S but no functions in spi.c or further details. I think leaflabs planned it, but never realized it so the last "real maple" (with RET6) wasn't supported even by leaflabs themselves .
A starting point could be https://github.com/mubase/STM32F4-Ardui ... m32f4codec
But the files are different from the STMF1 ones and maybe (or sure) outdated.
An important point should be to enable an interrupt if the TX buffer (maybe also RX, but i dont need that) is empty, this is a little bit different to "normal" SPI

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: Waveform Generator (Two DAC examples)

Post by madias » Wed Aug 26, 2015 4:00 pm

About I2S:
Ok, I tried to combine all the stuff mubase made for the F4 https://github.com/mubase/STM32F4-Arduino-core
Result: I give up (not even a blink sketch runs anymore after doing changes in rcc.h/c, spi.h/c). Spend more than 8 hours fooling around. It's totally to high to me to implement I2S from level zero into this API. Here I really miss my PIC32MX: I got I2S on those MCU's running only with the help of the datasheet....
BTW there are too much files with same or - nearly the same - names and too much crossings like rcc.h, rcc_f1.h, rcc_private.h and so on. This makes it too much difficult to reverse engineer anything. Example: There are 4 files with the name "spi.h" (ok, one is SPI.h as the library wrapper) with different behaviors.
(Sorry for my bad mood, I'm suffering from a bad illness for about one week that I got in my holidays...)

User avatar
RogerClark
Posts: 6880
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Waveform Generator (Two DAC examples)

Post by RogerClark » Wed Aug 26, 2015 9:10 pm

Hi Matthias

Sorry to hear you are ill :-(

Perhaps we need to start to push to get @Sheepdoll's core fully operational.

( That core may also helo with the GD32 boards, but I don't think GD use HAL, I think they just use CMSIS etc)

I may have some time at the weekend to look at the sheepdoll core.

Post Reply