View previous topic :: View next topic |
Author |
Message |
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Sun Jul 22, 2018 9:30 am Post subject: |
|
|
hzz wrote: | There is still a lag to call and return from the ISR. |
Try this modification. Add parameter Nosave to the line "On Tcc0_ovf Blank_isr Nosave" and change ISR code into:
Code: | Blank_isr:
!PUSH R23
!PUSH R24
!IN R24, SREG
!PUSH R24
!in R24, RAMPZ
!EOR R24, R24 'clear R24
!OUT RAMPZ, R24
' Blank pulse
Tlc_blank = 1
Tlc_blank = 0
!POP R24
!OUT RAMPZ, R24
!POP R24
!OUT SREG, R24
!POP R23
Return |
Those PUSHs and POPs are valid only for operation you show in the previous post because Bascom often use R23 for read/set pheripherials like Ports.
If you add something into the code then PUSHs and POPs may need correction. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Jul 22, 2018 9:34 am Post subject: |
|
|
hzz wrote: | I'm not sure I understand. There is still a lag to call and return from the ISR. |
With 'lag' I've described the delay created by ISR-call, entry and command execution, which led to improper timing of 257...µs.
By using an ISR you will always have a lag, you'll even have jitter, as if an interrupt is triggered, the processor finishes the momentary executed opcode.
Opcodes in 8bit-AVR last between 1 and 3 processor cycles and this uncertainty depending on which command is executed at the very moment of triggering the interrupt creates jitter, while the lag between triggering, execution of the interrupt vector till the ISR-commands is always the same.
If your timing-requirements would allow it, why do you not use CTC to create a 12-bit PWM with duty-cycle 1/4096? This would you get rid of lag and jitter, the pulse would last a minimum of 62,5ns or multiples thereof.
If that don't work, the following approach would at least minimize lag:
Code: | Tlc_blank_port Alias PORTD : Const Tlc_blank_pin = 5
' ...
On Tcc0_ovf Blank_isr NOSAVE
' ...
Blank_isr:
!PUSH R16
!IN R16, SREG
!PUSH R16
!LDS R16, Tlc_blank_port
!SBR R16, 2 ^ Tlc_blank_pin
!STS Tlc_blank_port, R16
!LDS R16, Tlc_blank_port
!CBR R16, 2 ^ Tlc_blank_pin
!STS Tlc_blank_port, R16
!POP R16
!OUT SREG, R16
!POP R16
Return |
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Jul 22, 2018 10:28 am Post subject: |
|
|
EDC wrote: |
Code: | ' ...
!in R24, RAMPZ
!EOR R24, R24
!OUT RAMPZ, R24
' Blank pulse
Tlc_blank = 1
Tlc_blank = 0
!POP R24
!OUT RAMPZ, R24
' ... |
|
That's the problem if you mix Bascom commands and ASM, you never know how it is compiled in detail.
While this is no problem in regular code, where proper execution does not depend on saved registers, it becomes a problem in an lean ISR where as few registers as possible are to be saved.
If Mark decides to use different registers for temporary use than R23/R24, your code will fail, while mine will still work.
The compiler's use of certain registers for temporary purposes is not guaranteed.
Quote: | Those PUSHs and POPs are valid only for operation you show in the previous post because Bascom often use R23 for read/set pheripherials like Ports.
If you add something into the code then PUSHs and POPs may need correction. |
That's exactly what I tell: If I write parts in ASM and have to check the created ASM-code anyway for not to mess it up, then I can write it completely in ASM and have peace of mind.
An 'often use R23' is an uncertainty I do not want in my code.
For example: In your code checking RAMPZ does not harm, but is unnecessary, because the access to OUTSET and OUTCLR is done via STS, while RAMPZ is only required for indirect addressing via LD/LDD/ST/STD.
But as you don't know what code is created, it could be that the compiler uses ST and then not setting RAMPZ to the zero-page may fail. |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Sun Jul 22, 2018 11:08 am Post subject: |
|
|
Maybe Im lazy, but maybe I only like to make some automations in my life
So I made program "NoSave Tool" that parse generated OBJ file and checking used registers after compile.
My posted code was generated by that program. So it was Bascom that "safely" check RAMPZ and my program simply listed this.
In the code I keep compiler/Bascom version so it should always compile with this compiler version.
Im agree with your arguments but I have my own too.
First Im not that good for writing whole ISRs myself in ASM so I simply list registers used by Bascom.
Second. this is a quick solution for me
Third wild be example why I preffer use "registers frequently used by the compiler"
Maybe example is not to good for this case but there is a library for alphanumeric LCDs via I2C adapter with PCF8571.
Unfortunatelly library uses R16 and everything works fine but program will crash if you use Spc() function because counter for spaces is in the R16...
Someone dont take this into the account.
This is not the case in the ISR if you write it yourself from the beginning to the end in asm and ofcourse save and restore used regs.
But here my first and the second point will appear again when ISR is some bigger |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Jul 22, 2018 12:02 pm Post subject: |
|
|
EDC wrote: | Maybe Im lazy, but maybe I only like to make some automations in my life |
Then these automations are valid for you, but not necessarily for others.
Quote: | So I made program "NoSave Tool" that parse generated OBJ file and checking used registers after compile. |
See what I mean? Do others have your program?
Quote: | My posted code was generated by that program. So it was Bascom that "safely" check RAMPZ and my program simply listed this. |
As your program listed it, it should have listed a bunch of other registers saved by the ISR, but most of these other registers you did leave out, while the 'Angst'-RAMPZ you have kept.
Quote: | In the code I keep compiler/Bascom version so it should always compile with this compiler version.
Im agree with your arguments but I have my own too.
First Im not that good for writing whole ISRs myself in ASM so I simply list registers used by Bascom.
Second. this is a quick solution for me
Third wild be example why I preffer use "registers frequently used by the compiler" |
It's fine if it works for you, but as a general advice for everybody it may be unsuitable.
Quote: | But here my first and the second point will appear again when ISR is some bigger |
As said, if you know what you do it's perfectly ok, but as general advice I would avoid it, as it can lead to broken code. |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Sun Jul 22, 2018 12:36 pm Post subject: |
|
|
Thanks EDC, MWS,
Lag and jitter of ~1us will have no effect (for the TLC5940/59401 driver all this is for) so I prefer not to use ASM to assure compatibility with future BASCOM versions.
What does incomodate me is having an interrupt every 256us. I can live with it but rather avoid it if possible.
I was trying to generate a second event in channel 1 with the overflow of the 4096 counter instead of generating an interrupt, as follows
Code: | ' B) The following counter counts channel 0 events;
Config Tcc0 = 3 , Prescale = E0 , Event_source = 0 , Event_action = Restart
Tcc0_per = 4096 ' When the count reaches 4096 it starts again
'C) The following event system configuration generates an event at each overflow of timer TCC0
Config Event_system = Dummy , Mux1 = Tcc0_ovf , Digflt0 = 1 |
But I don't know what to do with this event. I though it will be possible to output it through any pin, accordint to Atmel manual:
Quote: | 13.10 Clock and Event Output
It is possible to output the peripheral clock and any of the event channels to the port pins (using EVCTRL register).
|
However the mentioned EVCTRL register does not allow to "to output the peripheral clock and any of the event channels" but one events from channel 0, which I'm already using to ouput the 16MHz signal
Quote: | 13.14.4 CLKEVOUT – Clock and Event Out register
Bit 5:4 – EVOUT[1:0]: Event Output Port
These bits decide which port event channel 0 from the event system will be output to |
Can you think about any other way to generate a pulse at a pin from an event in channel 1 or other different than 0?
Another solution to avoid ISR's is pointed at by MWS but I don`t know if I undestand it:
Quote: | If your timing-requirements would allow it, why do you not use CTC to create a 12-bit PWM with duty-cycle 1/4096? This would you get rid of lag and jitter, the pulse would last a minimum of 62,5ns or multiples thereof. |
Do you mean to configure two timers: one in frequency mode generation at 16MHz and another in PWM mode generating a signal with period 16MHz/4096 and PWM=1/4096? (The problem is that the maximum prescale is 1024) |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sun Jul 22, 2018 2:02 pm Post subject: |
|
|
hzz wrote: | Do you mean to configure two timers: one in frequency mode generation at 16MHz and another in PWM mode generating a signal with period 16MHz/4096 and PWM=1/4096? (The problem is that the maximum prescale is 1024) |
You already use this timer to create the 256us interrupt with 4096 steps.
AVR timers have all a mode where one compare, in your case CCA, sets TOP of the PWM, while another compare within value from 0 to TOP sets the PWM's duty cycle.
The timing you seek to create can be considered a PWM with duty cycle 1 of 4096, which can be done with one timer. |
|
Back to top |
|
|
aphawk
Joined: 23 Jan 2010 Posts: 168 Location: Brazil
|
Posted: Sun Jul 22, 2018 4:03 pm Post subject: |
|
|
MWS wrote: | EDC wrote: | Maybe Im lazy, but maybe I only like to make some automations in my life |
Then these automations are valid for you, but not necessarily for others.
Quote: | So I made program "NoSave Tool" that parse generated OBJ file and checking used registers after compile. |
See what I mean? Do others have your program?
Quote: | My posted code was generated by that program. So it was Bascom that "safely" check RAMPZ and my program simply listed this. |
As your program listed it, it should have listed a bunch of other registers saved by the ISR, but most of these other registers you did leave out, while the 'Angst'-RAMPZ you have kept.
Quote: | In the code I keep compiler/Bascom version so it should always compile with this compiler version.
Im agree with your arguments but I have my own too.
First Im not that good for writing whole ISRs myself in ASM so I simply list registers used by Bascom.
Second. this is a quick solution for me
Third wild be example why I preffer use "registers frequently used by the compiler" |
It's fine if it works for you, but as a general advice for everybody it may be unsuitable.
Quote: | But here my first and the second point will appear again when ISR is some bigger |
As said, if you know what you do it's perfectly ok, but as general advice I would avoid it, as it can lead to broken code. |
Well, about NoSave tool : I have this program.
I have used it for many years. In fact, I have made it a must in allmost my ISR.
Never had find one problem, always this little utility had the job without any fall. I keep it updated.
I wish to thanks EDC because this little wonder made possible many projects be successful without the need of know how all internal compiler works.
As a regular user of Basic language since 1979, and without any knowledge of C language, I know that many projects that need quickly ISR can't be made using only Bascom. But NoSave tool made this possible to me and many other users.
I have a regular Forum in Brasil since 2011, about BASCOM projects with Atmega and Attiny to all people that want learn about microprocessor possibilities, and many of my projects shows the NoSave tool usage, and can't be made working without this tool.
Bascom is a wonderful compiler, and NoSave tool can expand the usage for the projects where microseconds timing are imperative, without the need of mastering ASM language.
Paulo
Last edited by aphawk on Mon Jul 23, 2018 2:36 am; edited 3 times in total |
|
Back to top |
|
|
hzz
Joined: 20 Feb 2007 Posts: 314
|
Posted: Sun Jul 22, 2018 5:03 pm Post subject: |
|
|
Thanks again MWS
Quote: | You already use this timer to create the 256us interrupt with 4096 steps.
AVR timers have all a mode where one compare, in your case CCA, sets TOP of the PWM, while another compare within value from 0 to TOP sets the PWM's duty cycle.
The timing you seek to create can be considered a PWM with duty cycle 1 of 4096, which can be done with one timer. |
I will work on this.
So far, I have been able to make a working driver for TLC59401 and TLC5940, finally!
It is published at the end of thread:
https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=14193
BASCOM is great as it is this forum thanks to users like you.
Regards
Hector |
|
Back to top |
|
|
|
|
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 You cannot attach files in this forum You cannot download files in this forum
|
|