HPWM mallfunction since version > 3.7.3.6 and < 4.0.0.6

Started by diebobo, May 14, 2022, 01:33 PM

Previous topic - Next topic

diebobo

Hi Les,

On my 24FJ64GA004 device / project the HPWM function stopped working correctly after version 3.7.3.6 . Searching the . ASM file i noticed that there is a mention of "optimised with pattern 5".. See code below.. In my program i never declares optimiser level, so not mentioned at all. Still the .asm file mentions that. If i use Declare Optimiser_Level = 0 then the HPWM label in the .asm file isn't mentioning the optimising level 5 (+ 2 lines of code are different ) and the HPWM function works as usuall.

Ps. i am always in doubt in which section to post 8/24/ abnormally's.. move as you like ;)

Faulty code :
_hpwm_psc__loop_:
    repeat #17
    div.u W9,W10
    mov.w W0,W2
    dec.w WREG2
    mov.w #512,W1
    sub.w W2,W1,[W15]
    bra gtu,_hpwm_test__prc8_
    sub.w W2,#1,[W15]
    bra leu,_hpwm_test__prc8_
    mov.w W2,W0 ; optimised with pattern 5
    mul.uu W7,W0,W0
    sl.w W1,#8,W2
    lsr.w W0,#8,W0
    ior.w W2,W0,W0
    mov.w W0,W1
    bset T2CON,#15
    bra _hpwm_chse__chan_

Correct code:
_hpwm_psc__loop_:
    repeat #17
    div.u W9,W10
    mov.w W0,W2
    dec.w WREG2
    mov.w #512,W1
    sub.w W2,W1,[W15]
    bra gtu,_hpwm_test__prc8_
    sub.w W2,#1,[W15]
    bra leu,_hpwm_test__prc8_
    mov.w W2,PR2
    mov.w PR2,W0
    mul.uu W7,W0,W0
    sl.w W1,#8,W2
    lsr.w W0,#8,W0
    ior.w W2,W0,W0
    mov.w W0,W1
    bset T2CON,#15
    bra _hpwm_chse__chan_

top204

I will take a look at the PIC24FJ64GA004 for the HPM commands, but it has not been touched for the PIC24F devices since I created the compiler.

The internal optimising pass has been with the compiler since day one and all it does is remove multiple mnemonics that can be replaced with fewer mnemonics. i.e. When an intermediate WREGx is loaded but it does not need to be because it is loading another WREGx directly after it


top204

There does seem to be an anomaly with the HPWM commands on the PIC24F devices now, for some reason. The code has not been changed, so it may be down to when I updated the C++ compiler a while back. I'll get back into the code and see what is causing it. It seems to be a frequency problem because the duty seems to be working, but the frequency is low.

For the PIC24F and PIC24H devices, you would be better off using the "PWM_24.inc" library that is installed with the compilers. It offers a lot more flexability than the HPWM commands, which are remnants from earlier compiler versions. The included libraries are all located here "C:\Users\User Name\PDS\Includes\", and any .inc file in the "Includes" folder can be see by all programs.

A demo listing below shows the "PWM_24.inc" library working:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Hardware PWM manipulation procedure demo
' The "PWM_24.Inc" library is for use with PIC24F and PIC24H devices
'
' Written by Les Johnson for the Positron16 compiler
'
    Device = 24FJ64GA004
    Declare Xtal = 32
'
' Setup the pins for the PWM peripherals
'   
    Declare CCP1_Pin = PORTB.0
    Declare CCP2_Pin = PORTB.1
    Declare CCP3_Pin = PORTB.2
    Declare CCP4_Pin = PORTB.3    
 
    Include "PWM_24.inc"                       ' Load the Hardware PWM procedures into the program
   
    Dim MyDuty As Byte
    Dim MyFrequency As Word
         
'---------------------------------------------------------------------------
' The main program starts here
'
Main:    
    CLKDIV = 0                                          ' \
    Write_OSCCONH($10)                                  ' / Enable the PLL to operate the device at 32MHz
   
    PPS_Output(cOut_Pin_RP14, cOut_Fn_U1TX)             ' Make RP14(RB14) the pin for UART1 TX
    PPS_Output(cOut_Pin_RP0, cOut_Fn_OC1)               ' Make RP0(RB0) the pin for PWM1
    PPS_Output(cOut_Pin_RP1, cOut_Fn_OC2)               ' Make RP1(RB1) the pin for PWM2
'
' Fixed Frequency, Variable Duty Cycle
'       
    HPWM1_SetFreq(1000, 0)                              ' PWM1: 1KHz, 0% duty
    HPWM2_SetFreq(1000, 0)                              ' PWM2: 1KHz, 0% duty
   
    For MyDuty = 0 To 255                               ' Create a loop for the duty cycle
        HPWM1_Duty(MyDuty)                              ' Alter the duty cycle of PWM1
        HPWM2_Duty(MyDuty)                              ' Alter the duty cycle of PWM2
        DelayMS 10                                      ' A small delay to see the change more clearly
    Next
'
' Variable Frequency, Fixed Duty Cycle
'
    For MyFrequency = 1 To 65535 Step 64                ' Create a loop for the frequency
        HPWM1_SetFreq(MyFrequency, 127)                 ' Alter PWM2
        HPWM2_SetFreq(MyFrequency, 127)                 ' Alter PWM2 as well
    Next                                                ' Close the loop

'-------------------------------------------------------------------------------------------------------------
' For internal 8MHz oscillator with PLL
' OSC pins are general purpose I/O
'
    Config Config1 = JTAGEN_OFF, GCP_OFF, BKBUG_OFF, COE_OFF, ICS_PGx1, FWDTEN_OFF, WINDIS_OFF, FWPSA_PR128, WDTPOST_PS256
    Config Config2 = IOL1WAY_OFF, COE_OFF, IESO_OFF, FNOSC_FRCPLL, FCKSM_CSECME, OSCIOFNC_ON, POSCMOD_NONE

Yasin

A few days ago I noticed a problem myself. My problem is that it fails to read analog from AN1. When I examined the ASM code, I saw that RA1 changed as output. The reason was due to the "HPWM.inc" library I used. The mcu I am using is PIC18f87K90. Although there is "Declare CCP2_Pin PORTC.1" in the definitions. Converted to PORTA.1 in ASM output.

$define HPWM2_Start() '
    CCP2CON = $0C     '
    Output __CCP2_PIN

I change it

$define HPWM2_Start() '
    CCP2CON = $0C     '
    Output PORTC.1

top204

You are correct Yasin.

I had forgotted to change the library file's code when I had to change the assembler .defines for the newer Asm30 program, quite a few years ago.

So, within the "PWM_24.inc" listing, change the lines of code:

Output __CCP1_PIN

to

Output __CCP1_PORT.__CCP1_PIN

And do the same for the CCP2, CCP3, CCP4, CCP5 port and pins, and the Inputs when disabling PWM for a channel.

I have corrected the anomaly in the Positron16 compiler's HPWM command library routines. It was the C++ compiler update because in the code tidying function it was seeing the code:

mov.w W2,PR2
mov.w PR2,W0


As:
 
mov.w W2,W2
mov.w W2,W0


And removing the wasted mov.w W2,W2 mnemonics.

So I have found out why it was doing it and corrected it. It was not remembering an indirect char array variable that held the "PR2" text, and was corrupting it for some reason, and it saw, by a freak chance, "W2" instead of "PR2". So even the compilers that cost many hundreds of pounds do not always get it right. :-)

I'll upload a corrections update ASAP.

Yasin

Hi Les. "Input __CCP1_PIN" Will this need to be changed?
$define HPWM1_Stop() '
   Input __CCP1_PIN  '
   CCP1CON = $00


top204

Yes. Both the outputs and inputs need to be changed.

QuoteAnd do the same for the CCP2, CCP3, CCP4, CCP5 port and pins, and the Inputs when disabling PWM for a channel.


Yasin


top204

Please do not apologise Yasin, there is no need. Your English is 100 times better than my other languages, which are none. :-)

Apart from computer languages. LOL