CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

dsPIC33CK32MC102 DACOUT
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

dsPIC33CK32MC102 DACOUT
PostPosted: Wed Mar 24, 2021 9:55 pm     Reply with quote

I'm trying to use sine tables and a DAC to generate some nice-sounding tones. I started out using 16LF1614 and got good results, but there were not any cycles left to do any other work.
I searched the Microchip Parametrics and settled on dsPIC33CK32MC102 since it would run at 100MIPS and has a 10-bit DAC. Should be plenty of time to generate the DAC outputs and do a little extra work.
I went through all the joys of working with a new chip, got it running at 100MIPS, generated my sine values and tried to feed them to the DAC. Apparently this DAC does not behave as I expected. Not being an EE I don't understand a lot of the data sheet, but since there doesn't even seem to be a Vref for the DAC I apparently chose the wrong device.

Am I missing something?

Is there another device I can use instead? Or am I going to have to feed the sine table values to an external DAC, at the cost of precious cycles?

Thanks for any insights - current code is attached.
Cheers.
Code:
#include <33CK32MC102.h>
#device ansi
#device PASS_STRINGS=IN_RAM

#FUSES  FRC_PLL

//#use delay(internal=100M)
#use delay(internal=200M,clock_out)

// Serial debug data via SW. INVERT so can connect directly to legacy PC serial port
#use rs232( BAUD=19200, XMIT=PIN_B6, INVERT, STREAM=JGSDBG )

#define LEDHB     PIN_A0    // heartbeat LED
#define LED0      PIN_B15   // loop LED

typedef unsigned int8   UINT8;
typedef unsigned int16  UINT16;
typedef int1            BIT;

//--------------------------- CONSTANTS ---------------------------------------

//--------------------------- Macros and Globals ------------------------------
//
// Sine Table Generator:
//  https://www.daycounter.com/Calculators/Sine-Generator-Calculator.phtml

#define SINE_STEPS  40

UINT16 SINE_WAVE[SINE_STEPS] = {

0x200,0x250,0x29e,0x2e8,0x32c,0x369,0x39d,0x3c7,
0x3e6,0x3f9,0x3ff,0x3f9,0x3e6,0x3c7,0x39d,0x369,
0x32c,0x2e8,0x29e,0x250,0x200,0x1af,0x161,0x117,
0xd3,0x96,0x62,0x38,0x19,0x6,0x0,0x6,
0x19,0x38,0x62,0x96,0xd3,0x117,0x161,0x1af

};

UINT8 sine_index = 0;                   // pointer into sine table

//-------------------------------------- INT_TIMER1 ---------------------------
//
UINT16 offset=0xF63B; //for 1KHz sine wave

#int_timer1
void SineTime()
{
  set_timer1( offset );
 
  dac_write( 0, SINE_WAVE[sine_index] ); // ?? don't know what first parm should be

  if(++sine_index==SINE_STEPS) {
    sine_index=0;
  }

  output_toggle( PIN_B5 );    // verify timing with OScope here
}

//------------------------------------- main() ---------------------------------
void main()
{
  setup_adc_ports( NO_ANALOGS);
 
  setup_comparator_dac( COMP_COMMON_DAC_ENABLE );  // ?? Guessing at this...

  // Timer1 - 16-bit    Prescalar: 1/8/64/256
  // 200MHz -> 100MIPS / 65535 -> 1525.9 ticks per second - yup, works!
  //
  setup_timer1( TMR_INTERNAL | TMR_DIV_BY_1, 0xFFFF ); // Tick timer - adjust as needed via scope

  enable_interrupts(INT_TIMER1);        // for tick timer
  enable_interrupts(GLOBAL);

  delay_ms( 500 );                      // allow serial port to warm up :)
  fprintf(JGSDBG,"\r\n%s %s %s\r\n",__FILENAME__, __DATE__, __TIME__);

  while( TRUE ){
    delay_ms( 500 );
    output_toggle( LED0 );
  }//end of BIG LOOP

}//end of main()

_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Mar 25, 2021 2:47 am     Reply with quote

It doesn't have a simple DAC as you are thinking. It has a pulse modulation
DAC. This generates a pulse train, which is then integrated by an internal
filter to generate the output voltage. It is 12bit, not 10bit.
Now you could do exactly the same yourself by simply adding an RC filter
to a PWM output, and this would then give simple control.

The DAC is assumed to always feed a comparator, and the actual output
enable has to be done by this..
The comparator channel is the first value in the dac_write command, and
in the slope setup commands. The DAC is actually controlled by the
comparator settings, so it is here that you have to set what clock it is
going to use, etc. You are currently missing these settings.
First thing you need is to select the comparator to use COMP_DAC_CMPXA.
Then enable the output COMP_OUTPUT_DAC. This sets which one is fed
to the output. Only one can be selected at any time.
The clock source for the DAC is set by COMP_DAC_CLK_SRC_xxxxx

Now the slope generator module can feed the DAC, and be programed
to output a table of values from memory automatically. However you are
currently trying to just drive is 'directly', and this is the simpler mode.
So. Probably missed some, but:
Code:

  setup_comparator_dac( COMP_COMMON_DAC_ENABLE | COMP_FILTER_CLK_DIV_1 | COMP_DAC_CLK_DIV_1 | COMP_DAC_CLK_SRC_FVCODIV); //This is the fastest clock settings.
  setup_comparator_slope ( 1, COMP_DISABLE_SLOPE_FUNCTION ); //manual setting not slope
  setup_comparator(1, COMP_DAC_CMPXA | COMP_OUTPUT_DAC ); //select this comparator to use DAC, and output it.


//Then to output:

   dac_write( 1, SINE_WAVE[sine_index] ); // selecting comparator 1.

I think I have remembered all the settings that had to happen!...
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Mar 25, 2021 9:41 am     Reply with quote

Thank you, T. I'll give that a try.

I've tried the RC, and LC, filter approach but haven't had much luck at sub 1KHz frequencies, despite trying a lot of the sample circuits I've found. The range of frequencies for this project is 800 to 40 Hz. This analog stuff is fairly new territory for me, I'm much more comfortable with switch on, switch off Smile

I appreciate your tireless support of this forum - I've learned a lot from you and your fellow responders over the years.

Cheers,
_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Mar 25, 2021 11:07 am     Reply with quote

You'd want the PWM frequency as high as possible. This then allows a
small filter to be used, and still give fast responses.
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Mar 25, 2021 12:31 pm     Reply with quote

I tried the DAC setup setup you suggested but not a wiggle on DACOUT. Ordering external DAC.

If I understand correctly, what you are suggesting is set up a PWM and then adjust the duty periodically per my sine table, and a sufficiently high frequency PWM should make the smoothing of the wave form easier. I can certainly give that a try, even though I'm dubious about getting a pretty result. Something to do while I wait for my DAC to arrive.

Sigh, I should be used to this, what I thought would be a simple afternoon project for a friend is turning into a months-long affair, especially with the currently long shipping delays from suppliers.

Cheers,
_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Mar 26, 2021 1:39 am     Reply with quote

That is what the DAC on the chip you are trying to use actually does....

Understand that a 'real' (resistive array) DAC to give 10+ bits is
expensive. Hence once you get above perhaps 10 bits, the 'standard'
way to build cheaper DAC's, for low frequencies is by using PWM modulation.

Now the final result is dependant on a series of things:
1) How accurate the frequency and duty cycle is (easy).
2) How accurate the source voltage is (applies to all DAC's).
3) How small the voltage drop is in the switching elements (with modern
FET's can be very small).
4) The switching times of the gates.
5) How good the output filter used is.

For your application, a bandpass filter designed to only pass signals below
a couple of KHz, should give excellent results.

However you should be able to get the output to work on your PIC. I'd
need to go through the assembler and see if the compiler is actually
making the settings correctly. I used a similar DAC on another chip,
and this one worked once I had everything clocked correctly.
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Mar 26, 2021 12:06 pm     Reply with quote

Thanks. I'm digging into the data sheets, especially the family reference manual for 24/33 parts. I'm having trouble relating the CCS functions to what I want to do - lots of trial and error: code, look at the assembler, repeat. I'm just going to go with setting the registers directly.

I also see now, after my initial disappointment about there being only 1 timer that there are actually quite a few more in the CCP module.

Looks like the "Dual Edge Buffered Compare Mode" will be fun to play with Smile

Still holding the external DAC in reserve - several on the way. 8 bits is plenty. I'm comfortable with switch on/switch off, not so much with the stuff in between (analog). I (sorta) understand the theory behind band-pass filters but they never seem to work for me in real life.

Onward...
_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Mar 26, 2021 1:05 pm     Reply with quote

If you look at what the functions set, and the values given, which registers
they actually put values into becomes obvious. Alternatively simply enable
symbolic mode for the output listing file, send a value, and then look at
the assembler. The functions are not complex. What is 'awkward' is the
way that the comparators and the DAC are crosslinked. So the DAC
output value actually goes into a CCP register. Very strange design indeed....
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PWM setup difficulties
PostPosted: Sat Mar 27, 2021 12:28 am     Reply with quote

I'm working my way through the CCP modules, timer and interrupt is working great, now on to PWM. Found a lot of articles on using PWM as a DAC. I've worked out my maths and now am ready to try it. Here is my code for setting up a basic 25% duty cycle:
Code:

  pin_select( "CCP2OUT", PIN_B3 );   // CCP2 output for PWM demo

  setup_ccp2( CCP_PWM | CCP_DIV_BY_1 | CCP_SYSTEM_CLOCK );
  set_timer_period_ccp2( 0x4000, 0xFFFF );            // sets PR to 0x4000
  set_pwm2_duty( 0x1000 ); // should be a 25% duty    // sets RB to 0x1000, 


I checked the listing and all the registers seem to be set correctly but nothing comes out on B3.
Any suggestions?
Is there a problem with the Pin Select? One doc labels the output pin as OC2, the device spec sheet lists the assignable pin as OCM2A and CCS lists it as CCP2OUT in the header file. I'm hoping these are all the same.
_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Mar 27, 2021 2:31 am     Reply with quote

Yes.

Actually, correct myself. Your chip does have a CCP. Amazed. Didn't think
any of the DSPIC's did have!... On most of the DSPIC's there is not a CCP
module instead there is an input capture and output compare modules.

However, the CCP output, is not the PWM output. The PWM output is not
a relocatable output.
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Mar 27, 2021 11:46 am     Reply with quote

So where does the signal go? My 33/24 CCP reference says it goes to "OCx Pin Output". I can't find any reference to that in the device sheet. I tried all the pins, no signal.
_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Mar 27, 2021 12:37 pm     Reply with quote

First thing, have you actually verified your chio is operating?. A simple
output toggle on a single pin with a time delay. Does the pin toggle at the
frequency expected?. Would explain a lot if it is not actually working.
Then the CCP data says that the PWM operates the PWMx pins.
So for PWM1, PWM1H and PWM1L.
The pwm also support fault disable, so this needs to be turned off,
or the fault input needs to be off.
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Mar 27, 2021 12:57 pm     Reply with quote

Yes, I've been around a while and am familiar with that first step.
The chip is running, LED is toggling, serial output message is displayed. I'm generating a Timer1 and CCP1 timer interrupts that toggle pins, and all speeds are as expected.

PWMxH/L pins seem to be associated with the HSPWM module, which uses a totally different set of registers from the CCP module. I'll look for the fault disable.

I perused a PIC24 datasheet and found an OC1 pin. Perhaps my device doesn't support that particular feature, even though all the registers are there. Sigh... Looks like I'll be digging into the HSPWM - based on previous posts, it causes a lot of grief.

Thanks for your attention.
_________________
Jürgen
www.jgscraft.com
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Mar 28, 2021 12:45 am     Reply with quote

OK.

I don't see anywhere you saying what compiler version you are using?. This
is vital. All my assumptions are based on a modern compiler.
So what version do you have?.

There is also an issue with what you were originally trying to do.
If you read the data on the DACOUT, it allows values between 0xCD and
0xF32. It only supports operation between 5% and 95%. So your data
would have to change to use this.

With this asked and said, I therefore decided to try setting up the DACOUT
and make sure the compiler does generate sensible settings.
Will come back as soon as I have done this.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Mar 28, 2021 2:28 am     Reply with quote

OK.
Had a quick play. Generated some test code, and looked at the assembler
versus the MicroChip application note on this peripheral. Turns out there
are two other bits setup by CCS that need to be enabled to generate the
output:
Code:

#include <33CK32MC102.h>
#device ICSP=1
#device ansi
#device PASS_STRINGS=IN_RAM

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled

#use delay(internal=200M,clock_out)

// Serial debug data via SW. INVERT so can connect directly to legacy PC serial port
#use rs232( BAUD=19200, XMIT=PIN_B6, INVERT, STREAM=JGSDBG )

#define LEDHB     PIN_A0    // heartbeat LED
#define LED0      PIN_B15   // loop LED

typedef unsigned int8   UINT8;
typedef unsigned int16  UINT16;
typedef int1            BIT;

//--------------------------- CONSTANTS ---------------------------------------

//--------------------------- Macros and Globals ------------------------------
//
// Sine Table Generator:

#define SINE_STEPS  40

//Modified sine table for 5% to 95% allowed for DACOUT
UINT16 SINE_WAVE[SINE_STEPS] = {
0x7FF,0x91E,0xA37,0xB42,0xC39,0xD14,0xDD0,0xE67,
0xED5,0xF19,0xF2F,0xF19,0xED5,0xE67,0xDD0,0xD14,
0xC39,0xB42,0xA37,0x91E,0x7FE,0x6DF,0x5C6,0x4BB,
0x3C4,0x2E9,0x22D,0x196,0x128,0xE4,0xCE,0xE4,
0x128,0x196,0x22D,0x2E9,0x3C4,0x4BB,0x5C6,0x6DF
};

UINT8 sine_index = 0;                   // pointer into sine table

//-------------------------------------- INT_TIMER1 ---------------------------
//

#int_timer1
void SineTime()
{
  dac_write( 1, SINE_WAVE[sine_index] ); // selecting comparator 1.
   
  if(++sine_index==SINE_STEPS) {
    sine_index=0;
  }
  output_toggle( PIN_B5 );    // verify timing with OScope here
}

//------------------------------------- main() ---------------------------------
void main()
{
  setup_adc_ports( NO_ANALOGS);

  setup_comparator_dac(COMP_COMMON_DAC_ENABLE | COMP_FILTER_CLK_DIV_1 | COMP_DAC_CLK_DIV_1 | COMP_DAC_CLK_SRC_FVCODIV); //This is the fastest clock settings.
  setup_comparator_slope (1, COMP_DISABLE_SLOPE_FUNCTION, 0); //manual setting not slope
  setup_comparator(1, COMP_DAC_CMPXA | COMP_OUTPUT_DAC ); //select this comparator to use DAC, and output it. .

  setup_timer1( TMR_INTERNAL | TMR_DIV_BY_1, 2499 ); // set for 40KHz interrupt
  //Fed by Fosc/2, so need /2500 = 2499 for count (0..2499)
 
  C1OUT = TRUE;
  C1ENV = TRUE; //Need to add these. Enables the output.
 
  enable_interrupts(INT_TIMER1);        // for tick timer
  enable_interrupts(GLOBAL);

  delay_ms( 500 );                      // allow serial port to warm up :)
  fprintf(JGSDBG,"\r\n%s %s %s\r\n",__FILENAME__, __DATE__, __TIME__);

  while( TRUE ){
    delay_ms( 500 );
    output_toggle( LED0 );
  }//end of BIG LOOP

}//end of main()   


As you can see I've tweaked the output table to produce legal values,
and changed the timer code to give the correct tick without loading a value.
(On the DSPIC's you can set the timer to actually 'tick' at an exact
frequency). Added the extra output enables.

On 5.103, this produces exactly the same register values that MicroChip
says are needed to output a DAC value. Hopefully will work. Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group