; Saturation Current Tester for power inductors as used in switchmode power supplies
; Filename: sct.asm
; Contact: pic@polonai.se Polonaise PIC Projects
; v0.0 190820 New project
; v1.0 190825 Release
; v1.1 190825 Increase PWM period to allow inductor current to decay
; v1.2 190901 Better granularity with short pulse length (4/8/16 µs)
; v1.3 190901 PWM setup to prevent spurious long MOSFET ON pulse after reset
LIST P=12F617, F=INHX8M
#include <p12f617.inc>
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _CP_OFF & _IOSCFS_4MHZ & _BOR_OFF
; Equates
RESET_V EQU 0x00 ; Address of RESET Vector
; Registers
FLAGS EQU 0x20
DEBOUNCE EQU 0x21 ; Debounce counter for UP button because TMR0 only is too fast
; Ports
; GPIO2 (PWM/CCP1) has no name defined
#define UP GPIO,GP4 ; UP button (pin #3)
#define DIP FLAGS,0 ; Debounce In Progress
ORG 0x00
GOTO START
ORG 0x04
; Interrupt handlers
; TMR2 interrupt, needed for completing PWM setup
BTFSC PIR1,TMR2IF
GOTO PWMSETUP
; TMR0 interrupt
BTFSC INTCON,TMR0IF
GOTO BUTTONHANDLER
JIC
RETFIE ; Just In Case
PWMSETUP
BANKSEL PIE1
BCF PIE1,TMR2IE ; Disable TMR2 interrupts
BCF TRISIO,2 ; Make PWM output
BANKSEL PIR1
BCF PIR1,TMR2IF ; Clear TMR2 interrupt flag
RETFIE
BUTTONHANDLER ; When button pushed or held increase PWM time
BCF INTCON,TMR0IF ; Clear interrupt source
MOVLW 0x80 ; Check button every 33 ms
MOVWF TMR0
BTFSC UP ; Button pressed?
GOTO CANCELDIP ; No
BTFSS DIP ; Debounce In Progress?
GOTO CONTTIME ; No
DECFSZ DEBOUNCE
RETFIE
MOVLW 0x09
MOVWF DEBOUNCE
GOTO CONTTIME ; Repeat increase time
CANCELDIP
BCF DIP
MOVLW 0x09
MOVWF DEBOUNCE
RETFIE
CONTTIME
BSF DIP
MOVLW 0xFA
SUBWF CCPR1L,W ; Test for long pulse
BTFSS STATUS,C ; W<CCPR1L?
GOTO LONGPULSE ; Yes
MOVLW 0xFE
SUBWF CCPR1L,W ; Test for medium pulse
BTFSS STATUS,C ; W<CCPR1L?
GOTO MEDPULSE ; Yes
BANKSEL CCP1CON
BTFSC CCP1CON,4 ; Test PWM[0]
GOTO PWMX1 ; 1
BSF CCP1CON,4 ; 0->1
BTFSC CCP1CON,5 ; Test PWM[1]
GOTO PWM0X ; 1
BSF CCP1CON,4
BSF CCP1CON,5
BANKSEL CCPR1L
DECF CCPR1L,F ; 0
RETFIE
PWMX1
BCF CCP1CON,4 ; 1->0
BTFSS CCP1CON,5 ; Test PWM[1]
GOTO PWM0X ; 1
BSF CCP1CON,5 ; 0->1
BANKSEL CCPR1L
RETFIE
PWM0X
BCF CCP1CON,5 ; 1->0
BANKSEL CCPR1L
RETFIE
MEDPULSE
BANKSEL CCP1CON
BTFSC CCP1CON,5 ; Test PWM[1]
GOTO PWM1X ; 1
BSF CCP1CON,5 ; 0->1
BANKSEL CCPR1L
DECF CCPR1L,F ; 0
RETFIE
PWM1X
BCF CCP1CON,5 ; 1->0
BANKSEL CCPR1L
RETFIE
LONGPULSE
DECF CCPR1L,F
MOVLW 0xE0
SUBWF CCPR1L,W
BTFSC STATUS,C ; W<CCPR1L?
RETFIE ; No
MOVLW 0xE0 ; Prevent PWM duty cycle to become too high
MOVWF CCPR1L
RETFIE
START
CLRF STATUS ; Do initialization, Select bank 0
CLRF INTCON ; Clear int-flags, Disable interrupts
BANKSEL TRISIO
MOVLW B'00011100'
MOVWF TRISIO ; GP0,1 out, GP2-4 in, GP5 out
BANKSEL GPIO
BSF GPIO,GP2 ; Make sure MOSFET drive is OFF (HIGH)
MOVLW B'00000111'
BANKSEL OPTION_REG
MOVWF OPTION_REG ; Weak pullups, prescaler Timer0, 1:256 (0.26ms per count for Timer0)
CLRF APFCON
BANKSEL CMCON0
CLRF CMCON0
CLRF CMCON1
CLRF VRCON
CLRF ADCON0
BANKSEL ANSEL
CLRF ANSEL
CLRF PIE1 ; Disable all peripheral interrupts
BSF PIE1,TMR2IE ; Except TMR2 (for PWM setup)
BANKSEL PIR1
CLRF PIR1
CLRF T1CON
MOVLW B'00000110' ; Timer2 enabled (needed for PWM), prescaler 1:16
MOVWF T2CON
MOVLW B'00010000' ; Weak pullup on GP4
BANKSEL WPU
MOVWF WPU
CLRF IOC
MOVLW 0xFF
MOVWF PR2 ; 4 ms PWM
MOVLW 0xFF
BANKSEL CCPR1L
MOVWF CCPR1L ; Load PWM <9:2>
MOVLW B'00101100' ; PWM with LSB clear, P1A (CCP1) PWM out
MOVWF CCP1CON
MOVLW 0x09
MOVWF DEBOUNCE
CLRF FLAGS
MOVLW B'10100000' ; Enable global interrupts and Timer0 interrupt
MOVWF INTCON
MAIN
GOTO MAIN
END