PDA

View Full Version : I2CWRITE not writing anything on PIC18F45K80



CuriousOne
- 13th March 2023, 14:03
Hello.
I have PCF8574 connected to PIC18F45K80.
The timings and configs are correct, tried to generate some pulses and frequencies are correct.
Tried just to pull up and down SDA/SCL pins and check result with scope, while having PCF8574 connected - I can see proper pulses on the scope.
However, when I try to I2CWRITE, I see no activity at all on either SDA or SCL pins, and sure does not work. Adding I2C SLOW does not change anything.

Here's my code:



#config
CONFIG RETEN = OFF
CONFIG INTOSCSEL = HIGH
CONFIG SOSCSEL = DIG
CONFIG XINST = ON ;Enabled
CONFIG FOSC = INTIO1
CONFIG PLLCFG = OFF
CONFIG FCMEN = OFF ;Disabled
CONFIG PWRTEN = OFF ;Disabled
CONFIG BOREN = OFF ;Disabled in hardware, SBOREN disabled
CONFIG WDTEN = OFF ;WDT disabled in hardware; SWDTEN bit disabled
CONFIG CANMX = PORTB
CONFIG MCLRE = OFF


#endconfig


'OSCTUNE.6 = 1 ; Enable 4x PLL
OSCCON = %01110000
ANCON1=0 'DISABLE ADC D3-D2-D1-D0-
ANCON0=0
ADCON0=0
TRISC=%00000000 'set PORTC as output all
TRISD=%00000000 'set PORTD as output all
TRISB=%00000000 'set PORTB as output all
TRISA=%00000000 'set PORTA 2 as input, others as output
TRISE=%0000000 'set PORTE as output all
define OSC 16
DEFINE I2C_SLOW 1
ADR VAR BYTE
ADR=$48


SDA VAR PORTD.3
SCL VAR PORTD.2


'dfe:
'high sda
'pause 1
'low sda
'pause 1
'goto dfe


FEDO:
I2CWRITE SDA,SCL,ADR,[%11111111]
PAUSE 50
I2CWRITE SDA,SCL,ADR,[%00000000]
PAUSE 50
GOTO FEDO

Ioannis
- 13th March 2023, 14:34
I think you are missing the control before the address of the I2C commands.

Also DEFINE I2C_SLOW 1 is NOT needed.

try this

Cont = %01000000

I2CWRITE SDA,SCL,Cont,[%11111111]
PAUSE 500
I2CWRITE SDA,SCL,Cont,[%00000000]
pause 500


Ioannis

CuriousOne
- 13th March 2023, 17:57
And where to put address?
I have several PCFs....

Ioannis
- 13th March 2023, 20:30
OK, in the cont constant will be the address. What chip do you have? Is it the "A" type?

The "A" type needs cont=%0111AAA0

The plain PCF8574 needs cont=%01000AAA0

where AAA is the address bits.

Ioannis

richard
- 13th March 2023, 23:26
provided it is wired correctly and the chip is pcf8574 the original code works just fine
although technically
TRISD=%00000000 'set PORTD as output all
should be
TRISD=%00001100 'set PORTD

9339

CuriousOne
- 14th March 2023, 05:47
The chips are PCF8574T.
I have pull up resistors 4.7K and SDA and SCL pins of 3 pcs. PCF chips are in parallel.
I tried adding that cont variable and changing TRIS for D port pins. Still nothing.
On the startup, SCL gets high and that's all, there is no activity on these pins.
But if I run simple high/low statements for those pins, then I can see these pins getting high or low on scope.

CuriousOne
- 14th March 2023, 05:55
By the way, I have DS3231 hooked to another pins of same CPU.
It also not working - no activity on SDA/SCL pins while performing I2CREAD.
So maybe some config error?

richard
- 14th March 2023, 06:08
So maybe some config error?

if you mean its wiring error or the chips aren't what you say , probably

schematic ?

CuriousOne
- 14th March 2023, 09:10
No, there is no wiring error and when using HIGH or LOW statements, I can pull these pins up and down as normal.
I mean, maybe there is some config error for 18F, which prevents I2CREAD/I2CWRITE from working?

richard
- 14th March 2023, 10:41
to be clear

provided it is wired correctly and the chip is pcf8574 the original code works just fine

tumbleweed
- 14th March 2023, 14:11
Change CONFIG XINST setting to OFF.

Very few compilers are compatible with ON

CuriousOne
- 13th April 2023, 15:18
Yes, you were right!
Also XINST messes with LCDOUT.
When XINST=ON, then DEC/HEX/BIN etc. modifiers of LCDOUT statement do not work.

But why this is not mentioned in manual?
Also, turning off XINST means we're turning off these extended instructions of 18F, so loosing all advantages these series have?

tumbleweed
- 13th April 2023, 16:21
XINST changes the way some instructions work, so unless you have a compiler that supports it (like almost none), always set it off.

You're not missing out on anything.

CuriousOne
- 14th April 2023, 07:42
I've compared this code on 16F1939 @ 16 Mhz and 18F45K80 @ 64 Mhz and see zero improvement in speed (screen redraw time). I'm doing something wrong, or it should be that way? Here's config for 18F:



OSCTUNE.6 = 1 ; Enable 4x PLL
OSCCON = %01110000
ANCON1=0 'DISABLE ADC D3-D2-D1-D0-
ANCON0=0
ADCON0=0
TRISC=%00000000 'set PORTC as output all
TRISD=%00000000 'set PORTD as output all
TRISB=%00000000 'set PORTB as output all
TRISA=%00000000 'set PORTA 2 as input, others as output
TRISE=%0000000 'set PORTE as output all
define OSC 64


And this is the main code (ST7920 library with custom fonts)



topline var byte [18]
arraywrite topline, ["SOMETEXT HERE 123"]
C=0
gosub GCODER
arraywrite topline, ["SOMETEXT HERE 567"]
c=8
gosub gcoder
arraywrite topline, ["SOMETEXT HERE 890"]
c=16
gosub gcoder
C=24
arraywrite topline, ["SOMETEXT HERE XXX"]
GOSUB GCODER
stop




GCODER:
FOR X=0 TO 17 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
Y=(topline[x]-65)*8
Z=(topline[x+1]-65)*8 'READ INTO VARIABLE AS TWINS
FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
READ Y+I,A 'READ EEPROM BYTES INTO VAR
READ Z+I,B
LCDOUT $FE,$80+i+c 'UPDATE Y POSITION
LCDOUT $FE,$80+x/2 'UPDATE X POSITION
if topline[x]=32 then a=0
if topline[x+1]=32 then b=0 'blanker
LCDOUT a
LCDOUT b 'WRITE TO SCREEN
NEXT I
NEXT X
return

tumbleweed
- 14th April 2023, 11:47
It could be that the LCDOUT dominates the execution time, although I'd be surprised if it's "0 difference"

Do you still have CONFIG FOSC = INTIO1?
With that, you can measure the CLKOUT on the RA6/OSC2 pin just to verify the settings.

CuriousOne
- 14th April 2023, 15:44
I make a pin high when this code starts and make it low when it ends. Length of the pulse is measured with scope.
By setting
DEFINE LCD_COMMANDUS 900
DEFINE LCD_DATAUS 35

instead of default 1500/50, additional speed gains can be achieved, but it works same way on both MCU.

I will check the CLKOUT later. I have not measured it, but I did some PAUSE loops and times were correct, so I assume, chip is running at 64mhz.

Ioannis
- 14th April 2023, 21:24
LCD's are very slow. What are you expecting in terms of speed?

Ioannis

HenrikOlsson
- 14th April 2023, 21:57
Of course it's the same.
You tell the compiler: "Look, the LCD controller I have connected needs 35us to process data and 900us to process commands, please give me code for that". The compiler will give you code for that, making sure that it gives the LCD controller 35us to process data and 900us to process commands.

Running at 4MHz* or 64MHz makes no difference, each datatransfer WILL take 35us and each command WILL take 900us because that IS what you, the programer, have told the compiler that you WANT it to take.

I can assure you that if run:

LATB.0 = 1
arraywrite topline, ["SOMETEXT HERE XXX"]
LATB.0 = 0


and



LATB.0 = 1
LCDOUT $FE,$80+i+c 'UPDATE Y POSITION
LATB.0 = 0


at both 16MHz and 64MHz you'll be able to measure a considerable increase in speed on the first but very tiny on the second (because, as explained, most time spent executing that statement is spent doing nothing).

* At 4MHz it MIGHT not be able to stick to 35us, it MIGHT take slightly longer, I don't know for sure.

CuriousOne
- 14th April 2023, 21:59
Average blue/white LCD can do 10 fps. Yellow-black can do 20 fps. Special, color persistence LCD (with RGB backlight), can do 200 fps.

Currently I'm getting 1 fps on 128x64 display and about 2 fps on 144x32 display. This is very slow, when updating screen or navigating thru on screen menu.

CuriousOne
- 14th April 2023, 22:02
But people are making fast update to these screens via U8G and other libraries. Check this video from 7th minute.
I want similar speed, but with PBP.

CuriousOne
- 14th April 2023, 22:06
https://www.youtube.com/watch?v=aACOC9XBBks
Link to video.

HenrikOlsson
- 14th April 2023, 23:16
As long as you send the display DATA it will be sort of fast (35us per data byte according to your own information). But each time you send a command it will take 900us - and you do that two times per pass thru the inner loop.

Your FOR/NEXT loop:

GCODER:
FOR X=0 TO 17 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
Y=(topline[x]-65)*8
Z=(topline[x+1]-65)*8 'READ INTO VARIABLE AS TWINS

FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
READ Y+I,A 'READ EEPROM BYTES INTO VAR
READ Z+I,B
LCDOUT $FE,$80+i+c 'UPDATE Y POSITION ' 900us + some
LCDOUT $FE,$80+x/2 'UPDATE X POSITION ' 900us + some
if topline[x]=32 then a=0
if topline[x+1]=32 then b=0 'blanker
LCDOUT a ' 35us + some
LCDOUT b 'WRITE TO SCREEN 35us + some
NEXT I

NEXT X
return

Each time thru the inner loop takes 1870us + whatever time the READ and the IF and all the other statementes takes, let's call it 2000us in total. Your doint the inner loop 8 times for each pass thru the outer loop which in turn you do 9(?) times for a total of 72 times. 72*2000us is 144ms and this does not include any time spent outside of these two nested loop. Measure it yourself and see how much time it takes.

I don't know the ST7920 at all and I'm surprised it, being a graphical display controller, are "compatible" with HD44780 but are you sure you need to perform the "update position" commands each iteration thru the loop? Doesn't the controller increment position automatically, like the HD44780?

HenrikOlsson
- 14th April 2023, 23:33
Looking at this datasheet (https://www.waveshare.com/datasheet/LCD_en_PDF/ST7920.pdf) it looks like all commands except clear executes in 72us which is like 1/12 of the 900us you're telling the compiler it takes. Obviously you'd need to add additional delays to any CLEAR SCREEN command, like

LCDOUT $FE, 1
PAUSEUS 1500 ' Extra delay for this specific command which takes 1600us instead of 72us like all other commands.

If the two "command statements" in the inner loop took 72us each instead of 900us each the the whole thing would take 5.2ms instead of 144ms.

richard
- 14th April 2023, 23:37
Your doint the inner loop 8 times for each pass thru the outer loop which in turn you do 9(?) times for a total of 72 times. 72*2000us is 144ms and this does not include any time spent outside of these two nested loop. Measure it yourself and see how much time it takes.


as i pointed out a year ago
https://www.picbasic.co.uk/forum/showthread.php/24652-My-quot-Library-quot-for-ST7920-Graphical-displays-works-fine-but...?p=148923#post148923
post #7

there are much better ways indicated in that post too

CuriousOne
- 15th April 2023, 06:24
Ok, here are the answers.

ST7920 based display modules have great advantages over any common LCD controllers:

1. They are physically and pin to pin compatible with common 1602 LCD modules, HD44780 based.
2. In most applications they work as a drop in replacement for 1602 display (no need for code change), providing better visual appearance on screen, due to having far higher number of pixels - 144x32 vs 80x16 on common 1602 LCD
3. They have built-in 8192 characters for Chinese language, so whenever you need to use them, you don't need to mess with the graphics statements at all, just send an unicode code of char to display.
4. They have graphical mode, which also has hardware overlay and scroll function - text output (and CGRAM) in standard 1602 mode and graphics data are stored in separate areas of memory, which allows many fancy things to be done, like smooth parallax scrolling at different speeds, without need of software overlay calculation.
5. Due to high pixel density, in size of 1602 LCD, where you have 16 chars @ 2 rows, with 5x7 pixel fonts, here you can have 18 chars @ 4 rows, with 8x8 pixel fonts.

For the timing, datasheet shows nanosecond grade timings for writing the display. However, the above mentioned LCDOUT delays are practical observations - if I reduce them further, display gets garbled. So most likely, PBP is messing something up.

The datasheet mentions following way of graphic data sending, which I'm following in my code:

Graphic display RAM supports 64x256 bits bit-mapped memory space. GDRAM address is set by writing 2
consecutive bytes for vertical address and horizontal address. Two-bytes data write to GDRAM for one address.
Address counter will automatically increase by one for the next two-byte data. (This appears to be not working in the way you think it does) The procedure is as followings.
1. Set vertical address( Y) for GDRAM
2. Set horizontal address( X) for GDRAM
3. Write D15〜D8 to GDRAM 中(first byte)
4. Write D7〜D0 to GDRAM 中(second byte)


Yes I know there are other graphical displays there, including OLED and color TFTs, but no matter how hard I tried, I was never able to use any code provided here - 99% not compiling, giving some errors, and ones that compile, will never work. So I have to "develop" my own code for Graphic displays. So far these are for ST7920 and WS0010.

HenrikOlsson
- 15th April 2023, 11:21
So most likely, PBP is messing something up.
Of course it does...
Me thinks it's far more likely that the particular controller that's on your display doesn't live up to the specifications in the datasheet. Quite common on cheap HD44780 compatible displays as well so I would no be surprised if this is the case. It could also be electrical, crosstalk, capacitive loading of the outputs due to long wires between PIC and display, RMW issues etc. Have you looked at the signals (with a scope) as they enter the display?

Again, the datasheet specifies 72us for all commands except clear. You're using 900us and executing a LOT of commands so it takes a LOT of time.

CuriousOne
- 15th April 2023, 11:38
Well, default values of 1500/50 are in PBP manual and I guess they had reasons to write so.
I have tested different brands/makers of 1602 LCD, including genuine hitachi made modules. Some show slightly better results, some - worse.
Have not checked it with scope, by the way....

HenrikOlsson
- 15th April 2023, 12:08
The original Hitachi datasheet specifies 1.52ms for the HOME command and 37us for data and that's likely where the 1500/50 comes from.

CuriousOne
- 15th April 2023, 15:24
I don't remember exactly, but if not mistaken, the fastest display with HD44780 interface I tested with PBP was VFD module from Noritake - 1500 was reduced to 300 without any issues.

CuriousOne
- 22nd April 2023, 07:01
Found another bug/issue.

Here's simple code:



topline var byte [16] 'top part of the screen array
botline var byte [16] 'bottom part of screen


arraywrite topline,["0123456789ABCDEF"]
arraywrite botline,["0123456789ABCDEF"]






FOR X=0 TO 30 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
if X<=15 then
Y=(botline[x]-48)*8
Z=(botline[x+1]-48)*8 'READ INTO VARIABLE AS TWINS
endif




FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
LCDOUT $FE,$80+c+i 'UPDATE Y POSITION
LCDOUT $FE,$80+x/2 'UPDATE X POSITION
READ Y+I,A 'READ EEPROM BYTES INTO VAR
READ Z+I,B


if topline[x]=32 or botline[x]=32 then a=0
if topline[x+1]=32 or botline[x+1]=32 then b=0 'blanker


if atrib=1 and X<16 then
a=A^%11111111
b=b^%11111111
endif


if a=$FE then a=0
if b=$fe then b=0




LCDOUT a
LCDOUT b 'WRITE TO SCREEN
NEXT I
NEXT X


It should display 0123456789ABCDEF on LCD screen. It does, but there's an issue.

If reading text from 1st declared array (topline), then it is displayed correctly. However, if reading from 2nd declared array (botline), one of characters will be randomly missing in displayed text. This is not issue of my code, because if I do not declare "topline" array, then "botline" reading works fine.

So what this means, 18F45K80 can't handle two 16 byte arrays at same time?

tumbleweed
- 22nd April 2023, 11:45
Your arrays are declared as 'var byte[16]'


topline var byte [16]
botline var byte [16]

That means a valid array index is from 0-15

This code here will fail when x=15


if X<=15 then
Y=(botline[x]-48)*8
Z=(botline[x+1]-48)*8 'READ INTO VARIABLE AS TWINS

Z will try and access botline[x+1] = botline[16], which is invalid

CuriousOne
- 22nd April 2023, 12:40
X is being incremented in steps of 2, so it will never be 15.
I even modified code so that X will never exceed 14 - issue is still here, but there is some logic in it.

I tried to add code in loop and look at output.
it changes in the following way based on loop step:

012345 789ABCDEF
0123456789 BCDEF
012345678 ABCDEF
01234567 9ABCDE

CuriousOne
- 22nd April 2023, 12:44
Did a test with various size of arrays.
If both arrays do not exceed 24 bytes total, then everything is fine. As they exceed 24 bytes, issues start to appear.

tumbleweed
- 22nd April 2023, 13:58
Fair enough, but what about this when x >= 16


if topline[x]=32 or botline[x]=32 then a=0
if topline[x+1]=32 or botline[x+1]=32 then b=0 'blanker

CuriousOne
- 22nd April 2023, 15:47
I don't see any relation :)
I modified code and X now changes from 0 to 14 - still same issue.

tumbleweed
- 22nd April 2023, 16:38
You've been using x, y, and z to get values to set a and b.
You've been shoving invalid data out to the lcd and wondering why the display is wrong.

It's probably still wrong.

CuriousOne
- 22nd April 2023, 17:16
LOL.
I'm trying to explain that if I add one extra array definition, another array gets screwed. How this is related to LCD?
I just wrote another code, which simply reads values of array and writes data on 1602LCD.
Issue still exists - data in array gets damaged, if total array length exceeds 24 bytes.

tumbleweed
- 22nd April 2023, 18:41
I just did this with an 18F45K80


' device = 18F45K80

topline var byte [16] 'top part of the screen array
botline var byte [16] 'bottom part of screen

ix var byte
ct var byte
cb var byte

' clear arrays
for ix = 0 to 15
topline[ix] = 0
botline[ix] = 0
next ix

' read array data
arraywrite topline,["0123456789ABCDEF"]
arraywrite botline,["0123456789ABCDEF"]

ix = 0

'read array char by char
for ix = 0 to 15
ct = topline[ix]
cb = botline[ix]
next ix

ix = 0

When it gets to the end, topline and botline arrays are exactly as specified... each is 16 chars "0"-"F"
Reading the arrays byte by byte also does as expected.
I even added a third array of 16 chars... works too.

Your problem is elsewhere... not with the arrays themselves.

CuriousOne
- 22nd April 2023, 20:28
Thanks, have you tried to read the same array several times?
Problem is definitely in arrays, because if I make say topline 4 bytes and botline 16 bytes (even without writing anything to any of them) - there are no problems, but as soon their total "length" exceeds 24 bytes, issues start to appear.

richard
- 23rd April 2023, 03:20
Your problem is elsewhere... not with the arrays themselves.

code snippets , a complete waste of time and effort

tumbleweed
- 23rd April 2023, 12:09
just saying... "Problem is definitely in arrays... but as soon their total length exceeds 24 bytes, issues start to appear. " doesn't seem to pan out.

The following reads three 16-byte arrays (48 bytes total) 20K times and verifies the arrayreads. No errors.
Same with the original two 16-byte arrays.



' device = 18F45K80

topline var byte [16] 'top part of the screen array
botline var byte [16] 'bottom part of screen
line3 var byte [16] 'more array data

ix var byte
ct var byte
cb var byte
c3 var byte

i var word
fail var word

fail = 0

for i = 0 to 20000
' clear arrays
for ix = 0 to 15
topline[ix] = 0
botline[ix] = 0
line3[ix] = 0
next ix

' read array data
arraywrite topline,["ABCDEFGHIJKLMNOP"]
arraywrite botline,["QRSTUVWXYZ[\]^_`"]
arraywrite line3, ["abcdefghijklmnop"]

'read array char by char and check
for ix = 0 to 15
ct = topline[ix]
if (ct-"A" <> ix) then fail = fail + 1
cb = botline[ix]
if (cb-"Q" <> ix) then fail = fail + 1
c3 = line3[ix]
if (c3-"a" <> ix) then fail = fail + 1
next ix
next i

' check for failure
if (fail > 0) then
i = fail
endif



Tried both PBP 3.16 and PBPL. No difference.


I just wrote another code, which simply reads values of array and writes data on 1602LCD.
Issue still exists
Post the complete code that doesn't work.

CuriousOne
- 26th April 2023, 05:07
Thanks, sure
this weekend :)

CuriousOne
- 9th May 2023, 10:12
The "complete" code is about 700 lines (and it is not complete yet).
Found another bug.
I call some subroutine, which uses own set of variables (verified)
after calling it, value of totally different variable (not used in that part of code) gets random values.

Very disturbing.
Can this be compiler issues or maybe faulty chip itself?

richard
- 9th May 2023, 10:45
Found another bug.
I call some subroutine, which uses own set of variables (verified)
after calling it, value of totally different variable (not used in that part of code) gets random values.


Very disturbing.
Can this be compiler issues or maybe faulty chip itself?


if you can produce a minimal, complete and verifiable example [MCVE] that demonstrates the problem it would be the first
ever case. do continue

tumbleweed
- 9th May 2023, 11:22
The "complete" code is about 700 lines (and it is not complete yet)
You just said...

I just wrote another code, which simply reads values of array and writes data on 1602LCD.
Issue still exists
That's the code that's 700 lines?

If you're having issues then continuing to add more code isn't going to help.
You should stop, and start trimming things down bit by bit until it starts working.
Then you'll know what to look at.

While compiler and chip issues are always a possibility, there's a much better chance you're just doing something wrong.

CuriousOne
- 9th May 2023, 11:30
No that different code :)
Now I'm back to "big" code.

I'm trying now to isolate the problem and writing all from the scratch, part by part, verifying.

CuriousOne
- 9th May 2023, 11:34
What I 100% figured out, by writing the small code is the 18F issue with ST7920 LCD.
When I turn on the graphic mode, by sending LCDOUT $FE,$2E , there are high chances that random character in text mode will be displayed in top left corner.
I tried adjusting timings and OSC settings - no change. Same code, same PCB, same LCD - no issues with 16F1939.

CuriousOne
- 9th May 2023, 14:18
OK here it is. Here's a code.
It works properly only on first run after the flashing the code. If I unplug the power, next it will run with the same error.
The left picture shows correct result, how display should look, and right picture shows how it looks after cycling the power.



#config
CONFIG RETEN = OFF
CONFIG INTOSCSEL = HIGH
CONFIG SOSCSEL = DIG
CONFIG XINST = OFF ;Enabled
CONFIG FOSC = INTIO1
CONFIG PLLCFG = OFF
CONFIG FCMEN = OFF ;Disabled
CONFIG PWRTEN = OFF ;Disabled
CONFIG BOREN = OFF ;Disabled in hardware, SBOREN disabled
CONFIG WDTEN = OFF ;WDT disabled in hardware; SWDTEN bit disabled
CONFIG CANMX = PORTB
CONFIG MCLRE = OFF


#endconfig


OSCTUNE.6 = 1 ; Enable 4x PLL
OSCCON = %01110000
ANCON1=0 'DISABLE ADC D3-D2-D1-D0-
ANCON0=0
ADCON0=0
TRISC=%11110000 'set PORTC as output first 4
TRISD=%00000000 'set PORTD as output all
TRISB=%00000000 'set PORTB as output all
TRISA=%00000000 'set PORTA 2 as input, others as output
TRISE=%0000000 'set PORTE as output all
define OSC 64


DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 3
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 850
DEFINE LCD_DATAUS 30


'i var byte
high portb.4 'enable LCD backlight


'digits
data $3E, $67, $6F, $7B, $73, $63, $3E, $00 'NOLI
data $1C, $3C, $6C, $0C, $0C, $0C, $7F, $00 'ERTI
data $3E, $63, $03, $3E, $60, $60, $7F, $00 'ORI
data $3E, $63, $03, $0E, $63, $63, $3E, $00 'SAMI
data $63, $63, $63, $3F, $03, $03, $03, $00 'OTXI
data $7F, $60, $60, $7E, $03, $63, $3E, $00 'XUTI
data $3E, $63, $60, $7E, $63, $63, $3E, $00 'EQVSI
data $7F, $63, $03, $06, $0C, $0C, $0C, $00 'SHVIDI
data $3E, $63, $63, $3E, $63, $63, $3E, $00 'RVA
data $3E, $63, $63, $3F, $03, $63, $3E, $00 'CXRA
'SYMBOLS
data $00, $00, $18, $18, $00, $18, $18, $00 'orcertili
data $00, $00, $18, $18, $00, $18, $18, $30 'certilmdzime
data $06, $0c, $18, $30, $18, $0c, $06, $00 'aket
data $00, $00, $7e, $7e, $00, $7e, $7e, $00 'tolia
data $30, $18, $0C, $06, $0C, $18, $30, $00 'iket
data $3E, $63, $63, $06, $0C, $00, $0C, $00 'KITXVA
data $7C, $C6, $DE, $F6, $DC, $C0, $7E, $00 'LOKOKINA


'font georgian alphabet without squeek door
data $0C, $0C, $06, $03, $63, $63, $3E, $00' data ' Char 048 (0)
data $38, $0C, $0C, $3E, $63, $63, $3E, $00'data ' Char 049 (1)
data $26, $63, $66, $63, $63, $63, $3E, $00'data ' Char 050 (2)
data $3E, $63, $63, $7E, $60, $60, $3E, $00'data ' Char 051 (3)
data $3E, $63, $03, $03, $63, $63, $3E, $00'data ' Char 052 (4)
data $36, $6B, $6B, $36, $03, $63, $3E, $00'data ' Char 053 (5)
data $3E, $63, $03, $1E, $33, $63, $3E, $00'data ' Char 054 (6)
data $1E, $03, $0E, $03, $0E, $63, $3E, $00'data ' Char 055 (7)
data $3E, $63, $63, $63, $63, $63, $22, $00'data ' Char 056 (8)
data $0C, $3F, $0C, $06, $63, $63, $3E, $00'data ' Char 057 (9)
data $06, $03, $0E, $03, $63, $63, $3E, $00'data ' Char 058 (:)
data $3E, $63, $63, $62, $60, $60, $3E, $00'data ' Char 059 (;)
data $3E, $63, $03, $3F, $63, $63, $3E, $00'data ' Char 060 (<)
data $7F, $60, $60, $7E, $63, $63, $3E, $00'data ' Char 061 (=)
data $3E, $6B, $6B, $6B, $63, $63, $22, $00'data ' Char 062 (>)
data $0C, $06, $03, $06, $63, $63, $3E, $00'data ' Char 063 (?)
data $03, $03, $0F, $1B, $03, $63, $3E, $00'data ' Char 064 (@)
data $60, $60, $60, $7E, $63, $63, $63, $00'data ' Char 065 (A)
data $60, $60, $60, $63, $63, $63, $3E, $00'data ' Char 066 (B)
data $2E, $6B, $6B, $63, $63, $63, $3E, $00'data ' Char 067 (C)
data $36, $6B, $4B, $03, $63, $63, $3E, $00'data ' Char 068 (D)
data $3E, $63, $03, $06, $63, $63, $3E, $00'data ' Char 069 (E)
data $3E, $6B, $60, $7E, $63, $63, $3E, $00'data ' Char 070 (F)
data $60, $60, $60, $7E, $63, $63, $3E, $00'data ' Char 071 (G)
data $63, $63, $63, $3F, $03, $63, $3E, $00'data ' Char 072 (H)
data $38, $6C, $6C, $3E, $1B, $1B, $0E, $00'data ' Char 073 (I)
data $3E, $6B, $6B, $6B, $6B, $6B, $32, $0 'data for TH [
data $07, $4F, $5B, $33, $03, $63, $3E, $00 '\ jh
data $3E, $6B, $6B, $62, $60, $60, $3E, $00 '] RR
data $36, $5B, $03, $3F, $63, $63, $3E, $00 '^sh
data $3C, $66, $6C, $7E, $63, $63, $63, $00 '_ ch
data $03, $03, $03, $3F, $63, $63, $3E, $00 '` dz


'indicators CORRESPOND SMALL LETTERS
data $EC, $A4, $A4, $A4, $A4, $A4, $EE, $00 '01
data $EE, $AA, $A2, $AE, $A8, $A8, $EE, $00 '02
data $EE, $A2, $A2, $AE, $A2, $A2, $EE, $00 '03
data $EA, $AA, $AA, $AE, $A2, $A2, $E2, $00 '04
data $EE, $A8, $A8, $AE, $A2, $AA, $EE, $00 '05
data $EE, $AA, $A8, $AE, $AA, $AA, $EE, $00 '06
data $EE, $AA, $A2, $A2, $A2, $A2, $E2, $00 '07
data $EE, $AA, $AA, $AE, $AA, $AA, $EE, $00 '08
data $EE, $AA, $AA, $AE, $A2, $AA, $EE, $00 '09
data $CE, $4A, $4A, $4A, $4A, $4A, $EE, $00 '10
data $CC, $44, $44, $44, $44, $44, $EE, $00 '11
data $CE, $42, $42, $4E, $48, $48, $EE, $00 '12
data $CE, $42, $42, $4E, $42, $42, $EE, $00 '13
data $CA, $4A, $4A, $4E, $42, $42, $E2, $00 '14
data $CE, $48, $48, $4E, $42, $4A, $EE, $00 '15
data $CE, $48, $48, $4E, $4A, $4A, $EE, $00 '16
data $CE, $4A, $42, $42, $42, $42, $E2, $00 '17
data $CE, $4A, $4A, $4E, $4A, $4A, $EE, $00 '18
data $CE, $4A, $4A, $4E, $42, $4A, $EE, $00 '19
data $EE, $AA, $2A, $EA, $8A, $8A, $EE, $00 '20
data $EC, $A4, $24, $E4, $84, $84, $EE, $00 '21
data $EE, $AA, $22, $EE, $88, $88, $EE, $00 '22
data $EE, $A2, $22, $EE, $82, $82, $EE, $00 '23
data $EA, $AA, $2A, $EE, $82, $82, $E2, $00 '24
data $10, $28, $48, $48, $48, $28, $10, $00 'light oFF
data $20, $56, $90, $96, $90, $56, $20, $00 'LIGHT ON


'''''''LCD HANDLER VARIABLES
x var byte ' counter variable
z var WORD ' temp variable
y var WORD 'eeprom reader var
i var byte 'counter
a var byte
b var byte 'temps
c var byte
astart var byte 'inversion atribute start
aend var byte 'inversion end


'----------- RTC


RTCYear Var Byte: RTCMonth Var Byte: RTCDate Var Byte: RTCDay Var Byte: RTCHour Var Byte
RTCMin Var Byte: RTCSec Var Byte: RTCCtrl Var Byte
SDA VAR PORTB.3
SCL VAR PORTB.2


SAATI VAR BYTE
CUTI VAR BYTE
'CELI VAR BYTE
TVE VAR BYTE
RICXVI VAR BYTE
DGE VAR BYTE
CAMI VAR BYTE
dro var byte
cvlileba var byte 'clock trigger set




'------------- PCF IO
padr var byte
PSDA var portd.0
PSCL var portd.1




'-----GLOBAL VARIABLES
ABSTIME VAR WORD 'CURRENT ABSOLUTE TIME, HOURS*60+MINUTES FROM RTC
MENUITEM VAR BYTE 'CURRENT MENU POSITION VARIABLE
time var bit[24]


'INPUTS
UPBT VAR PORTC.5 'UP BUTTON
DNBT VAR PORTC.4 'DOWN BUTTON
LBUT VAR PORTC.7 'LEFT/BACK BUTTON
RBUT VAR PORTC.6 'RIGHT/OK BUTTON


sdao var portd.0
sclo var portc.3


'OUTPUTS PCF - 66 CON EDGE, 64 MIDDLE, 78 BUTTON SIDE
adr var byte 'OUTPUT PCF ADDRESS
adr=78


'[\]`^_ th zh R dz sh ch
topline var byte [32] 'top part of the screen array
botline var byte [32] 'bottom part of screen


lcdout $fe, $20 'enable text mode - this is required to fix issue of 18F
LCDOUT $FE,$2, "TEST"
pause 100
LCDOUT $FE,$2, " "
pause 500
LCDOUT $FE,$2E 'enable graphic mode
pause 500
'z=0
gosub gpt 'clear screen
'1234567890ABCDEF
arraywrite topline, ["1234567890ABCDEF"]
arraywrite botline, ["GHIJKLMNOPQRSTUV"]
for c=0 to 24 step 8
gosub gcoder
next
astart=5
aend=10
arraywrite BOTLINE, ["SACDELI XAZI z "]
C=24
GOSUB GCODER




stop












GCODER:
FOR X=0 TO 30 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
if X<15 then
Y=(topline[x]-48)*8
Z=(topline[x+1]-48)*8 'READ INTO VARIABLE AS TWINS
endif


if x>15 then
Y=(botline[x-16]-48)*8
Z=(botline[x-15]-48)*8 'READ INTO VARIABLE AS TWINS
endif




FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
LCDOUT $FE,$80+c+i 'UPDATE Y POSITION
LCDOUT $FE,$80+x/2 'UPDATE X POSITION
READ Y+I,A 'READ EEPROM BYTES INTO VAR
READ Z+I,B


if topline[x]=32 or botline[x-16]=32 then a=0
if topline[x+1]=32 or botline[x-15]=32 then b=0 'blanker


if X=>astart and x<=aend then
a=A^%11111111
b=b^%11111111
endif


if a=$FE then a=0
if b=$fe then b=0
LCDOUT a
LCDOUT b 'WRITE TO SCREEN
NEXT I
NEXT X
return


GPT:
for y=0 to 30 step 2
LCDOUT $FE,$80+y
LCDOUT $FE,$80
FOR x=1 TO 16
LCDOUT 0
NEXT
next
return


9395 9396

CuriousOne
- 9th May 2023, 14:24
The position of inversion depends on two variables, ASTART and AEND.
They are assigned values of 5 and 10.
On 1st run code works fine and inversion starts at 5th char and ends on 10th.
But after power off and back on, seems like these two variables are not same any more.

tumbleweed
- 9th May 2023, 16:29
The variables astart and aend are not assigned values until right before the last time gcoder is called.
What do you expect them to be the first time the program runs since they are uninitialized?

CuriousOne
- 9th May 2023, 17:03
"The last call" of gcoder is the code that makes that inversion, so variables are assigned before their use.

tumbleweed
- 9th May 2023, 17:50
"The last call" of gcoder is the code that makes that inversion, so variables are assigned before their use.

They're used BEFORE the "last call", they're used on EVERY call to gcoder, and they're NOT assigned values.
If that's how you think this all works you should give up now.

CuriousOne
- 9th May 2023, 21:01
OK, that was my fault, you're right
but I have caught this variable space array bug again. What happens here. If code I've selected with BOLD is active, it causes topline last byte to be replaced by space too.
So whenever there are even seconds, instead of last digit of the date at the end of the line, I'm getting an empty space.
As you can see, that code section does nothing - it just changes value of certain variable, which is not used elsewhere.
But if I comment that piece of code, the error is gone.

how this is possible?



#config
CONFIG RETEN = OFF
CONFIG INTOSCSEL = HIGH
CONFIG SOSCSEL = DIG
CONFIG XINST = OFF ;Enabled
CONFIG FOSC = INTIO1
CONFIG PLLCFG = OFF
CONFIG FCMEN = OFF ;Disabled
CONFIG PWRTEN = OFF ;Disabled
CONFIG BOREN = OFF ;Disabled in hardware, SBOREN disabled
CONFIG WDTEN = OFF ;WDT disabled in hardware; SWDTEN bit disabled
CONFIG CANMX = PORTB
CONFIG MCLRE = OFF


#endconfig


OSCTUNE.6 = 1 ; Enable 4x PLL
OSCCON = %01110000
ANCON1=0 'DISABLE ADC D3-D2-D1-D0-
ANCON0=0
ADCON0=0
TRISC=%11110000 'set PORTC as output first 4
TRISD=%00000000 'set PORTD as output all
TRISB=%00000000 'set PORTB as output all
TRISA=%00000000 'set PORTA 2 as input, others as output
TRISE=%0000000 'set PORTE as output all
define OSC 64


DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 3
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 850
DEFINE LCD_DATAUS 30


'i var byte
high portb.4 'enable LCD backlight


'digits
data $3E, $67, $6F, $7B, $73, $63, $3E, $00 'NOLI
data $1C, $3C, $6C, $0C, $0C, $0C, $7F, $00 'ERTI
data $3E, $63, $03, $3E, $60, $60, $7F, $00 'ORI
data $3E, $63, $03, $0E, $63, $63, $3E, $00 'SAMI
data $63, $63, $63, $3F, $03, $03, $03, $00 'OTXI
data $7F, $60, $60, $7E, $03, $63, $3E, $00 'XUTI
data $3E, $63, $60, $7E, $63, $63, $3E, $00 'EQVSI
data $7F, $63, $03, $06, $0C, $0C, $0C, $00 'SHVIDI
data $3E, $63, $63, $3E, $63, $63, $3E, $00 'RVA
data $3E, $63, $63, $3F, $03, $63, $3E, $00 'CXRA
'SYMBOLS
data $00, $00, $18, $18, $00, $18, $18, $00 'orcertili
data $00, $00, $18, $18, $00, $18, $18, $30 'certilmdzime
data $06, $0c, $18, $30, $18, $0c, $06, $00 'aket
data $00, $00, $7e, $7e, $00, $7e, $7e, $00 'tolia
data $30, $18, $0C, $06, $0C, $18, $30, $00 'iket
data $3E, $63, $63, $06, $0C, $00, $0C, $00 'KITXVA
data $7C, $C6, $DE, $F6, $DC, $C0, $7E, $00 'LOKOKINA


'font georgian alphabet without squeek door
data $0C, $0C, $06, $03, $63, $63, $3E, $00' data ' Char 048 (0)
data $38, $0C, $0C, $3E, $63, $63, $3E, $00'data ' Char 049 (1)
data $26, $63, $66, $63, $63, $63, $3E, $00'data ' Char 050 (2)
data $3E, $63, $63, $7E, $60, $60, $3E, $00'data ' Char 051 (3)
data $3E, $63, $03, $03, $63, $63, $3E, $00'data ' Char 052 (4)
data $36, $6B, $6B, $36, $03, $63, $3E, $00'data ' Char 053 (5)
data $3E, $63, $03, $1E, $33, $63, $3E, $00'data ' Char 054 (6)
data $1E, $03, $0E, $03, $0E, $63, $3E, $00'data ' Char 055 (7)
data $3E, $63, $63, $63, $63, $63, $22, $00'data ' Char 056 (8)
data $0C, $3F, $0C, $06, $63, $63, $3E, $00'data ' Char 057 (9)
data $06, $03, $0E, $03, $63, $63, $3E, $00'data ' Char 058 (:)
data $3E, $63, $63, $62, $60, $60, $3E, $00'data ' Char 059 (;)
data $3E, $63, $03, $3F, $63, $63, $3E, $00'data ' Char 060 (<)
data $7F, $60, $60, $7E, $63, $63, $3E, $00'data ' Char 061 (=)
data $3E, $6B, $6B, $6B, $63, $63, $22, $00'data ' Char 062 (>)
data $0C, $06, $03, $06, $63, $63, $3E, $00'data ' Char 063 (?)
data $03, $03, $0F, $1B, $03, $63, $3E, $00'data ' Char 064 (@)
data $60, $60, $60, $7E, $63, $63, $63, $00'data ' Char 065 (A)
data $60, $60, $60, $63, $63, $63, $3E, $00'data ' Char 066 (B)
data $2E, $6B, $6B, $63, $63, $63, $3E, $00'data ' Char 067 (C)
data $36, $6B, $4B, $03, $63, $63, $3E, $00'data ' Char 068 (D)
data $3E, $63, $03, $06, $63, $63, $3E, $00'data ' Char 069 (E)
data $3E, $6B, $60, $7E, $63, $63, $3E, $00'data ' Char 070 (F)
data $60, $60, $60, $7E, $63, $63, $3E, $00'data ' Char 071 (G)
data $63, $63, $63, $3F, $03, $63, $3E, $00'data ' Char 072 (H)
data $38, $6C, $6C, $3E, $1B, $1B, $0E, $00'data ' Char 073 (I)
data $3E, $6B, $6B, $6B, $6B, $6B, $32, $0 'data for TH [
data $07, $4F, $5B, $33, $03, $63, $3E, $00 '\ jh
data $3E, $6B, $6B, $62, $60, $60, $3E, $00 '] RR
data $36, $5B, $03, $3F, $63, $63, $3E, $00 '^sh
data $3C, $66, $6C, $7E, $63, $63, $63, $00 '_ ch
data $03, $03, $03, $3F, $63, $63, $3E, $00 '` dz


'indicators CORRESPOND SMALL LETTERS
data $EC, $A4, $A4, $A4, $A4, $A4, $EE, $00 '01
data $EE, $AA, $A2, $AE, $A8, $A8, $EE, $00 '02
data $EE, $A2, $A2, $AE, $A2, $A2, $EE, $00 '03
data $EA, $AA, $AA, $AE, $A2, $A2, $E2, $00 '04
data $EE, $A8, $A8, $AE, $A2, $AA, $EE, $00 '05
data $EE, $AA, $A8, $AE, $AA, $AA, $EE, $00 '06
data $EE, $AA, $A2, $A2, $A2, $A2, $E2, $00 '07
data $EE, $AA, $AA, $AE, $AA, $AA, $EE, $00 '08
data $EE, $AA, $AA, $AE, $A2, $AA, $EE, $00 '09
data $CE, $4A, $4A, $4A, $4A, $4A, $EE, $00 '10
data $CC, $44, $44, $44, $44, $44, $EE, $00 '11
data $CE, $42, $42, $4E, $48, $48, $EE, $00 '12
data $CE, $42, $42, $4E, $42, $42, $EE, $00 '13
data $CA, $4A, $4A, $4E, $42, $42, $E2, $00 '14
data $CE, $48, $48, $4E, $42, $4A, $EE, $00 '15
data $CE, $48, $48, $4E, $4A, $4A, $EE, $00 '16
data $CE, $4A, $42, $42, $42, $42, $E2, $00 '17
data $CE, $4A, $4A, $4E, $4A, $4A, $EE, $00 '18
data $CE, $4A, $4A, $4E, $42, $4A, $EE, $00 '19
data $EE, $AA, $2A, $EA, $8A, $8A, $EE, $00 '20
data $EC, $A4, $24, $E4, $84, $84, $EE, $00 '21
data $EE, $AA, $22, $EE, $88, $88, $EE, $00 '22
data $EE, $A2, $22, $EE, $82, $82, $EE, $00 '23
data $EA, $AA, $2A, $EE, $82, $82, $E2, $00 '24
data $10, $28, $48, $48, $48, $28, $10, $00 'light oFF
data $20, $56, $90, $96, $90, $56, $20, $00 'LIGHT ON
data $01, $03, $06, $0C, $18, $30, $60, $00 '/ side line { this char


'''''''LCD HANDLER VARIABLES
x var byte ' counter variable
z var WORD ' temp variable
y var WORD 'eeprom reader var
i var byte 'counter
a var byte
b var byte 'temps
c var byte
astart var byte 'inversion atribute start
aend var byte 'inversion end
separ var byte 'dual dot separator


'----------- RTC


RTCYear Var Byte: RTCMonth Var Byte: RTCDate Var Byte: RTCDay Var Byte: RTCHour Var Byte
RTCMin Var Byte: RTCSec Var Byte: RTCCtrl Var Byte
SDA VAR PORTB.3
SCL VAR PORTB.2


SAATI VAR BYTE
CUTI VAR BYTE
'CELI VAR BYTE
TVE VAR BYTE
RICXVI VAR BYTE
DGE VAR BYTE
CAMI VAR BYTE
dro var byte
cvlileba var byte 'clock trigger set




'------------- PCF IO
padr var byte
PSDA var portd.0
PSCL var portd.1




'-----GLOBAL VARIABLES
ABSTIME VAR WORD 'CURRENT ABSOLUTE TIME, HOURS*60+MINUTES FROM RTC
MENUITEM VAR BYTE 'CURRENT MENU POSITION VARIABLE
time var bit[24]


'INPUTS
UPBT VAR PORTC.5 'UP BUTTON
DNBT VAR PORTC.4 'DOWN BUTTON
LBUT VAR PORTC.7 'LEFT/BACK BUTTON
RBUT VAR PORTC.6 'RIGHT/OK BUTTON


sdao var portd.0
sclo var portc.3


'OUTPUTS PCF - 66 CON EDGE, 64 MIDDLE, 78 BUTTON SIDE
adr var byte 'OUTPUT PCF ADDRESS
adr=78


'[\]`^_ th zh R dz sh ch
topline var byte [32] 'top part of the screen array
botline var byte [32] 'bottom part of screen


lcdout $fe, $20 'enable text mode - this is required to fix issue of 18F
LCDOUT $FE,$2, "TEST"
pause 100
LCDOUT $FE,$2, " "
pause 500
LCDOUT $FE,$2E 'enable graphic mode
pause 500
'z=0
gosub gpt 'clear screen


astart=0
aend=0 '1234567890ABCDEF
arraywrite topline, [" "]
arraywrite botline, [" "]
for c=0 to 24 step 8
gosub gcoder
next
drk:
gosub gettime


if CAMi.0=1 then 'blink the dots each second
separ=58
else
separ=32
endif



arraywrite TOPLINE, [dec saati dig 1,dec saati dig 0,32, dec cuti dig 1, dec cuti dig 0,32, dec cami dig 1, dec cami dig 0,32, dec TVE DIG 1, DEC TVE DIG 0,"{", DEC ricxvi DIG 1, DEC ricxvi dig 0]
C=0
'astart=1+16
'aend=2+16
if cvlileba=1 then GOSUB GCODER
pause 50
goto drk




stop






GCODER:
FOR X=0 TO 30 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
if X<15 then
Y=(topline[x]-48)*8
Z=(topline[x+1]-48)*8 'READ INTO VARIABLE AS TWINS
endif


if x>15 then
Y=(botline[x-16]-48)*8
Z=(botline[x-15]-48)*8 'READ INTO VARIABLE AS TWINS
endif




FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
LCDOUT $FE,$80+c+i 'UPDATE Y POSITION
LCDOUT $FE,$80+x/2 'UPDATE X POSITION
READ Y+I,A 'READ EEPROM BYTES INTO VAR
READ Z+I,B


if topline[x]=32 or botline[x-16]=32 then a=0
if topline[x+1]=32 or botline[x-15]=32 then b=0 'blanker


if X=>astart and x<=aend and astart<>aend then
a=A^%11111111
b=b^%11111111
endif


if a=$FE then a=0
if b=$fe then b=0
LCDOUT a
LCDOUT b 'WRITE TO SCREEN
NEXT I
NEXT X
return


GPT:
for y=0 to 30 step 2
LCDOUT $FE,$80+y
LCDOUT $FE,$80
FOR x=1 TO 16
LCDOUT 0
NEXT
next
return


gettime:
I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
CAMI=(RTCSEC >> 4)*10+RTCSEC // 16
CUTI=(RTCmin >> 4)*10+RTCmin // 16 'decode seconds
SAATI=(RTCHour >> 4)*10+RTCHour // 16 'decode hours
TVE=(RTCmonth >> 4)*10+RTCmonth // 16 'decode month
RICXVI=(RTCdate >> 4)*10+RTCdate // 16 'decode month
DGE=RTCday
if DRO<>rtcsec then 'check for time changes, so display only is refreshed when time is changed
cvlileba=1
else
cvlileba=0
endif
DRO=rtcmin
Return

tumbleweed
- 9th May 2023, 22:53
There are still places where things can go wrong, so until they're fixed all bets are off.

For example in gcoder you have the following (I've removed some of the code for clarity)


FOR X=0 TO 30 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
...
FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
...
if topline[x]=32 or botline[x-16]=32 then a=0
if topline[x+1]=32 or botline[x-15]=32 then b=0 'blanker

Follow that code through for X=0 to 14. What happens to a and b?

CuriousOne
- 10th May 2023, 05:33
These are code parts which insert the empty space when in the array we do have code for ASCII space (32).
And this part of code works just fine.
The issue is that another, non-related part of code is causing problems.
Why changing value of certain variable, which is not used at all, causes issues with another variable?

Ioannis
- 10th May 2023, 07:51
Maybe because you are altering places in memory of the PIC that you are not aware of?

In the above example, if x=0, the



botline[x-16]=32 then a=0


how does evaluate?

Do you see the consequences of?

Ioannis

tumbleweed
- 10th May 2023, 11:15
And this part of code works just fine.
The issue is that another, non-related part of code is causing problems.
Why changing value of certain variable, which is not used at all, causes issues with another variable?
Ioannis gets it. You don't. That code doesn't "work just fine".

Your array index statements are screwed up, so you're accessing who knows what in memory.
That would explain the mysterious "I add unrelated code and things change".

There are any number of places for all that to go south... I don't trust many of those array accesses to be valid.

CuriousOne
- 10th May 2023, 20:28
Well, that is interesting.
As I understand, there is no "index out of bounds" error type supported by PBP? :)

I've modified that part of code to look like this:



if topline[x]=32 then a=0
if topline[x+1]=32 then b=0 'blanker


if X=>16 and botline[x-16]=32 then a=0
if x=>16 and botline[x-15]=32 then b=0


So far, works fine. Will keep you updated :)

Ioannis
- 10th May 2023, 20:40
Well, that is interesting.
As I understand, there is no "index out of bounds" error type supported by PBP?


Page 275 of the manual:

7.6.1 The Danger
The techniques about to be discussed are not monitored by PBP during compilation
or execution of the program. This means that you can write some crazy code that
could totally wreck the RAM on the PIC MCU. PBP won't warn you or generate an
error message.

The greatest opportunity for trouble lies in the fact that PBP doesn't monitor (isn't
even aware) of array variable sizes. When you declare an array in PBP and specify
a size, all that really happens is that PBP skips a number of RAM locations after the
base variable name is allocated.



my_array VAR WORD[16] ' Allocates "my_array" as two
bytes, then skips (reserves) a
block of 30 bytes in RAM


Even if you blatantly write to a location that is beyond the size of an array you created,
PBP won't complain.

CuriousOne
- 11th May 2023, 04:46
Yes I have read that.
But same manual also says that array size is limited for 16F series and only limited by available RAM on 18F, so I thought that this should work fine, but as it seems, it does not :)

Now I have another everlasting issue to solve - how to send $FE data via LCDOUT statement (it interprets $FE as command, not data transfer).
Solving this issue will help me to add ability to draw graphics to my ST7920 "Library".

richard
- 11th May 2023, 05:03
But same manual also says that array size is limited for 16F series and only limited by available RAM on 18F, so I thought that this should work fine

how can you interpret that to mean that writes involving array boundary violations are an acceptable programming technique ?

CuriousOne
- 11th May 2023, 06:37
Well, as my experience with ZX Spectrum BASIC shows (In case of array misreading: Error 3: Subscript wrong), when you do something not allowed, you will get an error message.
Even Visual Basic does that check.

richard
- 11th May 2023, 07:40
its totally up to you to decide how much time you are prepared to waste learning this lesson.

continually wheeling out the old "ZX Spectrum BASIC" excuse leads nowhere and never will , compiled code is what it is
you need to deal with it

Ioannis
- 11th May 2023, 09:00
Since the index to array can be number or calculation then it is not possible for the compiler to check that!

The interpreter is totally different story. Do not compare the two.

Richard has it just right.

Ioannis

HenrikOlsson
- 11th May 2023, 11:45
Exactly, we've been thru this before. Your beloved ZX Spectrum runs a BASIC interpreter which interprets and executes the code as it runs. It (the interpreter) can check things like out of bounds errors at run-time, a task that I'm sure makes array-indexing slow as f-k.

PBP is a compiler. It COMPILES your BASIC source into instructions that the PIC executes natively, it's not an interpreter. It is IMPOSSIBLE for the compiler to detect out of bounds issues at COMPILE TIME.

And even if the compiler was built to generate code that DID check array boundries on every access at runtime what do you suggest should happen when such an error is detected? It's not like there's a TV or monitor connected that can display the error message. Nope, the program would just crash with no way to tell the user why. In what way is that better than what it does now?

CuriousOne
- 11th May 2023, 20:11
Yes I know what is the difference between the compiler and interpreter.

And I'm not asking about RUNTIME error handling. I'm asking about boundary checking during the compile.
It can be clearly seen from the code that reading past array boundaries WILL occur in compiled code:

1. Compiler knows that X is starting from 0
2. Compiler knows that array is being read at X-16 position, which is definitely an error.

So some kind of notification like - "possible out of boundary array access" is very well possible and would be great.

HenrikOlsson
- 12th May 2023, 07:09
It can be clearly seen from the code that reading past array boundaries WILL occur in compiled code:

And yet, on 22nd April 2023, you said:

This is not issue of my code, because if I do not declare "topline" array, then "botline" reading works fine.
Clearly putting blame on anything BUT your code, be it the PIC itself, the compiler, the assembler or whatever - just not your code.

But, you're right, some situations could be confidently detected and some could be flagged as "potential" at compile time but it's a "can of worms".

As it is, the rules are clear and they are spelled out in the manual, section 7.6 that Ioannis pointed to earlier. You are responsibly, a fair price to pay for a powerful feature. It is what it is.

CuriousOne
- 12th May 2023, 08:49
Oh yes, XINST issues are solely my code fault too, right? :)

HenrikOlsson
- 12th May 2023, 10:22
Well, yes!

Since the compiler doesn't generate code for the extended instruction set the XINST config setting is set to OFF in the default configuration files for the devices that has that option.

Are you saying that is not the case for 45K80 and that there's a problem with the default config?

My humble guess is no, probably not. Instead you took a decision to change a default setting without knowing what it does. Things went south and once again it's the tools fault.

I'm not saying PBP and it's documentation is without shortcomings but, as has been proven, people don't read the documentation anyway. For example, can you honestly say that you went looking for XINST in the PBP manual BEFORE you decided to change that setting to ON or BEFORE tumbleweed pointed you the problem?

If you DID look for it in the manual you would've seen that every time it IS mentioned it shows the setting being OFF but you STILL decided to change it to ON and blame the tool.