;; ;; 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'0020' BUF_ENDL EQU H'0060' ;; 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 btfsc TMP,7 clrf TMP movlb .0 call wbuf_next bcf INT 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 movlb .0 call rbuf_next btfss UNDERRUN goto int_spi_0_loadnext bsf INT goto int_fsr_norestore int_spi_0_loadnext movlb .4 movf INDFR,w 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 if DEBUG == 1 bcf DBG1 bsf DBG2 endif 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 if DEBUG == 1 bcf DBG2 endif 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 bsf DBG1 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 bcf DBG1 endif movf FSRWH,w xorwf FSRRH,w btfss STATUS,Z return movf FSRWL,w xorwf FSRRL,w btfss STATUS,Z return bsf UNDERRUN if DEBUG == 1 bsf DBG2 endif 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' ; SMP=0,CKE=1 movwf SSP1STAT movlw b'00010000' ; BOEN=1 movwf SSP1CON3 movlw b'00100100' ; SSPEN=1,CKP=0,SSPM=0100(SPI Slave with SS) 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 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 bsf INT 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