Hello!
I'm stuck at this problem. I have .ino and .S files, whole point is in working with TM1637 7-seg display without using library, to save space which is scarce in ATtiny13, which is my platform in this sketch.
You can ignore SETUP part, and LOOP is writting "1111" and "2222" to display alternately. Now, function which writes "2222" is identical to the routine which writes "1111", but 1111 is written well and 2222 is not. Difference is in that in "2222" registers r16, r17, r18 and r19 - one register for each digit - are used to pass value to r24 (r24 holds argument for function "TM1637_write_byte_parameter_r24_uses_r25_returns_r24").
Code is organised in the way that INO file mostly just calls functions defined in S file.
INO file:
// C:\Users\ADAS\AppData\Local\Temp\arduino_build_112814>objdump -S tm1637cpp.ino.elf > tm1637cpp.txt
// TM 1637 7-seg display test code, no library
#define TM1637_DIO_PIN PB0
#define TM1637_CLK_PIN PB1
extern "C" {
// function prototypes
void TM1637_DELAY_US();
void TM1637_start();
void TM1637_stop();
void TM1637_write_segments_arguments_r16_r17_r18_r19_uses_r24();
void TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
}
void setup()
{
asm("in r24, 0x17");
asm("ori r24, 0x03");
asm("out 0x17, r24");
// initialise display and set brightness
// 0x88 is dim and increasing value to 0x8C increases brightness
TM1637_start();
asm("ldi r24, 0x8c");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
TM1637_stop();
// clear display
TM1637_start();
asm("ldi r24, 0x40");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
TM1637_stop();
TM1637_start();
asm("ldi r24, 0xc0");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0xff");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0xff");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0xff");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0xff");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
TM1637_stop();
}
void loop()
{
// this routine is working good, it writes "1111" on display:
TM1637_start();
asm("ldi r24, 0x40");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
TM1637_stop();
TM1637_start();
asm("ldi r24, 0xc0");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0x06");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0x06");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0x06");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
asm("ldi r24, 0x06");
TM1637_write_byte_parameter_r24_uses_r25_returns_r24();
TM1637_stop();
delay(800);
// this routine is identic to previous, but does not work well
// (something about using those registers?), it tries to write "2222":
asm("ldi r16, 0x5b");
asm("ldi r17, 0x5b");
asm("ldi r18, 0x5b");
asm("ldi r19, 0x5b");
TM1637_write_segments_arguments_r16_r17_r18_r19_uses_r24();
delay(800);
}
S file:
#define DIO_PIN 0 ; PB0
#define CLK_PIN 1 ; PB1
#define DDRB 0x17
#define PORTB 0x18
.global TM1637_DELAY_US
.global TM1637_start
.global TM1637_stop
.global TM1637_write_segments_arguments_r16_r17_r18_r19_uses_r24
.global TM1637_write_byte_parameter_r24_uses_r25_returns_r24
TM1637_DELAY_US: ; 50 us at 1.2 mhz
; rcall takes 3 cycles
; ret takes 4 cycles
; we need another 53 cycles
ldi r18, 25 ; 1 cycle
L1: dec r18
breq L1 ; 1 cycle for true and 2 for false
ret
TM1637_start:
sbi PORTB, DIO_PIN
sbi PORTB, CLK_PIN
rcall TM1637_DELAY_US
cbi PORTB, DIO_PIN
ret
TM1637_stop:
cbi PORTB, CLK_PIN
rcall TM1637_DELAY_US
cbi PORTB, DIO_PIN
rcall TM1637_DELAY_US
sbi PORTB, CLK_PIN
rcall TM1637_DELAY_US
sbi PORTB, DIO_PIN
ret
; This function does the same thing as the routine in THE LOOP
; but this one doesn't work well:
TM1637_write_segments_arguments_r16_r17_r18_r19_uses_r24:
rcall TM1637_start
ldi r24, 0x40
rcall TM1637_write_byte_parameter_r24_uses_r25_returns_r24
rcall TM1637_stop
rcall TM1637_start
ldi r24, 0xc0
rcall TM1637_write_byte_parameter_r24_uses_r25_returns_r24
mov r24, r16
rcall TM1637_write_byte_parameter_r24_uses_r25_returns_r24
mov r24, r17
rcall TM1637_write_byte_parameter_r24_uses_r25_returns_r24
mov r24, r18
rcall TM1637_write_byte_parameter_r24_uses_r25_returns_r24
mov r24, r19
rcall TM1637_write_byte_parameter_r24_uses_r25_returns_r24
rcall TM1637_stop
ret
TM1637_write_byte_parameter_r24_uses_r25_returns_r24:
ldi r25, 0x08 ; r25 will serve as counter in for loop (i)
forloop:
cbi 0x18, 1 ; CLK_PIN - LOW
rcall TM1637_DELAY_US
sbrs r24, 0 ; skip if first bit is 1
rjmp r24_first_bit_aint_1
sbi 0x18, 0 ; DIO - HIGH
rjmp r24_first_bit_is_1
r24_first_bit_aint_1:
cbi 0x18, 0 ; DIO_PIN - LOW
r24_first_bit_is_1:
sbi 0x18, 1 ; CLK_PIN - HIGH
rcall TM1637_DELAY_US
lsr r24 ; r24 shift right by one place
subi r25, 0x01 ; i--
brne forloop ; jump if i isn't null
cbi 0x18, 1 ; CLK - LOW
cbi 0x17, 0 ; DIO - INPUT
sbi 0x18, 0 ; DIO – ENABLE PULL-UP
rcall TM1637_DELAY_US
sbic 0x16, 0 ; skip if DIO_PIN (set as input) reads false
rjmp ack_is_true ; if (ack), jump downthere
ldi r24, 0x00 ; return ACK (not used, should remove this line)
continue_execution:
rcall TM1637_DELAY_US
sbi 0x18, 1 ; CLK_PIN - HIGH
rcall TM1637_DELAY_US
cbi 0x18, 1 ; CLK_PIN - LOW
rcall TM1637_DELAY_US
sbi 0x17, 0 ; DIO_PIN - OUTPUT
ret
ack_is_true:
sbi 0x17, 0 ; set DIO_PIN as output
cbi 0x18, 0 ; DIO_PIN - LOW
ldi r24, 0x01 ; return ACK (not used, should remove this line)
rjmp continue_execution