# HG changeset patch # User Tero Marttila # Date 1283118338 -10800 # Node ID d7eac199d323fd0dd815f591073662f6aff12cd0 # Parent f430b507a8850f88890a89c5b318eef1081285d4 Implement Text_Load/ShowString diff -r f430b507a885 -r d7eac199d323 Makefile --- a/Makefile Sun Aug 29 22:49:32 2010 +0300 +++ b/Makefile Mon Aug 30 00:45:38 2010 +0300 @@ -13,7 +13,7 @@ all: $(PROG).hex -matrix.hex: spi.inc matrix.inc timer.inc delay.inc macros.inc font.inc +matrix.hex: spi.inc matrix.inc timer.inc delay.inc macros.inc font.inc font.def led7seg.hex: spi.inc led7seg.inc adc.inc timer.inc delay.inc macros.inc timer.hex: timer.inc macros.inc diff -r f430b507a885 -r d7eac199d323 font-compile.py --- a/font-compile.py Sun Aug 29 22:49:32 2010 +0300 +++ b/font-compile.py Mon Aug 30 00:45:38 2010 +0300 @@ -50,8 +50,14 @@ # skip return None + + elif len(ascii) == 1 : + print 'read_charblock', 'simplechar', ascii + + else : + ascii = ascii.decode('string_escape') - print 'read_charblock', 'ascii', ascii + print 'read_charblock', 'decodechar', ascii assert len(ascii) == 1 @@ -119,7 +125,7 @@ """ fh.write( - ("; '%s'\n" % ascii) + ("; %r\n" % ascii) + (".db %s\n" % (', '.join(bin(col) for col in cols))) + ("\n") ) @@ -143,9 +149,11 @@ charmap[ascii] = cols print 'compile_fonts', 'read', ascii - - font_start = '0' - font_end = '9' + + # detect min/max syms + syms = charmap.keys() + font_start = min(syms) + font_end = max(syms) assert(ord(font_start) < ord(font_end)) @@ -153,17 +161,20 @@ outf.write( ";; AUTOMATICALLY GENERATED - Do not edit!\n" ";; 8x6 font, '0' - '1', rows-by-col format\n" - + (".equ FONT_8x6_START = %d ; '%s'\n" % (ord(font_start), font_start)) - + (".equ FONT_8x6_END = %d ; '%s'\n" % (ord(font_end), font_end)) + + (".equ FONT_8x6_START = %d ; %r\n" % (ord(font_start), font_start)) + + (".equ FONT_8x6_END = %d ; %r\n" % (ord(font_end), font_end)) + (".equ FONT_8x6_COLS = %d\n" % (6, )) + (".equ FONT_8x6_ROWS = %d\n" % (8, )) + "FONT_8x6:\n" "\n" ) - for char in xrange(ord('0'), ord('9') + 1) : + # default symbol for unknown chars + defsym = charmap['\0'] + + for char in xrange(ord(font_start), ord(font_end) + 1) : ascii = chr(char) - cols = charmap[ascii] + cols = charmap.get(ascii, defsym) write_chardef(outf, ascii, cols) diff -r f430b507a885 -r d7eac199d323 font.inc --- a/font.inc Sun Aug 29 22:49:32 2010 +0300 +++ b/font.inc Mon Aug 30 00:45:38 2010 +0300 @@ -23,17 +23,26 @@ ; test under-range ldi r17, FONT_START cp r16, r17 - brlt f_render_invalid + brlt font_r_invalid ; test over-range ldi r17, FONT_END cp r17, r16 - brlt f_render_invalid + brlt font_r_invalid - ; Locate font char ; compute offset in chars (r16) subi r16, FONT_START + ; ok + rjmp font_r_render + +font_r_invalid: + ; use first sym + ldi r16, 0 + + cbi PORTD, PIND7 + +font_r_render: ; compute offset in bytes (r1:r0) ldi r17, FONT_COLS mul r16, r17 @@ -49,16 +58,15 @@ ; Copy column pixel data ; count columns ldi r16, FONT_COLS -f_render_cpy: +font_r_cpy: ; copy via r17 lpm r17, Z+ st Y+, r17 dec r16 - brne f_render_cpy + brne font_r_cpy -f_render_invalid: ; Done ret diff -r f430b507a885 -r d7eac199d323 font.txt --- a/font.txt Sun Aug 29 22:49:32 2010 +0300 +++ b/font.txt Mon Aug 30 00:45:38 2010 +0300 @@ -1,3 +1,33 @@ +; \x00 +------ +-####- +-#--#- +-#--#- +-#--#- +-#--#- +-####- +------ + +; \x20 +------ +------ +------ +------ +------ +------ +------ +------ + +; ! +--##-- +--##-- +--##-- +--##-- +--##-- +------ +--##-- +--##-- + ; 0 -####- #----# @@ -98,6 +128,76 @@ -----# ----#- +; h +#----- +#----- +#----- +#----- +#-###- +##---# +#----# +#----# + +; e +--##-- +-#--#- +#----# +###### +#----- +#---#- +-###-- +------ + +; l +--##-- +---#-- +---#-- +---#-- +---#-- +---#-- +---#-- +--###- + +; o +------ +------ +------ +-####- +#----# +#----# +#----# +-####- + +; w +------ +------ +------ +#---#- +#---#- +#---#- +#-#-#- +-#-#-- + +; r +------ +------ +#----- +#-##-- +##---- +#----- +#----- +#----- + +; d +----#- +----#- +----#- +-####- +#---#- +#---#- +#---#- +-###-- + ; ------ ------ diff -r f430b507a885 -r d7eac199d323 matrix.inc --- a/matrix.inc Sun Aug 29 22:49:32 2010 +0300 +++ b/matrix.inc Mon Aug 30 00:45:38 2010 +0300 @@ -39,6 +39,17 @@ ; this determines the starting offset for the visible viewport's left edge from the start of the framebuffer in columns matrix_colshift: .byte 1 ; viewport left column offset + +;; Text +; Maximum length of message +.set TEXT_MAXLENGTH = 64 + +; Scrolling speed (kiloticks per frame) +.set TEXT_SPEED = 1 + +text_buffer: .byte TEXT_MAXLENGTH ; display message buffer +text_offset: .byte 1 ; current offset in text + .cseg ;; Normalize the outputs, enable the matrix, and set up buffers @@ -258,3 +269,155 @@ ; done ret +;; Rewinds the currently visible viewport to the beginning of the framebuffer +; This copies the currently visible viewport data to the beginning of the framebuffer and resets the offset +Matrix_ShiftRewind: + ; current view offset + ldi XL, low(matrix_colbuf) + ldi XH, high(matrix_colbuf) + + ; offset + lds r16, matrix_colshift + + ; add + ldi r17, 0 + add XL, r16 + adc XH, r17 + + ; start of framebuffer + ldi YL, low(matrix_colbuf + 0) + ldi YH, high(matrix_colbuf + 0) + + ; viewport width + ldi r17, MATRIX_COLS + +matrix_shiftrew_loop: + ; copy + ld r16, X+ + st Y+, r16 + + ; count + dec r17 + brne matrix_shiftrew_loop + + ; done, reset offset + rjmp MAtrix_ShiftZero + + +;; Load a NUL-terminated ASCII string from PGM into the text buffer +; Input: Z - Address of NUL-terminated ASCII string in PGM +Text_LoadString: + ; Setup + ; storage buffer + ldi YL, low(text_buffer) + ldi YH, high(text_buffer) + + ; max. length + ldi r18, TEXT_MAXLENGTH + +text_loads_loop: + ; Test max length + ; count and check for overflow + dec r18 + brne text_loads_char + + ; Load char + ; force NUL + ldi r16, 0x00 + +text_loads_char: + ; load next char + lpm r16, Z+ + +text_loads_store: + ; Store and test NUL + ; store it + st Y+, r16 + + ; test for NUL + tst r16 + brne text_loads_loop + + ; Update scroll offset + ; reset offset + ldi r17, 0 + sts text_offset, r17 + + ; done + ret + +;; Shows the loaded string of ASCII text on the display, scrolling it horizontally +; Uses font.inc for rendering +; XXX: uses blocking timer sleeps and doesn't return until done +Text_ShowString: + ; Load initial char + ldi XL, low(text_buffer + 0) + ldi XH, high(text_buffer + 0) + + ; load char + ld r16, X+ + push XL + push XH + + ; one column spacing + ldi YL, low(matrix_colbuf + 1) + ldi YH, high(matrix_colbuf + 1) + + ; render to framebuffer + rcall Font_Render + + ; reset viewport + rcall Matrix_ShiftZero + + ; Load next char +text_shows_next: + ; next char + pop XH + pop XL + ld r16, X+ + push XL + push XH + + ; test NUL + tst r16 + breq text_shows_end + + ; offscreen + ldi YL, low(matrix_colbuf + 1 + 6 + 1) + ldi YH, high(matrix_colbuf + 1 + 6 + 1) + + ; render + rcall Font_Render + + ; Animate to next char + ldi r20, 7 + +text_shows_animloop: + ; sleep + ldi XH, high(TEXT_SPEED * 1024) + ldi XL, low(TEXT_SPEED * 1024) + + rcall Timer_Sleep + + ; shift + rcall Matrix_ShiftRight + + ; count + dec r20 + brne text_shows_animloop + + ; Rewind to next char + rcall Matrix_ShiftRewind + + sbi PIND, PIND7 + + ; load next char and animate it in + rjmp text_shows_next + +text_shows_end: + ; Done + pop XH + pop XL + + ret + diff -r f430b507a885 -r d7eac199d323 matrix.s --- a/matrix.s Sun Aug 29 22:49:32 2010 +0300 +++ b/matrix.s Mon Aug 30 00:45:38 2010 +0300 @@ -202,33 +202,23 @@ Main_ScanText: -stxt_start: - ; char to render - ldi r24, 48 ; '0' + ; Constants +stxt_message: ; text to render + .db 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0 ; 'hello world!' - ; Render char -stxt_loop: - ; target buffer - ldi YL, low(matrix_colbuf + 0) - ldi YH, high(matrix_colbuf + 0) - - ; render r24 to Y - mov r16, r24 - rcall Font_Render + ; Load into buffer + ldi ZL, low(stxt_message * 2) + ldi ZH, high(stxt_message * 2) - ; Wait - ldi XH, high(10 * 1024) - ldi XL, low(10 * 1024) - - rcall Timer_Sleep + rcall Text_LoadString - ; Next char - inc r24 - cpi r24, 57 + 1 ; '9' - brsh stxt_start ; start again from zero +sbi PORTD, PIND7 - ; render this char - rjmp stxt_loop + ; Display + rcall Text_ShowString + + ; Done + ret Main: init: