hippy
Ex-Staff (retired)
Introduction
On PICAXE-28X2 and 40X2 parts any new 'pwmout' command will reset 'pwmdiv' divider settings used in previous 'pwmout' commands.
This issue only applies if:
Any 'pwmdiv' divider previously used on any other pin is reset to the default (1) via the latest 'pwmout' command.
This issue can be worked around by manually resetting the 'pwmdiv' settings on the other pins using 'pokesfr' commands.
Detailed Description
On the 28X2 and 40X2 any change to the 'pwmdiv' settings of a particular 'pwmout' channel affects the 'pwmdiv' settings of other 'pwmout' channels. When using multiple 'pwmout' channels and 'pwmdiv' settings the outcome may not always be as anticipated.
This is an issue which only affects the PICAXE-28X2 and 40X2 parts, only when using multiple 'pwmout' channels. Whether there may be an unexpected outcome or not depends on which 'pwmout' channels are used, the 'pwmdiv' settings required and the order any changes to 'pwmdiv' settings are applied.
On 28X2 and 40X2 devices the following pins can be used for 'pwmout' -
Due to the way the firmware interacts with the internal chip control registers to provide 'pwmout' only the last 'pwmdiv' applied takes affect and other 'pwmout' channels are reset to what is effectively 'pwmdiv1'.
To give a clarifying example -
B.0 is initialised with the desired 'pwmdiv4' but after B.5 is initialised B.0 is reset to 'pwmdiv1'; so the outcome is as if the code executed were -
If 'pwmout' channels C.1 or C.2 are active they too will be reset to 'pwmdiv1'.
When using C.1 and C.2 for 'pwmout', because these use the same timer, a change to one will always affect the other, so for -
The outcome is as would be expected; C.1 was using 'pwmdiv4', and setting C.2 to 'pwmdiv4' sets C.1 to the same, which is what it was already set to.
In addition though, a change to C.1 or C.2 will reset B.0 and B.5 to 'pwmdiv1'.
When using multiple 'pwmout' channels and altering 'pwmdiv', the final outcome will depend upon which 'pwmout' channels are being used, which 'pwmdiv' settings are applied, and the order in which 'pwmdiv' settings are applied.
Unfortunately it is not possible to track what 'pwmdiv' settings have been used within the firmware, nor can the compiler determine where 'pwmdiv' settings for timers would need to be adjusted automatically.
There is however a solution and that is to manually reset the timers for 'pwmout' channels to the desired 'pwmdiv' value when necessary. This can be achieved using the 'peeksfr' and 'pokesfr' commands to access the internal registers which hold the 'pwmdiv' settings for the timer which drives the 'pwmout' channel. The code required to do this for each 'pwmout' channel is detailed later.
For example, to achieve setting both B.0 and B.5 to 'pwmdiv4', where the setting of B.5 will have reset B.0 to 'pwmdiv1', force the 'pwmdiv' setting for B.0 after setting B.5 -
The code required to force each 'pwmout' channel to a specific 'pwmdiv' setting is detailed below -
To force B.0 to 'pwmdiv4'
To force B.0 to 'pwmdiv16'
To force B.5 to 'pwmdiv4'
To force B.5 to 'pwmdiv16'
To force C.1 and C.2 to 'pwmdiv4'
To force C.1 and C.2 to 'pwmdiv16'
On PICAXE-28X2 and 40X2 parts any new 'pwmout' command will reset 'pwmdiv' divider settings used in previous 'pwmout' commands.
This issue only applies if:
- You are using a 28X2 or 40X2 part,
- You are using multiple 'pwmout' commands on different pins,
- You are using 'pwmdiv' dividers within these 'pwmout' commands.
Any 'pwmdiv' divider previously used on any other pin is reset to the default (1) via the latest 'pwmout' command.
This issue can be worked around by manually resetting the 'pwmdiv' settings on the other pins using 'pokesfr' commands.
Detailed Description
On the 28X2 and 40X2 any change to the 'pwmdiv' settings of a particular 'pwmout' channel affects the 'pwmdiv' settings of other 'pwmout' channels. When using multiple 'pwmout' channels and 'pwmdiv' settings the outcome may not always be as anticipated.
This is an issue which only affects the PICAXE-28X2 and 40X2 parts, only when using multiple 'pwmout' channels. Whether there may be an unexpected outcome or not depends on which 'pwmout' channels are used, the 'pwmdiv' settings required and the order any changes to 'pwmdiv' settings are applied.
On 28X2 and 40X2 devices the following pins can be used for 'pwmout' -
- B.0
- B.5
- C.1 - Shares timer with C.2
- C.2 - Shares timer with C.1
Due to the way the firmware interacts with the internal chip control registers to provide 'pwmout' only the last 'pwmdiv' applied takes affect and other 'pwmout' channels are reset to what is effectively 'pwmdiv1'.
To give a clarifying example -
Code:
pwmout pwmdiv4, B.0, [i]period[/i], [i]duty[/i]
pwmout pwmdiv4, B.5, [i]period[/i], [i]duty[/i]
B.0 is initialised with the desired 'pwmdiv4' but after B.5 is initialised B.0 is reset to 'pwmdiv1'; so the outcome is as if the code executed were -
Code:
pwmout B.0, [i]period[/i], [i]duty[/i]
pwmout pwmdiv4, B.5, [i]period[/i], [i]duty[/i]
If 'pwmout' channels C.1 or C.2 are active they too will be reset to 'pwmdiv1'.
When using C.1 and C.2 for 'pwmout', because these use the same timer, a change to one will always affect the other, so for -
Code:
pwmout pwmdiv4, C.1, [i]period[/i], [i]duty[/i]
pwmout pwmdiv4, C.2, [i]period[/i], [i]duty[/i]
The outcome is as would be expected; C.1 was using 'pwmdiv4', and setting C.2 to 'pwmdiv4' sets C.1 to the same, which is what it was already set to.
In addition though, a change to C.1 or C.2 will reset B.0 and B.5 to 'pwmdiv1'.
When using multiple 'pwmout' channels and altering 'pwmdiv', the final outcome will depend upon which 'pwmout' channels are being used, which 'pwmdiv' settings are applied, and the order in which 'pwmdiv' settings are applied.
Unfortunately it is not possible to track what 'pwmdiv' settings have been used within the firmware, nor can the compiler determine where 'pwmdiv' settings for timers would need to be adjusted automatically.
There is however a solution and that is to manually reset the timers for 'pwmout' channels to the desired 'pwmdiv' value when necessary. This can be achieved using the 'peeksfr' and 'pokesfr' commands to access the internal registers which hold the 'pwmdiv' settings for the timer which drives the 'pwmout' channel. The code required to do this for each 'pwmout' channel is detailed later.
For example, to achieve setting both B.0 and B.5 to 'pwmdiv4', where the setting of B.5 will have reset B.0 to 'pwmdiv1', force the 'pwmdiv' setting for B.0 after setting B.5 -
Code:
pwmout pwmdiv4, B.0, [i]period[/i], [i]duty[/i]
pwmout pwmdiv4, B.5, [i]period[/i], [i]duty[/i]
peeksfr $4A, b0
bit0 = 1
bit1 = 0
pokesfr $4A, b0
The code required to force each 'pwmout' channel to a specific 'pwmdiv' setting is detailed below -
To force B.0 to 'pwmdiv4'
peeksfr $4A, b0
bit0 = 1
bit1 = 0
pokesfr $4A, b0
bit0 = 1
bit1 = 0
pokesfr $4A, b0
To force B.0 to 'pwmdiv16'
peeksfr $4A, b0
bit1 = 1
pokesfr $4A, b0
bit1 = 1
pokesfr $4A, b0
To force B.5 to 'pwmdiv4'
peeksfr $51, b0
bit0 = 1
bit1 = 0
pokesfr $51, b0
bit0 = 1
bit1 = 0
pokesfr $51, b0
To force B.5 to 'pwmdiv16'
peeksfr $51, b0
bit1 = 1
pokesfr $51, b0
bit1 = 1
pokesfr $51, b0
To force C.1 and C.2 to 'pwmdiv4'
peeksfr $BA, b0
bit0 = 1
bit1 = 0
pokesfr $BA, b0
bit0 = 1
bit1 = 0
pokesfr $BA, b0
To force C.1 and C.2 to 'pwmdiv16'
peeksfr $BA, b0
bit1 = 1
pokesfr $BA, b0
bit1 = 1
pokesfr $BA, b0
Last edited: