; PWM Fan Controller Noise Killer
; Filename: pwmkill.asm
; Corrects PWM CPU fan control when implemented anally
; Target system: HP DC7900 USDT but should work on many different mother boards
; Contact: pic@polonai.se Polonaise PIC Projects
; V0.0 170319 New project
; V0.1 IN polarity test, HS XTAL Oscillator
; V0.2 First determine PWM high and low times
; V0.3 170320 New concept: just shorten high time by delaying low->high transition. Easy peasy
; V0.4 Another new concept: double fan tacho out frequency to trick mobo firmware into thinking fan runs at double speed
; V0.5 170611 Enable weak pull-up tacho IN, get rid of NPN out by tristating OUT port emulating open collector/drain output (3V/5V tolerant)
LIST P=12F629, F=INHX8M
#include <P12F629.INC>
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_OFF
; Equates
RESET_V EQU 0x00 ; Address of RESET Vector
OSC_FREQ EQU D'4000000' ; Internal RC Oscillator Frequency is 4.0 MHz
; Registers
TACHO EQU 0x20 ; Tacho IN high/low time
DELAY EQU 0x21 ; Used for prescaler for tacho IN period time
; Ports
#define OUT GPIO,0 ; Tacho out to mobo, drives open collector transistor
#define IN GPIO,5 ; Tacho in from fan
ORG 0x00
GOTO START
ORG 0x04
; Interrupt handlers
BTFSS INTCON,GPIF ; Int from GPIO change?
GOTO INTTMR0 ; No, goto TMR0 int handler
CLRF INTCON
MOVFW TACHO ; Get period time
SUBLW 0xFF ; Get TMR0 offset
MOVWF TMR0
MOVLW 0x2B
MOVWF DELAY
CLRF TACHO
BANKSEL TRISIO
MOVLW B'00101000' ; All outputs except GPIO5 (PWM IN)and GPIO3 (CLR)
MOVWF TRISIO
BANKSEL GPIO
BCF OUT ; Tacho OUT LOW
GOTO ENDINT
INTTMR0
CLRF INTCON
BANKSEL TRISIO
MOVLW B'00101001' ; All outputs except GPIO5 (PWM IN), GPIO3 (CLR) and GPIO0 (OUT)
MOVWF TRISIO
BANKSEL GPIO
BSF OUT ; Tacho OUT HIGH (Hi-Z)
ENDINT
MOVLW B'10101000' ; Re-enable interrupts
MOVWF INTCON
RETFIE
START
CLRF STATUS ; Do initialization, Select bank 0
CLRF INTCON ; Clear int-flags, Disable interrupts
CLRF PCLATH ; Keep in lower 2KByte
BANKSEL TRISIO
MOVLW B'00101000' ; All outputs except GPIO5 (PWM IN) and GPIO3 (CLR)
MOVWF TRISIO
MOVLW B'00100000' ; Enable interrupt and weak pull-up on GPIO5
MOVWF IOC
MOVWF WPU
MOVLW B'00000101' ; TMR0 Prescaler 1:64
MOVWF OPTION_REG
BANKSEL T1CON
CLRF T1CON
MOVLW B'00000111' ; Comparators off
MOVWF CMCON
MOVLW B'10101000' ; Enable global (GIE), Timer0 (T0IE) and GP change (GPIE) interrupts
MOVWF INTCON
CLRF GPIO
MAIN
MOVLW 0x2B
MOVWF DELAY
PRESCALE
DECFSZ DELAY,1
GOTO PRESCALE
INCF TACHO,1
GOTO MAIN
END