//************************************************************************ // ch552.pas //************************************************************************ Unit ch552; Interface {$IDATA } type sfr = Byte; // keil sfr types sfr16 = Record case byte of 0: (w:Word); 1: (l,h: Byte); end; sbit = Boolean; var PSW : sfr absolute $D0; volatile; // program status word CY : sbit absolute PSW.7; // carry flag AC : sbit absolute PSW.6; // auxiliary carry flag F0 : sbit absolute PSW.5; // bit addressable general purpose flag 0 RS1 : sbit absolute PSW.4; // register R0-R7 bank selection high bit RS0 : sbit absolute PSW.3; // register R0-R7 bank selection low bit OV : sbit absolute PSW.2; // overflow flag F1 : sbit absolute PSW.1; // bit addressable general purpose flag 1 P : sbit absolute PSW.0; // ReadOnly: parity flag const MASK_PSW_RS = $18; // bit mask of register R0-R7 bank selection var ACC : sfr absolute $E0; volatile; // accumulator B : sfr absolute $F0; volatile; // general purpose register B SP : sfr absolute $81; volatile; // stack pointer DPL : sfr absolute $82; volatile; // data pointer low DPH : sfr absolute $83; volatile; // data pointer high SAFE_MOD : sfr absolute $A1; volatile; // WriteOnly: writing safe mode CHIP_ID : sfr absolute $A1; volatile; // ReadOnly: reading chip ID //---------------------------------- GLOBAL_CFG: sfr absolute $B1; volatile; // global config, Write@SafeMode const bBOOT_LOAD = $20; // ReadOnly: boot loader status for discriminating BootLoader or Application: set 1 by power on reset, clear 0 by software reset bSW_RESET = $10; // software reset bit, auto clear by hardware bCODE_WE = $08; // enable flash-ROM (include code & Data-Flash) being program or erasing: 0=writing protect, 1=enable program and erase bDATA_WE = $04; // enable Data-Flash (flash-ROM data area) being program or erasing: 0=writing protect, 1=enable program and erase bLDO3V3_OFF = $02; // disable 5V->3.3V LDO: 0=enable LDO for USB and internal oscillator under 5V power, 1=disable LDO, V33 pin input external 3.3V power bWDOG_EN = $01; // enable watch-dog reset if watch-dog timer overflow: 0=as timer only, 1=enable reset if timer overflow //---------------------------------- var PCON : sfr absolute $87; volatile; // power control and reset flag const SMOD = $80; // baud rate selection for UART0 mode 1/2/3: 0=slow(Fsys/128 @mode2, TF1/32 @mode1/3, no effect for TF2), // 1=fast(Fsys/32 @mode2, TF1/16 @mode1/3, no effect for TF2) bRST_FLAG1 = $20; // ReadOnly: recent reset flag high bit bRST_FLAG0 = $10; // ReadOnly: recent reset flag low bit MASK_RST_FLAG = $30; // ReadOnly: bit mask of recent reset flag RST_FLAG_SW = $00; RST_FLAG_POR = $10; RST_FLAG_WDOG = $20; RST_FLAG_PIN = $30; GF1 = $08; // general purpose flag bit 1 GF0 = $04; // general purpose flag bit 0 PD = $02; // power-down enable bit, auto clear by wake-up hardware { bPC_RST_FLAG1 & bPC_RST_FLAG0: recent reset flag 00 - software reset, by bSW_RESET=1 @(bBOOT_LOAD=0 or bWDOG_EN=1) 01 - power on reset 10 - watch-dog timer overflow reset 11 - external input manual reset by RST pin } //---------------------------------- var CLOCK_CFG : sfr absolute $B9; volatile; // system clock config: lower 3 bits for system clock Fsys, Write@SafeMode const bOSC_EN_INT = $80; // internal oscillator enable and original clock selection: 1=enable & select internal clock, 0=disable & select external clock bOSC_EN_XT = $40; // external oscillator enable, need quartz crystal or ceramic resonator between XI and XO pins bWDOG_IF_TO = $20; // ReadOnly: watch-dog timer overflow interrupt flag, cleared by reload watch-dog count or auto cleared when MCU enter interrupt routine bROM_CLK_FAST = $10; // flash-ROM clock frequency selection: 0=normal(for Fosc>=16MHz), 1=fast(for Fosc<16MHz) bRST = $08; // ReadOnly: pin RST input bT2EX_ = $08; // alternate pin for T2EX bCAP2_ = $08; // alternate pin for CAP2 MASK_SYS_CK_SEL = $07; // bit mask of system clock Fsys selection { Fxt = 24MHz(8MHz~25MHz for non-USB application), from external oscillator @XI&XO Fosc = bOSC_EN_INT ? 24MHz : Fxt Fpll = Fosc * 4 => 96MHz (32MHz~100MHz for non-USB application) Fusb4x = Fpll / 2 => 48MHz (Fixed) MASK_SYS_CK_SEL[2] [1] [0] Fsys = Fpll/3 = 32MHz: 1 1 1 Fsys = Fpll/4 = 24MHz: 1 1 0 Fsys = Fpll/6 = 16MHz: 1 0 1 Fsys = Fpll/8 = 12MHz: 1 0 0 Fsys = Fpll/16 = 6MHz: 0 1 1 Fsys = Fpll/32 = 3MHz: 0 1 0 Fsys = Fpll/128 = 750KHz: 0 0 1 Fsys = Fpll/512 =187.5KHz: 0 0 0 } //---------------------------------- var WAKE_CTRL : sfr absolute $A9; volatile; // wake-up control, Write@SafeMode const bWAK_BY_USB = $80; // enable wake-up by USB event bWAK_RXD1_LO = $40; // enable wake-up by RXD1 low level bWAK_P1_5_LO = $20; // enable wake-up by pin P1.5 low level bWAK_P1_4_LO = $10; // enable wake-up by pin P1.4 low level bWAK_P1_3_LO = $08; // enable wake-up by pin P1.3 low level bWAK_RST_HI = $04; // enable wake-up by pin RST high level bWAK_P3_2E_3L = $02; // enable wake-up by pin P3.2 (INT0) edge or pin P3.3 (INT1) low level bWAK_RXD0_LO = $01; // enable wake-up by RXD0 low level //---------------------------------- var RESET_KEEP: sfr absolute $FE; volatile; // value keeper during reset WDOG_COUNT: sfr absolute $FF; volatile; // watch-dog count, count by clock frequency Fsys/65536 // Interrupt Registers IE : sfr absolute $A8; volatile; // interrupt enable EA : sbit absolute IE.7; // enable global interrupts: 0=disable, 1=enable if E_DIS=0 E_DIS : sbit absolute IE.6; // disable global interrupts, intend to inhibit interrupt during some flash-ROM operation: 0=enable if EA=1, 1=disable ET2 : sbit absolute IE.5; // enable timer2 interrupt ES : sbit absolute IE.4; // enable UART0 interrupt ET1 : sbit absolute IE.3; // enable timer1 interrupt EX1 : sbit absolute IE.2; // enable external interrupt INT1 ET0 : sbit absolute IE.1; // enable timer0 interrupt EX0 : sbit absolute IE.0; // enable external interrupt INT0 //---------------------------------- IP : sfr absolute $B8; volatile; // interrupt priority and current priority PH_FLAG : sbit absolute IP.7; // ReadOnly: high level priority action flag PL_FLAG : sbit absolute IP.6; // ReadOnly: low level priority action flag PT2 : sbit absolute IP.5; // timer2 interrupt priority level PS : sbit absolute IP.4; // UART0 interrupt priority level PT1 : sbit absolute IP.3; // timer1 interrupt priority level PX1 : sbit absolute IP.2; // external interrupt INT1 priority level PT0 : sbit absolute IP.1; // timer0 interrupt priority level PX0 : sbit absolute IP.0; // external interrupt INT0 priority level //---------------------------------- IE_EX : sfr absolute $E8; volatile; // extend interrupt enable IE_WDOG : sbit absolute IE_EX.7; // enable watch-dog timer interrupt IE_GPIO : sbit absolute IE_EX.6; // enable GPIO input interrupt IE_PWMX : sbit absolute IE_EX.5; // enable PWM1/2 interrupt IE_UART1: sbit absolute IE_EX.4; // enable UART1 interrupt IE_ADC : sbit absolute IE_EX.3; // enable ADC interrupt IE_USB : sbit absolute IE_EX.2; // enable USB interrupt IE_TKEY : sbit absolute IE_EX.1; // enable touch-key timer interrupt IE_SPI0 : sbit absolute IE_EX.0; // enable SPI0 interrupt //---------------------------------- var IP_EX : sfr absolute $E9; volatile; // extend interrupt priority const bIP_LEVEL = $80; // ReadOnly: current interrupt nested level: 0=no interrupt or two levels, 1=one level bIP_GPIO = $40; // GPIO input interrupt priority level bIP_PWMX = $20; // PWM1/2 interrupt priority level bIP_UART1 = $10; // UART1 interrupt priority level bIP_ADC = $08; // ADC interrupt priority level bIP_USB = $04; // USB interrupt priority level bIP_TKEY = $02; // touch-key timer interrupt priority level bIP_SPI0 = $01; // SPI0 interrupt priority level //---------------------------------- var GPIO_IE : sfr absolute $C7; volatile; // GPIO interrupt enable const bIE_IO_EDGE = $80; // enable GPIO edge interrupt: 0=low/high level, 1=falling/rising edge bIE_RXD1_LO = $40; // enable interrupt by RXD1 low level / falling edge bIE_P1_5_LO = $20; // enable interrupt by pin P1.5 low level / falling edge bIE_P1_4_LO = $10; // enable interrupt by pin P1.4 low level / falling edge bIE_P1_3_LO = $08; // enable interrupt by pin P1.3 low level / falling edge bIE_RST_HI = $04; // enable interrupt by pin RST high level / rising edge bIE_P3_1_LO = $02; // enable interrupt by pin P3.1 low level / falling edge bIE_RXD0_LO = $01; // enable interrupt by RXD0 low level / falling edge //---------------------------------- //FlashROM and Data-Flash Registers var ROM_ADDR :sfr16 absolute $84; volatile; // address for flash-ROM, little-endian ROM_ADDR_L: sfr absolute $84; volatile; // address low byte for flash-ROM ROM_ADDR_H: sfr absolute $85; volatile; // address high byte for flash-ROM ROM_DATA :sfr16 absolute $8E; volatile; // data for flash-ROM writing, little-endian ROM_DATA_L: sfr absolute $8E; volatile; // data low byte for flash-ROM writing, data byte for Data-Flash reading/writing ROM_DATA_H: sfr absolute $8F; volatile; // data high byte for flash-ROM writing ROM_CTRL : sfr absolute $86; volatile; // WriteOnly: flash-ROM control ROM_STATUS: sfr absolute $86; volatile; // ReadOnly: flash-ROM status const ROM_CMD_WRITE = $9A; // WriteOnly: flash-ROM word or Data-Flash byte write operation command ROM_CMD_READ = $8E; // WriteOnly: Data-Flash byte read operation command bROM_ADDR_OK = $40; // ReadOnly: flash-ROM writing operation address valid flag, can be reviewed before or after operation: 0=invalid parameter, 1=address valid bROM_CMD_ERR = $02; // ReadOnly: flash-ROM operation command error flag: 0=command accepted, 1=unknown command //---------------------------------- //Port Registers var P1 : sfr absolute $90; volatile; // port 1 input & output P1_0 :sbit absolute P1.0; P1_1 :sbit absolute P1.1; P1_2 :sbit absolute P1.2; P1_3 :sbit absolute P1.3; P1_4 :sbit absolute P1.4; P1_5 :sbit absolute P1.5; P1_6 :sbit absolute P1.6; P1_7 :sbit absolute P1.7; SCK : sbit absolute P1.7; // serial clock for SPI0 TXD1 : sbit absolute P1.7; // TXD output for UART1 TIN5 : sbit absolute P1.7; // TIN5 for Touch-Key MISO : sbit absolute P1.6; // master serial data input or slave serial data output for SPI0 RXD1 : sbit absolute P1.6; // RXD input for UART1 TIN4 : sbit absolute P1.6; // TIN4 for Touch-Key MOSI : sbit absolute P1.5; // master serial data output or slave serial data input for SPI0 PWM1 : sbit absolute P1.5; // PWM output for PWM1 TIN3 : sbit absolute P1.5; // TIN3 for Touch-Key UCC2 : sbit absolute P1.5; // CC2 for USB type-C AIN2 : sbit absolute P1.5; // AIN2 for ADC T2_ : sbit absolute P1.4; // alternate pin for T2 CAP1_ : sbit absolute P1.4; // alternate pin for CAP1 SCS : sbit absolute P1.4; // slave chip-selection input for SPI0 TIN2 : sbit absolute P1.4; // TIN2 for Touch-Key UCC1 : sbit absolute P1.4; // CC1 for USB type-C AIN1 : sbit absolute P1.4; // AIN1 for ADC TXD_ : sbit absolute P1.3; // alternate pin for TXD of UART0 RXD_ : sbit absolute P1.2; // alternate pin for RXD of UART0 T2EX : sbit absolute P1.1; // external trigger input for timer2 reload & capture CAP2 : sbit absolute P1.1; // capture2 input for timer2 TIN1 : sbit absolute P1.1; // TIN1 for Touch-Key VBUS2 : sbit absolute P1.1; // VBUS2 for USB type-C AIN0 : sbit absolute P1.1; // AIN0 for ADC T2 : sbit absolute P1.0; // external count input CAP1 : sbit absolute P1.0; // capture1 input for timer2 TIN0 : sbit absolute P1.0; // TIN0 for Touch-Key P1_MOD_OC : sfr absolute $92; volatile; // port 1 output mode: 0=push-pull, 1=open-drain P1_DIR_PU : sfr absolute $93; volatile; // port 1 direction for push-pull or pullup enable for open-drain P2 : sfr absolute $A0; volatile; // port 2 does not exist P3 : sfr absolute $B0; volatile; // port 3 input & output P3_0 : sbit absolute P3.0; P3_1 : sbit absolute P3.1; P3_2 : sbit absolute P3.2; P3_3 : sbit absolute P3.3; P3_4 : sbit absolute P3.4; P3_5 : sbit absolute P3.5; P3_6 : sbit absolute P3.6; P3_7 : sbit absolute P3.7; UDM : sbit absolute P3.7; // ReadOnly: pin UDM input UDP : sbit absolute P3.6; // ReadOnly: pin UDP input T1 : sbit absolute P3.5; // external count input for timer1 PWM2 : sbit absolute P3.4; // PWM output for PWM2 RXD1_ : sbit absolute P3.4; // alternate pin for RXD1 T0 : sbit absolute P3.4; // external count input for timer0 INT1 : sbit absolute P3.3; // external interrupt 1 input TXD1_ : sbit absolute P3.2; // alternate pin for TXD1 INT0 : sbit absolute P3.2; // external interrupt 0 input VBUS1 : sbit absolute P3.2; // VBUS1 for USB type-C AIN3 : sbit absolute P3.2; // AIN3 for ADC PWM2_ : sbit absolute P3.1; // alternate pin for PWM2 TXD : sbit absolute P3.1; // TXD output for UART0 PWM1_ : sbit absolute P3.0; // alternate pin for PWM1 RXD : sbit absolute P3.0; // RXD input for UART0 P3_MOD_OC : sfr absolute $96; volatile; // port 3 output mode: 0=push-pull, 1=open-drain P3_DIR_PU : sfr absolute $97; volatile; // port 3 direction for push-pull or pullup enable for open-drain //---------------------------------- PIN_FUNC : sfr absolute $C6; volatile; // pin function selection const bUSB_IO_EN = $80; // USB UDP/UDM I/O pin enable: 0=P3.6/P3.7 as GPIO, 1=P3.6/P3.7 as USB bIO_INT_ACT = $40; // ReadOnly: GPIO interrupt request action status bUART1_PIN_X = $20; // UART1 alternate pin enable: 0=RXD1/TXD1 on P1.6/P1.7, 1=RXD1/TXD1 on P3.4/P3.2 bUART0_PIN_X = $10; // UART0 alternate pin enable: 0=RXD0/TXD0 on P3.0/P3.1, 1=RXD0/TXD0 on P1.2/P1.3 bPWM2_PIN_X = $08; // PWM2 alternate pin enable: 0=PWM2 on P3.4, 1=PWM2 on P3.1 bPWM1_PIN_X = $04; // PWM1 alternate pin enable: 0=PWM1 on P1.5, 1=PWM1 on P3.0 bT2EX_PIN_X = $02; // T2EX/CAP2 alternate pin enable: 0=T2EX/CAP2 on P1.1, 1=T2EX/CAP2 on RST bT2_PIN_X = $01; // T2/CAP1 alternate pin enable: 0=T2/CAP1 on P1.1, 1=T2/CAP1 on P1.4 //---------------------------------- var XBUS_AUX : sfr absolute $A2; volatile; // xBUS auxiliary setting const bUART0_TX = $80; // ReadOnly: indicate UART0 transmittal status bUART0_RX = $40; // ReadOnly: indicate UART0 receiving status bSAFE_MOD_ACT = $20; // ReadOnly: safe mode action status GF2 = $08; // general purpose flag bit 2 bDPTR_AUTO_INC = $04; // enable DPTR auto increase if finished MOVX_@DPTR instruction DPS = $01; // dual DPTR selection: 0=DPTR0 selected, 1=DPTR1 selected //---------------------------------- var TCON : sfr absolute $88; volatile; // timer 0/1 control and external interrupt control TF1 : sbit absolute TCON.7; // timer1 overflow & interrupt flag, auto cleared when MCU enter interrupt routine TR1 : sbit absolute TCON.6; // timer1 run enable TF0 : sbit absolute TCON.5; // timer0 overflow & interrupt flag, auto cleared when MCU enter interrupt routine TR0 : sbit absolute TCON.4; // timer0 run enable IE1 : sbit absolute TCON.3; // INT1 interrupt flag, auto cleared when MCU enter interrupt routine IT1 : sbit absolute TCON.2; // INT1 interrupt type: 0=low level action, 1=falling edge action IE0 : sbit absolute TCON.1; // INT0 interrupt flag, auto cleared when MCU enter interrupt routine IT0 : sbit absolute TCON.0; // INT0 interrupt type: 0=low level action, 1=falling edge action //---------------------------------- TMOD : sfr absolute $89; volatile; // timer 0/1 mode const T1_GATE = $80; // gate control of timer1: 0=timer1 run enable while TR1=1, 1=timer1 run enable while P3.3 (INT1) pin is high and TR1=1 bT1_CT = $40; // counter or timer mode selection for timer1: 0=timer, use internal clock, 1=counter, use P3.5 (T1) pin falling edge as clock bT1_M1 = $20; // timer1 mode high bit bT1_M0 = $10; // timer1 mode low bit MASK_T1_MOD = $30; // bit mask of timer1 mode bT0_GATE = $08; // gate control of timer0: 0=timer0 run enable while TR0=1, 1=timer0 run enable while P3.2 (INT0) pin is high and TR0=1 bT0_CT = $04; // counter or timer mode selection for timer0: 0=timer, use internal clock, 1=counter, use P3.4 (T0) pin falling edge as clock bT0_M1 = $02; // timer0 mode high bit bT0_M0 = $01; // timer0 mode low bit MASK_T0_MOD = $03; // bit mask of timer0 mode { bT1_M1 & bT1_M0: timer1 mode 00: mode 0, 13-bit timer or counter by cascaded TH1 and lower 5 bits of TL1, the upper 3 bits of TL1 are ignored 01: mode 1, 16-bit timer or counter by cascaded TH1 and TL1 10: mode 2, TL1 operates as 8-bit timer or counter, and TH1 provide initial value for TL1 auto-reload 11: mode 3, stop timer1 } //---------------------------------- var TL0 : sfr absolute $8A; volatile; // low byte of timer 0 count TL1 : sfr absolute $8B; volatile; // low byte of timer 1 count TH0 : sfr absolute $8C; volatile; // high byte of timer 0 count TH1 : sfr absolute $8D; volatile; // high byte of timer 1 count //---------------------------------- SCON : sfr absolute $98; volatile; // UART0 control (serial port control) SM0 : sbit absolute SCON.7; // UART0 mode bit0, selection data bit: 0=8 bits data, 1=9 bits data SM1 : sbit absolute SCON.6; // UART0 mode bit1, selection baud rate: 0=fixed, 1=variable SM2 : sbit absolute SCON.5; // enable multi-device communication in mode 2/3 REN : sbit absolute SCON.4; // enable UART0 receiving TB8 : sbit absolute SCON.3; // the 9th transmitted data bit in mode 2/3 RB8 : sbit absolute SCON.2; // 9th data bit received in mode 2/3, or stop bit received for mode 1 TI : sbit absolute SCON.1; // transmit interrupt flag, set by hardware after completion of a serial transmittal, need software clear RI : sbit absolute SCON.0; // receive interrupt flag, set by hardware after completion of a serial receiving, need software clear { SM0 & SM1 UART0 mode 00 - mode 0, shift Register, baud rate fixed at: Fsys/12 01 - mode 1, 8-bit UART, baud rate = variable by timer1 or timer2 overflow rate 10 - mode 2, 9-bit UART, baud rate fixed at: Fsys/128@SMOD=0, Fsys/32@SMOD=1 11 - mode 3, 9-bit UART, baud rate = variable by timer1 or timer2 overflow rate } const MASK_UART0_MOD = $E0; // bit mask of UART0 mode //---------------------------------- var SBUF : sfr absolute $99; volatile; // UART0 data buffer: reading for receiving, writing for transmittal //---------------------------------- T2CON : sfr absolute $C8; volatile; // timer 2 control TF2 : sbit absolute SCON.7; // timer2 overflow & interrupt flag, need software clear, the flag will not be set when either RCLK=1 or TCLK=1 CAP1F : sbit absolute SCON.7; // timer2 capture 1 interrupt flag, set by T2 edge trigger if bT2_CAP1_EN=1, need software clear EXF2 : sbit absolute SCON.6; // timer2 external flag, set by T2EX edge trigger if EXEN2=1, need software clear RCLK : sbit absolute SCON.5; // selection UART0 receiving clock: 0=timer1 overflow pulse, 1=timer2 overflow pulse TCLK : sbit absolute SCON.4; // selection UART0 transmittal clock: 0=timer1 overflow pulse, 1=timer2 overflow pulse EXEN2 : sbit absolute SCON.3; // enable T2EX trigger function: 0=ignore T2EX, 1=trigger reload or capture by T2EX edge TR2 : sbit absolute SCON.2; // timer2 run enable C_T2 : sbit absolute SCON.1; // timer2 clock source selection: 0=timer base internal clock, 1=external edge counter base T2 falling edge CP_RL2 : sbit absolute SCON.0; // timer2 function selection (force 0 if RCLK=1 or TCLK=1): 0=timer and auto reload if count overflow or T2EX edge, 1=capture by T2EX edge T2MOD : sfr absolute $C9; volatile; // timer 2 mode and timer 0/1/2 clock mode const bTMR_CLK = $80; // fastest internal clock mode for timer 0/1/2 under faster clock mode: 0=use divided clock, 1=use original Fsys as clock without dividing bT2_CLK = $40; // timer2 internal clock frequency selection: 0=standard clock, Fsys/12 for timer mode, Fsys/4 for UART0 clock mode, // 1=faster clock, Fsys/4 @bTMR_CLK=0 or Fsys @bTMR_CLK=1 for timer mode, Fsys/2 @bTMR_CLK=0 or Fsys @bTMR_CLK=1 for UART0 clock mode bT1_CLK = $20; // timer1 internal clock frequency selection: 0=standard clock, Fsys/12, 1=faster clock, Fsys/4 if bTMR_CLK=0 or Fsys if bTMR_CLK=1 bT0_CLK = $10; // timer0 internal clock frequency selection: 0=standard clock, Fsys/12, 1=faster clock, Fsys/4 if bTMR_CLK=0 or Fsys if bTMR_CLK=1 bT2_CAP_M1 = $08; // timer2 capture mode high bit bT2_CAP_M0 = $04; // timer2 capture mode low bit T2OE = $02; // enable timer2 generated clock output: 0=disable output, 1=enable clock output at T2 pin, frequency = TF2/2 bT2_CAP1_EN= $01; // enable T2 trigger function for capture 1 of timer2 if RCLK=0 & TCLK=0 & CP_RL2=1 & C_T2=0 & T2OE=0 { bT2_CAP_M1 & bT2_CAP_M0: timer2 capture point selection x0: from falling edge to falling edge 01: from any edge to any edge (level changing) 11: from rising edge to rising edge } var RCAP2 : sfr16 absolute $CA; volatile; // reload & capture value, little-endian RCAP2L : sfr absolute $CA; volatile; // low byte of reload & capture value RCAP2H : sfr absolute $CB; volatile; // high byte of reload & capture value T2COUNT: sfr16 absolute $CC; volatile; // counter, little-endian TL2 : sfr absolute $CC; volatile; // low byte of timer 2 count TH2 : sfr absolute $CD; volatile; // high byte of timer 2 count T2CAP1 : sfr16 absolute $CE; volatile; // ReadOnly: capture 1 value for timer2 T2CAP1L: sfr absolute $CE; volatile; // ReadOnly: capture 1 value low byte for timer2 T2CAP1H: sfr absolute $CF; volatile; // ReadOnly: capture 1 value high byte for timer2 PWM_DATA2 : sfr absolute $9B; volatile; // PWM data for PWM2 PWM_DATA1 : sfr absolute $9C; volatile; // PWM data for PWM1 //---------------------------------- PWM_CTRL : sfr absolute $9D; volatile; // PWM 1/2 control const bPWM_IE_END = $80; // enable interrupt for PWM mode cycle end bPWM2_POLAR = $40; // PWM2 output polarity: 0=default low and high action, 1=default high and low action bPWM1_POLAR = $20; // PWM1 output polarity: 0=default low and high action, 1=default high and low action bPWM_IF_END = $10; // interrupt flag for cycle end, write 1 to clear or write PWM_CYCLE or load new data to clear bPWM2_OUT_EN = $08; // PWM2 output enable bPWM1_OUT_EN = $04; // PWM1 output enable bPWM_CLR_ALL = $02; // force clear FIFO and count of PWM1/2 //---------------------------------- var PWM_CK_SE : sfr absolute $9E; volatile; // clock divisor setting SPI0_STAT : sfr absolute $F8; volatile; // SPI 0 status S0_FST_ACT :sbit absolute SPI0_STAT.7; // ReadOnly: indicate first byte received status for SPI0 S0_IF_OV :sbit absolute SPI0_STAT.6; // interrupt flag for slave mode FIFO overflow, direct bit address clear or write 1 to clear S0_IF_FIRST :sbit absolute SPI0_STAT.5; // interrupt flag for first byte received, direct bit address clear or write 1 to clear S0_IF_BYTE :sbit absolute SPI0_STAT.4; // interrupt flag for a byte data exchanged, direct bit address clear or write 1 to clear or accessing FIFO to clear if bS0_AUTO_IF=1 S0_FREE :sbit absolute SPI0_STAT.3; // ReadOnly: SPI0 free status S0_T_FIFO :sbit absolute SPI0_STAT.2; // ReadOnly: tx FIFO count for SPI0 S0_R_FIFO :sbit absolute SPI0_STAT.0; // ReadOnly: rx FIFO count for SPI0 SPI0_DATA : sfr absolute $F9; volatile; // FIFO data port: reading for receiving, writing for transmittal //---------------------------------- SPI0_CTRL : sfr absolute $FA; volatile; // SPI 0 control const bS0_MISO_OE = $80; // SPI0 MISO output enable bS0_MOSI_OE = $40; // SPI0 MOSI output enable bS0_SCK_OE = $20; // SPI0 SCK output enable bS0_DATA_DIR = $10; // SPI0 data direction: 0=out(master_write), 1=in(master_read) bS0_MST_CLK = $08; // SPI0 master clock mode: 0=mode 0 with default low, 1=mode 3 with default high bS0_2_WIRE = $04; // enable SPI0 two wire mode: 0=3 wire (SCK+MOSI+MISO), 1=2 wire (SCK+MISO) bS0_CLR_ALL = $02; // force clear FIFO and count of SPI0 bS0_AUTO_IF = $01; // enable FIFO accessing to auto clear S0_IF_BYTE interrupt flag //---------------------------------- var SPI0_CK_SE : sfr absolute $FB; volatile; // clock divisor setting SPI0_S_PRE : sfr absolute $FB; volatile; // preset value for SPI slave //---------------------------------- SPI0_SETUP : sfr absolute $FC; volatile; // SPI 0 setup const bS0_MODE_SLV = $80; // SPI0 slave mode: 0=master, 1=slave bS0_IE_FIFO_OV = $40; // enable interrupt for slave mode FIFO overflow bS0_IE_FIRST = $20; // enable interrupt for first byte received for SPI0 slave mode bS0_IE_BYTE = $10; // enable interrupt for a byte received bS0_BIT_ORDER = $08; // SPI0 bit data order: 0=MSB first, 1=LSB first bS0_SLV_SELT = $02; // ReadOnly: SPI0 slave mode chip selected status: 0=unselected, 1=selected bS0_SLV_PRELOAD = $01; // ReadOnly: SPI0 slave mode data pre-loading status just after chip-selection //---------------------------------- var SCON1 : sfr absolute $C0; volatile; // UART1 control (serial port control) U1SM0 : sbit absolute SCON1.7; // UART1 mode, selection data bit: 0=8 bits data, 1=9 bits data U1SMOD : sbit absolute SCON1.5; // UART1 2X baud rate selection: 0=slow(Fsys/32/(256-SBAUD1)), 1=fast(Fsys/16/(256-SBAUD1)) U1REN : sbit absolute SCON1.4; // enable UART1 receiving U1TB8 : sbit absolute SCON1.3; // the 9th transmitted data bit in 9 bits data mode U1RB8 : sbit absolute SCON1.2; // 9th data bit received in 9 bits data mode, or stop bit received for 8 bits data mode U1TI : sbit absolute SCON1.1; // transmit interrupt flag, set by hardware after completion of a serial transmittal, need software clear U1RI : sbit absolute SCON1.0; // receive interrupt flag, set by hardware after completion of a serial receiving, need software clear SBUF1 : sfr absolute $C1; volatile;// UART1 data buffer: reading for receiving, writing for transmittal SBAUD1 : sfr absolute $C2; volatile;// UART1 baud rate setting // ADC and comparator Registers ADC_CTRL : sfr absolute $80; volatile; // ADC control CMPO : sbit absolute ADC_CTRL.7; // ReadOnly: comparator result input CMP_IF : sbit absolute ADC_CTRL.6; // flag for comparator result changed, direct bit address clear ADC_IF : sbit absolute ADC_CTRL.5; // interrupt flag for ADC finished, direct bit address clear ADC_START : sbit absolute ADC_CTRL.4; // set 1 to start ADC, auto cleared when ADC finished CMP_CHAN : sbit absolute ADC_CTRL.3; // comparator IN- input channel selection: 0=AIN1, 1=AIN3 ADC_CHAN1 : sbit absolute ADC_CTRL.1; // ADC/comparator IN+ channel selection high bit ADC_CHAN0 : sbit absolute ADC_CTRL.0; // ADC/comparator IN+ channel selection low bit { ADC_CHAN1 & ADC_CHAN0: ADC/comparator IN+ channel selection 00: AIN0(P1.1) 01: AIN1(P1.4) 10: AIN2(P1.5) 11: AIN3(P3.2) } ADC_CFG : sfr absolute $9A; volatile; // ADC config const bADC_EN = $08; // control ADC power: 0=shut down ADC, 1=enable power for ADC bCMP_EN = $04; // control comparator power: 0=shut down comparator, 1=enable power for comparator bADC_CLK = $01; // ADC clock frequency selection: 0=slow clock, 384 Fosc cycles for each ADC, 1=fast clock, 96 Fosc cycles for each ADC var ADC_DATA : sfr absolute $9F; volatile;// ReadOnly: ADC data // Touch-key timer Registers TKEY_CTRL : sfr absolute $C3; volatile;// touch-key control const bTKC_IF = $80; // ReadOnly: interrupt flag for touch-key timer, cleared by writing touch-key control or auto cleared when start touch-key checking bTKC_2MS = $10; // touch-key timer cycle selection: 0=1mS, 1=2mS bTKC_CHAN2 = $04; // touch-key channel selection high bit bTKC_CHAN1 = $02; // touch-key channel selection middle bit bTKC_CHAN0 = $01; // touch-key channel selection low bit { bTKC_CHAN2 & bTKC_CHAN1 & bTKC_CHAN0: touch-key channel selection 000: disable touch-key 001: TIN0(P1.0) 010: TIN1(P1.1) 011: TIN2(P1.4) 100: TIN3(P1.5) 101: TIN4(P1.6) 110: TIN5(P1.7) 111: enable touch-key but disable all channel } var TKEY_DAT : sfr16 absolute $C4; volatile; // ReadOnly: touch-key data, little-endian TKEY_DATL : sfr absolute $C4; volatile; // ReadOnly: low byte of touch-key data TKEY_DATH : sfr absolute $C5; volatile; // ReadOnly: high byte of touch-key data const bTKD_CHG = $80; // ReadOnly: indicate control changed, current data maybe invalid // USB Device Registers var USB_C_CTRL : sfr absolute $91; volatile; // USB type-C control const bVBUS2_PD_EN = $80; // USB VBUS2 10K pulldown resistance: 0=disable, 1=enable pullup bUCC2_PD_EN = $40; // USB CC2 5.1K pulldown resistance: 0=disable, 1=enable pulldown bUCC2_PU1_EN = $20; // USB CC2 pullup resistance control high bit bUCC2_PU0_EN = $10; // USB CC2 pullup resistance control low bit bVBUS1_PD_EN = $08; // USB VBUS1 10K pulldown resistance: 0=disable, 1=enable pullup bUCC1_PD_EN = $04; // USB CC1 5.1K pulldown resistance: 0=disable, 1=enable pulldown bUCC1_PU1_EN = $02; // USB CC1 pullup resistance control high bit bUCC1_PU0_EN = $01; // USB CC1 pullup resistance control low bit { bUCC?_PU1_EN & bUCC?_PU0_EN: USB CC pullup resistance selection 00: disable pullup resistance 01: enable 56K pullup resistance for default USB power 10: enable 22K pullup resistance for 1.5A USB power 11: enable 10K pullup resistance for 3A USB power } var UDEV_CTRL : sfr absolute $D1; volatile; // USB device physical port control const bUD_PD_DIS = $80; // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable bUD_DP_PIN = $20; // ReadOnly: indicate current UDP pin level bUD_DM_PIN = $10; // ReadOnly: indicate current UDM pin level bUD_LOW_SPEED = $04; // enable USB physical port low speed: 0=full speed, 1=low speed bUD_GP_BIT = $02; // general purpose bit bUD_PORT_EN = $01; // enable USB physical port I/O: 0=disable, 1=enable var UEP1_CTRL : sfr absolute $D2; volatile; // endpoint 1 control const bUEP_R_TOG =$80; // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1 bUEP_T_TOG =$40; // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1 bUEP_AUTO_TOG =$10; // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle bUEP_R_RES1 =$08; // handshake response type high bit for USB endpoint X receiving (OUT) bUEP_R_RES0 =$04; // handshake response type low bit for USB endpoint X receiving (OUT) MASK_UEP_R_RES =$0C; // bit mask of handshake response type for USB endpoint X receiving (OUT) UEP_R_RES_ACK =$00; UEP_R_RES_TOUT =$04; UEP_R_RES_NAK =$08; UEP_R_RES_STALL=$0C; { bUEP_R_RES1 & bUEP_R_RES0: handshake response type for USB endpoint X receiving (OUT) 00: ACK (ready) 01: no response, time out to host, for non-zero endpoint isochronous transactions 10: NAK (busy) 11: STALL (error) } bUEP_T_RES1 =$02; // handshake response type high bit for USB endpoint X transmittal (IN) bUEP_T_RES0 =$01; // handshake response type low bit for USB endpoint X transmittal (IN) MASK_UEP_T_RES =$03; // bit mask of handshake response type for USB endpoint X transmittal (IN) UEP_T_RES_ACK =$00; UEP_T_RES_TOUT =$01; UEP_T_RES_NAK =$02; UEP_T_RES_STALL=$03; { bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN) 00: DATA0 or DATA1 then expecting ACK (ready) 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions 10: NAK (busy) 11: STALL (error) } var UEP1_T_LEN : sfr absolute $D3; volatile; // endpoint 1 transmittal length UEP2_CTRL : sfr absolute $D4; volatile; // endpoint 2 control UEP2_T_LEN : sfr absolute $D5; volatile; // endpoint 2 transmittal length UEP3_CTRL : sfr absolute $D6; volatile; // endpoint 3 control UEP3_T_LEN : sfr absolute $D7; volatile; // endpoint 3 transmittal length USB_INT_FG : sfr absolute $D8; volatile; // USB interrupt flag U_IS_NAK : sbit absolute USB_INT_FG.7; // ReadOnly: indicate current USB transfer is NAK received U_TOG_OK : sbit absolute USB_INT_FG.6; // ReadOnly: indicate current USB transfer toggle is OK U_SIE_FREE : sbit absolute USB_INT_FG.5; // ReadOnly: indicate USB SIE free status UIF_FIFO_OV : sbit absolute USB_INT_FG.4; // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear UIF_SUSPEND : sbit absolute USB_INT_FG.2; // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear UIF_TRANSFER : sbit absolute USB_INT_FG.1; // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear UIF_BUS_RST : sbit absolute USB_INT_FG.0; // bus reset event interrupt flag, direct bit address clear or write 1 to clear USB_INT_ST : sfr absolute $D9; volatile; // ReadOnly: USB interrupt status const bUIS_IS_NAK = $80; // ReadOnly: indicate current USB transfer is NAK received bUIS_TOG_OK = $40; // ReadOnly: indicate current USB transfer toggle is OK bUIS_TOKEN1 = $20; // ReadOnly: current token PID code bit 1 received bUIS_TOKEN0 = $10; // ReadOnly: current token PID code bit 0 received MASK_UIS_TOKEN = $30; // ReadOnly: bit mask of current token PID code received UIS_TOKEN_OUT = $00; UIS_TOKEN_SOF = $10; UIS_TOKEN_IN = $20; UIS_TOKEN_SETUP = $30; MASK_UIS_ENDP = $0F; // ReadOnly: bit mask of current transfer endpoint number { bUIS_TOKEN1 & bUIS_TOKEN0: current token PID code received 00: OUT token PID received 01: SOF token PID received 10: IN token PID received 11: SETUP token PID received } var USB_MIS_ST : sfr absolute $DA; volatile; // ReadOnly: USB miscellaneous status const bUMS_SIE_FREE = $20; // ReadOnly: indicate USB SIE free status bUMS_R_FIFO_RDY = $10; // ReadOnly: indicate USB receiving FIFO ready status (not empty) bUMS_BUS_RESET = $08; // ReadOnly: indicate USB bus reset status bUMS_SUSPEND = $04; // ReadOnly: indicate USB suspend status var USB_RX_LEN : sfr absolute $DB; volatile; // ReadOnly: USB receiving length UEP0_CTRL : sfr absolute $DC; volatile; // endpoint 0 control UEP0_T_LEN : sfr absolute $DD; volatile; // endpoint 0 transmittal length UEP4_CTRL : sfr absolute $DE; volatile; // endpoint 4 control UEP4_T_LEN : sfr absolute $DF; volatile; // endpoint 4 transmittal length USB_INT_EN : sfr absolute $E1; volatile; // USB interrupt enable const bUIE_DEV_SOF = $80; // enable interrupt for SOF received bUIE_DEV_NAK = $40; // enable interrupt for NAK responded bUIE_FIFO_OV = $10; // enable interrupt for FIFO overflow bUIE_SUSPEND = $04; // enable interrupt for USB suspend or resume event bUIE_TRANSFER = $02; // enable interrupt for USB transfer completion bUIE_BUS_RST = $01; // enable interrupt for USB bus reset event var USB_CTRL : sfr absolute $E2; volatile; // USB base control const //bUC_HOST_MODE = $80; // 554 only hostmode bUC_LOW_SPEED = $40; // enable USB low speed: 0=full speed, 1=low speed bUC_DEV_PU_EN = $20; // USB device enable and internal pullup resistance enable bUC_SYS_CTRL1 = $20; // USB system control high bit bUC_SYS_CTRL0 = $10; // USB system control low bit MASK_UC_SYS_CTRL = $30; // bit mask of USB system control { bUC_SYS_CTRL1 & bUC_SYS_CTRL0: USB system control 00: disable USB device and disable internal pullup resistance 01: enable USB device and disable internal pullup resistance, need external pullup resistance 1x: enable USB device and enable internal pullup resistance bUC_INT_BUSY = $08; // enable automatic responding busy during interrupt flag UIF_TRANSFER valid bUC_RESET_SIE = $04; // force reset USB SIE, need software clear bUC_CLR_ALL = $02; // force clear FIFO and count of USB bUC_DMA_EN = $01; // DMA enable and DMA interrupt enable for USB } var USB_DEV_AD : sfr absolute $E3; volatile; // USB device address, lower 7 bits for USB device address const bUDA_GP_BIT = $80; // general purpose bit MASK_USB_ADDR = $7F; // bit mask for USB device address var UEP2_DMA : sfr16 absolute $E4; volatile; // endpoint 2 buffer start address, little-endian UEP3_DMA : sfr16 absolute $E6; volatile; // endpoint 3 buffer start address, little-endian UEP2_DMA_L : sfr absolute $E4; volatile; // endpoint 2 buffer start address low byte UEP2_DMA_H : sfr absolute $E5; volatile; // endpoint 2 buffer start address high byte UEP3_DMA_L : sfr absolute $E6; volatile; // endpoint 3 buffer start address low byte UEP3_DMA_H : sfr absolute $E7; volatile; // endpoint 3 buffer start address high byte UEP4_1_MOD : sfr absolute $EA; volatile; // endpoint 4/1 mode const bUEP1_RX_EN = $80; // enable USB endpoint 1 receiving (OUT) bUEP1_TX_EN = $40; // enable USB endpoint 1 transmittal (IN) bUEP1_BUF_MOD = $10; // buffer mode of USB endpoint 1 { bUEPn_RX_EN & bUEPn_TX_EN & bUEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA 0 0 x: disable endpoint and disable buffer 1 0 0: 64 bytes buffer for receiving (OUT endpoint) 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes 0 1 0: 64 bytes buffer for transmittal (IN endpoint) 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes } bUEP4_RX_EN = $08; // enable USB endpoint 4 receiving (OUT) bUEP4_TX_EN = $04; // enable USB endpoint 4 transmittal (IN) { bUEP4_RX_EN & bUEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes } var UEP2_3_MOD : sfr absolute $EB; volatile; // endpoint 2/3 mode const bUEP3_RX_EN = $80; // enable USB endpoint 3 receiving (OUT) bUEP3_TX_EN = $40; // enable USB endpoint 3 transmittal (IN) bUEP3_BUF_MOD = $10; // buffer mode of USB endpoint 3 bUEP2_RX_EN = $08; // enable USB endpoint 2 receiving (OUT) bUEP2_TX_EN = $04; // enable USB endpoint 2 transmittal (IN) bUEP2_BUF_MOD = $01; // buffer mode of USB endpoint 2 var UEP0_DMA : sfr16 absolute $EC; volatile; // endpoint 0 buffer start address, little-endian UEP1_DMA : sfr16 absolute $EE; volatile; // endpoint 1 buffer start address, little-endian UEP0_DMA_L : sfr absolute $EC; volatile; // endpoint 0 buffer start address low byte UEP0_DMA_H : sfr absolute $ED; volatile; // endpoint 0 buffer start address high byte UEP1_DMA_L : sfr absolute $EE; volatile; // endpoint 1 buffer start address low byte UEP1_DMA_H : sfr absolute $EF; volatile; // endpoint 1 buffer start address high byte //----- XDATA: xRAM ------------------------------------------ const XDATA_RAM_SIZE = $0400; // size of expanded xRAM, xdata SRAM embedded chip //----- Reference Information -------------------------------------------- //ID_CH554 = $54; // chip ID ID_CH552 = $52; // chip ID //ID_CH551 = $51; // chip ID // Interrupt routine address and interrupt number INT_ADDR_INT0 = $0003; // interrupt vector address for INT0 INT_ADDR_TMR0 = $000B; // interrupt vector address for timer0 INT_ADDR_INT1 = $0013; // interrupt vector address for INT1 INT_ADDR_TMR1 = $001B; // interrupt vector address for timer1 INT_ADDR_UART0 = $0023; // interrupt vector address for UART0 INT_ADDR_TMR2 = $002B; // interrupt vector address for timer2 INT_ADDR_SPI0 = $0033; // interrupt vector address for SPI0 INT_ADDR_TKEY = $003B; // interrupt vector address for touch-key timer INT_ADDR_USB = $0043; // interrupt vector address for USB INT_ADDR_ADC = $004B; // interrupt vector address for ADC INT_ADDR_UART1 = $0053; // interrupt vector address for UART1 INT_ADDR_PWMX = $005B; // interrupt vector address for PWM1/2 INT_ADDR_GPIO = $0063; // interrupt vector address for GPIO INT_ADDR_WDOG = $006B; // interrupt vector address for watch-dog timer INT_NO_INT0 = 0; // interrupt number for INT0 INT_NO_TMR0 = 1; // interrupt number for timer0 INT_NO_INT1 = 2; // interrupt number for INT1 INT_NO_TMR1 = 3; // interrupt number for timer1 INT_NO_UART0 = 4; // interrupt number for UART0 INT_NO_TMR2 = 5; // interrupt number for timer2 INT_NO_SPI0 = 6; // interrupt number for SPI0 INT_NO_TKEY = 7; // interrupt number for touch-key timer INT_NO_USB = 8; // interrupt number for USB INT_NO_ADC = 9; // interrupt number for ADC INT_NO_UART1 = 10; // interrupt number for UART1 INT_NO_PWMX = 11; // interrupt number for PWM1/2 INT_NO_GPIO = 12; // interrupt number for GPIO INT_NO_WDOG = 13; // interrupt number for watch-dog timer // Special Program Space DATA_FLASH_ADDR = $C000; // start address of Data-Flash BOOT_LOAD_ADDR = $3800; // start address of boot loader program ROM_CFG_ADDR = $3FF8; // chip configuration information address ROM_CHIP_ID_HX = $3FFA; // chip ID number highest byte (only low byte valid) ROM_CHIP_ID_LO = $3FFC; // chip ID number low word ROM_CHIP_ID_HI = $3FFE; // chip ID number high word { New Instruction: MOVX @DPTR1,A Instruction Code: 0xA5 Instruction Cycle: 1 Instruction Operation: step-1. write ACC @DPTR1 into xdata SRAM embedded chip step-2. increase DPTR1 ASM example: INC XBUS_AUX MOV DPTR,#TARGET_ADDR ;DPTR1 DEC XBUS_AUX MOV DPTR,#SOURCE_ADDR ;DPTR0 MOV R7,#xxH LOOP: MOVX A,@DPTR ;DPTR0 INC DPTR ;DPTR0, if need DB 0A5H ;MOVX @DPTR1,A & INC DPTR1 DJNZ R7,LOOP } Implementation end.