;; **************************************************************************** ;; PIC12/16 Pseudo Real Time Operating System ;; **************************************************************************** LIST P=PIC16F88 INCLUDE "P16F88.INC" __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB3 & _MCLR_OFF & _PWRTE_ON & _WDT_ON & _HS_OSC &_LVP_OFF __CONFIG _CONFIG2, _FCMEN_OFF & _IESO_OFF ; *** Define constant *** STACKLEVEL EQU (D'8'-D'1') MAXID EQU H'0F' TMR0SET EQU H'00' ;;; Task IDs TMR0TASKID EQU D'0' ;;; TMR0IE location IFNDEF TMR0IE IFDEF T0IE TMR0IE SET T0IE ELSE TMR0IE SET D'5' ENDIF ENDIF ;;; TMR0IF location IFNDEF TMR0IF IFDEF T0IF TMR0IF SET T0IF ELSE TMR0IF SET D'2' ENDIF ENDIF ; *** Provide register/routine *** GLOBAL INITIALIZE GLOBAL INTERRUPT GLOBAL IDLE GLOBAL SP,TOPSTACK,RA GLOBAL VALUE0,VALUE1,ARGUMENT0,ARGUMENT1,TEMP0,TEMP1 ; *** Request register/routine *** ; EXTERN RECIEVE ;Software serial receiver. EXTERN USER_INITIALIZE ;User define initialize routine ; *** Define GPR *** ;;; Interrupt Temporary SFRs TEMP_REGISTERS UDATA STATUS_TEMP RES D'1' FSR_TEMP RES D'1' PCLATH_TEMP RES D'1' SFR_SP RES D'1' ;Stack pointer for interrupt temporary SFRs ;;; Stack for temporary SFRs SFR_STACK UDATA SFR_EOS RES STACKLEVEL*D'4' ;End of stack for Special Function Register ;;; Stack for general purpose STACK UDATA TOPSTACK RES D'96' ;End of stack for general purpose ;;; OS16 system register SYSTEM_REGISTER UDATA CLOCK RES D'2' ;System clock (big endian) TASKSTATUS RES (MAXID+D'1') ;Task Status Registers ACTIVE EQU D'7' ; __7bit____6bit____5bit___4bit-0bit_ READY EQU D'6' ; |_ACTIVE_|_READY_|_WAIT_|_parameter_| WAIT EQU D'5' TASKCON RES D'1' ;Task Control Register EXCLUSION EQU D'7' ; ____7bit________6bit-0bit____ ;|_Exclusion_|_current_task_id_| ;;; OS16 system register in shared area UDATA_SHR WREG_TEMP RES D'1' ;Interrupt temporary register for WREG ;;; Pseudo CPU registers SP RES D'1' ;Stack pointer for general purpose RA RES D'2' ;2Byte Return Address (big endian) VALUE0 RES D'4' ;32bit return value No.0 (big endian) ARGUMENT0 RES D'4' ;32bit argument No.0 (big endian) TEMP0 RES D'4' ;32bit temporary registr CPU_REGISTER UDATA VALUE1 RES D'4' ;32bit return value No.1 (big endian) ARGUMENT1 RES D'4' ;32bit argument NO.1 (big endian) TEMP1 RES D'4' ;32bit temporary registr ; *** Include macro *** INCLUDE "MACRO.INC" ; *** Program area *** MAIN CODE H'0005' ; *** Task Scheduler *** INTERRUPT ;;Save registers MOVWF WREG_TEMP ;Save Working register SWAPF STATUS,W ;Save STATUS register BANKSEL(STATUS_TEMP) MOVWF STATUS_TEMP MOVF FSR,W ;Save FSR register MOVWF FSR_TEMP MOVF PCLATH,W ;Save PCLATH register MOVWF PCLATH_TEMP PAGESEL(INTERRUPT) ;;; Pseudo non-maskable Interrupt ;;;; Software serial receiver IFDEF RECIEVE BTFSS INTCON,INTF GOTO $+D'4' PAGESEL(RECIEVE) GOTO RECIEVE FILL (NOP),D'2' ;Dumy NOP for PAGESEL ENDIF ;;; Create task from interrupt BANKSEL(TASKSTATUS) ;Change BANK ;;;; TMR0 Overflow Interrup TASK IFDEF TMR0TASKID BTFSS INTCON,TMR0IF GOTO $+D'3' BSF TASKSTATUS+TMR0TASKID,READY BCF INTCON,TMR0IF ;Clear TMR0IF ENDIF ;;;; RB Port Change Interrupt TASK IFDEF CHANGE_TASKID BTFSS INTCON,RBIF GOTO $+D'3' BSF TASKSTATUS+CHANGE_TASKID,READY BCF INTCON,RBIF ;Clear RBIF ENDIF ;;;; INT External Interrup TASK IFDEF INT_TASKID BTFSS INTCON,INTF GOTO $+D'3' BSF TASKSTATUS+INT_TASKID,READY BCF INTCON,INTF ;Clear INTF ENDIF ;;;; EE Write Complete Interrupt TASK IFDEF EE_TASKID BANKSEL(EECON1) ;Change BANK BTFSS EECON1,EEIF GOTO $+D'5' BCF EECON1,EEIF ;Clear EEIF BANKSEL(TASKSTATUS) ;Change BANK 2 cycle BSF TASKSTATUS+EE_TASKID,READY NOP ;Dummy NOP for BANKSEL ENDIF ;;; Check Exclusion Control BANKSEL(TASKCON) BTFSC TASKCON,EXCLUSION GOTO RETURN_INTERRUPT ;;; Save temporary registers to stack BANKSEL(SFR_SP) MOVLW LOW(SFR_EOS+D'1') SUBWF SFR_SP,W BTFSS STATUS,C GOTO RETURN_INTERRUPT BANKISEL(SFR_EOS) DECF SFR_SP,W MOVWF FSR ;;;; Save temporary Working register MOVF WREG_TEMP,W MOVWF INDF DECF FSR,F ;;;; Save temporary STATUS register MOVF STATUS_TEMP,W MOVWF INDF DECF FSR,F ;;;; Save temporary FSR register MOVF FSR_TEMP,W MOVWF INDF DECF FSR,F ;;;; Save temporary PCLATH register MOVF PCLATH_TEMP,W MOVWF INDF MOVF FSR,W MOVWF SFR_SP BSF INTCON,GIE ;Enable interrupt SCHEDULER ;;; Task schaduling BANKSEL(TASKCON) CLRF TASKCON ;Clear Task Control register SWITCH MACRO _TASKID,_LABEL,_STACK LOCAL NEXT BTFSS TASKSTATUS+_TASKID,READY GOTO NEXT ;Next task BTFSC TASKSTATUS+_TASKID,ACTIVE GOTO RESUME ;If current TASK is already active. MOVLW (TOPSTACK-_STACK) SUBWF SP,W BTFSS STATUS,C GOTO RESUME BSF TASKSTATUS+_TASKID,ACTIVE PAGESEL(_LABEL) GOTO _LABEL NEXT INCF TASKCON,F ENDM SWITCH TMR0TASKID,TMR0TASK,D'0' ;ID=H'00' : Timer0 Task RESUME ;;; Return from Task Scheduler BCF INTCON,GIE ;Forbid interrupt ;;; Save temporary registers to stack BANKISEL(SFR_EOS) BANKSEL(SFR_SP) MOVF SFR_SP,W MOVWF FSR ;;;; Return temporary PCLATH register MOVF INDF,W MOVWF PCLATH_TEMP INCF FSR,F ;;;; Return temporary FSR register MOVF INDF,W MOVWF FSR_TEMP INCF FSR,F ;;;; Return temporary STATUS register MOVF INDF,W MOVWF STATUS_TEMP INCF FSR,F ;;;; Return temporary working register MOVF INDF,W MOVWF WREG_TEMP RETURN_INTERRUPT ;;; Return from Task or Interrupt MOVF PCLATH_TEMP,W ;Return PCLATH register MOVWF PCLATH MOVF FSR_TEMP,W ;Return FSR resgister MOVWF FSR SWAPF STATUS_TEMP,W ;Return STATUS register MOVWF STATUS SWAPF WREG_TEMP,F ;Return Working register SWAPF WREG_TEMP,W RETFIE ; *** ID=H'00': Timer0 Task *** TMR0TASK CLRWDT ;Clear watch dog timer. BANKSEL(TMR0) ;Change BANK : 2cycle MOVLW TMR0SET ;Reset TMR0 ADDWF TMR0,F ;;; Clock countup BANKSEL(TASKSTATUS) VARIABLE TASKID=D'0' WHILE MAXID>=TASKID BTFSC TASKSTATUS+TASKID,WAIT INCF TASKSTATUS+TASKID,F TASKID=TASKID+D'1' ENDW BANKSEL(CLOCK) ;Change BANK : 2cycle INCF CLOCK+D'1',F BTFSC STATUS,Z INCF CLOCK,F ;;; END TASK BANKSEL(TASKSTATUS) CLRF TASKSTATUS+TMR0TASKID PAGESEL(SCHEDULER) GOTO SCHEDULER ; *** In Idle state *** IDLE GOTO IDLE ; *** Initialize routine *** INITIALIZE ;;; Kill all Modules ;;;; STATUS Register CLRF STATUS ;Change to BANK0 ;;;; Power Control Register IFDEF PCON BANKSEL(PCON) ;Change BANK BSF PCON,NOT_POR ;Set Power-on Reset Status BSF PCON,NOT_BOR ;Set Brown-out Reset Status ENDIF ;;;; Interrupt Control Register CLRF INTCON ;;;; Peripheral Interrupt Enable Register 1 IFDEF PIE1 BANKSEL PIE1 ;Change BANK CLRF PIE1 ENDIF ;;;; Peripheral Interrupt Enable Register 2 IFDEF PIE2 BANKSEL(PIE2) ;Change BANK CLRF PIE2 ENDIF ;;;; Peripheral Interrupt Request (FLAG) Register 1 IFDEF PIR1 BANKSEL(PIR1) ;Change BANK CLRF PIR1 ENDIF ;;;; Peripheral Interrupt Request (FLAG) Register 2 IFDEF PIR2 BANKSEL(PIR2) ;Change BANK CLRF PIR2 ENDIF ;;;; OPTION_REG Register BANKSEL(OPTION_REG) ;Change BANK CLRF OPTION_REG ;;;; ADC module IFDEF ADCON0 BANKSEL(ADCON0) ;Change BANK CLRF ADCON0 ;Disable ADC ENDIF IFDEF ANSEL BANKSEL(ANSEL) ;Change BANK CLRF ANSEL ENDIF IFDEF ADCON1 BANKSEL(ADCON1) ;Change BANK CLRF ADCON1 ENDIF ;;;; Comparater module IFDEF CMCON BANKSEL(CMCON) MOVLW B'00000111' MOVWF CMCON ;Stop comparater ENDIF ;;;; USART module IFDEF RCSTA BANKSEL(RCSTA) CLRF RCSTA ;Disable USART ENDIF ;;;; SSP module IFDEF SSPCON BANKSEL(SSPCON) CLRF SSPCON ;Disable SSP ENDIF ;;; Operating System initialize ;;;; Stack pointer for interrupt temporary SFRs BANKSEL(SFR_SP) MOVLW LOW(SFR_EOS+STACKLEVEL*D'4') MOVWF SFR_SP ;;;; TMR0 initialize BANKSEL(TMR0) MOVLW TMR0SET ;Reset TMR0 MOVWF TMR0 ;;; User initialize PAGESEL(USER_INITIALIZE) CALL USER_INITIALIZE ;;; Clear watch dog timer. CLRWDT PAGESEL(IDLE) GOTO IDLE END ;; **************************************************************************** ;; ;; Copyright (c) Hitoshi Gomi ;; All rights reserved. ;; ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions are met: ;; ;; 1.Redistributions of source code must retain the above copyright notice, ;; this list of conditions and the following disclaimer. ;; 2.Redistributions in binary form must reproduce the above copyright notice, ;; this list of conditions and the following disclaimer in the documentation ;; and/or other materials provided with the distribution. ;; 3.The names of the author may not be used to endorse or promote products ;; derived from this software without specific prior written permission. ;; ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ;; POSSIBILITY OF SUCH DAMAGE. ;; ;; ****************************************************************************