|
|
View previous topic :: View next topic |
Author |
Message |
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
How to ? setup_cog( ) on 16F1769 |
Posted: Tue Mar 19, 2019 5:08 pm |
|
|
I expect to use two PWMs to drive two COGs.
Essentially, both COGs provide push-pull outputs,
but at different frequencies.
Generating the PWMs doesn't seem to be a problem, but
the COG setup is not completely explained by CCS.
I'd rather do this in C and not do inline assembly.
Anyone have the secret sauce to use CCS for COGs ?
Cheers! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Wed Mar 20, 2019 1:54 am |
|
|
Unfortunately, CCS have not done a COG example yet.
However the functions are fairly well documented in the manual.
but the problem is that the setting only make sense once you understand
the peripheral....
I'm reading what you want as simple complementary outputs from two
PWM's. There are two ways of doing this. You can generate the two
waveforms with the COG using half bridge mode, or you can
set the COG to generate the inverse of the PWM, and use the PWM
output for one waveform, and the COG output for the other.
Honestly the push pull mode is the easiest once you realise one critical
thing. On this chip, you can enable a PWM, and have it not generate an
output.
So a basic setup for COG1, would be:
Code: |
#PIN_SELECT COG1A = PIN_A0
#PIN_SELECT COG1B = PIN_A1
//Pin for the primary and complementary half bridge outputs
void main()
{
setup_timer_2(T2_DIV_BY_1, 255,1); //setup timer for PWM
setup_pwm3(PWM_ENABLED | PWM_TIMER2 | PWM_STANDARD); //this
//enables the PWM but doesn't feed it out to a
//physical pin.
//Now setup the COG fed from this PWM, to generate complementary
//outputs
setup_COG(COG_FALLING_SOURCE_PWM3 |
COG_RISING_SOURCE_PWM3
| COG_ENABLED | COG_CLOCK_FOSC | COG_HALF_BRIDGE);
|
Now exactly the same can be done for COG2, with selects for COG2,
and a different PWM source. If you want you can add deadband between
the outputs etc., but for the basic inverted output this is all that is needed. |
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
COG NOCOG |
Posted: Wed Mar 20, 2019 10:13 am |
|
|
Thanx, but still no function.
I pasted what you provided directly.
I'm using latest CCS 5.083, PIC16F1769, ICDU-64Rev3, SW 5.054, FW 3.35
I assume there is no #use pwm ()
I'm still missing a clear idea how to access this COG function.
Shouldn't "COG_PULSE_STEERING_A|COG_PULSE_STEERING_B"
be included in COG setup?
Since 3 parameters are in the setup, I use;
setup_COG(COG_FALLING_SOURCE_PWM3 | COG_RISING_SOURCE_PWM3 | COG_ENABLED | COG_CLOCK_FOSC | COG_HALF_BRIDGE
,
COG_NO_AUTO_SHUTDOWN
,
COG_PULSE_STEERING_A|COG_PULSE_STEERING_B);
AE |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Wed Mar 20, 2019 11:03 am |
|
|
No, Pulse steering, is for single output mode, and then steers the output to a
particular pin. Here the half bridge mode automatically outputs on output A,
and output B.
Look at the data sheet. First output mode is 'steered PWM mode'. This is what
pulse steering is for. Then you have full bridge, half bridge and push-pull
modes, which don't use the steering.
I've used the COG on a different chip, and here it ran fine as I've posted.
I was setting a deadband though.
Try adding a second parameter to the setup_COG,
', COG_NO_AUTOSHUTDOWN'
With the comma after the values already posted. I had an issue when I
first tried to use it that on my chip the shutdown was defaulting to enabled
so the outputs were being turned off. The next compiler version fixed that
for me. COG_status reported this, so I was able to know what was wrong. |
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
|
Posted: Wed Mar 20, 2019 11:33 am |
|
|
OK,
removed steering, no 3rd parameter in setup,
COG_NO_AUTOSHUTDOWN as 2nd parameter
outputs are static as A=low, B=high
something still missing? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Wed Mar 20, 2019 11:58 am |
|
|
Test that the PWM is running. Presumably you have given it a duty cycle (won't do anything till you do)?.
You can test it by enabling it's output (with a suitable pin select also needed). |
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
|
Posted: Wed Mar 20, 2019 12:10 pm |
|
|
No PWM output.
pin setup as follows:
Code: |
#pin_select COG1A=PIN_C5
#pin_select COG1B=PIN_C4
#pin_select COG2C=PIN_B6
//#pin_select COG2D=PIN_B7
#pin_select PWM3=PIN_B7 |
Code: |
setup_timer_2(T2_DIV_BY_1, 255,1);
setup_pwm3(PWM_ENABLED | PWM_TIMER2 | PWM_STANDARD);
set_pwm3_duty(33);
setup_COG(COG_FALLING_SOURCE_PWM3|COG_RISING_SOURCE_PWM3|COG_ENABLED|COG_CLOCK_FOSC|COG_HALF_BRIDGE,COG_NO_AUTO_SHUTDOWN); |
outputs are static
A=low, B=high, PWM3=low |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Wed Mar 20, 2019 12:23 pm |
|
|
you should post your complete test program. You may have a 'fuse' incorrectly set or even a 'typo' that even though code compiles won't operte the way you want it to.
Jay |
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
|
Posted: Wed Mar 20, 2019 12:47 pm |
|
|
I had the PWM(s) operating with the #use pwm setup.
There appears no fuses associated with the COGs.
Everything else works, but COGs.
I'd display all code, but it's spread over 17 files, so that's not convenient.
main.h is just
Code: |
#INCLUDE <16F1769.h>
//#opt 5 // 9 is default optimization without compression
#DEVICE ADC=10
///#DEVICE(WRITE_EEPROM=ASYNC) // Prevents WRITE_EEPROM hang while writing occurs
#DEVICE *=16 // use 16 bit pointers to use all RAM
//#DEVICE ICD=TRUE // code compatible with Microchips ICD debugging hardware
#FUSES NODEBUG
#FUSES INTRC_IO
#FUSES BORV25 // brownout trip
#FUSES PUT // pwr up timer
#FUSES STVREN //stack overflow reset enable
#FUSES NOMCLR
#FUSES NOCLKOUT
#FUSES NOWDT //Watch Dog Timer added last
#FUSES NOPROTECT //#FUSES PROTECT // use this for production ?
#FUSES NOWRT
//----------------------------------------------------------------------------
#USE delay(internal=32MHZ)
#PRIORITY INT_RDA,INT_TIMER0 // decide on priority interrupts |
|
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
|
Posted: Wed Mar 20, 2019 1:17 pm |
|
|
I find using the #use pwm, I get the 2 COGs to work,
but I need to assign extra pins for pwm outputs.
Oddly, you can use the Vpp/MCLR pin as a PWM output ....
I need all of the 20 pins so I'm still stuck.
Another Item is the phase between the two PWMs/COGs
isn't easy to maintain when the duty is varied.
Microchip hardware might be a little retarded about using multiple PWMs
in a power system. Lots of functionality, just not the right ones.
I'd do this in an FPGA if it weren't for the cost/size concerns.
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Wed Mar 20, 2019 1:57 pm |
|
|
OK. In which case it is easy (hopefully...). It sounds as if on this chip
the COG input doesn't get a signal unless the PWM is enabled, Different
from the one I was trying. In which case the answer is to not use the
half bridge mode. Instead use the pulse steering, so:
setup_COG(COG_FALLING_SOURCE_PWM3|COG_RISING_SOURCE_PWM3|COG_ENABLED|COG_CLOCK_FOSC|COG_COGA_ACTIVE_LOW,COG_NO_AUTO_SHUTDOWN,COG_PULSE_STEERING_A);
This should generate an inverted copy of the PWM on output A.
Obviously you need output A pin selected.
I think I've got the inverted syntax right (not got a compiler on this machine
to check). |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Wed Mar 20, 2019 2:34 pm |
|
|
By 'test' program I mean a small 'COG feature' only program. That way it's easy to figure out what's going on, what registers are being used, etc.
Once that's working THEN incorporate the COG into your main program. If COG doesn't work, then you KNOW it's a 'conflict' with main code.
Jay |
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
|
Posted: Wed Mar 20, 2019 2:37 pm |
|
|
My application is a two stage proprietary power converter.
This is what I have working, but the pwm outputs must be defined:
Code: |
#pin_select COG1A=PIN_C5
#pin_select COG1B=PIN_C4
#pin_select COG2A=PIN_B6
#pin_select COG2B=PIN_B7
#pin_select PWM5=PIN_A3 //MCLR pin ?
#pin_select PWM6=PIN_C0
#DEFINE PWM1SET TIMER=2,FREQUENCY=250Khz,DUTY=50,PWM_ON //,OUTPUT=PWMout1 //
#DEFINE PWM2SET TIMER=4,FREQUENCY=250Khz,DUTY=50,PWM_ON //,OUTPUT=PWMout2 //
#use PWM(PWM5,PWM1SET,STREAM=Buck)
#use PWM(PWM6,PWM2SET,STREAM=Boost)
#DEFINE COGySET COG_ENABLED|COG_CLOCK_FOSC,COG_NO_AUTO_SHUTDOWN // common set
#DEFINE COG1SET COG_FALLING_SOURCE_PWM5|COG_RISING_SOURCE_PWM5|COG_HALF_BRIDGE
#DEFINE COG2SET COG_FALLING_SOURCE_PWM6|COG_RISING_SOURCE_PWM6|COG_PUSH_PULL|COG_COGA_ACTIVE_LOW|COG_COGB_ACTIVE_LOW
void initializepwm() {
xboost=110; // start fixed overlap about 55%
xbuck=1; // 0<buck<128? if buck rise sync boost, boost overlap shrinks or dies
set_PWM5_phase(63); // align rising buck edge with rising boost edge when not using rising edge of buck to boost
setup_COG(COG1SET|COGySET); setup_COG2(COG2SET|COGySET);
pwm_set_duty(buck,xbuck); pwm_set_duty(boost,xboost);
}
|
Issues of phase relationship with PWM5
come into play when PWM6 changes duty.
If COG_RISING_SOURCE_PWM6 is changed to COG_RISING_SOURCE_PWM5 on COG2, then phase is not a problem
until PWM5 duty is either 0 or 100%, then COG2 is dead.
Perhaps there's a way to force the RISING_SOURCE_ to a timer
rather than PWM.
Like I said, MicroChip has limited smarts in power conversion.
|
|
|
avatarengineer
Joined: 13 May 2013 Posts: 51 Location: Arizona
|
|
Posted: Wed Mar 20, 2019 3:50 pm |
|
|
Still buggy. Duty cycle misbehaves on COG1.
Code: |
#DEFINE PWM1SET TIMER=2,FREQUENCY=250Khz,DUTY=50,PWM_OFF //,OUTPUT=PWMout1 // use pin select instead
#use PWM(PWM5,PWM1SET,STREAM=Buck) |
IF you do not define a duty cycle within #use statement,
the pwm_set_duty(Buck,value); will produce a random duty cycle
unless it is repeated within a loop statement.
This is a bizarre bug ! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Thu Mar 21, 2019 12:42 pm |
|
|
Actually I kinda understand it..maybe, though I'm not 100% sure....
If YOU don't put a value in for 'duty cycle' (a variable named 'duty' ?), then whatever is stored in the RAM location will be the value for 'duty'.
Unless you use the #ZERO RAM pp directive, RAM locations can have anything in them.
Jay |
|
|
|
|
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
|