glcd-Nokia3310.lib 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. Copyright =
  2. Www =
  3. Email =
  4. Comment = Nokia 3310 Graphic Display Library
  5. Libversion = 1.0
  6. Date = February 2014
  7. Statement =
  8. History=
  9. [_GLCD]
  10. $EXTERNAL _LPMBYTE,WAITMS
  11. _Init_lcd:
  12. _LCD_INIT:
  13. _SET_DISPLAY:
  14. *#If varexist("_GLCD_PORT_RST")
  15. * cbi _GLCD_PORT_RST,_glcd_rst ; reset low
  16. #Endif
  17. Ldi r24,100 ; reset 100 mS
  18. Clr R25
  19. * Call _Waitms
  20. *#If varexist("_GLCD_PORT_RST")
  21. * sbi _GLCD_PORT_RST,_glcd_rst ; reset high
  22. #Endif
  23. * cbi _GLCD_PORT_SCL,_glcd_scl ; clock low
  24. *#If varexist("_GLCD_PORT_CS1")
  25. * sbi _GLCD_PORT_CS1,_glcd_cs1 ; disable chip
  26. #Endif
  27. ldi r24,&H21 ; Extended command mode
  28. rcall _gwrite_cmd
  29. ldi r24,&HC8 ; Middle contrast (&H80...&HFF)
  30. rcall _gwrite_cmd
  31. ldi r24,&H06 ; Temperature setting
  32. rcall _gwrite_cmd
  33. ldi r24,&H13 ; Bias 1:48
  34. rcall _gwrite_cmd
  35. ldi r24,&H20 ; Normal command mode
  36. rcall _gwrite_cmd
  37. ldi r24,&H0C ; Uninverted Screen
  38. rcall _gwrite_cmd
  39. Ret
  40. ; send command or data to LCD =====================================================================
  41. _gwrite_cmd:
  42. _Lcd_control:
  43. * cbi _GLCD_PORT_a0,_glcd_a0 ; command - DC=0
  44. Rjmp _Gwrite_DataMisc ; same code
  45. _gwrite_data:
  46. * sbi _GLCD_PORT_a0,_glcd_a0 ; data - DC=1
  47. * #IF varexist("Negative_lcd")
  48. * #IF Negative_lcd > 0
  49. com r24 ; Inverted Screen
  50. #Endif
  51. #Endif
  52. *#If varexist("Rotate_lcd")
  53. *#If Rotate_lcd>0
  54. mov r25,r24
  55. bst r25,0
  56. bld r24,7
  57. bst r25,1
  58. bld r24,6
  59. bst r25,2
  60. bld r24,5
  61. bst r25,3
  62. bld r24,4
  63. bst r25,4
  64. bld r24,3
  65. bst r25,5
  66. bld r24,2
  67. bst r25,6
  68. bld r24,1
  69. bst r25,7
  70. bld r24,0
  71. #Endif
  72. #Endif
  73. _gwrite_datamisc:
  74. push r23
  75. *#If varexist("_GLCD_PORT_CS1")
  76. * cbi _GLCD_PORT_CS1,_glcd_cs1 ; enable chip - CS=0
  77. #Endif
  78. ldi r25,8 ; 8 bits
  79. _gwrite_datamisc8:
  80. lsl r24 ; bit into carry
  81. brcc _gwrite_datamisc_0 ; bit was 0
  82. * sbi _GLCD_PORT_SI, _glcd_si ; set bit
  83. rjmp _gwrite_datamisc_next
  84. _gwrite_datamisc_0:
  85. * cbi _GLCD_PORT_SI, _glcd_si ; clear bit
  86. _gwrite_datamisc_next:
  87. @genus(1)
  88. * sbi _GLCD_PORT_SCL,_glcd_scl ; SCL=1
  89. @genus(1)
  90. * cbi _GLCD_PORT_SCL,_glcd_scl ; SCL=0
  91. dec r25
  92. brne _gwrite_datamisc8 ; do 8 bits
  93. *#If varexist("_GLCD_PORT_CS1")
  94. * sbi _GLCD_PORT_CS1,_glcd_cs1 ; disable chip - CS=1
  95. #Endif
  96. pop r23
  97. ret
  98. ;there is no difference between clear text and clear graphics!==================================================
  99. _clear_graph:
  100. _clear_text:
  101. Ldi r24,&H20 ; normal command mode
  102. Rcall _gwrite_cmd
  103. Ldi r24,&H40 ; row 0
  104. Rcall _gwrite_cmd
  105. Ldi r24,&H80 ; column 0
  106. Rcall _gwrite_cmd
  107. ldi r16,0
  108. Ldi r17,84 ; 84 pages
  109. Clr r24
  110. _clear_graph1:
  111. rcall _GWrite_data ; write 0
  112. Dec r17
  113. Brne _clear_graph1 ; write 84 times
  114. Inc r16
  115. Cpi r16,6 ; 6 rows
  116. Brne _clear_graph1
  117. ret
  118. ;character in r24 ============================================================================
  119. ;in order to draw multiple fontsizes the fontdata stores the
  120. ;number of bytes and the number of rows.
  121. ; .db 1,8,8,0 , means 1 row, 8 bits width, block size total, last param is spacing for true type fonts
  122. _gwrite_lcdchar:
  123. $EXTERNAL _LPMBYTE, _MUL8, _GLOCATE
  124. Push r30 ; save registers
  125. Push r31
  126. lds r21,{___lcdrow} ; the row
  127. push r21 ; save it
  128. lds r7,{___lcdcol}
  129. Lds r30 ,{___fonttable} ; start of font data
  130. Lds r31 ,{___fonttable +1}
  131. #IF _ROMSIZE>65536
  132. * In R3,RAMPZ ; save RAMPZ page
  133. * Lds r0,{___fonttable +2} ; load page number for the used font
  134. * Out RampZ,r0 ; set page number
  135. #ENDIF
  136. Call _lpmbyte ; Get Y Bytes 1 For Example
  137. mov r18,r0 ; save Y
  138. call _lpmbyte ; get X bytes , 8 for an 8*8 font
  139. mov r19,r0 ; save X
  140. call _lpmbyte ; get blocksize
  141. mov r16,r0 ; in accu
  142. call _lpmbyte ; get blocksize
  143. mov r22,r0 ; spacing, should be 1 or 2
  144. subi r24,32 ; chars start at 32 (space)
  145. mov r20,r24
  146. call _mul8 ; get offset
  147. Add r30,r20 ; add to start of font data
  148. Adc r31,r21
  149. #IF _ROMSIZE>65536
  150. rcall _glcd_rampcheck_inc ; check boundery
  151. #ENDIF
  152. ;--------optional true type option ----
  153. clr r12
  154. ;we need to determine the left space of the character so that we can skip these zeros
  155. ;we store the left in r15
  156. clr r1 ; we need a reg with zero
  157. mov r14,r18 ; Y bytes
  158. cpi r22,0 ; test for 0
  159. breq _gwrite_lcdchar_rows ; it is 0 so skip this option
  160. clr r13
  161. dec r13 ; put 255 into r13
  162. mov r12,r13 ; and also in r12
  163. _truetypey:
  164. clr r15
  165. mov r16,r19 ; x bits
  166. _trueTypeX:
  167. call _lpmbyte ; get data in r0
  168. breq _trueType1 ; it is zero so skip
  169. dec r16 ; adjust
  170. Add r30,r16 ; skip the rest of the bytes
  171. Adc r31,r1 ; add zero
  172. #IF _ROMSIZE>65536
  173. rcall _glcd_rampcheck_inc ; check boundery
  174. #ENDIF
  175. rjmp _truetype2 ; skip code
  176. _truetype1:
  177. inc r15 ; inc zero bytes counter
  178. dec r16
  179. brne _trueTypeX ; check the other x bytes
  180. _truetype2:
  181. cp r15,r13 ; check the previous with the new value
  182. brsh _truetype3 ; if r15 same or higher then we skip
  183. mov r13,r15 ;save the smallest in r13
  184. _truetype3:
  185. dec r14 ; next row of bytes
  186. brne _trueTypeY ; check again for Y
  187. ;now r13 contains the number of left bytes to skip
  188. ;we now check the same in reverse so we get the rgt space and the Z pointe is at the right pos
  189. mov r14,r18 ; Y bytes
  190. _truetypeyr:
  191. clr r15
  192. mov r16,r19 ; x bits
  193. _truetypexr:
  194. sbiw r30,1 ; dec Z pointer
  195. #IF _ROMSIZE>65536
  196. rcall _glcd_rampcheck_dec ; check boundery
  197. #ENDIF
  198. lpm ; get byte
  199. tst r0 ; test for zero
  200. breq _truetype1R
  201. dec r16
  202. sub r30,r16
  203. sbc r31,r1
  204. #IF _ROMSIZE>65536
  205. rcall _glcd_rampcheck_dec ; check boundery
  206. #ENDIF
  207. rjmp _truetype2R
  208. _truetype1r:
  209. inc r15
  210. dec r16
  211. brne _truetypeXR
  212. _truetype2r:
  213. cp r15,r12
  214. brsh _truetype3R
  215. mov r12,r15
  216. _truetype3r:
  217. dec r14
  218. brne _truetypeYR
  219. ;now R12 contains right space
  220. cp r13,r19 ; check if left is empty char
  221. brne _gwrite_lcdchar_rows ; no so continue
  222. mov r13,r22 ; use defined spaces since a space would be all zero
  223. clr r12 ; clear right space otherwise it mess up
  224. _gwrite_lcdchar_rows:
  225. sts {___lcdcol},r7 ; restore column
  226. mov r23,r19 ; x bits 8 12 or 16
  227. sub r23,r12 ; minus right space
  228. _gwrite_lcdchar1:
  229. lds r20,{___lcdcol}
  230. lds r21,{___lcdrow}
  231. push r21
  232. *#If varexist("Rotate_lcd")
  233. *#If Rotate_lcd>0
  234. push r25
  235. ldi r25,7 ; row position
  236. sub r25,r21
  237. mov r21,r25
  238. pop r25
  239. #Endif
  240. #Endif
  241. call _Glocate ; set right position ------------------------------------------------ LOCATE
  242. pop r21
  243. cpi r22,0 ; test for 0
  244. breq _gwrite_lcdchar2 ; normal font
  245. tst r13 ; check spaces
  246. breq _gwrite_lcdchar2 ; if zero then skip
  247. mov r21,r13 ; skips
  248. _gwrite_lcdcharSkips:
  249. call _lpmbyte ; get byte
  250. dec r21
  251. brne _gwrite_lcdcharSkips
  252. sub r23,r13 ; adjust x bits
  253. _gwrite_lcdchar2:
  254. call _lpmbyte ; get byte
  255. mov r24,r0
  256. lds r21,{___LCDrev} ; reverse display?
  257. tst r21
  258. breq _gwrite_lcdchar3
  259. com r24 ; not 0 so complement
  260. _gwrite_lcdchar3:
  261. lds r20,{___lcdcol}
  262. cpi r20,85 ; is it Horisontal offscreen?
  263. brge _skip_offscreen
  264. *#If varexist("Rotate_lcd")
  265. *#If Rotate_lcd>0
  266. push r24
  267. ldi r24,83 ; col position
  268. sub r24,r20
  269. sbr r24,$80
  270. call _GWrite_cmd
  271. pop r24
  272. cpi r20,84 ; is it Horisontal offscreen?
  273. brge _skip_offscreen
  274. #Endif
  275. #Endif
  276. call _GWrite_data ; write char data ------------------------------------------- WRITE DATA
  277. _skip_offscreen:
  278. lds r21,{___lcdcol} ; increase column
  279. inc r21
  280. sts {___lcdcol},r21
  281. dec r23 ; dec bits dones
  282. brne _gwrite_lcdchar2 ; write all X bytes
  283. add r30,r12 ; move z pointer with right space so we keep the proper pointer value
  284. adc r31,r1 ; r1 was 0
  285. #IF _ROMSIZE>65536
  286. rcall _glcd_rampcheck_inc ; check boundery
  287. #ENDIF
  288. ;now add some space
  289. cpi r22,0 ; is it true type?
  290. breq _gwrite_lcdchar5 ; no so exit
  291. lds r21,{___LCDrev} ; reverse display?
  292. mov r23,r22 ; right space columns
  293. _gwrite_rightspace:
  294. clr r24
  295. tst r21 ; test inverse
  296. breq _gwrite_rightspace2 ; skip if normal
  297. com r24 ; inverse
  298. _gwrite_rightspace2:
  299. call _GWrite_data ; write char data -----------------------------------------------------------
  300. dec r23
  301. brne _gwrite_rightspace
  302. lds r21,{___lcdcol} ; increase column
  303. add r21,r22
  304. sts {___lcdcol},r21
  305. _gwrite_lcdchar5:
  306. lds r21,{___lcdrow} ; inc row
  307. inc r21
  308. sts {___lcdrow},r21
  309. dec r18 ; dec rows
  310. breq _gwrite_lcdchar4 ; all done so skip code
  311. rjmp _gwrite_lcdchar_rows ; for all rows
  312. _gwrite_lcdchar4:
  313. pop r21 ; get original row back
  314. sts {___lcdrow},r21 ; restore
  315. #IF _ROMSIZE>65536
  316. * OUT RAMPZ, R3 ; restore RAMPZ for next character
  317. #ENDIF
  318. Pop R31
  319. Pop R30
  320. ret
  321. #IF _ROMSIZE>65536
  322. _glcd_rampcheck_inc:
  323. Brcc _glcd_rampcheck_inc1 ; no boundery
  324. In R2,RAMPZ
  325. Inc R2
  326. Out RAMPZ,R2
  327. _glcd_rampcheck_inc1:
  328. ret
  329. _glcd_rampcheck_dec:
  330. Brcc _glcd_rampcheck_dec1 ; no boundery
  331. In R2,RAMPZ
  332. Dec R2
  333. Out RAMPZ,R2
  334. _glcd_rampcheck_dec1:
  335. ret
  336. #ENDIF
  337. [END]
  338. [_GLOCATE]
  339. ; called with R21 row R20 col
  340. _glocate:
  341. Dec r20 ; adjust column
  342. Dec r21 ; adjust row
  343. _setcol:
  344. Ldi r24,&H20 ; normal command mode
  345. Rcall _gwrite_cmd
  346. ldi r24,&H40
  347. add r24,r21
  348. rcall _GWrite_cmd ; row address
  349. ldi r24,&H80
  350. add r24,r20
  351. rjmp _GWrite_cmd ; column address
  352. [END]
  353. ;r22 - x2
  354. ;r20- x1
  355. ;r21 - y
  356. [_CLS_LINE]
  357. $EXTERNAL _GLOCATE
  358. _Cls_Line:
  359. rcall _glocate ; select right location
  360. _Cls_Line_loop:
  361. lds r24,{___LCDrev} ;read value to use from reverse
  362. rcall _gwrite_data ; clear
  363. ; inc r21 >>> Edit by MWS <<<
  364. ; cp r21,r22 >>> Edit by MWS <<<
  365. inc r20 ;>>> Added by MWS <<<
  366. cp r20,r22 ;>>> Added by MWS <<<
  367. brlo _Cls_Line_loop
  368. Ret
  369. [END]
  370. [_getbytefromrom_eprom]
  371. $EXTERNAL _READEEPROM, _LPMBYTE
  372. ; get a byte from code ROM or from EEPROM
  373. ;you could write code to get the data from an external EEPROM
  374. _getbytefromrom:
  375. Tst R23 ; is it 0 ?
  376. Breq _GetByteFromROM1 ; yes get from flash
  377. Clr R26 ; point to R0
  378. Clr R27
  379. jmp _ReadEEPROM1 ; get data in r0
  380. _getbytefromrom1:
  381. jmp _LpmByte ; returns data in r0
  382. [END]
  383. [_showpicture]
  384. $EXTERNAL _DIV8 , _MUL8 , _GETBYTEFROMROM_EPROM , _GLOCATE
  385. ; RLE encoded. When the data after the byte is AA, it means it is a repeating
  386. ; sequence and the byte after it hold the number of repeats
  387. ; AB, AC , AF,AA, EE means show AB,AC and AF EE times
  388. ; needs more code but needs less picture data!
  389. ; show a picture with ShowPic x,y , label
  390. ; y+2 holds X, y+1 holds Y , y+0 holds EPROM/ROM flag, Z points to picture data
  391. ; The calling code uses for example
  392. ; clr r20
  393. ; clr r21
  394. ; st -y,r20 this way it will be referred to with y+4
  395. ; st -y,r21 and y+3
  396. ; ldi zl,low(plaatje * 2) to point to picture data
  397. ; ldi zh,high(plaatje * 2)
  398. ; in the SED data is stored column after column with 8 rows of data
  399. _showpicture:
  400. CLR R1 ; repeats
  401. CLR R2 ; char to repeat
  402. clr r3 ; temp register
  403. ld r23,y+ ; 255 means get from EEPROM, 0 means get from flash
  404. Call _getbytefromrom ; Get Height Of Picture In Pixels
  405. Mov r16,r0 ;
  406. Ldi r20,8
  407. Call _Div8 ; divide by 8
  408. St -y,r16 ; y+2 number of rows to do
  409. Call _getbytefromrom ; Get Width Of Picture In Pixels
  410. st -y,r0 ; number of cols into y+1
  411. st -y,r0 ; number of cols into y+0
  412. ld r16,y+3 ; get Y pos
  413. Ldi R20 , 8
  414. Call _div8 ; Correct
  415. st y+3,r16 ; save row
  416. _showpicture1:
  417. ld r20,y+4 ; get X
  418. mov r15,r20
  419. ld r21,y+3 ; get Y
  420. Rcall _setcol ; set address -----------------------------------------------
  421. _showpicture2:
  422. ; *** New RLE encoding routine ***
  423. cp r1,r3 ; is repeats 0 ?
  424. brne _ShowPicture8 ; no
  425. Call _getbytefromrom ; Get Next Char
  426. mov r2,r0 ; save char
  427. mov r24,r0
  428. cpi r24,&HAA ; test for repeat char must always be shown
  429. breq _ShowPicture9 ; we need to show AA
  430. Call _getbytefromrom ; Is It Rle print
  431. mov r24,r0
  432. cpi r24,&HAA ; is it a RLE encoded char?
  433. breq _ShowPicture10 ; yes
  434. sbiw R30,1 ; no readjust pointer to graphic data
  435. rjmp _ShowPicture11 ; show it
  436. _showpicture9:
  437. adiw r30,1 ; skip 0
  438. rjmp _ShowPicture11
  439. _showpicture8:
  440. ;we are repeating
  441. dec r1 ; adjust repeat counter
  442. breq _showpicture2
  443. rjmp _ShowPicture11 ; show it
  444. _showpicture10:
  445. Call _getbytefromrom ; Get Number Of Repeats
  446. Mov r24,r0
  447. Tst r24 ; is it zero?
  448. Brne _showpicture15 ; no a real sequenc
  449. Sbiw r30,2 ; adjust pointer
  450. Rjmp _showpicture11 ; skip somebytes
  451. _showpicture15:
  452. mov r1,r0 ; save number of repeats
  453. _showpicture11:
  454. mov r24,r2
  455. ; *** end of RLE code ***
  456. ;--------------
  457. lds r25,{___LCDrev} ; reverse display?
  458. tst r25
  459. breq _showpicture12
  460. com r24
  461. _showpicture12:
  462. ;---------------
  463. push r24
  464. mov r20,r15
  465. ldd r21,y+3
  466. *#If varexist("Rotate_lcd")
  467. *#If Rotate_lcd>0
  468. push r20
  469. push r21
  470. ldi r24,83
  471. sub r24,r20
  472. mov r20,r24
  473. ldi r24,5
  474. sub r24,r21
  475. mov r21,r24
  476. #Endif
  477. #Endif
  478. Rcall _setcol ; set address -----------------------------------------
  479. *#If varexist("Rotate_lcd")
  480. *#If Rotate_lcd>0
  481. pop r21
  482. pop r20
  483. #Endif
  484. #Endif
  485. pop r24
  486. cpi r20,84 ; is it Horisontal offscreen?
  487. brge _offscreen
  488. cpi r21,7 ; is it Vertical offscreen?
  489. brge _offscreen
  490. rcall _Gwrite_Data ;-------------------------------------------------------
  491. _offscreen:
  492. inc r15
  493. ld r24,y+1 ; get column counter
  494. dec r24
  495. st y+1,r24 ; save col counter
  496. brne _ShowPicture2 ; for all columns
  497. ld r24,y+3 ; next page
  498. inc r24
  499. st y+3,r24
  500. ld r24,y+0 ; get num of cols
  501. st y+1,r24 ; save for the new row
  502. ld r24,y+2 ; get row counter
  503. dec r24
  504. st y+2,r24
  505. brne _showpicture1a ; for all rows
  506. adiw r28,5 ; adjust soft stack
  507. Ret
  508. _showpicture1a:
  509. Rjmp _showpicture1
  510. [END]