![]() |
Forum Index : Microcontroller and PC projects : MM2, MM+: SSD1306 OLED loadable drivers updated
![]() ![]() |
|||||
Author | Message | ||||
ajkw Senior Member ![]() Joined: 29/06/2011 Location: AustraliaPosts: 290 |
Sorry help needed. When I clean and build I get these errors. Any ideas please. Please note, I had to move Cfunctions.h up a folder level so it could be found otherwise there was a error for that as well. Also in the code view there is a error that starg.h cannot be found. Anthony. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10013 |
Replace cfunction.h with attached CFunctions.zip Can't help with srdarg.h as that should be standard C |
||||
ajkw Senior Member ![]() Joined: 29/06/2011 Location: AustraliaPosts: 290 |
stdarg.h was not a problem in the end. Thanks for the updated cfunction.h, all has compiled fine. I can now draw to every pixel on my OLED ![]() ![]() ![]() ![]() ![]() Step 2 is sending the contrast command and byte value. With the all-Basic-driver you can access an internal routine of the driver (oled_write_command) to send it but am really not sure how you would get to an internal sub of a csub from MMbasic. There are some other commands that can be sent that can scroll the screen vertically, turn it on/off (saving the ram for when it comes back on) and inverse as well. I'll keep looking but any help appreciated. Anthony. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10013 |
Change the main function so it takes an extra parameter. Use this to decide the function you want to use. init, sendcommand, senddata Below is the main function for the SD CFunction as an example void main(long *mode, char *p1, long *p2, long *p3, long *p4){ char fn[16]; int j,k,l,m,nextsector, loopend; DWORD secstart,secoffset; FATFS *FatFs; DIR *DIRFS; FILINFO *fileinfo; char *s, *p; #ifndef useSPI2 CFuncRam[17]=SPIBRG; //save any user SPI setup CFuncRam[18]=SPICON; CFuncRam[19]=SPICON2; #endif if(ExtCurrentConfig[Option->SDCARD_CS] == EXT_BOOT_RESERVED){ SPICON=0x8260; SPICON2=0xC00;// this is defined in IOPorts.h SPIBRG=Option->pins[0]; } FatFs=(void*)&CFuncRam[20]; DIRFS=(void*)&CFuncRam[30]; fileinfo=(void*)&CFuncRam[40]; if(*mode==1 || *mode==6 || *mode==7 || *mode==4) { for(l=0;l<=p1[0];l++)fn[l]=p1[l]; fn[p1[0]+1]=0; if(*mode==6)ClearProgram(); } if(*mode==1 || *mode==6 || *mode==7 || *mode==4){//initialise and mount the SDcard if(ExtCurrentConfig[Option->SDCARD_CS] != EXT_BOOT_RESERVED)errstring(FR_NOT_MOUNTED); if(ExtCurrentConfig[SPI_OUT_PIN] != EXT_BOOT_RESERVED) { ExtCfg(SPI_OUT_PIN, EXT_DIG_OUT, 0); ExtCfg(SPI_OUT_PIN, EXT_RESERVED, 0); ExtCfg(SPI_INP_PIN, EXT_DIG_IN, 0); ExtCfg(SPI_INP_PIN, EXT_RESERVED, 0); ExtCfg(SPI_CLK_PIN, EXT_DIG_OUT, 0); ExtCfg(SPI_CLK_PIN, EXT_RESERVED, 0); } SPI_PPS_OPEN; SPICON=0x8260; SPICON2=0xC00;// this is defined in IOPorts.h filepos=0; errstring(pf_mount(FatFs)); } if(*mode==1){ //open a file errstring(pf_open(FatFs,&fn[1])); } if(*mode==2 ){ //read a file if(*p2>=0){ errstring(pf_lseek(FatFs,*p2)); } if(*p3<256){ //return as a string errstring(pf_read(FatFs,p1+1,*p3,&j )); p1[0]=j; } else { errstring(pf_read(FatFs,p1,*p3,&j )); } *p4=j; } if(*mode==3){ if(*p2<0)*p2=filepos; filepos+=*p3; secstart= *p2 & 0xFFFFFE00; //point to sector start secoffset= *p2 & 0x1FF; //offset into the sector errstring(pf_lseek(FatFs,secstart)); s=p1; if(*p3<256) s=p1+1; //move past the length byte if a string if(secstart!=*p2){ //not sector aligned p=GetTempMemory(512); errstring(pf_read(FatFs,p,512,&j )); errstring(pf_lseek(FatFs,secstart)); //read OK if(512 < *p3+secoffset){ loopend=512; nextsector=*p3+secoffset-512; } else { loopend=*p3+secoffset; nextsector=0; } for(k=secoffset;k< loopend ;k++){ p[k]=s[k-secoffset]; //write the new data into the buffer } errstring(pf_write(FatFs,p,j,&j )); *p4=j-secoffset; if(*p4>*p3)*p4=*p3; if(nextsector){ errstring(pf_write(FatFs,s+(*p3-nextsector),nextsector,&j )); *p4+=j; } errstring(pf_write(FatFs,0,0,&j )); //finish the write } else { errstring(pf_write(FatFs,s,*p3,&j )); *p4=j; errstring(pf_write(FatFs,0,0,&j )); } } if(*mode==4){ errstring(pf_opendir(FatFs,DIRFS,&fn[1])); } if(*mode==5){ errstring(pf_readdir(FatFs,DIRFS,fileinfo)); if(fileinfo->fattrib==22){ errstring(pf_readdir(FatFs,DIRFS,fileinfo)); } if(fileinfo->fname[0]!=0){ k=1; if(fileinfo->fattrib & 0x10){ p1[1]='<'; p1[2]='D'; p1[3]='i'; p1[4]='r'; p1[5]='>'; k=6; } for(j=0;j<12;j++)p1[j+k]=fileinfo->fname[j]; p1[0]=mystrlen(fileinfo->fname)+k-1; } else p1[0]=0; } if(*mode==6){//load program from SDcard s=p=GetTempMemory(51200); k=1; l=0; errstring(pf_open(FatFs,&fn[1])); errstring(pf_lseek(FatFs,0)); do { errstring(pf_read(FatFs,s,128,&j)); for(m=0;m<j;m++){ if(s[m]==0 && k){ j=m; k=0; } } s+=j; l+=j; } while(j==128); p[l]=0; p[l+1]=0; SaveProgramToFlash(p,0); } if(*mode==7){ //save program to SDcard errstring(pf_open(FatFs,&fn[1])); errstring(pf_lseek(FatFs,0)); char *b=GetTempMemory(256); char *p=(void *)ProgFlash; while(!(*p == 0 || *p == 0xff)) { // normally a LIST ends at the break so this is a safety precaution if(*p == 1) { p = llist(b, p); // otherwise expand the line k=mystrlen(b); b[k++]=13; b[k++]=10; errstring(pf_write(FatFs,b,k,&j )); if(p[0] == 0 && p[1] == 0) break; // end of the listing ? } } b[0]=0; b[1]=0; errstring(pf_write(FatFs,b,2,&j )); errstring(pf_write(FatFs,0,0,&j )); } if(*mode==0){ Option->SDCARD_CS=*p1; if(p2!=NULL){ Option->pins[0]=*p2; } else { Option->pins[0]=2; } if(ExtCurrentConfig[Option->SDCARD_CS] != EXT_BOOT_RESERVED){ ExtCfg(Option->SDCARD_CS,EXT_DIG_OUT,0); ExtCfg(Option->SDCARD_CS,EXT_BOOT_RESERVED,0); } PinSetBit(Option->SDCARD_CS, TRISCLR); PinSetBit(Option->SDCARD_CS, LATSET); } #ifndef useSPI2 SPIBRG=CFuncRam[17]; //restore user (or my) setup SPICON=CFuncRam[18]; SPICON2=CFuncRam[19]; #endif } Edited 2021-11-03 23:02 by matherp |
||||
ajkw Senior Member ![]() Joined: 29/06/2011 Location: AustraliaPosts: 290 |
Thanks again Peter. I can now send a command byte, and associated data byte where required, to my 1.3" 12C SH1106 from mmbasic via the loadable driver. In this video mmbasic only draws the initial Hello World screen and then the rest is done via commands to the OLED. You can change the Contrast (0 - 256 but 0 is not black) Turn screen off/on (preserving the ram memory for instant on) Inverse the display and Scroll vertically up or down. The screen wraps around. Particularly with the contrast and on/off functions I will now be able to significantly reduce the burn-in that I have experienced with these screens. ![]() Cheers, Anthony. Video is a link to a MS One drive file. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10013 |
Nice job - always great to see someone getting to grips with CFunctions so effectively. Please do post your code for others to see and use |
||||
ajkw Senior Member ![]() Joined: 29/06/2011 Location: AustraliaPosts: 290 |
I don't know if I have fully got to grips with cfunctions however I was able to make some changes and managed to compile them. Works for me but I have had a couple of CPU exceptions from MMbasic particularly when first copying a new version of the driver. Seems to settle. Probably can be done better, hope it works for somebody else - no guarantee or warranty. I have added a parameter that is passed to the driver to control its mode. sh1106ext(x,i2c addr,pin,pin,height,rot) 0 intialise lcd, eg sh1106ext(0,&h3c,15,16,64,1) 1 write 1 byte to Oled eg sh1106ext(1,&h3c,&hae) - turn off 2 write 2 bytes to Oled eg sh1106ext(2,&h3c,&h81,&h7f) - set contrast AE/AF Screen on / off 81 is contrast with data of 00 - FF or 0 -255 40-7F is screen offset A6/A7 is Normal/Inverse ![]() Previously to solve the 2 pixel offset I had I simply added 2 to x in this sub. void OLED_setxy(int x,int y){ x+=2 ; //move right 2 bytes oled_write_command(0xB0+y) ; //set page address oled_write_command(0x10 | ((x>>4) & 0x0F)) ; //set high col address oled_write_command(x & 0x0f) ; //set low col address Library save it, you can get CPU Exceptions if used in normal program memory. SH1106ext.zip Let me know if it works for you. Anthony. Edited 2021-11-06 17:24 by ajkw |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |