aboutsummaryrefslogtreecommitdiffstats
path: root/src/avr-asm.gmo
blob: b442434f264712d6b29d1e89d8f5679ccfb21fab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# avr-asm

explorando programación de microcontroladores avr a través de asm, en attiny85. {s-camino}

# attiny85

## diagrama de pines

```diagrama de pines
     ┌──────┐
PB5  │1    8│  VCC
PB3  │2    7│  PB2
PB4  │3    6│  PB1
GND  │4    5│  PB0
     └──────┘
```

además, cada pin es:

* 1: PB5 / PCINT5 / ~RESET / ADC0 / dW
* 2: PB3 / PCINT3 / XTAL1 / CLKI / ~OC1B / ADC3
* 3: PB4 / PCINT4 / XTAL2 / CLKO / OC1B / ADC2
* 5: PB0 / MOSI / DI / SDA / AIN0 / OC0A / ~OC1A / AREF / PCINT0
* 6: PB1 / MISO / DO / AIN1 / OC0B / OC1A / PCINT1
* 7: PB2 / SCK / USCK / SCL / ADC1 / T0 / INT0 / PCINT2

para flashear nos interesan los pines desde el punto de vista de SPI:

```pines spi
       ┌──────┐
~RESET │1    8│  VCC
       │2    7│  SCK
       │3    6│  MISO
GND    │4    5│  MOSI
       └──────┘
```

## programador

=> https://www.fischl.de/usbasp/ USBasp - USB programmer for Atmel AVR controllers (web)

## makefile

para ensamblar y flashear

```makefile
# Makefile
# nombre del programa sin .S :
PROG = test
# config hardware
BOARD = attiny85
PROGRAMMER = usbasp

# ensambla programa a .hex
hex:
	avr-gcc -Os -DF_CPU=8000000 -mmcu=$(BOARD) -c $(PROG).S 
	avr-ld -o $(PROG).elf $(PROG).o
	avr-objcopy $(PROG).elf -O ihex $(PROG).hex
	rm $(PROG).o $(PROG).elf

# flashea
flash:
	avrdude -c $(PROGRAMMER) -p $(BOARD) -U flash:w:$(PROG).hex:i

# lee la memoria flash a read.hex
read:
	avrdude -c $(PROGRAMMER) -p $(BOARD) -U flash:r:read.hex:i

# prueba conexión con programador y micro
test:
	avrdude -c $(PROGRAMMER) -p $(BOARD)
```



# programas

software experimental, compartido como referencia y sin garantía de ningún tipo :)


## test.S

enciende un el pin PB0 — conecta un led

```
; test.S
; enciende un pin
#include <avr/io.h>
.org 0x0000

        ldi r17, (1<<DDB0)      ; configura al PB0 como salida
        sts DDRB, r17

        ldi r16, (1<<PB0)       ; enciende el bit correspondiente al PB0
        sts PORTB, r16          ; actualiza el puerto

        sleep                   ; duerme por siempre (?)
```

## blink.S

parpadea el pin PB0 usando el timer/counter0 — conecta un led

```
; blink.S
; parpadea el pin PB0 (OC0A)!
; r16 y r17 se usan como registros auxiliares

; el programa usa el timer/counter 0 con:
; * waveform generation mode (WGM0): 2, que es CTC (clear timer on compare match)
; * compare match output A mode (COM0A): 1, que es toggle en compare match
; * clock select (CS0): 5, que utiliza el reloj i/o dividido entre 1024

; notas sobre el reloj:
; por default el attiny85 va a 8MHz, y el reloj i/o va a 1MHz
; 1MHz/1024 ~= 967 Hz

#include <avr/io.h>
; ***********************
; vectores de interrupts:
; ***********************
; Reset
.org 0x0000
	rjmp main

; ***********************
; Main
; ***********************
.org 0x0010
main:
	; pin PB0 (OC0A) como pin de salida
	ldi r16, (1<<DDB0) ; pin de salida
	sts DDRB, r16

	; togglea OC0A en Compare match (1 en COM0A[1:0])
	; y usa modo Clear Timer on Compare Match (2 en WGM0[2:0])
	ldi r16, (0<<COM0A1) | (1<<COM0A0) | (1<<WGM01) | (0<<WGM00)
	sts TCCR0A, r16

	; completa el modo WGM (waveform generaton mode, bit 2)
	; establece el tipo de reloj: 0b101 en CS0 es clk/1024
	ldi r16, (0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00)
	sts TCCR0B, r16

	; el TOP es el valor en OCR0A
	ldi r16, 0x80
	sts OCR0A, r16

loop:
	sleep
	rjmp loop
```

## buzz.S

zumba el pin PB0 — conecta un buzzer

```
; buzz.S
; haz zumbar el pin PB0 (OC0A)!
; el código es igual a blink.S, pero con diferentes frecuencias
; r16 y r17 se usan como registros auxiliares

; el programa usa el timer/counter 0 con:
; * waveform generation mode (WGM0): 2, que es CTC (clear timer on compare match)
; * compare match output A mode (COM0A): 1, que es toggle en compare match
; * clock select (CS0): 4, que utiliza el reloj i/o dividido entre 256

; notas sobre el reloj:
; por default el attiny85 va a 8MHz, y el reloj i/o va a 1MHz
; 1MHz/256 ~= 3906 Hz (/2 para el periodo completo ~=1953Hz)

#include <avr/io.h>
; ***********************
; vectores de interrupts:
; ***********************
; Reset
.org 0x0000
	rjmp main

; ***********************
; Main
; ***********************
.org 0x0010
main:
	; pin PB0 (OC0A) como pin de salida
	ldi r16, (1<<DDB0) ; pin de salida
	sts DDRB, r16

	; togglea OC0A en Compare match (1 en COM0A[1:0])
	; y usa modo Clear Timer on Compare Match (2 en WGM0[2:0])
	ldi r16, (0<<COM0A1) | (1<<COM0A0) | (1<<WGM01) | (0<<WGM00)
	sts TCCR0A, r16

	; completa el modo WGM (waveform generaton mode, bit 2)
	; establece el tipo de reloj: 0b100 en CS0 es clk/256
	ldi r16, (0<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00)
	sts TCCR0B, r16

	; el TOP es el valor en OCR0A
	ldi r16, 0x02
	sts OCR0A, r16

loop:
	sleep
	rjmp loop
```

## alarm.S

zumbido intermitente en el pin PB0 — conecta un buzzer

```
; alarm.S
; zumbido intermitente en el pin PB0 (OC0A)!
; r16 y r17 se usan como registros auxiliares
; r20 tiene el valor de TCCR0A para apagar sonido
; r21 tiene el valor de TCCR0A para encenderlo

; el programa usa el timer/counter 0 con:
; * waveform generation mode (WGM0): 2, que es CTC (clear timer on compare match)
; * compare match output A mode (COM0A): 1, que es toggle en compare match
; * clock select (CS0): 3, que utiliza el reloj i/o dividido entre 64

; y el timer/counter 1 con:
; * clock select (CS1): 0b1010, que es clk/512
; * interrupciones de overflow y de compare match A:
;	- en compare match A el zumbido se apaga
;	- en overflow el zumbido inicia

; notas sobre el reloj:
; por default el attiny85 va a 8MHz, y el reloj i/o va a 1MHz
; 1MHz/256 ~= 3906 Hz (/2 para el periodo completo ~=1953Hz)

#include <avr/io.h>
; ***********************
; vectores de interrupts:
; ***********************
; Reset
.org 0x0000
	rjmp main

; dirección 0x0003 * 2
.org 0x0006
	rjmp timer1compareA_isr

; dirección 0x0004 * 2
.org 0x0008
	rjmp timer1overflow_isr

; ***********************
; Main
; ***********************
.org 0x001E
main:
	;----------------------------------
	; configuración general
	;----------------------------------

	; habilita interrupciones
	sei

	; pin PB0 (OC0A) como pin de salida
	ldi r16, (1<<DDB0) ; pin de salida
	sts DDRB, r16

	; valores de TCCR0A para encender o apagar sonido
	ldi r20, (0<<COM0A1) | (0<<COM0A0) | (1<<WGM01) | (0<<WGM00)
	ldi r21, (0<<COM0A1) | (1<<COM0A0) | (1<<WGM01) | (0<<WGM00)

	;----------------------------------
	; configuración TIMER0 para buzzer
	;----------------------------------
	; togglea OC0A en Compare match (1 en COM0A[1:0])
	; y usa modo Clear Timer on Compare Match (2 en WGM0[2:0])
	sts TCCR0A, r21

	; completa el modo WGM (waveform generaton mode, bit 2)
	; establece el tipo de reloj: 0b011 en CS0 es clk/64
	ldi r16, (0<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00)
	sts TCCR0B, r16

	; el TOP es el valor en OCR0A
	; más pequeño es más agudo
	ldi r16, 0x06
	sts OCR0A, r16

	;----------------------------------
	; configuración TIMER1 para alternar entre sonido on/off
	;----------------------------------
	; CS1 en 0b1010 es CK/512
	ldi r16, (1<<CS13) | (0<<CS12) | (1<<CS11) | (0<<CS10)
	sts TCCR1, r16

	; establece el valor A al que cuenta el timer1 antes de apagar sonido
	; menor valor, menor tiempo de sonido (duty cycle)
	ldi r16, 0x30
	sts OCR1A, r16

	; set Timer overflow interrupt enable 1
	; y timer output compare A interrupt enable 1
	ldi r16, (1<<TOIE1) | (1<<OCIE1A)
	sts TIMSK, r16

loop:
	sleep
	rjmp loop

timer1compareA_isr:
	; apaga la salida
	sts TCCR0A, r20
	reti

timer1overflow_isr:
	; enciende la salida
	sts TCCR0A, r21
	; regresa de la interrupción
	reti
```


## llega(n) aquí

=> ./s-camino.gmi {s-camino}
Un proyecto texto-plano.xyz