@@ -97,47 +97,52 @@ void tinyuart_init(void)
97
97
98
98
void tinyuart_send_uint8 (uint8_t data )
99
99
{
100
- uint8_t cnt ;
100
+ uint8_t cnt ;
101
+ uint8_t mask = 1 <<TINYUART_IO_TX ;
101
102
102
103
asm volatile
103
104
(
104
- "mov %[cnt], %[data] \n\t" // use cnt as scratch pad
105
+ "mov %[cnt], %[data] \n\t" // use cnt as scratch pad
105
106
106
- "cbi %[port], %[io] \n\t" // Setup START bit => moved for cycles bevore delay loop for accurate timing
107
+ "sbi %[pin], %[io] \n\t" // Setup START bit => moved for cycles bevore delay loop for accurate timing
107
108
108
- "subi %[cnt], 128 \n\t" // invert MSB
109
- "lsl %[cnt] \n\t" // shift to a) generate pattern with XOR b) place msb in carry
110
- "eor %[data], %[cnt] \n\t" // generate toggle pattern
111
- "ldi %[cnt], 9 \n\t" // init counter: 8 bits + stop
109
+ "subi %[cnt], 128 \n\t" // invert MSB
110
+ "lsl %[cnt] \n\t" // shift to a) generate pattern with XOR b) place msb in carry
111
+ "eor %[data], %[cnt] \n\t" // generate toggle pattern
112
+ "ldi %[cnt], 9 \n\t" // init counter: 8 bits + stop
112
113
113
114
"send_bit:"
114
- "mov r0, %[loops] \n\t" // bit delay loop
115
+ "mov __tmp_reg__, %[loops] \n\t" // bit delay loop
115
116
116
- #if CYCLES_EXTRA == 2 // insert nops for cycle-accurate delays
117
- "nop \n\t"
118
- "nop \n\t"
117
+ #if CYCLES_EXTRA == 2 // insert nops for cycle-accurate delays
118
+ "nop \n\t"
119
+ "nop \n\t"
119
120
#elif CYCLES_EXTRA == 1
120
- "nop \n\t"
121
+ "nop \n\t"
121
122
#endif
122
123
123
124
"send_bit_delay:"
124
- "dec r0 \n\t"
125
- "brne send_bit_delay \n\t"
125
+ "dec __tmp_reg__ \n\t"
126
+ "brne send_bit_delay \n\t"
126
127
127
- "sbrc %[data], 0 \n\t" // toggle TX if change is required
128
- "sbi %[pin], %[io] \n\t"
128
+ "sbrc %[data], 0 \n\t" // toggle TX if change is required
129
+ "sbi %[pin], %[io] \n\t"
129
130
130
- "ror %[data] \n\t" // rotation to access the 9th bit in carry
131
- "dec %[cnt] \n\t"
132
- "brne send_bit \n\t"
131
+ "ror %[data] \n\t" // rotation to access the 9th bit in carry
132
+ "dec %[cnt] \n\t"
133
+ "brne send_bit \n\t"
133
134
134
- :
135
- : [data ] "r" (data ),
136
- [loops ] "r" ((uint8_t )(LOOP_DELAY + 1 )), // the 0th loop iteration already decrements, +1 as compensation
137
- [cnt ] "d" (cnt ),
135
+ // output values, can be safely written to. "+" attribute is read-write
136
+ : [data ] "+ r "(data), // use original value and allow overwrite
137
+ [cnt ] "= & d "(cnt) // let compiler pick temporary register
138
+
139
+ // input values; never write to any of the below
140
+ : [mask ] " r "(mask), // let compiler put mask in register
141
+ [loops ] "r" ((uint8_t )(LOOP_DELAY + 1 )), // the 0th loop iteration already decrements, +1 as compensation
138
142
[io ] "I" (TINYUART_IO_TX ),
139
- [port ] "I" (_SFR_IO_ADDR (TINYUART_PORT )),
140
143
[pin ] "I" (_SFR_IO_ADDR (TINYUART_PIN ))
141
- :
144
+
145
+ // cobblers: registers modified without compiler already knowing
146
+ : /*none*/
142
147
);
143
148
}
0 commit comments