News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Copy Data Table to Byte Array without a loop?

Started by trastikata, Jul 11, 2021, 11:17 AM

Previous topic - Next topic

trastikata

Hello all,

For the purpose of font efficiency, I was wondering if there is a way to directly copy a Data Table to Byte Array without using a loop? 

Regards

top204

#1
At the moment this is still in the Beta stage and will only work with byte arrays:

    Device = 18F25K20
    Declare Xtal = 16  
'
' Create a byte array
'
    Dim ByteArray[100] As Byte
'
' Create a flash data table
'
    Dim TableData As Flash8 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
                               10,11,12,13,14,15,16,17,18,19}
                                   
'---------------------------------------------------------
' The main program starts here
'
Main:
    ByteArray = TableData     ' Transfer the flash data table into the byte array

There is still a loop, there has to be, but it is within the assembler code.

Why does the font data need to be in RAM?

The assembler code for the transfer is:

F1_000038 equ $ ; in [TEST_18F25K20.BAS] BufferArray = TableData
    lfsr 0,0
    movlw ((TableData >> 8) & 0xFF)
    movwf TBLPTRLH,0
    movlw (TableData & 0xFF)
    movwf TBLPTRL,0
    movlw 100
_pblb__2
    tblrd*+
    movff TABLAT,POSTINC0
    decfsz WREG,F,0
    bra _pblb__2

See the loop?

The same code could, essentially, be done with the AddressOf directive and a Repeat-Until loop, within the BASIC code itself.

trastikata

Quote from: top204 on Jul 11, 2021, 03:55 PMWhy does the font data need to be in RAM?

Thank you for the code Les.

To answer your question - in my code I am using timer interrupts and fast ADC averaging. In one complete program loop, the free CPU time is fragmented while waiting for the next interrupt. Thus in order to print a line on a OLED without interfering with the main program task, I have to scatter the printing among the free cycles.

To do that I want to, generate the line contents to be printed in one time-frame, then pre-load the font characters in a RAM buffer as efficiently as possible in another free time-frame and then print the line on the OLED at another occasion.

John Drew

#3
I think you may be worrying unnecessarily.
If you're using I2C or SPI to talk to your oled then these are not worried by an interrupt.
I currently have a 18f25k22 running a slave i2c interrupt and a lower priority timer interrupt while I have touch and data from/to a graphic lcd operating. I also have two A/D ports measuring line volts and audio levels.
The interrupts don't cause any of the above to fail or misread.
I think if you try to second guess time slots things will slow, not speed up.
The graphic LCD is an ILI9341 type but I had a similar system but without the touch running on a little OLED display.
Cheers
John
PS forgot to mention the A/D have averaging.

trastikata

Quote from: John Drew on Jul 11, 2021, 11:52 PMI think you may be worrying unnecessarily.
If you're using I2C or SPI to talk to your oled then these are not worried by an interrupt.

Hello John,

I am actually concerned with the ADC sampling - at 1000 Hz there is not enough time to print all on the OLED without interfering with the time interrupt or stretching the time between interrupts here and there (which I want to avoid), so I want to spread the print in several free cycles between ADC sampling.

Regards

top204

#5
With sampling, each iteration of an interrupt can fill an element of a RAM array with a sample, then when the array is full a flag bit is set and a filter can be applied to it. Then the flag is cleared so the array will be filled again. So timing in the main program does not matter because the timing is actually fixed by the interrupt's interval so the samples within the array are of fixed times.

One of the simpler filters for a, relatively, small amount of samples is a bubble sort, because it can be used as a low, median or high pass filter by simply choosing where in the sorted array the final sample will be taken from.

Within the compiler's "Includes" folder, there is a set of library procedures for Median filtering: "C:\Users\User Name\PDS\Includes\Median_Filters.inc". However, they can be adapted to low or high pass filters by altering where the result from the procedure reads from within the sorted array. The "Median" filter reads from the middle of the sorted array.

I agree with John, as long as the interrupt is not too long and overburdened, timing will not effect most interfaces that are not reliant on timing.

Also, reading from flash memory directly is just the same, timing wise, as reading from RAM, because the compiler produces such tight code. The Cread8, Cread16, Cread24 and Cread32 functions act just like reading from a RAM array, so if the index variable is kept intact, the flash memory table can be read in intervals.