summaryrefslogtreecommitdiff
path: root/bootloader/bootloader-887.asm
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/bootloader-887.asm')
-rw-r--r--bootloader/bootloader-887.asm386
1 files changed, 386 insertions, 0 deletions
diff --git a/bootloader/bootloader-887.asm b/bootloader/bootloader-887.asm
new file mode 100644
index 0000000..03307df
--- /dev/null
+++ b/bootloader/bootloader-887.asm
@@ -0,0 +1,386 @@
+ ;;
+ ;; spreadspace pic utils
+ ;;
+ ;;
+ ;; Copyright (C) 2011 Christian Pointner <equinox@spreadspace.org>
+ ;;
+ ;; 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 <http://www.gnu.org/licenses/>.
+ ;;
+ ;; -------------------------------------
+ ;; 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 (chip/com specific)
+#define BOOTPIN PORTC,7
+USERVECT EQU H'100'
+ISRVECT EQU USERVECT + H'4'
+FLASH_BOUNDARY EQU b'00001111' ; flash write boundary is at 16 bytes boundaries
+
+VERSION_MAJ EQU .0
+VERSION_MIN EQU .1
+NAME_0 EQU '8'
+NAME_1 EQU '8'
+NAME_2 EQU '7'
+DEVID_L EQU H'82'
+DEVID_H EQU H'20'
+FLASH_SIZE_L EQU H'00'
+FLASH_SIZE_H EQU H'20' ; 0x2000 -> 8192 Words of Flash
+FSS EQU .16 ; writing is done 8 words at a time but 16 words get erased
+EEPROM_SIZE_L EQU H'00'
+EEPROM_SIZE_H EQU H'01' ; 0x0100 -> 256 Bytes of EEPROM
+MESS EQU .64 ; this limit is because of to combuff size and single byte len field for messages
+SUPPORTED_H EQU .0
+SUPPORTED_L EQU b'00000110' ; only read/write flash is supported by now
+
+#define HOOK_CMD_RESET cmd_not_impl
+#define HOOK_CMD_R_FLASH cmd_r_flash
+#define HOOK_CMD_W_FLASH cmd_w_flash
+#define HOOK_CMD_R_EEPROM cmd_not_impl
+#define HOOK_CMD_W_EEPROM cmd_not_impl
+#define HOOK_CMD_R_CONFIG cmd_not_impl
+#define HOOK_CMD_W_CONFIG cmd_not_impl
+
+ ;; Variables
+combuff EQU H'0020'
+combuff_end EQU H'006F'
+
+current_cmdlen EQU H'0070'
+csum EQU H'0071'
+
+flags EQU H'007D'
+#define F_CMD_STARTED flags,0
+
+cnt2 EQU H'007E'
+cnt EQU H'007F'
+
+
+ ;; -------------------------------------
+ ;; DEFINES (defines)
+ ;; 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
+E_VALUE_OOB EQU .7
+
+ ;; CMD codes
+CMD_INVALID EQU .0
+
+CMD_IDENTIFY EQU .1
+CMD_BOOT EQU .2
+CMD_RESET EQU .3
+CMD_R_FLASH EQU .4
+CMD_W_FLASH EQU .5
+CMD_R_EEPROM EQU .6
+CMD_W_EEPROM EQU .7
+CMD_R_CONFIG EQU .8
+CMD_W_CONFIG EQU .9
+
+CMD_MAX EQU .9
+CMD_MIN_LEN EQU .3
+
+ ;; -------------------------------------
+ ;; Boot test
+ org .0
+ ;; btfsc BOOTPIN
+ ;; goto USERVECT
+ goto com_init
+
+ ;; -------------------------------------
+ ;; goto user ISR
+ org .4
+isr
+ goto ISRVECT
+
+ ;; -------------------------------------
+ ;; Bootloader (Generic Subroutines)
+send_answer ; generic answer message, leave len of data in W
+ addlw .3
+ movwf combuff + .1
+ decf combuff + .1,w
+ movwf cnt
+ movlw combuff
+ movwf FSR
+ clrf csum
+send_answer_next
+ movf INDF,w
+ call com_tx_byte
+ incf FSR,f
+ decfsz cnt,f
+ goto send_answer_next
+
+ movf csum,w
+ call com_tx_byte
+ return
+
+ ;; ------------------
+ack_cmd ; short answers which only contain return code
+ movwf combuff + .2
+ movlw .1
+ call send_answer
+ return
+
+
+ ;; -------------------------------------
+ ;; Bootloader (com specific subroutines and init)
+ ;; ------------------
+com_tx_byte ;send one byte and add it to csum
+ btfss PIR1,TXIF
+ goto com_tx_byte
+ movwf TXREG
+ xorwf csum,f
+ return
+
+ ;; ------------------
+com_rx_byte
+ btfsc RCSTA,OERR
+ goto uart_rx_oe
+ btfss PIR1,RCIF
+ goto com_rx_byte
+ btfsc RCSTA,FERR
+ goto uart_rx_fe
+ movf RCREG,w
+ return
+
+uart_rx_oe ; recover from overflow
+ bcf RCSTA,CREN
+ bsf RCSTA,CREN
+ goto com_rx_byte
+
+uart_rx_fe ; recover from framing error
+ movf RCREG,w
+ goto com_rx_byte
+
+ ;; ------------------
+com_init
+ ;; 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
+
+ ;; bank 0
+ bcf STATUS,RP0
+ movlw b'10010000' ; enable Serial Port, 8bit, enable continues receive, disable address detection
+ movwf RCSTA
+
+ ;; -------------------------------------
+ ;; Bootloader (generic init)
+
+wait_new_cmd
+ movlw combuff
+ movwf FSR
+ clrf combuff
+ clrf current_cmdlen
+ clrf flags
+
+wait_cmd
+ call com_rx_byte
+ movwf INDF ; process received byte
+ incf FSR,f
+ btfss F_CMD_STARTED
+ goto wait_cmd_len
+ movf current_cmdlen,f
+ btfsc STATUS,Z
+ goto new_cmd
+ decfsz current_cmdlen,f
+ goto wait_cmd
+ goto exec_cmd
+
+wait_cmd_len ; command code received, now wait for length
+ bsf F_CMD_STARTED
+ goto wait_cmd
+
+new_cmd ; got new command code and length -> check it
+ movf combuff,w
+ sublw CMD_MAX
+ btfss STATUS,C
+ goto invalid_cmd
+ movlw CMD_MIN_LEN ; check for minimum command len
+ subwf combuff + .1,w
+ btfss STATUS,C
+ goto invalid_cmd
+ movlw .2 ; 2 bytes already received
+ subwf combuff + .1,w
+ movwf current_cmdlen
+ goto wait_cmd
+
+exec_cmd ; command is complete -> check csum
+ movlw combuff
+ movwf FSR
+ movf combuff + .1,w
+ movwf cnt
+ clrf csum
+exec_cmd_check_csum
+ movf INDF,w
+ xorwf csum,f
+ incf FSR,f
+ decfsz cnt,f
+ goto exec_cmd_check_csum
+ movf csum,f
+ btfss STATUS,Z
+ goto csum_error
+
+ movf combuff,w ; command is correct and complete -> dispatch
+ addwf PCL,f
+ goto wait_new_cmd
+ goto cmd_identify ; identify
+ goto cmd_boot ; boot
+ goto HOOK_CMD_RESET ; reset
+ goto HOOK_CMD_R_FLASH ; read flash segment
+ goto HOOK_CMD_W_FLASH ; write flash segment
+ goto HOOK_CMD_R_EEPROM ; read eeprom
+ goto HOOK_CMD_W_EEPROM ; write eeprom
+ goto HOOK_CMD_R_CONFIG ; read config
+ goto HOOK_CMD_R_CONFIG ; write config
+
+ ;; ** generic error messages *******
+invalid_cmd ; received command code is not known or len is bogus
+ movlw E_INV_CMD
+ call ack_cmd
+ goto wait_new_cmd
+
+csum_error ; received command has an invalid check sum
+ movlw E_BAD_CSUM
+ call ack_cmd
+ goto wait_new_cmd
+
+address_invalid ; received command uses invalid address (i.e. not aligned to 16bytes)
+ movlw E_ADDR_INVALID
+ call ack_cmd
+ goto wait_new_cmd
+
+address_prohibited ; received command uses prohibited address (i.e. FLASH < 0x100)
+ movlw E_ADDR_PROHIB
+ call ack_cmd
+ goto wait_new_cmd
+
+ ;; ** generic command handlers ************
+ ;; ** identify *******
+cmd_identify
+ clrf csum
+ movf combuff,w
+ call com_tx_byte
+
+ movlw .19
+ call com_tx_byte
+
+ movlw E_OK
+ call com_tx_byte
+
+ movlw VERSION_MIN
+ call com_tx_byte
+ movlw VERSION_MAJ
+ call com_tx_byte
+
+ movlw NAME_0
+ call com_tx_byte
+ movlw NAME_1
+ call com_tx_byte
+ movlw NAME_2
+ call com_tx_byte
+
+ movlw DEVID_L
+ call com_tx_byte
+ movlw DEVID_H
+ call com_tx_byte
+
+ movlw FLASH_SIZE_L
+ call com_tx_byte
+ movlw FLASH_SIZE_H
+ call com_tx_byte
+ movlw FSS
+ call com_tx_byte
+
+ movlw EEPROM_SIZE_L
+ call com_tx_byte
+ movlw EEPROM_SIZE_H
+ call com_tx_byte
+ movlw MESS
+ call com_tx_byte
+
+ movlw SUPPORTED_L
+ call com_tx_byte
+ movlw SUPPORTED_H
+ call com_tx_byte
+
+ movf csum,w
+ call com_tx_byte
+ goto wait_new_cmd
+
+ ;; ** boot *******
+cmd_boot
+ movlw E_OK
+ call ack_cmd
+ goto USERVECT
+
+ ;; ** not implemented commands *******
+cmd_not_impl
+ movlw E_NOT_IMPL
+ call ack_cmd
+ goto wait_new_cmd
+
+ ;; -------------------------------------
+ ;; chip specific commands
+#include "cmds-16f887.inc"
+
+ ;; -------------------------------------
+ ;; -------------------------------------
+ ;; 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 cnt
+usercnt
+ movlw .255
+ movwf cnt2
+usercnt2
+ decfsz cnt2,f
+ goto usercnt2
+ decfsz cnt,f
+ goto usercnt
+ goto userloop
+
+ ;; -------------------------------------
+ ;; END
+ end