PWM in HCS08PA16 stays silent

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

PWM in HCS08PA16 stays silent

1,298 Views
lucyperek
Contributor II

Hi,

maybe strange but I've started to suspect a bug in MCU. I want to generate just simple, trivial PWM on T0CH1 output pin (pin 29 in LQFP32 package). I went through all application notes, read several times RM. I have also tried differenet configurations : with ISR (updating channel registers - edge mode) or w/o. Also playing with MODE and other registers gives no results. Output pin stays at low level (but debugger shows counter activity and interrupt from timer 0 channel 1 works..).

Pin is not burned - I have configured it as I/O pin toggling at timer 0 overflow with required modulo also set up). So what can be the reason ? Frankly speaking I had several times problems with this PWM so I have generated it "manually" but this time I just want to "unload" from MCU this task .

regards

Jacek

0 Kudos
5 Replies

1,273 Views
lucyperek
Contributor II

OK, so let me put some code how it is initialized :

mov #0,t0modh
mov #100,t0modl                  modulo value is set
mov #%00001011,T0SC       clock source and prescaler

MOV #%00101000,T0SC1    PWM Edge, High active
mov #0,t0ch1h
mov #10,t0ch1l

On pin related to Timer 0 Channel 1 low state all the time.

The version with interrupts as below :

MOV #%01101000,T0SC1 ;PWM Edge, High active
mov #0,t0ch1h
mov #10,t0ch1l
lda t0sc1
bclr ch01f,t0sc1
bset chie01,t0sc1

----------------------


pwm:     interrupt from T0CH1 service routine

lda t0sc1
bclr ch01f,t0sc1
mov #0,t0ch1h         refreshing this value just for tirial (later on it will be increased in steps)
mov #10,t0ch1l
rti

this interrupt works and is called when counter reaches channel value indeed. But pin 29 (LQFP32) still stays on low state.

So what is wrong ??

0 Kudos

1,269 Views
vicentegomez
NXP TechSupport
NXP TechSupport

Sorry I am not good in ASM code but I have a C code that maybe can help you

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

#define OVF_COUNTS 50
unsigned char counts = OVF_COUNTS; //number of Timer Overflows before increasing the pulse-width
unsigned char up_down = 0; //0 for up, 1 for down
unsigned int capture;


void main(void) {
EnableInterrupts;
/* include your code here */
/* WDOG_CNT: CNT=0xC520 */
WDOG_CNT = 0xC520; /* First part of the WDG unlock sequence */
/* WDOG_CNT: CNT=0xD928 */
WDOG_CNT = 0xD928; /* Second part of the WDG unlock sequence */
/* WDOG_TOVAL: TOVAL=4 */
WDOG_TOVAL = 0x04;
/* WDOG_CS2: WIN=0,FLG=0,??=0,PRES=0,??=0,??=0,CLK=1 */
WDOG_CS2 = 0x01;
/* WDOG_CS1: EN=0,INT=0,UPDATE=0,TST=0,DBG=0,WAIT=0,STOP=0 */
WDOG_CS1 = 0x00; /* Disable watchdog */

//PTG0's Output Enable Register is set to enable output
PORT_PTGOE_PTGOE0 = 1 ;
//PTG0 pin is driven low (LED ON)
PORT_PTGD_PTGD0 = 0;
// FTM clock = BUSCLK = 8MHz, Overflow Interrupt Enabled
FTM2_SC = FTM2_SC_CLKS0_MASK | FTM2_SC_TOIE_MASK;
FTM2_MOD = 8000; // PWM frequency is about 1 KHz

// Configure channel 0 to PWM mode (high-true pulses)
FTM2_C0SC = FTM2_C0SC_ELSB_MASK | FTM2_C0SC_MSB_MASK;
FTM2_C0V = 80; // channel 0 set to 1%


// FTM clock = BUSCLK = 8MHz
FTM1_SC = FTM1_SC_CLKS0_MASK;

// Configure channel 0 to input capture mode, falling edge, channnel interrupt enable.
FTM1_C0SC = FTM1_C0SC_ELSB_MASK|FTM1_C0SC_CHIE_MASK;

for(;;) {
// __RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}


/**************************************************************************************************/

interrupt VectorNumber_Vftm2ovf void FTM2ovfISR (void)
{
//Clear interrupt flag
(void)FTM2_SC;
FTM2_SC_TOF = 0;

counts--;
if (!counts)
{
if (!up_down) //up counting
{
FTM2_C0V += 80;
if (FTM2_C0V == 7920) up_down = 1;
//when reaching 99%, change to down counting
}
else
{
FTM2_C0V -= 80;
if (FTM2_C0V == 80) up_down = 0;
//when reaching 1%, change to up counting
}
counts = OVF_COUNTS;
}
}

/**************************************************************************************************/

interrupt VectorNumber_Vftm1ch0 void FTM1ch0ISR (void)
{
//Clear interrupt flag
(void)FTM1_C0SC;
FTM1_C0SC_CHF = 0;
PORT_PTGD_PTGD0 = ~PORT_PTGD_PTGD0;
capture = FTM1_C0V;

}

/**************************************************************************************************/

 

0 Kudos

1,256 Views
lucyperek
Contributor II

Vicent, in your code there are many command which, according to RM are not needed. They do not say anything about enabling overflow interrupts. But I think that I have discovered the solution.......

I will check it more carefully but it looks that two commands sequence is critical for this operation :

1. First the channel status register MUST be configured for PWM, edge etc.

2. Then channel value registers must be set

If these channel registers will be loaded first and THEN the status register (ELSEA:B, MSA:B etc) as the second one, the PWM doesn't work. OK, it can be so but it's a pity that it is not VERY clearly mentioned in RM or AN that this sequence is critical and must be respected.

regards, Jacek

0 Kudos

1,252 Views
vicentegomez
NXP TechSupport
NXP TechSupport

I believe that in the old S08 RM there is a note for that, but not sure

 

Regards

Vicente  

0 Kudos

1,236 Views
lucyperek
Contributor II

Vicente,

in old SH8 RM there is quite detailed description of PWM but they mainly concentrate on Timer Channel writing sequence. OK, no problem, luckily I have discovered how to initialize PWM. But would be very helpful if NXP could make a small correction in RM specifying in bold that such a sequence is necessary (first TxSCx configuration and after that writing channel values).

Thanks for your replies !!

best regards

Jacek