Gracias por el código, Killer.
Tengo mis ciertas dudas del programa....
Como que ocurra el envio en un punto en que el contador ya esta terminandose, supongamos que en esos 2 segundos se envie a los 1.99s dejandote 10ms. Es lo unico que veo que puede fallar.
No es un problema, sólo un límite de tiempo. Eso se puede cambiar en el programa para ampliarlo hasta 4 segundos.
Por que me preocupa esto? Por que es una comunicacion RS232 y no sabes cuando se reseteo el micro, prefiero mil veces un boton el cual tenes un "control" de cuando vas a entrar al modo bootloader.
Tengo botones, pero no quiero utilizarlos. La placa está destinada a usuarios sin conocimientos. Si aprietan el botón por error, va a entrar el bootloader y pensarán que la placa no funciona. No quiero que dé esa impresión.
El pulso debe tener exactamente 15 milisegundos. No funciona con 14ms y tampoco con 16ms.
Si se lleva a Vcc no hay problema (no hay pulso). Si se lleva a GND no hay problema (el pulso es mayor de 15ms).
Es una condición muy difícil de cumplir por error.
Por otro lado es una condición muy sencilla de cumplir para el programa que carga el bootloader desde el PC.
Tampoco podes enviar nada indicando del reset por que sos un esclavo para el I2C. Y tenes que asegurarte de que no va a ocurrir con el I2C eso de mantenerlo por 15ms. Como por ejemplo que las resistencias de pull.up lo tenga la otra placa, y al alimentar la placa con el micro y el bootloader no tenga nada que lo este pulleando a VCC.
Sí que puedo enviar datos de vuelta. De hecho las líneas funcionan como RS232 en modo bootloader (con TX y RX) y funcionan en modo I2C el resto del tiempo.
Esa es otra razón por la que quiero evitar que la placa entre en modo bootloader así como así. Sólo debe hacerlo cuando realmente sea necesario.
En cuanto al I2C, es muy difícil que a 100kbaud vaya a generar un pulso bajo de exactamente 15ms, ni más ni menos.
Creo que podrias achicar un poco mas el programa con un cambio, no es mucho creo que son 2 instrucciones., pero nuevamente hay que ver los ciclos de las intrucciones.
boot_pulse:
ldi counter, lo8(BOOT_PULSE_COUNTER)
ldi counter_hi, hi8(BOOT_PULSE_COUNTER)
clr pulse_time ;
boot_pulse_loop: ;
ldi cycles, DELAY_3CY_COUNTER ;
rcall Delay3Cycle ; ???? Donde esta esa funcion ? ademas rcall lleva 3 ciclos tinyAVR + 4 del return y te llenaria el STACK si no usas un return.
sbis UART_PIN, UART_RX ;
rjmp boot_pulse_2 ;
boot_pulse_high: ;
cpi pulse_time, 246 ; Incremento en 1 por el efecto del inc pulse_time de abajo
brsh bootloader ;
clr pulse_time ;
boot_pulse_2:
inc pulse_time ;
sbiw counter, 1 ;
brne boot_pulse_loop ;
rjmp run_user_program ; GOTO run_user_program
Ese programa salta al bootloader si el pulso es mayor de 15ms (esto quiero evitarlo, como he comentado antes)
El código que falta es sencillo:
Delay3Cycle:
subi cycles, 1
brne Delay3Cycle
ret