diff --git a/colors.S b/colors.S index 0b77aee..397f3cf 100644 --- a/colors.S +++ b/colors.S @@ -1,17 +1,7 @@ #include "colors.h" +#define DIMM_FACTOR 3 .section ".rodata","a" -screendata_tmpl: - .global screendata_tmpl - .byte _red - .byte _magenta - .byte _blue - .byte _cyan - .byte _green - .byte _yellow -screendataend_tmpl: - .byte 0xff - ;; color definitions according to ;; https://learn.sparkfun.com/tutorials/lilypad-protosnap-plus-activity-guide/3-custom-color-mixing colors: @@ -20,29 +10,29 @@ colors: off: .byte 0x00, 0x00, 0x00, 0 blue: - .byte 0x00, 0x00, 0xff, 0 + .byte 0x00>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0 green: - .byte 0x00, 0xff, 0x00, 0 + .byte 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0 orange: - .byte 0xff, 0x80, 0x00, 0 + .byte 0xff>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0 rose: - .byte 0xff, 0x00, 0x80, 0 + .byte 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0 magenta: - .byte 0xff, 0x00, 0xff, 0 + .byte 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0 violet: - .byte 0x80, 0x00, 0xff, 0 + .byte 0x80>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0 azure: - .byte 0x00, 0x80, 0xff, 0 + .byte 0x00>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0 cyan: - .byte 0x00, 0xff, 0xff, 0 + .byte 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0 springgreen: - .byte 0x00, 0xff, 0x80, 0 + .byte 0x00>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x80>>DIMM_FACTOR, 0 chartreuse: - .byte 0x80, 0xff, 0x00, 0 + .byte 0x80>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0 yellow: - .byte 0xff, 0xff, 0x00, 0 + .byte 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0 white: - .byte 0xff, 0xff, 0xff, 0 + .byte 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0xff>>DIMM_FACTOR, 0 red: - .byte 0xff, 0x00, 0x00, 0 + .byte 0xff>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0x00>>DIMM_FACTOR, 0 diff --git a/main.S b/main.S index 318e5d8..977cf2d 100644 --- a/main.S +++ b/main.S @@ -1,5 +1,3 @@ - .file "main.S" - #include #include "colors.h" @@ -8,20 +6,23 @@ #define SR r2 +;; ---------------------------------------------------- +;; --- r4, r5 and r6 must not be used for any other --- +;; --- purpose --- +;; required for communication between drawscreen and isr #define SIGNAL_REGISTER r4 #define SIGNAL_OCTET_DONE 0x01 #define SIGNAL_ISR_ENABLE 0x02 #define SIGNAL_ALL_DATA_DONE 0x04 +#define SIGNAL_INIT_VALUE SIGNAL_OCTET_DONE - -#define DATA_NEXT_ADDRESS_REGISTER r7 -#define DATA_END_ADDRESS_REGISTER r8 +;; required for handover of data between drawscreen and isr #define DATA_REGISTER r5 -#define NEXT_DATA_REGISTER r9 +;; required for sequencing of isr #define BIT_COUNTER_REGISTER r6 #define BIT_COUNTER_INIT_VALUE 0x01 - +;; ---------------------------------------------------- ;; 2.48us @@ -52,11 +53,13 @@ .section ".data" screendata: - .rept 6 + .rept 60 ;; number of leds in hardward .byte 0 .endr screendataend: .byte 0xff +data_forward_pointer: + .word 0 ;; .text is the name of the section, it is a hint for the linker to @@ -65,6 +68,7 @@ screendataend: ;; @progbits is a hint for the linker to allocate this section into ;; program memory (flash) .section ".text","ax",@progbits +;; ---------------------------------------------------- _start: ;; disable watchdog mov.w #WDTPW|WDTHOLD,&WDTCTL @@ -78,21 +82,6 @@ _start: ;; initialize stack pointer with value from linker mov.w #__stack, SP - ;; ---------------------------------------------- - ;; load data from template area in rom into ram - ;; uses arbitrary register before loading registers - ;; for later use - mov.w #screendata, r7 - mov.w #screendataend, r8 - mov.w #screendata_tmpl, r9 -_start_load_next: - mov.b @r9, @r7 - inc.w r7 - inc.w r9 - cmp.w r7, r8 - jnz _start_load_next - ;; ---------------------------------------------- - init: ;; configuration of GPIO Ports ;; BIT0: data bit @@ -119,6 +108,103 @@ init: mov.w #OUTMOD_7,&TA1CCTL1 mov.w #OUTMOD_7,&TA1CCTL2 + ;; make sure the isr will not immediately start + mov.b #SIGNAL_INIT_VALUE, SIGNAL_REGISTER + + ;; start timer in up mode + bis.w #MC0,&TA1CTL + ;; enable interrupts + eint + + +;; ---------------------------------------------------- +mainloop: + call #forwardscreen_init + call #resetscreen + +mainloop_draw: + call #drawscreen + call #forwardscreen + + call #wait + + jmp mainloop_draw + + +;; ---------------------------------------------------- +wait: + push r11 + push r12 + + mov.w #0x0040, r11 +wait_continue_1: + mov.w #0xffff, r12 +wait_continue_2: + dec.w r12 + jnz wait_continue_2 + dec.w r11 + jnz wait_continue_1 + + pop r12 + pop r11 + ret + + +;; ---------------------------------------------------- +forwardscreen_init: + mov.w #screendata, &data_forward_pointer + ret + +;; ---------------------------------------------------- +forwardscreen: + push r8 + push r10 + + mov.w #screendataend, r8 + mov.w data_forward_pointer, r10 + mov.b #_off, @r10 + inc.w r10 + mov.b #_green, @r10 + cmp.w r10, r8 + jnz forwardscreen_done + mov.w #screendata, r10 +forwardscreen_done: + mov.w r10, data_forward_pointer + + pop r10 + pop r8 + ret + + +;; ---------------------------------------------------- +resetscreen: + push r7 + push r8 + + ;; reset screen data + mov.w #screendata, r7 + mov.w #screendataend, r8 +resetscreen_continue: + mov.b #_off, @r7 + inc.w r7 + cmp.w r7, r8 + jnz resetscreen_continue + + pop r8 + pop r7 + ret + + +;; ---------------------------------------------------- +drawscreen: + push r7 + push r8 + push r9 + +#define DATA_NEXT_ADDRESS_REGISTER r7 +#define DATA_END_ADDRESS_REGISTER r8 +#define NEXT_DATA_REGISTER r9 + ;; initialize bit-counter for isr mov.b #BIT_COUNTER_INIT_VALUE, BIT_COUNTER_REGISTER ;; initialize isr-sync register, signal BYTE_DONE for the first start @@ -129,15 +215,10 @@ init: ;; screen data end into r8 mov.w #screendataend, DATA_END_ADDRESS_REGISTER - ;; start timer in up mode - bis.w #MC0,&TA1CTL - ;; enable interrupts - eint - -mainloop: +drawscreen_continue: ;; prepare next byte to handle by isr cmp.w DATA_NEXT_ADDRESS_REGISTER, DATA_END_ADDRESS_REGISTER - jz mainloop_data_done + jz drawscreen_data_done ;; load next data byte mov.b @DATA_NEXT_ADDRESS_REGISTER, NEXT_DATA_REGISTER @@ -150,44 +231,45 @@ mainloop: ;; enable isr bis #SIGNAL_ISR_ENABLE, SIGNAL_REGISTER -mainloop_wait_for_isr_0: +drawscreen_wait_for_isr_0: ;; check bit0 in sync register bit #SIGNAL_OCTET_DONE, SIGNAL_REGISTER - jz mainloop_wait_for_isr_0 + jz drawscreen_wait_for_isr_0 ;; load data mov.b colors(NEXT_DATA_REGISTER), DATA_REGISTER ;; clear BYTE_DONE bic #SIGNAL_OCTET_DONE, SIGNAL_REGISTER -mainloop_wait_for_isr_1: +drawscreen_wait_for_isr_1: ;; check bit0 in sync register bit #SIGNAL_OCTET_DONE, SIGNAL_REGISTER - jz mainloop_wait_for_isr_1 + jz drawscreen_wait_for_isr_1 ;; load data mov.b colors+1(NEXT_DATA_REGISTER), DATA_REGISTER ;; clear BYTE_DONE bic #SIGNAL_OCTET_DONE, SIGNAL_REGISTER -mainloop_wait_for_isr_2: +drawscreen_wait_for_isr_2: ;; check bit0 in sync register bit #SIGNAL_OCTET_DONE, SIGNAL_REGISTER - jz mainloop_wait_for_isr_2 + jz drawscreen_wait_for_isr_2 ;; load data mov.b colors+2(NEXT_DATA_REGISTER), DATA_REGISTER ;; clear BYTE_DONE bic #SIGNAL_OCTET_DONE, SIGNAL_REGISTER ;; continue - jmp mainloop + jmp drawscreen_continue -mainloop_data_done: +drawscreen_data_done: ;; signal all data processed, isr finish bis #SIGNAL_ALL_DATA_DONE, SIGNAL_REGISTER - set_debug - ;; continue - jmp mainloop - - + + pop r9 + pop r8 + pop r7 + ret +;; ---------------------------------------------------- ; --- timer isr --- ;; r6: exclusively used by isr as bit-counter timer1_a0_isr: @@ -228,7 +310,7 @@ timer1_a0_isr_exit: reti - +;; ---------------------------------------------------- .section "__interrupt_vector_14","ax",@progbits .word timer1_a0_isr