Why dont my pointer works ? - Page 1
Forum section: electronics / general

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 02:01:37 pm
content: Hi, i am trying this with XC32 for PIC32MX170F256B :Code:unsigned char screen[ 64 ][ 16 ];unsigned long long * lcdptr;unsigned long long * lcdptrPlus127;// initlcdptr = ( unsigned long long * )screen;lcdptrPlus127 = lcdptr + 127;// ckear function// clear screen*(lcdptr++) = 0;// this part dont works :if( lcdptr == lcdptrPlus127 )stop clear function.Problem : the clear function wont stop.Ofcourse i can add a counter, i would like to use the pointer as counter.thanks

author: andersm
author_rank: Super Contributor
timestamp: November 18, 2018, 02:38:38 pm
content: Could you post your actual code? Also, alignment is important on MIPS CPUs. There is no guarantee that your char array will be to allow it to be accessed as anything but chars. As a sidenote, it's be really difficult to out-perform memset, which has the added bonus of being correct.

author: nctnico
author_rank: Super Contributor
timestamp: November 18, 2018, 02:47:01 pm
content: I'd use a counter to make sure. Also a pointer to a long (typically 32 bit) will be incremented by 4 bytes. Besides that try to use types (line uint32_t, in8_t, etc) from std_int.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 03:01:14 pm
content: Quote from: andersm on November 18, 2018, 02:38:38 pmSo the whole screen is not a solid piece of memory ?I thought from the first byte to last is all aligned behind eachother,i am keeping to in the memory range, to 127, instead of going over the memory range ( 128 ), something with pages or something could happen i imagined.For the memset :I am trying to spread out the function for in background rendering in main loop, dont stop the main loop for rendering functions since it is writing the backbuffer to screen.Anyways : this will be faster then memset i think, i can run some tests again for this PIC32, i,m almost sure already.btw : for clearing the screen is no problem, only the pointer.Clearing the screen with a counter still works the same, here it only wont stop the function.Quote from: nctnico on November 18, 2018, 02:47:01 pmHere its unsigned long long, increments of 8 bytes.

author: andersm
author_rank: Super Contributor
timestamp: November 18, 2018, 03:23:24 pm
content: Quote from: Jan Audio on November 18, 2018, 03:01:14 pmThat's not what I said at all. If the first byte of the array is not allocated on an address evenly divisible by 4, your program will crash.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 03:31:34 pm
content: Ooh, thanks.Now its getting more complicated with things i dont see in C language.

author: sokoloff
author_rank: Super Contributor
timestamp: November 18, 2018, 03:44:07 pm
content: Agree with the above request to post the whole code (or at least the relevant parts, more than you've posted above).You also have an off-by-one (or off by 8 bytes). The code above, once made to be correct, will never clear the last 8 bytes of the screen array.You might also consider switching to just a 32 bit type. I doubt the PIC is more efficient at clearing 64 bits at a time, and it might even be slower/higher overhead to do so.

author: IanB
author_rank: Super Contributor
timestamp: November 18, 2018, 03:49:33 pm
content: Quote from: Jan Audio on November 18, 2018, 03:01:14 pmIf you add 127 to a long long pointer, it will increment it by 127 long longs, i.e. 127*8 = 1016 bytes. If you were hoping to advance the pointer by 127 bytes it will not do that.

author: sokoloff
author_rank: Super Contributor
timestamp: November 18, 2018, 03:59:28 pm
content: Quote from: IanB on November 18, 2018, 03:49:33 pmThat part is right (though off-by-one in the last test). Screen is a 64x16 char array, which is 1024 bytes in memory.

author: Nusa
author_rank: Super Contributor
timestamp: November 18, 2018, 04:04:36 pm
content: Try:Code:union {unsigned long long lcd[ 128 ]; // will be 8-byte aligned by default nowunsigned char screen[ 64 ][ 16 ]; // by itself, might not have been aligned nicely}unsigned long long * lcdptr;unsigned long long * lcdptrPlus127;// initlcdptr = lcd;lcdptrPlus127 = &lcd;...

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 04:04:52 pm
content: Here is the code :Code://------------------------------------------------------------------------------// y , x * 8 ( 128 x 64 display swapping backbuffer )//------------------------------------------------------------------------------struct ScreenBuffer{unsigned char data[ 64 ][ 16 ];};//------------------------------------------------------------------------------struct ScreenBuffer*pScreen;struct ScreenBuffer*pInternalScreen;struct ScreenBuffer screen1,screen2;//------------------------------------------------------------------------------// clear graphical display backbuffer//------------------------------------------------------------------------------#define ClearScreen( screen ) lcdtemp = 0; \lcdptr = ( unsigned long long * )screen; \do{ *(lcdptr++) = 0; }while( lcdtemp++ != 127 );void ( *HandleRender )();// initpScreen = &screen1;pInternalScreen = &screen2;// set pointer for clearlcdptr = ( unsigned long long * )pScreen->data;lcdptrPlus127 = lcdptr + 127;HandleRender = Clear;//------------------------------------------------------------------------------// Clear//------------------------------------------------------------------------------void Clear(){*(lcdptr++) = 0;*(lcdptr++) = 0;*(lcdptr++) = 0;*(lcdptr) = 0;if( lcdptr++ == lcdptrPlus127 )HandleRender = PaintLine;}Now let me read the comments, thnx.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 04:05:30 pm
content: Thanks Nusa i tryd that, wont work.

author: andersm
author_rank: Super Contributor
timestamp: November 18, 2018, 04:19:27 pm
content: Slight rewrite:Code:void Clear(){*lcdptr = 0;lcdptr += 1;*lcdptr = 0;lcdptr += 1;*lcdptr = 0;lcdptr += 1;*lcdptr = 0;if (lcdptr == lcdptrPlus127)HandleRender = PaintLine;lcdptr += 1;}Do you see the problem there? Or, altenativelyCode:void Clear(){lcdptr = 0;lcdptr = 0;lcdptr = 0;lcdptr = 0;lcdptr += 3;if (lcdptr == lcdptrPlus127)HandleRender = PaintLine;lcdptr += 1;These two forms are functionally equivalent to the code you posted, and they all have the same problem.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 04:21:20 pm
content: Yes all the same.Should work right ?,Maybe i can use a union with unsigned long longs at same memory ?

author: andersm
author_rank: Super Contributor
timestamp: November 18, 2018, 05:03:46 pm
content: Quote from: Jan Audio on November 18, 2018, 04:21:20 pmNo. Simulate the code on paper if you can't figure it out.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 05:23:58 pm
content: Why dont you tell me the problem please ?

author: andersm
author_rank: Super Contributor
timestamp: November 18, 2018, 05:37:41 pm
content: I'm trying to be educational.Just to prove an earlier point, here's what you get with memset, compiled with -O1. Still sure you can do better?Code:#include <string.h>#include <stdint.h>typedef void(*renderfunc)(void);extern renderfunc pFun;void otherfunc(void);extern union {uint8_t b;uint32_t i;} a;extern int loop_index;void clear(void){memset(&a.i, 0, 32);loop_index += 8;if (loop_index == 256)pFun = otherfunc;}Code:00000000 <clear>:0:8f830000lwv1,0(gp)4:00032080slla0,v1,0x28:3c020000luiv0,0x0c:24420000addiuv0,v0,010:00441021adduv0,v0,a014:ac400000swzero,0(v0)18:ac400004swzero,4(v0)1c:ac400008swzero,8(v0)20:ac40000cswzero,12(v0)24:ac400010swzero,16(v0)28:ac400014swzero,20(v0)2c:ac400018swzero,24(v0)30:ac40001cswzero,28(v0)34:24620008addiuv0,v1,838:24030100liv1,2563c:14430004bnev0,v1,50 <clear+0x50>40:af820000swv0,0(gp)44:3c020000luiv0,0x048:24420000addiuv0,v0,04c:af820000swv0,0(gp)50:03e00008jrra54:00000000nop

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 18, 2018, 05:43:54 pm
content: Did you compare it with the unsigned long long filling ?What would be the solution to my problem without memset ?, dont you have that ?Set timer output on display, then also for the memset,i dont know about instructions.

author: cv007
author_rank: Frequent Contributor
timestamp: November 18, 2018, 07:03:50 pm
content: Code:#include "Osc.hpp"#include "Uart.hpp"#include "Cp0.hpp"#include <cstdio>#include <cstdint>#include <cstring> //memsetuint8_t screen[ 64 ][ 16 ];// clear screen//screen must be multiple of 128bytesvoid cls(){uint64_t* p = (uint64_t*)screen;for(uint32_t i = sizeof(screen); i; i-=128){*p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes*p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes*p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes*p++ = 0;*p++ = 0;*p++ = 0;*p++ = 0; //4*8=32bytes}}//tx onlyUart info { Uart::UART2TX, Pins::C6, 230400 };//so I can use printf with 'info' as the outputextern "C" void _mon_putc(char c){ info.putchar(c); }int main(){Osc osc;osc.pll_set ( osc.MUL12, osc.DIV4 );info.on ( true );printf( "\n\n&screen: 0x%04X\n", (uint32_t)screen );uint32_t t1 = Cp0::count();cls();uint32_t t2 = Cp0::count();;memset(screen, 0, sizeof(screen));uint32_t t3 = Cp0::count();printf( "cls: %d memset: %d\n", t2-t1, t3-t2 );for(;;);}/*&screen: 0x8000004Ccls: 154 memset: 212*/It also looks to me that xc32 will always align an array on 4bytes. If you create some vars as bytes, the addresses will of course only be byte aligned, but the minute you create a byte array of 1 or more,it seems to always be 4byte aligned. I don't know the rules, but that is what seems to happen. I tried to get 'screen' unaligned, but could not.QuoteIf you want screen buffer cleared while doing something else, use DMA.

author: richardman
author_rank: Frequent Contributor
timestamp: November 18, 2018, 08:56:22 pm
content: You ClearScreen() looks reasonably correct, but I think you must have other code here. If I have to guess, you are being clever using RenderHandler to first to set to Clear, and you would call it a number of times, and then when it clears the whole buffer, you set RenderHandler to some other "real" drawing routine.Without seeing your other code, we have no other what else you are doing. My advice is that it could be something simple, but generally, it looks a bit too "clever for clever" sake. Just have a ClearScreen() macro/function that you call to clear the whole screen, then another function to draw.Basically, pointers work, and if you code doesn't, there is something you do not understand, and it's hard to guess what it is.

author: hamster_nz
author_rank: Super Contributor
timestamp: November 18, 2018, 11:12:18 pm
content: It looks like you are trying to incrementally clean the buffer, four words at a time.Are you sure that your pointer is aligned as you expect at the start?Otherwise you need to test to see if you are at the end of the buffer more often.Code:void Clear(){int i;for(i = 0; i < 4; i++) {*lcdptr = 0;if (lcdptr == lcdptrPlus127) {HandleRender = PaintLine;return;}lcdptr++;}}It seems to be doing a very small amount of work to do each time though....

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 19, 2018, 02:01:07 pm
content: Quote from: cv007 on November 18, 2018, 07:03:50 pmThanks, here i am intrested.So i can use DMA for anything not only peripherals ?, nice.I need to generate some DMA code in MCC then,could i do my update routine also in another DMA ?, that would be even better.Quote from: richardman on November 18, 2018, 08:56:22 pmIt will take to long, and it will make my MIDI in signal be handled to late, also the screen updating routine will be delayed.Ofcourse like you say would be simpler, then i would need other things interrupt based, while MIDI data can not be handles in the interrupt, then it might be to slow to receive the next byte.Quote from: hamster_nz on November 18, 2018, 11:12:18 pmYes,yes, also yes small ammount to keep the main loop running,no problems, the screen updates a bit more then 20 frames per second with total redraw,enough time to clean and draw some lines and circles piece by piece.The only problem is with these sucky LCDs that the update is to fast for the pixels to show : a moving line is very vague.Anyways if it should work i will try some more, thanks.It is not compicated to make it complicated, it is very simple only not so common.I,m going to add some variables to the union for comparing.

author: bsudbrink
author_rank: Frequent Contributor
timestamp: November 19, 2018, 06:13:36 pm
content: I've read through this thread twice now and, since no one explicitly told you what your problem was, I will. Mr. andersm hinted around it, but you are hitting a problem that many novice (no offense) C programmers encounter. In the code in message 10, in the Clear function, the post-increment instruction in the if statement:if( lcdptr++ == lcdptrPlus127 )does not behave as you seem to expect. The behavior is a bit "fuzzy". In several of the C language definitions, in the descriptions of post-increment, you will find statements like:The increment will take place at the end of the execution unit.That leaves you wondering, "what is an execution unit"? I won't go any further other than to tell you the the increment takes place after the compare. You can go read the language definitions yourself if you are having trouble sleeping or enjoy headaches. I hope you can logically see that, due to this behavior, the if condition will never be true.

author: richardman
author_rank: Frequent Contributor
timestamp: November 19, 2018, 10:00:47 pm
content: Quote from: bsudbrink on November 19, 2018, 06:13:36 pmNot sure exactly what the OP's problem is, but this statement is "misleading"The C language is quite clear on what this statement means:The initial (pre-incremented) value of lcdptr is compared to lcdptrPlus127 and the result of the comparison is the (boolean) value of the test expression. lcdptr is incremented.The only thing "fuzzy" is when does the increment happens, which has no bearing whatsoever.

author: bsudbrink
author_rank: Frequent Contributor
timestamp: November 19, 2018, 10:07:53 pm
content: Quote from: richardman on November 19, 2018, 10:00:47 pmWhat about this:if ((lcdptr++) == lcdptrPlus127)

author: IanB
author_rank: Super Contributor
timestamp: November 19, 2018, 10:23:50 pm
content: Quote from: bsudbrink on November 19, 2018, 10:07:53 pmWhy would the parentheses make a difference?

author: nctnico
author_rank: Super Contributor
timestamp: November 19, 2018, 10:30:32 pm
content: Quote from: IanB on November 19, 2018, 10:23:50 pmProbably increment before comparing. However I'd strongly advice to split operations in single lines because code like this is wildly obfustigated and impossible to maintain long term. Screens are big nowadays so there is no need to cram as much C code as possible in a 80x40 terminal screen.

author: IanB
author_rank: Super Contributor
timestamp: November 19, 2018, 10:34:09 pm
content: Quote from: nctnico on November 19, 2018, 10:30:32 pmIt's still a post-increment operation. The value of (lcdptr++) should be evaluated before the comparison. The value of (lcdptr++) would be the value of lcdptr prior to the increment operation. If instead we wrote (++lcdptr) we would get the value of lcdptr after the increment.

author: cv007
author_rank: Frequent Contributor
timestamp: November 19, 2018, 10:34:53 pm
content: Its not how I would do it, but the Clear() function in post 10 works fine-this is simply printing out some info about the pointers, then running Clear() 1024/32 times where the last time shows that the pointers are a match (before the increment, as the 'end' pointer is one 'position' short of the end, which is a little different than most would do)pScreen: 0x80000058lcdptr: 0x80000058lcdptrPlus127: 0x80000450[Clear start][lcdptr: 0x80000058]lcdptr: 0x80000060lcdptr: 0x80000068lcdptr: 0x80000070lcdptr: 0x80000070[Clear end][lcdptr: 0x80000078][Clear start][lcdptr: 0x80000078]lcdptr: 0x80000080lcdptr: 0x80000088lcdptr: 0x80000090lcdptr: 0x80000090[Clear end][lcdptr: 0x80000098]......[Clear start][lcdptr: 0x80000438]lcdptr: 0x80000440lcdptr: 0x80000448lcdptr: 0x80000450lcdptr: 0x80000450lcdptr==lcdptrPlus127[Clear end][lcdptr: 0x80000458]FYI, this Clear() function run 32 times takes 340 cp0 cycles (680 cpu cycles), the cls function I showed earlier takes 308 cpu cycles and memset takes 424 cpu cycles. So by calling the Clear() function multiple times, it takes an extra 372 cycles.I don't know all the details of the C rules and which compiler follows them or not, but these 2 produce the same result in xc32-if ((lcdptr++) == lcdptrPlus127)if (lcdptr++ == lcdptrPlus127)

author: bsudbrink
author_rank: Frequent Contributor
timestamp: November 19, 2018, 10:39:33 pm
content: To make it really nasty (not that I would advocate using code like this in any serious fashion) how about:/* using simple variable names for clarity */if ((z == (y = x++)) && (x == 5)){printf ("%d\n", x);}Assuming that execution reaches the printf, what does it print?

author: bsudbrink
author_rank: Frequent Contributor
timestamp: November 19, 2018, 10:44:00 pm
content: Quote from: IanB on November 19, 2018, 10:23:50 pmExactly. Maybe I'm not remembering the correct terms any more, (I sure thought the concept was called an "execution unit") but that is the concept. Ponder my other example.

author: IanB
author_rank: Super Contributor
timestamp: November 19, 2018, 10:44:25 pm
content: Quote from: bsudbrink on November 19, 2018, 10:39:33 pmDon't we need to know the initial value of x before entering the if statement?

author: bsudbrink
author_rank: Frequent Contributor
timestamp: November 19, 2018, 10:54:42 pm
content: Quote from: IanB on November 19, 2018, 10:44:25 pmJust think about what it takes to make it to the printf. x must be 5, right? But when is the increment?Anyway, I can tell you that back in the late 1980s, this was fuzzy. I had a coworker code what was essentially this example "by accident". Depending on whether you used Lattice or Borland, you got 5 or 6 as the output.

author: IanB
author_rank: Super Contributor
timestamp: November 19, 2018, 11:02:53 pm
content: Quote from: bsudbrink on November 19, 2018, 10:54:42 pmOK, I see.It seems that in modern C++ the logical && operator introduces a sequence point, so the results of x++ should be complete before doing the (x == 5) comparison. Therefore modern C++ should print 5 and not 6.(This is logical because && short circuits. It is required that everything before the && is evaluated before looking at anything after the &&.)

author: bsudbrink
author_rank: Frequent Contributor
timestamp: November 19, 2018, 11:36:29 pm
content: Quote from: IanB on November 19, 2018, 11:02:53 pmHmmm... I'm not sure I follow the logic here. Shouldn't the various sub-clauses, connected with &&, be evaluatable in any order without changing the outcome? That would argue for carrying out the increment after the entire expression was evaluated. Of course, those kind of side effects are exactly why all of this should be avoided like the plague.

author: sokoloff
author_rank: Super Contributor
timestamp: November 19, 2018, 11:58:39 pm
content: Quote from: bsudbrink on November 19, 2018, 11:36:29 pmThey are logically, but the languagespecifiesthat && short-circuits. As soon as a false is encountered as the rvalue of the first operand, the language spec guarantees that the second operand is not evaluated.This permits you to do things like without a segfault if the pointer is 0:if (pointer && pointer->value > 0) ...If pointer is 0, pointer is never dereferenced.

author: richardman
author_rank: Frequent Contributor
timestamp: November 20, 2018, 02:45:44 am
content: People need to read a C book (or two) - yes, I wrote one.Anyway, || and && have ALWAYS been sequence points and shortcircuited, since K&R. Heck, since Ritchie's original compiler.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 20, 2018, 01:33:36 pm
content: Quote from: hamster_nz on November 18, 2018, 11:12:18 pmIt was my own stupid fault, you are right, the pointer was not init, only when redraw not on start, how stupid.Thanks for your mental support all.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 20, 2018, 01:41:44 pm
content: Quote from: andersm on November 18, 2018, 02:38:38 pmI like to have my code the fastest i can get and am willing to test the timing for various methods.Only i still have this problem : i can not set my PIC32MX in fast performance mode yet, take a look at this topic :https://www.microchip.com/forums/m404723.aspxThe codes they suggest are not working, seems to be outdated info.So i read :NO Caching turned onNO Prefetch buffer enabled7 FLASH wait states1 SRAM wait states.I only find one thing in the datasheet : BMXWSDRM: CPU Instruction or Data Access from Data RAM Wait State bitnothing about caching and other wait states.I will look a bit into more and maybe make another topic about this.Then i can proof if maybe my code is faster then memset.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 20, 2018, 01:59:45 pm
content: I read i make more problems then i asked for.Dont worry its all good, thanks.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 20, 2018, 06:59:52 pm
content: But yes, memcpy/memset lead to very efficient *inline* code (no call to a library's function) when using optimizations, at least with GCC, so doing the same "by hand" is rarely a good idea. GCC knows how to schedule the instructions in the most efficient way and will do so much more easily if you use memset() than if you devise your own assignments which may be harder for GCC to optimize. Hardly worth it.

author: sokoloff
author_rank: Super Contributor
timestamp: November 20, 2018, 07:13:07 pm
content: NB: you can still memset a portion (4, 8, 16, 32 bytes) at a time if you don't want to pause the program for the whole time.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 21, 2018, 02:04:44 pm
content: Indeed like Anders sayd,only without chip running optimal no point to do testing.

author: cv007
author_rank: Frequent Contributor
timestamp: November 21, 2018, 06:34:15 pm
content: QuoteYou don't have much to do on that chip except set the freq you want.You can simulate the various options, and just use cp0 count to time them. It really doesn't matter what the cpu speed is when simulating this, as you are counting cpu cycles not absolute time.Code:#include <xc.h>#include <stdint.h>#include <string.h>uint8_t screen ;uint32_t cls32(uint32_t addr){uint64_t* p = (uint64_t*) addr;*p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytesreturn (uint32_t)p;}void cls(){uint64_t* p = (uint64_t*) screen;uint32_t i = sizeof(screen)/128;for(; i; i--){*p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes*p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes*p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes*p++ = 0; *p++ = 0; *p++ = 0; *p++ = 0; //4*8bytes = 32bytes}}//volatile so not optimized away and can see in simulatorvolatile uint32_t t_mem, t_mem32, t_cls32, t_cls, t_dma;uint32_t zero = 0;void main(void) {uint32_t i = (uint32_t)screen;uint32_t j = i + sizeof(screen);//memsetuint32_t t = __builtin_mfc0(9, 0);memset(screen, 0, 64*16);t_mem = __builtin_mfc0(9, 0) - t;//memset - 32bytes at a timet = __builtin_mfc0(9, 0);for( ; i<j; memset((void*)i, 0, 32), i+=32);t_mem32 = __builtin_mfc0(9, 0) - t;//cls32 - 32bytes at a timet = __builtin_mfc0(9, 0);i = (uint32_t)screen;j = i + sizeof(screen);for(; i<j; i = cls32(i));t_cls32 = __builtin_mfc0(9, 0) - t;//clst = __builtin_mfc0(9, 0);cls();t_cls = __builtin_mfc0(9, 0) - t;//dmaDCH0SSA = 0x1FFFFFFF & (uint32_t)&zero;DCH0DSA = 0x1FFFFFFF & (uint32_t)screen;DCH0SSIZ = 4;DCH0DSIZ = sizeof(screen);DCH0CSIZ = sizeof(screen);DCH0CONbits.CHPRI = 3;DCH0CONbits.CHEN = 1;DMACONbits.ON = 1;DCH0ECONbits.CFORCE = 1;t = __builtin_mfc0(9, 0);while(DCH0CONbits.CHBUSY);t_dma = __builtin_mfc0(9, 0) - t;for(;;);}//-Os// CP0 count//t_mem = 0xCF (207) = 414 cpu cycles//t_mem32 = 0x2D2 (722) = 1444 cpu cycles//t_cls32 = 0x122 (290) = 580 cpu cycles//t_cls = 0x91 (145) = 290 cpu cycles//t_dma = 0x403 (1027)The dma code may not be correct, but it simulates ok. The memset is probably a bad thing to use in pieces as it takes a bit of code to get going (check alignment, etc). The all-in-one cls is fastest as you can eliminate much looping where cpu cycles are wasted in branching.You don't say what the lcd is driven by, so its not clear whether dma could also be used to send data to the lcd.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 22, 2018, 03:55:03 pm
content: Thank you CV.The diplay is driven by 4 bit mode.I have problems : sometimes i see chinese characters.The whole day its good, then all the sudden it give garbage on screen.So i think its a timing issue, and made the timing very slow, it wont help.Then i doubled my breadboard cables, added extra to be sure.It is so weird if something running all day without problems, then the next day its no good.Its very weird i have a few days wasted on this 12864B displsy.So my question now is : does anyone use this 12864B display in 4-bit parallel mode successfully ?I also readed that that display library, u8g lib also dont support 4 bit mode for this display, it got me thinking, maybe it wont work at all ?I hope anyone can confirm.

author: cv007
author_rank: Frequent Contributor
timestamp: November 22, 2018, 05:45:14 pm
content: QuoteYou will have to be more specific, 12864b probably describes every other lcd panel with those pixel dimensions.

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 26, 2018, 03:09:05 pm
content: Its with ST7920 chipset display from ebay china, i can make a picture tomorow.Only i dont know if the real ST7920 is in there, since the times can be set much faster then this manual :http://www.hpinfotech.ro/ST7920.pdf

author: richardman
author_rank: Frequent Contributor
timestamp: November 27, 2018, 08:09:35 am
content: Some of those LCDs are badly implemented. You sneeze a little and they don't work well. Some times you have a add timing delay between commands...

author: Jan Audio
author_rank: Frequent Contributor
timestamp: November 27, 2018, 10:23:31 am
content: Did i wreck it ?, i did connected it wrong one time.The thing is it works for a day, then problems arise, then next day all good, and repeat.I give up on this display, going for the full color TFT next time.