;=======================================================================

; tm1638cc.s - s'AVR version by EH, based on GIT version, 31-JUL-2017

; s'AVR version tested using LED&KEY board

;

; Examples of usage for tm1638 library

; written by Ralf Jardon (xxxxxxxx@xxx.xxx), May-July 2017

;

; Comments related to the datasheet refer to version 1.3 (en)

;

; License: GNU GENERAL PUBLIC LICENSE, Version 3, 29 June 2007

;

; Version: 0.1

;=======================================================================

 

;.NOLIST

 

.INCLUDE "tm1638cc_EH.def"  ; various definitions, originally tm1638cc.h

.INCLUDE "tm1638cc.mac"     ; TM1638 macros

 

.LIST

.LISTMAC

 

.CSEG

.ORG $0000

    rjmp    INIT            ; Reset vector

                            ; no interrupts are used   

   

;=======================================================================

;                           INIT and MAIN LOOP

;

;=======================================================================

.ORG $100                       ; EH

 

INIT:

    ldi     AKKU, HIGH(RAMEND)  ; Initialize stack pointer

    out     SPH, AKKU

    ldi     AKKU, LOW(RAMEND)

    out     SPL, AKKU

    rcall   TM1638_INIT         ; Initialize Ports, SPI & TM1638

 

LOOP                            ; Main Loop

    ldi     AKKU3, 1            ; Text "88888888", Block 1

    rcall   TM1638_PRINT_TXT8

    rcall   TM1638_LEDS_L       ; move LEDs

    rcall   TM1638_LEDS_R

 

    clr     AKKU3               ; Textblock "TM1638 DEMO"

    rcall   TM1638_PRINT_MOVETEXT

    rcall   TM1638_LEDS_L

    rcall   TM1638_LEDS_R

 

    FOR COUNT := #3

        rcall   TM1638_TWIST_CW ; twist cw

    ENDF

    rcall   TM1638_CLEAR

 

    FOR COUNT := #3

        rcall   TM1638_TWIST_CCW    ; twist ccw

    ENDF

    rcall   TM1638_CLEAR

    rcall   TM1638_LEDS_L       ; move LEDs

    rcall   TM1638_LEDS_R

 

    clr     AKKU3               ; Text "LEDS DIM", block 0

    rcall   TM1638_PRINT_TXT8  

    FOR AKKU2 := #1             ; DIM LEDs 1x (or 2x)

        FOR COUNT := #7         ; step darker

            mov     AKKU, COUNT

            rcall   TM1638_BRIGHTNESS

            rcall   Delay500ms

        ENDF

        REPEAT                  ; step brighter again

            mov     AKKU, COUNT

            rcall   TM1638_BRIGHTNESS

            rcall   Delay500ms

            subi    COUNT,-1

        UNTIL COUNT > #7

    ENDF

    rcall   TM1638_LEDS_L

    rcall   TM1638_LEDS_R

 

    ldi     AKKU3, 1            ; Textblock "BINARY COUNTER"

    rcall   TM1638_PRINT_MOVETEXT

    rcall   TM1638_COUNT_BIN

    rcall   Delay1s

    rcall   TM1638_LEDS_L

    rcall   TM1638_LEDS_R

 

    ldi     AKKU3, 2            ; Textblock "HEXACECIMAL COUNTER"

    rcall   TM1638_PRINT_MOVETEXT

    rcall   TM1638_COUNT_HEX

    rcall   Delay1s

    rcall   TM1638_LEDS_L

    rcall   TM1638_LEDS_R

 

    ldi     AKKU3, 3            ; Textblock "DECIMAL COUNTER"

    rcall   TM1638_PRINT_MOVETEXT

    rcall   TM1638_COUNT_DEC

    rcall   Delay1s

ENDL                            ; MAIN LOOP

 

;=======================================================================

;                           Subroutines

;=======================================================================

;

; LED chain right

;

TM1638_LEDS_R: 

    push    COUNT

    ldi TM1638_GRID_BYTE, 0x01      ; first LED address

    FOR COUNT := #8

        ldi TM1638_SEGM_BYTE,1      ; LED ON

        rcall   TM1638_SEND_DATA

        rcall   Delay100ms

        clr TM1638_SEGM_BYTE        ; LED OFF

        rcall   TM1638_SEND_DATA

        subi    TM1638_GRID_BYTE,-2 ; next LED address

    ENDF

    pop COUNT

    ret

;=======================================================================

;

; LED chain left

;

TM1638_LEDS_L: 

    push    COUNT

    ldi TM1638_GRID_BYTE, 0x0F      ; first LED address

    FOR COUNT := #8

        ldi     TM1638_SEGM_BYTE,1  ; LED ON

        rcall   TM1638_SEND_DATA

        rcall   Delay100ms

        clr     TM1638_SEGM_BYTE    ; LED OFF

        rcall   TM1638_SEND_DATA

        subi    TM1638_GRID_BYTE,2  ; next LED address

    ENDF

    pop     COUNT

    ret

 

;=======================================================================

;

; binary counter, 8 bit 0x00 through 0xff

;

TM1638_COUNT_BIN:

    push    AKKU

    clr AKKU

    REPEAT

        rcall   TM1638_PRINT_BIN    ; print value in AKKU

        rcall   Delay100ms

        inc     AKKU

    UNTIL AKKU == #0

    pop     AKKU

    ret

;=======================================================================

;

; hexadecimal counter, 8 bit 0x00 through 0xff

;

TM1638_COUNT_HEX:

    push    AKKU

    clr AKKU

    REPEAT

        rcall   TM1638_PRINT_HEX    ; print value in AKKU

        rcall   Delay100ms

        inc     AKKU

    UNTIL AKKU == #0

    pop     AKKU

    ret

;=======================================================================

;

; decimal counter, 16 bit, stop at a given value

;

TM1638_COUNT_DEC:

    push    AKKU2

    push    AKKU3

    clr     XL

    clr     XH

    REPEAT

        mov AKKU2, XL

        mov AKKU3, XH

        rcall   TM1638_PRINT_DEC    ; print values in AKKU2 and AKKU3

                                ; as 16 bit number (LO and HI-Byte)

        rcall   Delay10ms

        EXITIF XH >= #8         ; stop at max 2048 for the demo

        adiw    XH:XL,1

    UNTIL Z                     ; max would be all 16 bits 

    pop     AKKU3

    pop     AKKU2

    ret

;=======================================================================

;

; twist arround CW from segment a through f

; EH: replaced inner REPEAT loop by a FOR loop

;

TM1638_TWIST_CW:

    push    AKKU

    push    COUNT

    ldi     AKKU, 1             ; start with segment a

    clr     TM1638_GRID_BYTE

    REPEAT

        FOR COUNT := #8

            mov     TM1638_SEGM_BYTE,AKKU      

            rcall   TM1638_SEND_DATA    ; activates only one LED

                                ; position is given by GRID_BYTE (digit)

                                ; and SEGM_BYTE (LED segment)

            subi    TM1638_GRID_BYTE,-2

        ENDF

        rcall   delay100ms

        clr     TM1638_GRID_BYTE

        rol     AKKU            ; next LED segment

    ;UNTIL AKKU == #0b01000000

    UNTIL AKKU,6                ; until segment g (not shown)

    pop     COUNT

    pop     AKKU

    ret

;=======================================================================

;

; twist arround CCW from segment f through a

; EH: replaced inner REPEAT loop by a FOR loop

;

TM1638_TWIST_CCW:

    push    AKKU

    push    COUNT

    ldi     AKKU, 0b00100000    ; start with segment f

    clr     TM1638_GRID_BYTE

    REPEAT

        FOR COUNT := #8

            mov     TM1638_SEGM_BYTE,AKKU      

            rcall   TM1638_SEND_DATA    ; activates only one LED

                                ; position is given by GRID_BYTE (digit)

                                ; and SEGM_BYTE (LED segment)

            subi    TM1638_GRID_BYTE,-2

        ENDF

        rcall   delay100ms

        clr     TM1638_GRID_BYTE

        ror     AKKU            ; next LED segment

    UNTIL C                     ; until shifted out

    pop     COUNT

    pop     AKKU

    ret

;=======================================================================

; other subroutines and TM1638 character font:

 

; TM1638 library, compiled from "tm1638cc.inc_EH.s" using label prefix _I:

.INCLUDE "tm1638cc.inc_EH.asm"

 

; delay subroutines, compiled from "tm1638cc_delay_EH.s", label prefix _D:

.INCLUDE "tm1638cc_delay_EH.asm"

 

; NOTE: in general all included .asm files being generated by s'AVR

; must use different label prefixes (could be any from _A through _Z)

 

.INCLUDE "tm1638cc_font.inc"                ; TM1638 character font

 

;=======================================================================

; constant text:

 

MOVETEXT:                                   ; 35+1 characters each

.db "            TM1638 DEMO            ",0 ; TEXT_BLOCK 0

.db "          BINARY COUNTER           ",0 ; TEXT_BLOCK 1

.db "       HEXADECIMAL COUNTER         ",0 ; TEXT_BLOCK 2

.db "         DECIMAL COUNTER           ",0 ; TEXT_BLOCK 3

 

TEXT10:             ; 8+2 characters each

.db "LEDS DIM",0,0  ; TEXT10, Block 0

.db "88888888",0,0  ; TEXT10, Block 1, showing all 7 segments w/o DP

.db "(-88.88)",0,0  ; TEXT10, Block 2, showing extra characters ( - . )

 

.EXIT