📄 bdm.c
字号:
/* this is just to make things safe and to make sure there is a place to jump to in such a case */
unsigned char bdm_empty_rx_tx(void) {
command_buffer[0]=CMD_FAILED; /* if BDM command is executed with this routine set as either Tx or Rx it has failed... */
return(0);
}
/* initialises I/O pins and internal variables of the module */
void bdm_init() {
bdm_status.ackn = WAIT; /* select default behaviour & values */
bdm_status.target_type = HC12;
bdm_status.reset = NO_RESET_ACTIVITY;
bdm_status.speed = NO_INFO;
POCR_PAP=1; /* enable pullups on RESET_OUT, RESET_IN and BDM_DRIVE */
RESET_IN_DDR &= ~RESET_IN_MASK; /* RESET_IN is input */
RESET_OUT = 1; /* RESET_OUT inactive */
RESET_OUT_DDR &= ~RESET_OUT_MASK;/* RESET_OUT is input for the moment, only turn it out when needed as Rx routines interfere with RESET_OUT */
BDM_IN_DDR &= ~BDM_IN_MASK; /* BDM_IN is input */
BDM_OUT = 1; /* idle state of BDM line is high */
BDM_OUT_DDR |= BDM_OUT_MASK; /* BDM_OUT is output */
BDM_DIR2 = 0; /* prepare to drive the BDM once DIR2 is turned to output */
BDM_DIR2_DDR &= ~BDM_DIR2_MASK; /* turn BDM_DIR2 to input */
BDM_DIR1 = 1; /* do not drive the BDM */
BDM_DIR1_DDR |= BDM_DIR1_MASK; /* turn BDM_DIR1 to output */
/* now give the BDM interface enough time to soft reset in case it was doing something before */
TMOD = SOFT_RESET * BUS_FREQUENCY; /* load TMOD with the longest SOFT RESET time possible */
TSC = TSC_TRST_MASK; /* restart the timer */
TSC_TOF = 0; /* clear TOF */
while(TSC_TOF==0); /* wait for timeout */
KBIER = RESET_IN_MASK; /* enable RESET_IN as keyboard pin */
KBSCR = KBSCR_ACKK_MASK; /* acknowledge any pending interrupt and enable KBD to cause IRQ (once enabled) */
}
/* prepares transmit of BDM data */
/* assumes that BDM_OUT is 1 */
/* interrupts need to be disabled for the duration of all BDM commands */
/* it is up to the caller to see to this */
void bdm_tx_prepare(void) {
BDM_OUT_PORT = BDM_DIR1_MASK | BDM_OUT_MASK | RESET_OUT_MASK; /* make sure BDM will be driven high once the driver is enabled */
BDM_OUT_DDR = BDM_OUT_MASK; /* turn DIR1 & RESET_OUT to input (now the only output in PTA register is BDM_OUT) */
BDM_DIR2_DDR = BDM_DIR2_MASK; /* bring DIR low (start driving the BDM) */
}
/* finishes transmit of BDM data */
void bdm_tx_finish(void) {
BDM_OUT_PORT = BDM_DIR1_MASK | BDM_OUT_MASK | RESET_OUT_MASK; /* do not drive RESET nor BDM once DIR1 is output again */
BDM_DIR2_DDR = 0; /* stop driving DIR2 low */
BDM_DIR1_DDR = BDM_DIR1_MASK | BDM_OUT_MASK; /* enable DIR1 again, leave RESET_OUT as input */
}
/* receive 8 bit of data, MSB first */
/* expects DIR1 active and DIR2 inactive */
/* 6.75 - 9.75 MHz */
unsigned char bdm_rx1(void) {
#pragma NO_RETURN
asm {
LDA #BDM_DIR1_MASK+RESET_OUT_MASK /* contents of A will be driven to PTA in order to switch the driver off */
CLRX /* prepare HX to point to PTA */
CLRH
/* bit 7 (MSB) */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 6 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 5 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 4 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 3 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 2 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 1 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 0 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
/* now get the bit values (last value is in X, previous 7 on stack) */
JMP rx_stack_decode
}
}
/* 5.4 - 7.8 MHz */
unsigned char bdm_rx2(void) {
#pragma NO_RETURN
asm {
LDA #BDM_DIR1_MASK+RESET_OUT_MASK /* contents of A will be driven to PTA in order to switch the driver off */
CLRX /* prepare HX to point to PTA */
CLRH
/* bit 7 (MSB) */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 6 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 5 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 4 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 3 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 2 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 1 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 0 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
NOP /* wait 1 cycle */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
/* now get the bit values (last value is in X, previous 7 on stack) */
JMP rx_stack_decode
}
}
/* 4.5 - 6.5 MHz */
unsigned char bdm_rx3(void) {
#pragma NO_RETURN
asm {
LDA #BDM_DIR1_MASK+RESET_OUT_MASK /* contents of A will be driven to PTA in order to switch the driver off */
CLRX /* prepare HX to point to PTA */
CLRH
/* bit 7 (MSB) */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 6 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 5 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 4 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 3 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 2 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 1 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
/* bit 0 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BIT ,X /* wait 2 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
/* now get the bit values (last value is in X, previous 7 on stack) */
JMP rx_stack_decode
}
}
/* 3.86 - 5.57 MHz */
unsigned char bdm_rx4(void) {
#pragma NO_RETURN
asm {
LDA #BDM_DIR1_MASK+RESET_OUT_MASK /* contents of A will be driven to PTA in order to switch the driver off */
CLRX /* prepare HX to point to PTA */
CLRH
/* bit 7 (MSB) */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BRN 0 /* wait 3 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
NOP /* wait 1 cycle */
/* bit 6 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BRN 0 /* wait 3 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
NOP /* wait 1 cycle */
/* bit 5 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BRN 0 /* wait 3 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
NOP /* wait 1 cycle */
/* bit 4 */
STX ,X /* drive BDM low */
STA ,X /* switch BDM to high impedance */
BRN 0 /* wait 3 cycles */
LDX ,X /* load X with value on the PTA port (including BDM_IN) */
PSHX /* store the value on the stack */
CLRX /* clear X again */
NOP /* wait 1 cycle */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -