;; ;; spreadspace pic utils ;; ;; ;; Copyright (C) 2011 Christian Pointner ;; ;; This file is part of spreadspace pic utils. ;; ;; spreadspace pic utils is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; any later version. ;; ;; spreadspace pic utils is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with spreadspace pic utils. If not, see . ;; ;; ------------------------------------- ;; PREAMBLE LIST p=16F1847 include "p16f1847.inc" __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF __config _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LVP_OFF ;; ------------------------------------- ;; DEFINES #define DEBUG 1 ;; constants BUF_STARTH EQU H'0020' BUF_STARTL EQU H'0000' BUF_ENDH EQU H'0023' BUF_ENDL EQU H'00BF' #define FSRW FSR0 #define FSRWH FSR0H #define FSRWL FSR0L #define INDFW INDF0 #define FSRR FSR1 #define FSRRH FSR1H #define FSRRL FSR1L #define INDFR INDF1 ;; I/O Pins ;; PortA #define C1m PORTA,0 #define C2p PORTA,1 #define AMP_OUT PORTA,2 #define ADC_IN PORTA,3 #define SPEAKER PORTA,4 #define DBG2 PORTA,6 #define DBG1 PORTA,7 ;; PortB #define DBG0 PORTB,0 #define SDI PORTB,1 #define SDO PORTB,2 #define INT PORTB,3 #define SCK PORTB,4 #define CS PORTB,5 #define FILTER_EN PORTB,7 ;; variables ;; all Pages CMD EQU H'0070' TMP EQU H'0071' CMDS EQU H'007E' FLAGS EQU H'007F' ;; bits ;; CMDS #define CMD_READ CMDS,0 ;; FLAGS #define UNDERRUN FLAGS,0 #define OVERRUN FLAGS,1 ;; ------------------------------------- ;; Macros inc_fsr MACRO PTR,PTRH,PTRL LOCAL fsr_wraparound,inc_fsr_end addfsr PTR,1 movf PTRH,w sublw BUF_ENDH btfss STATUS,C goto fsr_wraparound btfss STATUS,Z goto inc_fsr_end movf PTRL,w sublw BUF_ENDL btfsc STATUS,C goto inc_fsr_end fsr_wraparound movlw BUF_STARTH movwf PTRH movlw BUF_STARTL movwf PTRL inc_fsr_end ENDM ;; ------------------------------------- ;; Reset Vector org .0 movlb .1 ; movlw b'01011000' ; 1 MHz ; movlw b'01100000' ; 2 MHz ; movlw b'01101000' ; 4 MHz ; movlw b'01110000' ; 8 MHz movlw b'01111000' ; 16 MHz movwf OSCCON goto init ;; ------------------------------------- ;; Interrupts org .4 movlb .0 if DEBUG == 1 bsf SPEAKER endif btfsc PIR1,SSP1IF goto int_spi btfsc PIR1,ADIF goto int_adc retfie ;; void adcInterrupt() ;; { ;; static char value = 0; ;; if (!overrun) { ;; *writePtr = ++value; ;; wbuf_next(); ;; } ;; } int_adc bcf PIR1,ADIF btfsc OVERRUN retfie ;; movlb .1 ;; movf ADRESH,w movf TMP,w movwf INDFW incf TMP,f call wbuf_next goto int_fsr_norestore ;; void sspInterrupt() ;; { ;; if (cmd_read && spiData == 0) { ;; *readPtr = 0; ;; rbuf_next(); ;; spiData = underrun ? -1 : *readPtr; ;; } else if (spiData == 'r') { ;; cmd_read = TRUE; ;; spiData = underrun ? -1 : *readPtr; ;; } else { ;; cmd_read = FALSE; ;; printf("%s\n", "I don't like you!"); ;; } ;; } int_spi bcf PIR1,SSP1IF movlb .4 movf SSP1BUF,w movwf CMD btfsc STATUS,Z goto int_spi_0 movlw 'r' xorwf CMD,w btfsc STATUS,Z goto int_spi_r ;; other commands clrf CMDS retfie int_spi_0 btfss CMD_READ retfie call rbuf_next movf INDFR,w btfss UNDERRUN movwf SSP1BUF goto int_fsr_norestore int_spi_r movf INDFR,w btfss UNDERRUN movwf SSP1BUF clrf CMDS bsf CMD_READ retfie int_fsr_norestore movlb .31 movf FSR0H,w movwf FSR0H_SHAD movf FSR0L,w movwf FSR0L_SHAD movf FSR1H,w movwf FSR1H_SHAD movf FSR1L,w movwf FSR1L_SHAD retfie ;; ------------------------------------- ;; SUBROUTINES ;; void buf_init() ;; { ;; writePtr = bufferStart; ;; readPtr = bufferStart; ;; overrun = FALSE; ;; underrun = TRUE; ;; cmd_read = FALSE; ;; } buf_init movlw BUF_STARTH movwf FSRWH movwf FSRRH movlw BUF_STARTL movwf FSRWL movwf FSRRL bcf OVERRUN bsf UNDERRUN movf BSR,w clrf BSR bsf INT if DEBUG == 1 bcf DBG1 bsf DBG2 endif movwf BSR return ;; ------------------- ;; void wbuf_next() ;; { ;; if (!overrun) { ;; writePtr++; ;; writePtr = writePtr > bufferEnd ? bufferStart : writePtr; ;; underrun = FALSE; ;; if(writePtr == readPtr) { ;; overrun = TRUE; ;; } ;; } ;; } wbuf_next btfsc OVERRUN return inc_fsr FSRW,FSRWH,FSRWL bcf UNDERRUN movf BSR,w clrf BSR bcf INT if DEBUG == 1 bcf DBG2 endif movwf BSR movf FSRRH,w xorwf FSRWH,w btfss STATUS,Z return movf FSRRL,w xorwf FSRWL,w btfss STATUS,Z return bsf OVERRUN if DEBUG == 1 movf BSR,w clrf BSR bsf DBG1 movwf BSR endif return ;; ------------------- ;; void rbuf_next() ;; { ;; if(!underrun) { ;; readPtr++; ;; readPtr = readPtr > bufferEnd ? bufferStart : readPtr; ;; overrun = FALSE; ;; if(readPtr == writePtr) { ;; underrun = TRUE; ;; } ;; } ;; } rbuf_next btfsc UNDERRUN return inc_fsr FSRR,FSRRH,FSRRL bcf OVERRUN if DEBUG == 1 movf BSR,w clrf BSR bcf DBG1 movwf BSR endif movf FSRWH,w xorwf FSRRH,w btfss STATUS,Z return movf FSRWL,w xorwf FSRRL,w btfss STATUS,Z return bsf UNDERRUN movf BSR,w clrf BSR bsf INT if DEBUG == 1 bsf DBG2 endif movwf BSR return ;; ------------------------------------- ;; INIT init ;; BANK 6 movlb .6 clrf CCPR4H movlw .124 movwf CCPR4L movlw b'00001011' movwf CCP4CON ;; BANK 4 movlb .4 movlw b'01000000' movwf SSP1STAT movlw b'00010000' movwf SSP1CON3 movlw b'00100100' movwf SSP1CON1 if DEBUG == 1 bsf DBG0 ; Pull-up for DBG0 endif ;; BANK 3 movlb .3 movlw b'00001111' ; PORTA0:3 analog, PORTA4:7, digital movwf ANSELA clrf ANSELB ; PORTB0:7 digital ;; BANK 1 movlb .1 movlw b'00101111' movwf TRISA movlw b'01110011' movwf TRISB movlw b'01010000' ; Left Justified, FOSC/16, NEG=VSS,POS=VDD movwf ADCON1 movlw b'00001101' ; AN3, ADC On movwf ADCON0 movlw b'01001000' ; ADIE,SSPIE movwf PIE1 movlw b'01011111' ; Enable Pull UPs, disable T0CKI movwf OPTION_REG ;; BANK 0 movlb .0 movlw .124 ; 8 kHz @ 16MHz movwf PR2 clrf TMR1H ; reset TMR1 clrf TMR1L movlw b'00100000' ; Source Fosc/4, Prescaler 1:4, LP-Osc off, Sync, Timer off movwf T1CON clrf T1GCON clrf PIR1 ; reset all used interupt flags movlw b'01000000' ; PEIE movwf INTCON bcf FILTER_EN call buf_init clrf CMDS clrf TMP bsf INTCON,GIE ;; ------------------------------------- ;; MAINLOOP main if DEBUG == 1 bcf SPEAKER btfss DBG0 goto enable_t1 btfsc T1CON,TMR1ON bcf T1CON,TMR1ON goto main enable_t1 btfss T1CON,TMR1ON bsf T1CON,TMR1ON endif btfss CS goto main powerdown: clrf CMDS ;; sleep ;; nop goto main ;; ------------------------------------- ;; END end