;; ;; 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=16F887 include "p16f887.inc" __config _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTOSC __config _CONFIG2, _BOR21V & _WRT_256 ;; ------------------------------------- ;; DEFINES #define BOOTPIN PORTC,7 USERVECT EQU H'100' ISRVECT EQU USERVECT + H'4' FSS EQU 8 MESS EQU 64 ;; ERROR codes E_OK EQU 0 E_INV_CMD EQU 1 E_BAD_CSUM EQU 2 E_NOT_IMPL EQU 3 E_FLASH_WERR EQU 4 E_ADDR_INVALID EQU 5 E_ADDR_PROHIB EQU 6 ;; CMD codes CCMD_IDENTIFY EQU 'i' CMD_IDENTIFY EQU 0 CCMD_BOOT EQU 'b' CMD_BOOT EQU 1 CCMD_RESET EQU 'r' CMD_RESET EQU 2 CCMD_R_FLASH EQU 'f' CMD_R_FLASH EQU 3 CCMD_W_FLASH EQU 'F' CMD_W_FLASH EQU 4 CCMD_R_EEPROM EQU 'e' CMD_R_EEPROM EQU 5 CCMD_W_EEPROM EQU 'E' CMD_W_EEPROM EQU 6 CCMD_R_CONFIG EQU 'c' CMD_R_CONFIG EQU 7 CCMD_W_CONFIG EQU 'C' CMD_W_CONFIG EQU 8 CMD_INVALID EQU H'FF' ;; Variables inbuff EQU H'0020' inbuff_end EQU H'006F' current_cmd EQU H'0070' current_cmdlen EQU H'0071' cnt1 EQU H'0070' cnt2 EQU H'0071' ;; ------------------------------------- ;; Boot test org 0 ;; btfsc BOOTPIN ;; goto USERVECT goto boot ;; ------------------------------------- ;; goto user ISR org 4 isr goto ISRVECT ;; ------------------------------------- ;; Bootloader (Subroutines) uart_tx_byte btfss PIR1,TXIF goto uart_tx_byte movwf TXREG return translate_cmd_codes xorlw CCMD_IDENTIFY btfsc STATUS,Z retlw CMD_IDENTIFY xorlw CCMD_BOOT ^ CCMD_IDENTIFY btfsc STATUS,Z retlw CMD_BOOT xorlw CCMD_RESET ^ CCMD_BOOT btfsc STATUS,Z retlw CMD_RESET xorlw CCMD_R_FLASH ^ CCMD_RESET btfsc STATUS,Z retlw CMD_R_FLASH xorlw CCMD_W_FLASH ^ CCMD_R_FLASH btfsc STATUS,Z retlw CMD_W_FLASH xorlw CCMD_R_EEPROM ^ CCMD_W_FLASH btfsc STATUS,Z retlw CMD_R_EEPROM xorlw CCMD_W_EEPROM ^ CCMD_R_EEPROM btfsc STATUS,Z retlw CMD_W_EEPROM xorlw CCMD_R_CONFIG ^ CCMD_W_EEPROM btfsc STATUS,Z retlw CMD_R_CONFIG xorlw CCMD_W_CONFIG ^ CCMD_R_CONFIG btfsc STATUS,Z retlw CMD_W_CONFIG retlw CMD_INVALID get_cmdlen addwf PCL,f retlw 1 ; identify: retlw 1 ; boot: retlw 1 ; reset: retlw 3 ; read flash: addr | retlw 3 + 2*FSS ; write flash: addr | data | retlw 5 ; read eeprom: addr | len | retlw 5 ; write eeprom: addr | len | data | (minimal) retlw 2 ; read config: nr | retlw 4 ; write config: nr | word | ;; ------------------------------------- ;; Bootloader (init) boot ;; bank 3 bsf STATUS,RP0 bsf STATUS,RP1 movlw b'00001000' ; TX non-inverted, 16bit Baudrate, no auto baud detect ;; movlw b'00011000' ; TX inverted, 16bit Baudrate, no auto baud detect movwf BAUDCTL ;; bank 1 bcf STATUS,RP1 movlw b'01110000' ; set internal OSC to 8MHz movwf OSCCON movlw b'00100100' ; Baudrate = High Speed, async mode, transmit enabled, 8bit movwf TXSTA movlw .34 ; Baudrate = 57600 (@ 8MHz) -> -0,79 % Error ;; movlw .51 ; Baudrate = 38400 (@ 8MHz) -> -0,002 % Error ;; movlw .103 ; Baudrate = 19200 (@ 8MHz) -> 0,16 % Error movwf SPBRG clrf SPBRGH bcf TRISD,0 ; DEBUG!!!! ;; bank 0 bcf STATUS,RP0 movlw b'10010000' ; enable Serial Port, 8bit, enable continues receive, disable address detection movwf RCSTA bsf PORTD,0 ; DEBUG!!!! wait_new_cmd movlw inbuff movwf FSR movlw CMD_INVALID movwf current_cmd clrf current_cmdlen wait_cmd btfsc PIR1,RCIF goto uart_rx_byte btfsc RCSTA,OERR goto uart_rx_oe goto wait_cmd uart_rx_oe bcf RCSTA,CREN bsf RCSTA,CREN goto wait_new_cmd uart_rx_byte btfsc RCSTA,FERR goto uart_rx_fe movf RCREG,w ; TODO: check parity?? movwf INDF incf FSR,f movf current_cmdlen,f btfsc STATUS,Z goto new_cmd decfsz current_cmdlen,f goto wait_cmd goto exec_cmd uart_rx_fe movf RCREG,w goto wait_new_cmd new_cmd call translate_cmd_codes movwf current_cmd xorlw CMD_INVALID btfsc STATUS,Z goto invalid_cmd movf current_cmd,w call get_cmdlen movwf current_cmdlen goto wait_cmd invalid_cmd movf inbuff,w call uart_tx_byte movlw E_INV_CMD call uart_tx_byte movlw E_INV_CMD xorwf inbuff,w call uart_tx_byte goto wait_new_cmd exec_cmd ;; TODO: execute received command bcf PORTD,0 movlw .255 movwf cnt1 dbgcnt1 movlw .255 movwf cnt2 dbgcnt2 decfsz cnt2,f goto dbgcnt2 decfsz cnt1,f goto dbgcnt1 bsf PORTD,0 goto wait_new_cmd ;; ------------------------------------- ;; dummy user code org USERVECT ;; goto USERVECT bsf STATUS,RP0 bcf TRISD,0 bcf STATUS,RP0 userloop movlw b'00000001' xorwf PORTD,f movlw .255 movwf cnt1 usercnt1 movlw .255 movwf cnt2 usercnt2 decfsz cnt2,f goto usercnt2 decfsz cnt1,f goto usercnt1 goto userloop ;; ------------------------------------- ;; END end