Okay, I think I have something working.
I found that the DRM135SW doesn't seem to put the FTM0 Channels into PWM mode (which is why the writes to the _C4V/_C5V registers wouldn't accept the write values) as well as disabling the outputs which prevents them from coming out.
Two questions for you:
1. Could you please review my code below and let me know if you have any concerns or comments for me? It is basically the DRM135SW taken from the FTM0_init method in "peripherals_init.c" with some modifications to enable the FTM0 clock, select the PWMs I am interested in and making the changes specified above.
2. Explain how the code in DRM135SW works? As well as masking the output, I don't see any statements putting the FTM0 channels into PWM mode or turning off the masks of the outputs?
Next steps are to:
a) Retime operation with the correct clocking available in the TWRK20D72M
b) Change the PWM value dynamically to change the motor speeds
c) Invert the PWM output to allow simple motor reversal
Thanx,
myke
#define TPM_C 48e6 // core clock (only for calculation, I does not afect real clock)
#define PWM_FREQ 16000 // PWM frequency [Hz]
#define MODULO ( TPM_C / PWM_FREQ ) // calculation the modulo for FTM0
// Enable clock for Flex Timers
// SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK | SIM_SCGC6_FTM1_MASK;
SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK;
FTM0_MODE &= ~FTM_MODE_WPDIS_MASK; /* Disable write protection */
FTM0_MODE |= FTM_MODE_FTMEN_MASK;
FTM0_CONF |= FTM_CONF_BDMMODE(3); // counter run in BDM mode
FTM0_MODE |= FTM_MODE_FAULTM_MASK | FTM_MODE_FTMEN_MASK;
/* Set PWM frequency; MODULO = Fclk/Fpwm */
FTM0_MOD = MODULO;
FTM0_CNTIN = 0x00;
FTM0_SYNCONF |= FTM_SYNCONF_SYNCMODE_MASK; // should be set enhanced PWM sync mode
/* CTNMAX = 1 - PWM update at counter in max. value */
FTM0_SYNC |= FTM_SYNC_CNTMAX_MASK;
FTM0_SYNC |= FTM_SYNC_SWSYNC_MASK;
/* Disable all channels outputs using the OUTPUT MASK feature.
However, the output pins are still driven as GPIO since the
channel mode is set to FTM channel disabled after RESET */
// FTM0_OUTMASK = FTM_OUTMASK_CH7OM_MASK | FTM_OUTMASK_CH6OM_MASK | FTM_OUTMASK_CH5OM_MASK | FTM_OUTMASK_CH4OM_MASK |
// FTM_OUTMASK_CH3OM_MASK | FTM_OUTMASK_CH2OM_MASK | FTM_OUTMASK_CH1OM_MASK | FTM_OUTMASK_CH0OM_MASK;
FTM0_OUTMASK = FTM_OUTMASK_CH7OM_MASK | FTM_OUTMASK_CH6OM_MASK |
FTM_OUTMASK_CH3OM_MASK | FTM_OUTMASK_CH2OM_MASK | FTM_OUTMASK_CH1OM_MASK | FTM_OUTMASK_CH0OM_MASK;
// /* COMBINE = 1 - combine mode set
// COMP = 1 - complementary PWM set
// DTEN = 1 - deadtime enabled
// SYNCEN = 1 - PWM update synchronization enabled
// FAULTEN = 1 - fault control enabled */
// FTM0_COMBINE = FTM_COMBINE_FAULTEN0_MASK | FTM_COMBINE_SYNCEN0_MASK | FTM_COMBINE_DTEN0_MASK
// | FTM_COMBINE_COMP0_MASK | FTM_COMBINE_COMBINE0_MASK
// | FTM_COMBINE_FAULTEN1_MASK | FTM_COMBINE_SYNCEN1_MASK | FTM_COMBINE_DTEN1_MASK
// | FTM_COMBINE_COMP1_MASK | FTM_COMBINE_COMBINE1_MASK
// | FTM_COMBINE_FAULTEN2_MASK | FTM_COMBINE_SYNCEN2_MASK | FTM_COMBINE_DTEN2_MASK
// | FTM_COMBINE_COMP2_MASK | FTM_COMBINE_COMBINE2_MASK;
// MAP: Put the FTM0 Channels into PWM mode
FTM0_C4SC |= FTM_CnSC_MSB_MASK;
FTM0_C5SC |= FTM_CnSC_MSB_MASK;
/* polarity setting, 3ppa driver high sides are active low */
// FTM0_POL = FTM_POL_POL0_MASK | FTM_POL_POL2_MASK | FTM_POL_POL4_MASK ;
/* Dead time = 1 us for 48 MHz core clock */
// FTM0_DEADTIME = 138;
// Notes (12) - Just using Channels 4 & 5
/* Initial setting of value registers */
// FTM0_C0V = 0;
// FTM0_C1V = MODULO/2;
// FTM0_C2V = 0;
// FTM0_C3V = MODULO/2;
// FTM0_C4V = 0;
// FTM0_C5V = MODULO/2;
FTM0_C4V = MODULO / 4;
FTM0_C5V = MODULO / 2;
/* SWSYNC = 1 - set PWM value update. This bit is cleared automatically */
FTM0_SYNC |= FTM_SYNC_SWSYNC_MASK;
/* Main loop */
/* ELSnB:ELSnA = 1:0 Set channel mode to generate positive PWM
Note:
1. From this moment the output pins are under FTM control. Since the PWM output is disabled by
the FTM0OUTMASK register, there is no change on PWM outputs. Before the channel mode is set,
the correct output pin polarity has to be defined.
2. Even if the odd channels are generated automatically by complementary logic, these channels
have to set to be in the same channel mode. */
// FTM0_C0SC |= FTM_CnSC_ELSB_MASK ;
// FTM0_C1SC |= FTM_CnSC_ELSB_MASK ;
// FTM0_C2SC |= FTM_CnSC_ELSB_MASK ;
// FTM0_C3SC |= FTM_CnSC_ELSB_MASK ;
FTM0_C4SC |= FTM_CnSC_ELSB_MASK ;
FTM0_C5SC |= FTM_CnSC_ELSB_MASK ;
FTM0_EXTTRIG |= FTM_EXTTRIG_INITTRIGEN_MASK;
FTM0_MODE |= FTM_MODE_INIT_MASK;
/* Set system clock as source for FTM0 (CLKS[1:0] = 01) */
FTM0_SC |= FTM_SC_CLKS(1);
//PORT for FTM0 initialization
// PORTC_PCR1 = PORT_PCR_MUX(4); // FTM0 CH0
// PORTC_PCR2 = PORT_PCR_MUX(4); // FTM0 CH1
// PORTC_PCR3 = PORT_PCR_MUX(4); // FTM0 CH2
// PORTA_PCR6 = PORT_PCR_MUX(3); // FTM0 CH3
// PORTA_PCR7 = PORT_PCR_MUX(3); // FTM0 CH4
// PORTD_PCR5 = PORT_PCR_MUX(4); // FTM0 CH5
PORTD_PCR4 |= PORT_PCR_MUX(4) | PORT_PCR_DSE_MASK; // FTM0 CH4 with high power operation
PORTD_PCR5 |= PORT_PCR_MUX(4) | PORT_PCR_DSE_MASK; // FTM0 CH5 with high power operation