'********************************************************************************
'Include "_FuncionesBaseTimer8_Pic16.bas" ***************************************
'Funciones para el control de 8 bases de tiempos, controla el flujo del programa.
'Se utiliza el TMR1, By COS, 09/2013, v. 1.2. ***********************************
'********************************************************************************
'_setupbt(), _basestiempos(), _rldbt(), _pause(), _pausewdt()
'********************************************************************************
'_setupbt(): Inicializa las bases de tiempos y TMR, al pricipio una vez.
'_basestiempos(): Actualiza bases de tiempos, se llama desde On Interrupt/Resume.
'_rldbt(): Recarga base tiempos indicada.
'_pause(): Hace una pausa, no resetea el Watchdog.
'_pausewdt(): Hace una pausa, resetea el Watchdog.
'********************************************************************************
'Los timepos en pasos de 1mSeg/4Mhz = 0xFC18
'Los tiempos en pasos de 1mSeg/8Mhz = 0xF830.
'Los tiempos en pasos de 10mSeg/8Mhz = 0xB1E0.
'Los tiempos en pasos de 1mSeg/20Mhz = 0xEC78.
'Los tiempos en pasos de 10mSeg/20Mhz = 0x3CB0.
'Ejemplo Call _setupbt(0xF830)
'Los flag de las bases son: _btimer.0 ... _btimer.7
'********************************************************************************
Dim _pausa As Word  'Control pausa, variable global
Function _btimer(_nbase As Byte, _tpbase As Word, _regtmr As Word, _setupbt As Byte) As Byte
	Dim _regtmr1 As Word  'Almacena el valor para el desborde del tmr
	Dim _tpbt(8) As Word  'Tiempos de desborde de las bases de tiempos
	Dim x As Byte
	'Inicializa variables y configura el TMR1
	If _setupbt = 1 Then  'Inicializa variables y registros del TMR1
		_btimer = 0xff  'Bases de tiempos desbordadas
		_regtmr1 = _regtmr  'Almacena el valor de carga del registro del tmr
		TMR1H = _regtmr1.HB  'Recarga el registro del tmr pic16f
		TMR1L = _regtmr1.LB  'Recarga el registro del tmr pic16f
		'Pic16F
		T1CON.TMR1CS = 0  'Bit de seleccion de reloj para el TMR1, interno fosc/4
		T1CON.T1CKPS0 = 0  'Bit de seleccion del prescaler para el reloj del TMR1
		T1CON.T1CKPS1 = 0  'Bit de seleccion del prescaler para el reloj del TMR1
		T1CON.TMR1ON = 1  'Activa el contador del TMR1
		'Pic18F
		't1con.rd16 = 1    contador a 16bit
		't1con.t1run = 1
		't1con.t1ckps1 = 0    Sin preescales
		't1con.t1ckps0 = 0    Sin preescales
		't1con.t1oscen = 0
		't1con.t1sync = 1
		't1con.tmr1cs = 0    reloj principal para el timer1
		't1con.tmr1on = 1    TMR1 a On
		PIE1.TMR1IE = 1  'Activa las interrupciones del TMR1
		Exit
	Endif
	'Activa la base de tiempos, reset a la base de tiempos
	If _setupbt = 2 Then  'Selecciona la base de tiempos especificada por _nbase
		x = %00000001  'Valor de entrada
		x = ShiftLeft(x, _nbase)  'Desplaza el bit, para seleccionar la base de tiempos
		x = x Nand 0xff  'Invierte los bit del registro
		_btimer = _btimer And x  'Pone el bit seleccionado a cero
		_tpbt(_nbase) = _tpbase  'Carga la base de tiempos
		Exit
	Endif
	'Recarga el desborde del TMR1 y actualiza la lógica de las bases de tiempos
	If _setupbt = 0 Then  'Si se hace la llamada desde las interrupciones
		TMR1H = _regtmr1.HB  'Recarga el registro del tmr pic16f
		TMR1L = _regtmr1.LB  'Recarga el registro del tmr pic16f
		'Base de tiempos 0 * 10mSeg.
		If _btimer.0 = 0 Then  'Control base tiempos _btimer.0
			_tpbt(0) = _tpbt(0) - 1  'Decrementa el contador
			If _tpbt(0) = 0 Then _btimer.0 = 1  'Para el contador e indica que termino
		Endif
		'Base de tiempos 1 en mSeg.
		If _btimer.1 = 0 Then  'Control base tiempos _btimer.1
			_tpbt(1) = _tpbt(1) - 1  'Decrementa el contador
			If _tpbt(1) = 0 Then _btimer.1 = 1  'Para el contador e indica que termino
		Endif
		'Base de tiempos 2 en mSeg.
		If _btimer.2 = 0 Then  'Control base tiempos _btimer.2
			_tpbt(2) = _tpbt(2) - 1  'Decrementa el contador
			If _tpbt(2) = 0 Then _btimer.2 = 1  'Para el contador e indica que termino
		Endif
		'Base de tiempos 3 en mSeg.
		If _btimer.3 = 0 Then  'Control base tiempos _btimer.3
			_tpbt(3) = _tpbt(3) - 1  'Decrementa el contador
			If _tpbt(3) = 0 Then _btimer.3 = 1  'Para el contador e indica que termino
		Endif
		'Base de tiempos 4 en mSeg.
		If _btimer.4 = 0 Then  'Control base tiempos _btimer.4
			_tpbt(4) = _tpbt(4) - 1  'Decrementa el contador
			If _tpbt(4) = 0 Then _btimer.4 = 1  'Para el contador e indica que termino
		Endif
		'Base de tiempos 5 en mSeg.
		If _btimer.5 = 0 Then  'Control base tiempos _btimer.5
			_tpbt(5) = _tpbt(5) - 1  'Decrementa el contador
			If _tpbt(5) = 0 Then _btimer.5 = 1  'Para el contador e indica que termino
		Endif
		'Base de tiempos 6 en mSeg.
		If _btimer.6 = 0 Then  'Control base tiempos _btimer.6
			_tpbt(6) = _tpbt(6) - 1  'Decrementa el contador
			If _tpbt(6) = 0 Then _btimer.6 = 1  'Para el contador e indica que termino
		Endif
		'Base de tiempos 7 en mSeg.
		If _btimer.7 = 0 Then  'Control base tiempos _btimer.7
			_tpbt(7) = _tpbt(7) - 1  'Decrementa el contador
			If _tpbt(7) = 0 Then _btimer.7 = 1  'Para el contador e indica que termino
		Endif
		'Control _Pause
		If _pausa > 0 Then _pausa = _pausa - 1  'Actualiza la pause
	Endif
End Function                                      
'Actualiza las bases de tiempo, se llama desde On Interrupt/Resume.
Proc _basestiempos()
	If PIR1.TMR1IF = 1 Then  'Si está activa la interrupción del TMR
		Call _btimer(0, 0, 0, 0b00)  'Actualización de las bases de tiempos.
		PIR1.TMR1IF = 0  'Borra la interrupción de TMR
	Endif
End Proc                                          
'Inicializa las bases de tiempos.
Proc _setupbt(_regtimer As Word)
	Disable  'Deshabilita las interrupciones
	Call _btimer(0, 0, _regtimer, 0b01)  'Inicializa bases de tiempos, recarga TMR.
	Enable  'Activa las interrupciones
End Proc                                          
'Recarga la base de tiempos indicada por _bt con el tiempo indicado por _tpbase.
Proc _rldbt(_bt As Byte, _tpbase As Word)
	Disable  'Deshabilita las interrupciones
	Call _btimer(_bt, _tpbase, 0, 0b10)  'Recarga el timer x con y, 0.5Seg, pasos de 1mSeg.
	Enable  'Activa las interrupciones
End Proc                                          
'Rutina Pause (Wait).
'Resetea el Watchdog
'Call pause(pausa)
Proc _pausewdt(_tpausa As Word)
	Disable  'Deshabilita las interrupciones
	_pausa = _tpausa  'Carga pausa
	Enable  'Activa las interrupciones
	While _pausa > 0  'Espera hasta que termine la base de tiempos
		ASM:        clrwdt  'Reinicia el Whatchdog
	Wend
End Proc                                          
'Rutina Pause (Wait).
'Call pause(pausa)
Proc _pause(_tpausa As Word)
	Disable  'Deshabilita las interrupciones
	_pausa = _tpausa  'Carga pausa
	Enable  'Activa las interrupciones
	While _pausa > 0
	Wend
End Proc                                          
'Gestión de interrupciones
'On Interrupt
'Save System
	'Call _basestiempos()  'Actualiza las bases de tiempos
'Resume