aphawk
Joined: 23 Jan 2010 Posts: 168 Location: Brazil
|
Posted: Mon May 05, 2014 3:36 am Post subject: Need Help to optimize interrupt routine with Assembly |
|
|
Hi,
I'm making one Portable Logic Analyzer, using one Atmega328P at 20 Mhz and one Nokia 5110 LCD.
At the moment, I can sample only about 150 Khz signals, because I have one interrupt routine that need to store one 24 bit timer ( made with Timer0 chained with Timer1 ) and the input state in one buffer ( Matrix ? ) to make the processing after and shows in display.
This routine is called from Interrupt-on-change in my 6 inputs.
I need to substitute this routine, I think that using assembly is easy to store these 4-bytes data in one buffer made inside one Matrix ( that is DIMmed with normal Bascom command to make the access easy when necessary ).
The program is simple, because I'm only optimizing the interrupt code at this time, I substitute one INCR command with Assembly equivalent, and make the PUSH and POP only for the affected registers :
Code: | ' Portable Logic Analyzer
' using an 24 bits timer counter to make precise timing, and
' using Timer0 connected in Timer1 Output to have 24 bits counter.
'
' Objective : can sample at least 500 Khz signals.
' At this time, I can sample only 150 Khz. The best chance is
' rewrite the interrupt routine in assembly.
'
' Working principle :
' Use the interrupt on change in all the 6 inputs, and when this happens,
' the routine interrupt must store the Timer1 and Timer0 Values, and the
' input state, in the 3 matrix's .
' There is space in RAM to store at least 400 samples (4x400=1600 bytes) .
' when all samples are taken, is easy to show the samples with a nokia5110
' lcd , and controlled by the buttons to navigate in the buffer, and make zoom.
' With the prescaler value of 8 in Timer1, I can sample more than 8 seconds.
' If change the prescaler to 64, sampling time will be more than 1 minute.
$regfile = "m328pdef.dat"
$crystal = 20000000
$hwstack = 40
$swstack = 40
$framesize = 50
'3 Matrix to make things faster
'first is for store LSB and MID from 24 bits counter
Dim Time1(401) As Word
'second is for store MSB for 24 bits counter
Dim Time0(401) As Byte
' third is for store the input data tha was changed
Dim SAMPLE_VALUE(401) As Byte
'This will be the master index for the 3 matrixs
Dim Index As Word
'this flag signalize that all 400 samples was taken
Dim FLAG_ENDSPACE As Byte
'this flag signalizes that the 24 bits counter overruns
Dim FLAG_24B_OVER As Byte
Dim Sample As Byte
Config Portc = Input
Config Portb = Input
Config Portb.1 = Output
Config Portd.0 = Output
A_input1 Alias Pinc.0
A_input2 Alias Pinc.1
A_input3 Alias Pinc.2
A_input4 Alias Pinc.3
A_input5 Alias Pinc.4
A_input6 Alias Pinc.5
Bstart Alias Pinb.4
Bback Alias Pinb.3
Bnext Alias Pinb.2
Bzoom Alias Pinb.0
Set Bstart
Set Bback
Set Bnext
Set Bzoom
Disable Int0
Disable Int1
'CONFIGURE THE TIMER1 FOR COUNT 16 BITS AND CHANGE THE OUTPUT
Config Timer1 = Timer , Prescale = 8 , Compare_a = Toggle , Compare_b = Disconnect
Compare1a = 65535
'CONFIGURE TIMER0 FOR COUNT 8 BITS
'NOW I HAVE 24 BITS - TIMER1L:TIMER1H:TIMER0
Config Timer0 = Counter , Edge = Rising
On Timer0 Furou_isr
Timer0 = 0
Start Timer0
Enable Timer0
Enable Timer1
'NOW CONFIGURE INTERRUPT ON CHANGE FOR THE SIX INPUTS
Enable Pcint1
On Pcint1 Sample_isr Nosave
Pcmsk1 = &B00111111
'NOW STORE THE INITIAL STATE FROM THE INPUTS
SAMPLE = Pinc
' FROM NOW, IS ONLY TO EVALUATE THE INTERRUPT LATENCY
Index = 1
FLAG_ENDSPACE = 0
FLAG_24B_OVER = 0
Start Timer1
Enable Interrupts
Do
If FLAG_ENDSPACE = 1 Then
Disable Pcint1
Goto Encheu_buffer
End If
If FLAG_24B_OVER = 1 Then
Disable Timer1
Disable Timer0
Goto Mudar_res
End If
Loop
Mudar_res:
Encheu_buffer:
' THE PROGRAM STOPS HERE WHEN SPACE WAS FULLFILED OR THE 24BITS TIMER HAS ENDED
Stop
'---------------------------------------------------------------------------------------------------------------
' THIS IS THE INTERRUPT ROUTINE TO BE OPTIMIZED WITH ASSEMBLER CODE
'---------------------------------------------------------------------------------------------------------------
Sample_isr:
PUSH R24
IN R24,SREG
PUSH R24
PUSH R25
PUSH R26
PUSH R27
PUSH R28
PUSH R29
PUSH R30
PUSH R31
PUSH R10
PUSH R11
PUSH R16
PUSH R17
push R23
Stop Timer1
SAMPLE = Pinc
Disable Pcint1
Time1(index) = Timer1
Time0(index) = Timer0
Sample_value(index) = Sample
'Incr Index
LDS R24,{index}
subi r24,$ff
sts {index},r24
lds r24,{index+1}
sbci r24,$ff
sts {index+1},r24
If Index = 400 Then
Flag_endspace = 1
End If
Enable Pcint1
Start Timer1
pop R23
pop R17
pop R16
pop R11
POP R10
POP R31
POP R30
POP R29
POP R28
POP R27
POP R26
POP R25
POP R24
!OUT SREG,R24
POP R24
Return
'-------------------- END OF ROUTINE TO BE OPTIMIZED ------------------------------
Furou_isr:
Flag_24b_over = 1
Disable Pcint1
Return
End |
If someone can help, please feel free to make the change , maybe using only one matrix to store, or other ideas...
The working principle is at the comments in code.
To make the simulation, I put in Attach the Bascom code, the circuit , the ISIS simulation, and the actual .hex .
Thanks for any help !
Paulo |
|