⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bdm.c

📁 Freescale的S08BDM开发工具制作资料
💻 C
📖 第 1 页 / 共 5 页
字号:
    bdm_status.sync_length=(time<<1)+(time<<3);   /* multiply by 10 to get the time in 60MHz ticks */
  #else
    bdm_status.sync_length=time*(60/BUS_FREQUENCY); /* if not 3 or 6 then do it the stupid way... */
  #endif
  bdm_status.speed = SYNC_SUPPORTED; /* SYNC feature is supported by the target */
  return(0);
}

/* waits 64 BDM cycles of the target MCU */
void bdm_wait64(void) {
  asm {
    LDA  bdm_status.wait64_cnt  /* number of loop iterations to wait */
  loop:  
    DBNZA loop                  /* 3 cycles per iteration */
  }
}

/* waits 150 BDM cycles of the target MCU */
void bdm_wait150(void) {
  asm {
    LDA  bdm_status.wait150_cnt  /* number of loop iterations to wait */
  loop:  
    DBNZA loop                  /* 3 cycles per iteration */
  }
}

/* enables ACKN and prepares the timer for easy ACKN timeout use */
void bdm_ackn_init(void) {
  T1MOD = ACKN_TIMEOUT * BUS_FREQUENCY;  /* the timer will set the TOF flag as soon as the timeout time is reached */
  T1SC = T1SC_TRST_MASK;    /* start the timer, prescaler = 1 */
  T1SC0 = T1SC0_ELS0A_MASK;	/* capture rising edges */
  bdm_status.ackn = ACKN; /* switch ACKN on */
  BDM_CMD_ACK_ENABLE();   /* send the enable command to the target */
}

/* waits for ACKN pulse from the target */
void bdm_ackn(void) {
  T1SC = T1SC_TRST_MASK;                      /* clear the TOF flag if set and restart the timer */
  T1SC_TOF = 0;                              /* clear TOF */
  while ((T1SC0_CH0F==0)&&(T1SC_TOF==0));     /* wait for capture or timeout */  
  T1SC0 = T1SC0_ELS0A_MASK;                   /* capture rising edge, clear capture flag */
  if (T1SC_TOF) {
    /* timeout */
    bdm_status.ackn = WAIT;                 /* switch the ackn feature off */
  }
}

/* selects Rx and Tx routine to be used according to SYNC length in bdm_status structure */
/* returns 0 on success and 1 when no appropriate function can be found */
unsigned char bdm_rx_tx_select(void) {
  signed char i;
  bdm_rx_ptr = bdm_empty_rx_tx;                         /* clear the pointers */
  bdm_tx_ptr = bdm_empty_rx_tx;
  for (i=(sizeof(bdm_tx_sel_tresholds)/2)-1;i>=0;i--) { /* search through the table */
    if ((bdm_status.sync_length*2)>=bdm_tx_sel_tresholds[i]) {
      bdm_tx_ptr = bdm_tx_sel_ptrs[i];                  /* is SYNC is >=, select this routine */
      break;                                            /* and finish the search */
    }
  }
  if (bdm_tx_ptr==bdm_empty_rx_tx) return(1);           /* check if valid routine has been found */
  for (i=(sizeof(bdm_rx_sel_tresholds)/2)-1;i>=0;i--) { /* do the same for Rx as well */
    if ((bdm_status.sync_length*2)>=bdm_rx_sel_tresholds[i]) {
      bdm_rx_ptr = bdm_rx_sel_ptrs[i];
      break;
    }
  }
  if (bdm_rx_ptr==bdm_empty_rx_tx) return(1);
  /* there is plenty of overhead: JSR, LDA and RTS of the WAIT, RTS from the previous routine, JSR to the next routine: at least 21 cycles */
  /* cannot subtract more than the smallest possible result -1 as the number must be > 0 */
  bdm_status.wait64_cnt = (bdm_status.sync_length*2)/(3*(60/BUS_FREQUENCY)*128/64)-6; 
  bdm_status.wait150_cnt =(bdm_status.sync_length*2)/(3*(60/BUS_FREQUENCY)*128/150)-7; 
  return(0);
}

/* when no function appropriate for the target speed can be found the following routine is selected */
/* 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 */  
  
  RESET_DR = 0; //Default is B to A for Input
  RESET_DR_DDR |= RESET_DR_MASK;  // Set as output to Drive the buffer
 
  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 = 1;                   /* prepare to drive the BDM once DIR2 is turned to output */
  BDM_DIR2_DDR &= ~BDM_DIR2_MASK; /* turn BDM_DIR2 to input */
  BDM_DIR1 = 0;                   /* 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 */
  T1MOD = SOFT_RESET * BUS_FREQUENCY;  /* load T1MOD with the longest SOFT RESET time possible */
  T1SC = T1SC_TRST_MASK;                /* restart the timer */
  T1SC_TOF = 0;                        /* clear TOF */
  while(T1SC_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_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_OUT_MASK | RESET_OUT_MASK;  /* do not drive RESET nor BDM once DIR1 is output again */
  BDM_DIR2_DDR &= ~BDM_DIR2_MASK;                                              /* 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   #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) */
   bset 7,0
   com  ,x
   
   //mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 6 */                
     bset 7,0
   com  ,x
   //mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 5 */                
     bset 7,0
   com  ,x//mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 4 */                
     bset 7,0
   com  ,x//mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 3 */                
     bset 7,0
   com  ,x//mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 2 */                
     bset 7,0
   com  ,x
   //mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 1 */                
     bset 7,0
   com  ,x
   //mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 0 */                
     bset 7,0
   com  ,x
   //mov #0x10,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   #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) */
    mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 6 */                
    mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 5 */                
    mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 4 */                
    mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 3 */                
    mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 2 */                
    mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 1 */                
    mov #0x10,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) */
    PSHX                    /* store the value on the stack */
    CLRX                    /* clear X again */
    /* bit 0 */                
    mov #0x10,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
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -