├── .gitignore ├── .gitmodules ├── Dockerfile ├── README.md ├── build.sh └── src ├── Makefile ├── config.h ├── hal.c ├── hal.h ├── main.c ├── spi.c └── uart.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.tmp 3 | *.bin 4 | *.ihx 5 | *.hex 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ch554_sdcc"] 2 | path = ch554_sdcc 3 | url = https://github.com/Blinkinlabs/ch554_sdcc 4 | 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | RUN apt update && apt install -y sdcc git make binutils 3 | COPY . /code 4 | WORKDIR /code 5 | RUN git submodule update --init 6 | WORKDIR /code/src 7 | RUN make 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Features 2 | ====== 3 | 4 | An USB to JTAG Converter firmware running on CH552T, with some Gowin Quirks. 5 | 6 | Issues 7 | -------------- 8 | 9 | Serial port is working but with some limitation. Because the CPU is running at 16MHz, generate 115200 baudrate is not possible. The fastest standard baudrate is 57600, you can use 125000 and up to 1Mbps baudrate. 10 | 11 | Pin layout 12 | -------------- 13 | 14 | P1.1 - TMS 15 | 16 | P1.4 & P1.7 - TCK 17 | 18 | P1.5 - TDI 19 | 20 | P1.6 - TDO 21 | 22 | P3.0 - RXD 23 | 24 | P3.1 - TXD 25 | 26 | 27 | Boards 28 | -------------- 29 | 30 | Sipeed Lichee Tang Nano. 31 | Simple JTAG 32 | 33 | Build 34 | -------------- 35 | 36 | It requires make, sdcc and binutils. 37 | 38 | If you got all of them, enter the src directory, and type "make" to generate binary file. 39 | 40 | Programming 41 | -------------- 42 | 43 | By WinchipHead's official WCHISPTOOL or LibreCH551 from rgwan. New chip with bootloader version > 2.30 may not working with librech551, it needs some fix. 44 | 45 | License 46 | -------------- 47 | 48 | MIT 49 | 50 | Authors 51 | -------------- 52 | 53 | Kongou Hikari 54 | 55 | Translations by 56 | -------------- 57 | Rabid Inventor 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | PROJECT=ch55xjtag 6 | 7 | docker build -t ${PROJECT} -f Dockerfile . 8 | docker run -v "${PWD}:/mnt" ${PROJECT} bash -c "cp -v /code/src/*.hex /mnt" 9 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = usb_jtag 2 | 3 | # Adjust the XRAM location and size to leave space for the USB DMA buffers 4 | # Buffer layout in XRAM: 5 | # 0x0000 Ep0Buffer[8] 6 | # 0x0040 Ep1Buffer[8] 7 | # 0x0080 EP2Buffer[2*64] 8 | # 9 | # This takes a total of 256bytes, so there are 768 bytes left. 10 | XRAM_SIZE = 0x0300 11 | XRAM_LOC = 0x0100 12 | 13 | FREQ_SYS = 16000000 14 | 15 | EXTRA_FLAGS = --opt-code-speed 16 | 17 | C_FILES = \ 18 | main.c \ 19 | hal.c \ 20 | uart.c \ 21 | spi.c \ 22 | ../ch554_sdcc/include/debug.c 23 | 24 | include ../ch554_sdcc/examples/Makefile.include 25 | 26 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #define SBAUD_TH 104U // 16M/16/9600 2 | #define SBAUD_SET 128000U // Baud rate of serial port 0 3 | 4 | #define HARD_ESP_CTRL 1 5 | 6 | #define MPSSE_DEBUG 0 7 | #define MPSSE_HWSPI 1 8 | 9 | #define GOWIN_INT_FLASH_QUIRK 1 10 | 11 | #define FAST_RECEIVE //UART 12 | 13 | /* 14 | * Use T0 to count the SOF_Count every 1ms 15 | * If you doesn't like this feature, define SOF_NO_TIMER 16 | * Background: The usb host must to send SOF every 1ms, but some USB host don't really do that 17 | * FTDI's driver has some bug, if it doesn't received empty packet with modem status, 18 | * it will causes BSoD, so highly recommended use T0 instead of SOF packet to generate empty packet report. 19 | */ 20 | //#define SOF_NO_TIMER 21 | 22 | //#define USB_SLEEP 23 | 24 | -------------------------------------------------------------------------------- /src/hal.c: -------------------------------------------------------------------------------- 1 | #include "hal.h" 2 | 3 | void Xtal_Enable(void) { // Enable external clock using xtal crystal 4 | USB_INT_EN = 0; 5 | USB_CTRL = 0x06; 6 | 7 | SAFE_MOD = 0x55; 8 | SAFE_MOD = 0xAA; 9 | CLOCK_CFG |= bOSC_EN_XT; // Enable external 24M crystal oscillator 10 | SAFE_MOD = 0x00; 11 | mDelaymS(50); 12 | 13 | // SAFE_MOD = 0x55; 14 | // SAFE_MOD = 0xAA; 15 | // CLOCK_CFG &= ~bOSC_EN_INT; //Turn off internal RC 16 | // SAFE_MOD = 0x00; 17 | mDelaymS(250); 18 | } 19 | 20 | void Jump_to_BL() { 21 | ES = 0; 22 | PS = 0; 23 | 24 | P1_DIR_PU = 0; 25 | P1_MOD_OC = 0; 26 | P1 = 0xff; 27 | 28 | USB_INT_EN = 0; 29 | USB_CTRL = 0x06; 30 | // UDEV_CTRL = 0x80; 31 | 32 | mDelaymS(100); 33 | 34 | EA = 0; 35 | 36 | while(1) { 37 | __asm 38 | LJMP 0x3800 39 | __endasm; 40 | } 41 | } 42 | 43 | 44 | //--------------------- Timer --------------------------------- 45 | /******************************************************************************* 46 | * Function Name : mTimer_x_ModInit(uint8_t x ,uint8_t mode) 47 | * Description : CH554 timer counter x mode setting 48 | * Input : uint8_t mode,Timer mode selection 49 | 0: Mode 0, 13-bit timer, the upper 3 bits of TLn are invalid 50 | 1: Mode 1, 16-bit timer 51 | 2: Mode 2, 8-bit automatic reload timer 52 | 3: Mode 3, two 8-bit timers Timer0 53 | (FIXME) 3: Mode 3, Timer1 stops 54 | * Output : None 55 | * Return : SUCCESS SUCCESS 56 | FAIL FAIL 57 | *******************************************************************************/ 58 | uint8_t mTimer_x_ModInit(uint8_t x, uint8_t mode) { 59 | if(x == 0) {TMOD = TMOD & 0xf0 | mode;} 60 | else if(x == 1) {TMOD = TMOD & 0x0f | (mode<<4);} 61 | else if(x == 2) {RCLK = 0; TCLK = 0; CP_RL2 = 0;} //16-bit automatic reload timer 62 | else return FAIL; 63 | return SUCCESS; 64 | } 65 | 66 | /******************************************************************************* 67 | * Function Name : mTimer_x_SetData(uint8_t x,uint16_t dat) 68 | * Description : CH554Timer0 TH0 and TL0 assignment 69 | * Input : uint16_t dat;timer assignment 70 | * Output : None 71 | * Return : None 72 | *******************************************************************************/ 73 | void mTimer_x_SetData(uint8_t x, uint16_t dat) { 74 | uint16_t tmp; 75 | tmp = 65536 - dat; 76 | if(x == 0) {TL0 = tmp & 0xff; TH0 = (tmp>>8) & 0xff;} 77 | else if(x == 1) {TL1 = tmp & 0xff; TH1 = (tmp>>8) & 0xff;} 78 | else if(x == 2) { 79 | RCAP2L = TL2 = tmp & 0xff; //16-bit automatic reload timer 80 | RCAP2H = TH2 = (tmp>>8) & 0xff; 81 | } 82 | } 83 | 84 | /******************************************************************************* 85 | * Function Name : CAP2Init(uint8_t mode) 86 | * Description : CH554 timer counter 2 T2EX pin capture function initialization 87 | uint8_t mode, edge capture mode selection 88 | 0: T2ex from falling edge to next falling edge 89 | 1: T2ex Between any edges 90 | 3: T2ex from rising edge to next rising edge 91 | * Input : None 92 | * Output : None 93 | * Return : None 94 | *******************************************************************************/ 95 | void CAP2Init(uint8_t mode) { 96 | RCLK = 0; 97 | TCLK = 0; 98 | C_T2 = 0; 99 | EXEN2 = 1; 100 | CP_RL2 = 1; //Start the capture function of T2ex 101 | T2MOD |= mode << 2; //Edge capture mode selection 102 | } 103 | 104 | /******************************************************************************* 105 | * Function Name : CAP1Init(uint8_t mode) 106 | * Description : CH554timer counter 2 T2 pin capture function initialization T2 107 | uint8_t mode, edge capture mode selection 108 | 0: T2ex from falling edge to next falling edge 109 | 1: T2ex between any edges 110 | 3: T2ex from rising edge to next rising edge 111 | * Input : None 112 | * Output : None 113 | * Return : None 114 | *******************************************************************************/ 115 | void CAP1Init(uint8_t mode) { 116 | RCLK = 0; 117 | TCLK = 0; 118 | CP_RL2 = 1; 119 | C_T2 = 0; 120 | T2MOD = T2MOD & ~T2OE | (mode << 2) | bT2_CAP1_EN; //Enable T2 pin capture function, edge capture mode selection 121 | } 122 | 123 | void init_timer() { 124 | mTimer0Clk12DivFsys(); //T0 timer clock setting, 12MHz/12=1MHz 125 | mTimer_x_ModInit(0, 1); //T0 timer mode setting 126 | mTimer_x_SetData(0, 1000); //T0 timer assignment, 1MHz/1000=1000Hz, 1ms 127 | mTimer0RunCTL(1); //T0 timer start 128 | ET0 = 1; //T0 timer interrupt is on 129 | EA = 1; 130 | } 131 | -------------------------------------------------------------------------------- /src/hal.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "config.h" 10 | 11 | void Xtal_Enable(void); // Enable external clock using xtal crystal 12 | void Jump_to_BL(); 13 | 14 | //Define the function return value 15 | #ifndef SUCCESS 16 | #define SUCCESS 0 17 | #endif 18 | #ifndef FAIL 19 | #define FAIL 0xFF 20 | #endif 21 | 22 | 23 | // -- timer -- 24 | 25 | //Define the start of the timer 26 | #ifndef START 27 | #define START 1 28 | #endif 29 | #ifndef STOP 30 | #define STOP 0 31 | #endif 32 | 33 | //CH554 Timer0 clock selection 34 | //bTMR_CLK affects Timer0&1&2 at the same time, please pay attention when using it (except for the standard clock used for timing) 35 | #define mTimer0Clk12DivFsys( ) (T2MOD &= ~bT0_CLK) //Timer, clock=Fsys/12 T0 standard clock 36 | #define mTimer0ClkFsys( ) (T2MOD |= bTMR_CLK | bT0_CLK) //Timer, clock=Fsys 37 | #define mTimer0Clk4DivFsys( ) (T2MOD &= ~bTMR_CLK;T2MOD |= bT0_CLK) //Timer, clock=Fsys/4 38 | #define mTimer0CountClk( ) (TMOD |= bT0_CT) //Counter, the falling edge of T0 pin is valid 39 | 40 | //CH554 Timer0 start (SS=1)/end (SS=0) 41 | #define mTimer0RunCTL( SS ) (TR0 = SS ? START : STOP) 42 | 43 | 44 | #define mTimer1Clk12DivFsys( ) (T2MOD &= ~bT1_CLK) //Timer, clock=Fsys/12 T1 standard clock 45 | #define mTimer1ClkFsys( ) (T2MOD |= bTMR_CLK | bT1_CLK) //Timer, clock=Fsys 46 | #define mTimer1Clk4DivFsys( ) (T2MOD &= ~bTMR_CLK;T2MOD |= bT1_CLK) //Timer, clock=Fsys/4 47 | #define mTimer1CountClk( ) (TMOD |= bT1_CT) //Counter, the falling edge of T0 pin is valid 48 | 49 | //CH554 Timer1 start (SS=1)/end (SS=0) 50 | #define mTimer1RunCTL( SS ) (TR1 = SS ? START : STOP) 51 | 52 | 53 | #define mTimer2Clk12DivFsys( ) {T2MOD &= ~ bT2_CLK;C_T2 = 0;} //Timer, clock=Fsys/12 T2 standard clock 54 | #define mTimer2ClkFsys( ) {T2MOD |= (bTMR_CLK | bT2_CLK);C_T2=0;} //Timer, clock=Fsys 55 | #define mTimer2Clk4DivFsys( ) {T2MOD &= ~bTMR_CLK;T2MOD |= bT2_CLK;C_T2 = 0;}//Timer, clock=Fsys/4 56 | #define mTimer2CountClk( ) {C_T2 = 1;} //Counter, the falling edge of T2 pin is valid 57 | 58 | //CH554 Timer2 start (SS=1)/end (SS=0) 59 | #define mTimer2RunCTL( SS ) {TR2 = SS ? START : STOP;} 60 | #define mTimer2OutCTL( ) (T2MOD |= T2OE) //T2 output frequency TF2/2 61 | #define CAP1Alter( ) (PIN_FUNC |= bT2_PIN_X;) //CAP1 is mapped from P10 to P14 62 | #define CAP2Alter( ) (PIN_FUNC |= bT2EX_PIN_X;) //CAP2 is mapped by P11 RST 63 | 64 | /******************************************************************************* 65 | * Function Name : mTimer_x_ModInit(uint8_t x ,uint8_t mode) 66 | * Description : CH554 timer counter x mode setting 67 | * Input : uint8_t mode,Timer mode selection 68 | 0: Mode 0, 13-bit timer, the upper 3 bits of TLn are invalid 69 | 1: Mode 1, 16-bit timer 70 | 2: Mode 2, 8-bit automatic reload timer 71 | 3: Mode 3, two 8-bit timers Timer0 72 | (FIXME) 3: Mode 3, Timer1 stops 73 | uint8_t x timer 0 1 2 74 | * Output : None 75 | * Return : SUCCESS SUCCESS 76 | FAIL FAIL 77 | *******************************************************************************/ 78 | uint8_t mTimer_x_ModInit(uint8_t x, uint8_t mode); 79 | 80 | /******************************************************************************* 81 | * Function Name : mTimer_x_SetData(uint8_t x,uint16_t dat) 82 | * Description : CH554Timer 83 | * Input : uint16_t dat;timer assignment 84 | uint8_t x timer 0 1 2 85 | * Output : None 86 | * Return : None 87 | *******************************************************************************/ 88 | void mTimer_x_SetData(uint8_t x, uint16_t dat); 89 | 90 | /******************************************************************************* 91 | * Function Name : CAP2Init(uint8_t mode) 92 | * Description : CH554 timer counter 2 T2EX pin capture function initialization 93 | uint8_t mode, edge capture mode selection 94 | 0: T2ex from falling edge to next falling edge 95 | 1: T2ex between any edges 96 | 3: T2ex from rising edge to next rising edge 97 | * Input : None 98 | * Output : None 99 | * Return : None 100 | *******************************************************************************/ 101 | void CAP2Init(uint8_t mode); 102 | 103 | /******************************************************************************* 104 | * Function Name : CAP1Init(uint8_t mode) 105 | * Description : CH554 timer counter 2 T2 pin capture function initialization T2 106 | uint8_t mode, edge capture mode selection 107 | 0: T2ex from falling edge to next falling edge 108 | 1: T2ex between any edges 109 | 3: T2ex from rising edge to next rising edge 110 | * Input : None 111 | * Output : None 112 | * Return : None 113 | *******************************************************************************/ 114 | void CAP1Init(uint8_t mode); 115 | void init_timer(); 116 | 117 | 118 | // -- uart -- 119 | void SerialPort_Config(); 120 | extern volatile __idata uint8_t Esp_Require_Reset; 121 | extern volatile __idata uint8_t WritePtr; //FIXME: hideme 122 | extern volatile __idata uint8_t ReadPtr; //FIXME: hideme 123 | 124 | 125 | // -- spi -- 126 | void SPI_Init(); 127 | 128 | #if MPSSE_HWSPI 129 | #define SPI_LSBFIRST() SPI0_SETUP |= bS0_BIT_ORDER 130 | #define SPI_MSBFIRST() SPI0_SETUP &= ~bS0_BIT_ORDER 131 | #define SPI_ON() SPI0_CTRL = bS0_MISO_OE | bS0_MOSI_OE | bS0_SCK_OE; 132 | #define SPI_OFF() SPI0_CTRL = 0; 133 | #else 134 | #define SPI_LSBFIRST() 135 | #define SPI_MSBFIRST() 136 | #define SPI_ON() 137 | #define SPI_OFF() 138 | #endif 139 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /********************************** (C) COPYRIGHT ******************************* 2 | * File Name : CDC.C 3 | * Author : Kongou Hikari 4 | * Version : V1.0 5 | * Date : 2019/02/16 6 | * Description : CH552 USB to JTAG with FTDI Protocol 7 | *******************************************************************************/ 8 | #include "hal.h" 9 | 10 | /* 11 | Memory map: 12 | EP0 Buf 00 - 3f 13 | EP4 Buf 40 - 7f 14 | EP1 Buf 80 - bf 15 | RingBuf 100 - 1ff 16 | EP2 Buf 300 - 37f 17 | EP3 Buf 380 - 3bf 18 | */ 19 | 20 | __xdata __at (0x0000) uint8_t Ep0Buffer[DEFAULT_ENDP0_SIZE]; // Endpoint 0 OUT & IN buffer must be an even address 21 | __xdata __at (0x0080) uint8_t Ep1Buffer[MAX_PACKET_SIZE]; // Endpoint 1 IN transmit buffer 22 | __xdata __at (0x0300) uint8_t Ep2Buffer[MAX_PACKET_SIZE * 2]; // Endpoint 2 OUT Receive Buffer 23 | __xdata __at (0x0380) uint8_t Ep3Buffer[MAX_PACKET_SIZE]; // Endpoint 3 IN transmit buffer 24 | __xdata __at (0x0040) uint8_t Ep4Buffer[MAX_PACKET_SIZE]; // Endpoint 4 OUT Receive Buffer 25 | __xdata __at (0x0100) uint8_t RingBuf[128]; 26 | 27 | uint16_t SetupLen; 28 | uint8_t SetupReq, Count, UsbConfig; 29 | uint8_t VendorControl; 30 | 31 | __code uint8_t * pDescr; // USB configuration flag 32 | uint8_t pDescr_Index = 0; 33 | USB_SETUP_REQ SetupReqBuf; // temporarily store the Setup package 34 | #define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer) 35 | 36 | /* Device descriptor */ 37 | __code uint8_t DevDesc[] = {0x12, 0x01, 0x00, 0x02, 38 | 0x00, 0x00, 0x00, DEFAULT_ENDP0_SIZE, 39 | 0x03, 0x04, 0x10, 0x60, 0x00, 0x05, 0x01, 0x02, 40 | 0x03, 0x01 41 | }; 42 | __code uint16_t itdf_eeprom [] = { 43 | 0x0800, 0x0403, 0x6010, 0x0500, 0x3280, 0x0000, 0x0200, 0x1096, 44 | 0x1aa6, 0x0000, 0x0046, 0x0310, 0x004f, 0x0070, 0x0065, 0x006e, 45 | 0x002d, 0x0045, 0x0043, 0x031a, 0x0055, 0x0053, 0x0042, 0x0020, 46 | 0x0044, 0x0065, 0x0062, 0x0075, 0x0067, 0x0067, 0x0065, 0x0072, 47 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 48 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 49 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 50 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1027 51 | }; 52 | __code uint8_t CfgDesc[] = { 53 | 0x09, 0x02, sizeof(CfgDesc) & 0xff, sizeof(CfgDesc) >> 8, 54 | 0x02, 0x01, 0x00, 0x80, 0x32, // Configuration descriptor (1 interface) 55 | 56 | // The following is the interface 0 (data interface) descriptor 57 | 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0x04, // Data interface descriptor 58 | 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, // Endpoint descriptor EP1 BULK IN 59 | 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, // Endpoint descriptor EP2 BULK OUT 60 | 61 | //The following is the interface 1 (data interface) descriptor 62 | 0x09, 0x04, 0x01, 0x00, 0x02, 0xff, 0xff, 0xff, 0x00, // Data interface descriptor 63 | 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, // Endpoint descriptor EP3 BULK IN 64 | 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, // Endpoint descriptor EP4 BULK OUT 65 | }; 66 | /* String descriptor */ 67 | unsigned char __code LangDes[] = {0x04, 0x03, 0x09, 0x04}; // Language descriptor 68 | 69 | unsigned char __code Prod_Des[] = { // Product string descriptor 70 | sizeof(Prod_Des), 0x03, 71 | 'S', 0x00, 'i', 0x00, 'p', 0x00, 'e', 0x00, 'e', 0x00, 'd', 0x00, 72 | '-', 0x00, 'D', 0x00, 'e', 0x00, 'b', 0x00, 'u', 0x00, 'g', 0x00 73 | }; 74 | unsigned char __code Jtag_Des[] = { // Product string descriptor 75 | sizeof(Jtag_Des), 0x03, 76 | 'S', 0x00, 'i', 0x00, 'p', 0x00, 'e', 0x00, 'e', 0x00, 'd', 0x00, 77 | '-', 0x00, 'J', 0x00, 'T', 0x00, 'A', 0x00, 'G', 0x00 78 | }; 79 | unsigned char __code Manuf_Des[] = { 80 | sizeof(Manuf_Des), 0x03, 81 | 'K', 0x00, 'o', 0x00, 'n', 0x00, 'g', 0x00, 'o', 0x00, 'u', 0x00, 82 | ' ', 0x00, 'H', 0x00, 'i', 0x00, 'k', 0x00, 'a', 0x00, 'r', 0x00, 'i', 0x00 83 | }; 84 | 85 | __code uint8_t QualifierDesc[] = { 86 | 10, /* bLength */ 87 | USB_DESCR_TYP_QUALIF, /* bDescriptorType */ 88 | 89 | 0x00, 0x02, /* bcdUSB */ 90 | 91 | 0xff, /* bDeviceClass */ 92 | 0xff, /* bDeviceSubClass */ 93 | 0xff, /* bDeviceProtocol */ 94 | 95 | DEFAULT_ENDP0_SIZE, /* bMaxPacketSize0 */ 96 | 0x00, /* bNumOtherSpeedConfigurations */ 97 | 0x00 /* bReserved */ 98 | }; 99 | 100 | /* Download control */ 101 | volatile __idata uint8_t USBOutLength = 0; 102 | volatile __idata uint8_t USBOutPtr = 0; 103 | volatile __idata uint8_t USBReceived = 0; 104 | 105 | volatile __idata uint8_t Serial_Done = 0; 106 | volatile __idata uint8_t USB_Require_Data = 0; 107 | 108 | volatile __idata uint8_t USBOutLength_1 = 0; 109 | volatile __idata uint8_t USBOutPtr_1 = 0; 110 | volatile __idata uint8_t USBReceived_1 = 0; 111 | /* Upload control */ 112 | volatile __idata uint8_t UpPoint1_Busy = 0; //Is the upload endpoint busy flag 113 | volatile __idata uint8_t UpPoint1_Ptr = 2; 114 | 115 | volatile __idata uint8_t UpPoint3_Busy = 0; //Is the upload endpoint busy flag 116 | volatile __idata uint8_t UpPoint3_Ptr = 2; 117 | 118 | /* Miscellaneous */ 119 | volatile __idata uint16_t SOF_Count = 0; 120 | volatile __idata uint8_t Latency_Timer = 4; // Latency Timer 121 | volatile __idata uint8_t Latency_Timer1 = 4; 122 | volatile __idata uint8_t Require_DFU = 0; 123 | 124 | /* Flow control */ 125 | volatile __idata uint8_t soft_dtr = 0; 126 | volatile __idata uint8_t soft_rts = 0; 127 | 128 | /* MPSSE settings */ 129 | 130 | volatile __idata uint8_t Mpsse_Status = 0; 131 | volatile __idata uint16_t Mpsse_LongLen = 0; 132 | volatile __idata uint8_t Mpsse_ShortLen = 0; 133 | 134 | #ifdef DE_PRINTF 135 | #define dbg_printf(...) printf(s__VA_ARGS__) 136 | #else 137 | #define dbg_printf(...) 138 | #endif 139 | 140 | /******************************************************************************* 141 | * Function Name : USBDeviceCfg() 142 | * Description : USB device mode configuration 143 | * Input : None 144 | * Output : None 145 | * Return : None 146 | *******************************************************************************/ 147 | void USBDeviceCfg() { 148 | USB_CTRL = 0x00; // clear the USB control register 149 | USB_CTRL &= ~bUC_HOST_MODE; // This bit is to select the device mode 150 | USB_CTRL |= bUC_DEV_PU_EN | bUC_INT_BUSY | bUC_DMA_EN; // USB device and internal pull-up enable, automatically return to NAK before the interrupt flag is cleared during the interrupt 151 | USB_DEV_AD = 0x00; // Device address initialization 152 | // USB_CTRL |= bUC_LOW_SPEED; 153 | // UDEV_CTRL |= bUD_LOW_SPEED; //Select low speed 1.5M mode 154 | USB_CTRL &= ~bUC_LOW_SPEED; 155 | UDEV_CTRL &= ~bUD_LOW_SPEED; // Select the full speed 12M mode, the default mode 156 | UDEV_CTRL = bUD_PD_DIS; // Prohibit DP/DM pull-down resistor 157 | UDEV_CTRL |= bUD_PORT_EN; // Enable physical port 158 | } 159 | 160 | /******************************************************************************* 161 | * Function Name : USBDeviceIntCfg() 162 | * Description : USB device mode interrupt initialization 163 | * Input : None 164 | * Output : None 165 | * Return : None 166 | *******************************************************************************/ 167 | void USBDeviceIntCfg() { 168 | USB_INT_EN |= bUIE_SUSPEND; // Enable device suspension interrupt 169 | USB_INT_EN |= bUIE_TRANSFER; // Enable USB transfer completion interrupt 170 | USB_INT_EN |= bUIE_BUS_RST; // Enable device mode USB bus reset interrupt 171 | USB_INT_EN |= bUIE_DEV_SOF; // Open SOF interrupt 172 | USB_INT_FG |= 0x1F; // Clear interrupt flag 173 | IE_USB = 1; // Enable USB interrupt 174 | EA = 1; // Allow MCU interrupt 175 | } 176 | /******************************************************************************* 177 | * Function Name : USBDeviceEndPointCfg() 178 | * Description : USB device mode endpoint configuration, simulation compatible HID device, in addition to endpoint 0 control transmission, also includes endpoint 2 batch upload and download 179 | * Input : None 180 | * Output : None 181 | * Return : None 182 | *******************************************************************************/ 183 | void USBDeviceEndPointCfg() { 184 | // TODO: Is casting the right thing here? What about endianness? 185 | UEP2_DMA = (uint16_t) Ep2Buffer; // Endpoint 2 OUT receiving data transmission address 186 | UEP3_DMA = (uint16_t) Ep3Buffer; 187 | UEP2_3_MOD = 0x48; // Endpoint 2 single-buffered reception, endpoint 3 single-buffered transmission 188 | //UEP2_3_MOD = 0x49; //Endpoint 3 single-buffered transmission, endpoint 2 double-buffered reception 189 | 190 | UEP2_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK; // Endpoint 2 automatically flips the synchronization flag, and OUT returns ACK 191 | UEP3_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; // Endpoint 3 sends back NAK 192 | 193 | //UEP4_DMA = (uint16_t) Ep4Buffer; //Ep4Buffer = Ep0Buffer + 64 194 | UEP1_DMA = (uint16_t) Ep1Buffer; // Endpoint 1 IN send data transmission address 195 | UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; // Endpoint 1 automatically flips the synchronization flag, and the IN transaction returns NAK 196 | UEP4_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK; // Endpoint 4 receives and returns ACK, which cannot be reversed automatically 197 | UEP4_1_MOD = 0x48; // Endpoint 1 single-buffered transmission, endpoint 4 single-buffered reception 198 | 199 | UEP0_DMA = (uint16_t) Ep0Buffer; // Endpoint 0 data transmission address 200 | UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; // Manually flip, OUT transaction returns ACK, IN transaction returns NAK 201 | } 202 | 203 | __code uint8_t HexToAscTab[] = "0123456789ABCDEF"; 204 | 205 | void uuidcpy(__xdata uint8_t *dest, uint8_t index, uint8_t len) { /* Use UUID to generate USB Serial Number */ 206 | uint8_t i; 207 | uint8_t p = 0; /* UUID format, decimal hexadecimal number */ 208 | __code uint8_t *puuid; 209 | for(i = index; i < (index + len); i++) { 210 | if(i == 0) 211 | dest[p++] = 22; // 10 * 2 + 2 212 | else if(i == 1) 213 | dest[p++] = 0x03; 214 | else { 215 | if(i & 0x01) { // odd 216 | dest[p++] = 0x00; 217 | } else { 218 | puuid = (__code uint8_t *) (0x3ffa + (i - 2) / 4); 219 | if(i & 0x02) 220 | dest[p++] = HexToAscTab[(*puuid) >> 4]; 221 | else 222 | dest[p++] = HexToAscTab[(*puuid) & 0x0f]; 223 | } 224 | } 225 | } 226 | } 227 | 228 | #define INTF1_DTR TIN1 229 | #define INTF1_RTS TIN0 230 | 231 | #define INTF2_DTR TIN3 232 | #define INTF2_RTS TIN2 233 | 234 | //volatile __idata uint8_t DTR_State = 0; 235 | volatile __idata uint8_t Modem_Count = 0; 236 | 237 | /******************************************************************************* 238 | * Function Name : DeviceInterrupt() 239 | * Description : CH559USB interrupt handler 240 | *******************************************************************************/ 241 | void DeviceInterrupt(void) __interrupt (INT_NO_USB) { // USB interrupt service routine, using register set 1 242 | uint16_t len; 243 | uint16_t divisor; 244 | if ((USB_INT_ST & MASK_UIS_TOKEN) == UIS_TOKEN_SOF) { 245 | #ifdef SOF_NO_TIMER 246 | SOF_Count ++; 247 | if(Modem_Count) 248 | Modem_Count --; 249 | if(Modem_Count == 1) { 250 | if(soft_dtr == 0 && soft_rts == 1) { 251 | INTF1_RTS = 1; 252 | INTF1_DTR = 0; 253 | } 254 | if(soft_dtr == 1 && soft_rts == 0) { 255 | INTF1_RTS = 0; 256 | INTF1_DTR = 1; 257 | } 258 | if(soft_dtr == soft_rts) { 259 | INTF1_DTR = 1; 260 | INTF1_RTS = 0; 261 | INTF1_RTS = 1; 262 | } 263 | } 264 | if(SOF_Count % 16 == 0) 265 | PWM2 = 1; 266 | #endif 267 | } 268 | if(UIF_TRANSFER) { // USB transfer complete flag 269 | switch (USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) { 270 | case UIS_TOKEN_IN | 1: // endpoint 1# endpoint bulk upload 271 | UEP1_T_LEN = 0; 272 | UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; // Default response NAK 273 | UpPoint1_Busy = 0; // Clear busy flag 274 | break; 275 | case UIS_TOKEN_OUT | 2: // endpoint 2# Endpoint batch download 276 | if ( U_TOG_OK ) { // out-of-sync packets will be discarded 277 | UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_R_RES | UEP_R_RES_NAK; // NAK after receiving a packet of data, the main function is processed, the main function will modify the response mode 278 | USBOutLength = USB_RX_LEN; 279 | USBOutPtr = 0; 280 | USBReceived = 1; 281 | } 282 | break; 283 | case UIS_TOKEN_IN | 3: // endpoint 3# endpoint bulk upload 284 | UEP3_T_LEN = 0; 285 | UEP3_CTRL = UEP3_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; // Default response NAK 286 | UpPoint3_Busy = 0; // Clear busy flag 287 | break; 288 | case UIS_TOKEN_OUT | 4: // endpoint 4# Endpoint batch download 289 | if ( U_TOG_OK ) { // out-of-sync packets will be discarded 290 | UEP4_CTRL ^= bUEP_R_TOG; // Synchronization flag bit flip 291 | UEP4_CTRL = UEP4_CTRL & ~ MASK_UEP_R_RES | UEP_R_RES_NAK; // NAK after receiving a packet of data, the main function is processed, the main function will modify the response mode 292 | USBOutLength_1 = USB_RX_LEN + 64; 293 | USBOutPtr_1 = 64; 294 | USBReceived_1 = 1; 295 | } 296 | break; 297 | case UIS_TOKEN_SETUP | 0: // SETUP transaction 298 | len = USB_RX_LEN; 299 | if(len == (sizeof(USB_SETUP_REQ))) { 300 | SetupLen = ((uint16_t)UsbSetupBuf->wLengthH << 8) | (UsbSetupBuf->wLengthL); 301 | len = 0; //The default is success and upload 0 length 302 | VendorControl = 0; 303 | SetupReq = UsbSetupBuf->bRequest; 304 | if ( ( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { // Non-standard request 305 | // TODO: rewrite 306 | VendorControl = 1; 307 | if(UsbSetupBuf->bRequestType & USB_REQ_TYP_READ) { 308 | // Read 309 | switch( SetupReq ) { 310 | case 0x90: // READ EEPROM 311 | divisor = UsbSetupBuf->wIndexL & 0x3f; 312 | Ep0Buffer[0] = itdf_eeprom[divisor] & 0xff; 313 | Ep0Buffer[1] = itdf_eeprom[divisor] >> 8; 314 | len = 2; 315 | break; 316 | case 0x0a: 317 | if(UsbSetupBuf->wIndexL == 2) 318 | Ep0Buffer[0] = Latency_Timer1; 319 | else 320 | Ep0Buffer[0] = Latency_Timer; 321 | len = 1; 322 | break; 323 | case 0x05: 324 | Ep0Buffer[0] = 0x01; 325 | Ep0Buffer[1] = 0x60; 326 | len = 2; 327 | break; 328 | default: 329 | len = 0xFF; /* Command not supported */ 330 | break; 331 | } 332 | } else { 333 | // Write 334 | switch( SetupReq ) { 335 | case 0x02: 336 | case 0x04: 337 | case 0x06: 338 | case 0x07: 339 | case 0x0b: 340 | case 0x92: 341 | len = 0; 342 | break; 343 | case 0x91: // WRITE EEPROM, FT_PROG action, jump directly to BL 344 | Require_DFU = 1; 345 | len = 0; 346 | break; 347 | case 0x00: 348 | if(UsbSetupBuf->wIndexL == 1) 349 | UpPoint1_Busy = 0; 350 | if(UsbSetupBuf->wIndexL == 2) { 351 | UpPoint3_Busy = 0; 352 | UEP4_CTRL &= ~(bUEP_R_TOG); 353 | } 354 | len = 0; 355 | break; 356 | case 0x09: // SET LATENCY TIMER 357 | if(UsbSetupBuf->wIndexL == 1) 358 | Latency_Timer = UsbSetupBuf->wValueL; 359 | else 360 | Latency_Timer1 = UsbSetupBuf->wValueL; 361 | len = 0; 362 | break; 363 | case 0x03: 364 | // divisor = wValue 365 | // U1SMOD = 1; 366 | //PCON |= SMOD; //Baud rate doubled 367 | //T2MOD |= bTMR_CLK; //Highest counting clock 368 | PCON |= SMOD; 369 | T2MOD |= bT1_CLK; 370 | 371 | divisor = UsbSetupBuf->wValueL | 372 | (UsbSetupBuf->wValueH << 8); 373 | divisor &= 0x3fff; //There is no way to take the integer part of the decimal, baudrate = 48M/16/divisor 374 | 375 | if(divisor == 0 || divisor == 1) { // baudrate> 3M 376 | if(UsbSetupBuf->wIndexL == 2) 377 | TH1 = 0xff; //I ca n't hold back 1M 378 | } else { 379 | uint16_t div_tmp = 0; 380 | div_tmp = 10 * divisor / 3; // 16M CPU clock 381 | if (div_tmp % 10 >= 5) divisor = div_tmp / 10 + 1; 382 | else divisor = div_tmp / 10; 383 | 384 | if(divisor > 256) { 385 | //TH1 = 0 - SBAUD_TH; //all use the default baud rate 386 | if(UsbSetupBuf->wIndexL == 2) { 387 | divisor /= 12; 388 | if(divisor > 256) { // Set the baud rate to be less than 488 389 | TH1 = (0 - SBAUD_TH)&0xff; // 9600bps 390 | } else { 391 | // PCON &= ~(SMOD); 392 | T2MOD &= ~(bT1_CLK); // low baud rate 393 | TH1 = 0 - divisor; 394 | } 395 | } 396 | } else { 397 | if(UsbSetupBuf->wIndexL == 2) 398 | TH1 = 0 - divisor; 399 | #if 0 400 | else //intf2 401 | SBAUD1 = 0 - divisor; 402 | #endif 403 | } 404 | } 405 | len = 0; 406 | break; 407 | case 0x01: // MODEM Control 408 | #if HARD_ESP_CTRL 409 | if(UsbSetupBuf->wIndexL == 2) { 410 | if(UsbSetupBuf->wValueH & 0x01) { 411 | if(UsbSetupBuf->wValueL & 0x01) { // DTR 412 | soft_dtr = 1; 413 | // INTF1_DTR = 0; 414 | } else { 415 | soft_dtr = 0; 416 | // INTF1_DTR = 1; 417 | } 418 | } 419 | if(UsbSetupBuf->wValueH & 0x02) { 420 | if(UsbSetupBuf->wValueL & 0x02) { // RTS 421 | soft_rts = 1; 422 | // INTF1_RTS = 0; 423 | } else { 424 | soft_rts = 0; 425 | // INTF1_RTS = 1; 426 | } 427 | } 428 | Modem_Count = 20; 429 | } 430 | #else 431 | if(Esp_Require_Reset == 3) { 432 | CAP1 = 0; 433 | Esp_Require_Reset = 4; 434 | } 435 | #endif 436 | len = 0; 437 | break; 438 | default: 439 | len = 0xFF; /* Command not supported */ 440 | break; 441 | } 442 | } 443 | 444 | } else { // standard request 445 | switch(SetupReq) { // Request code 446 | case USB_GET_DESCRIPTOR: 447 | switch(UsbSetupBuf->wValueH) { 448 | case USB_DESCR_TYP_DEVICE: // Device descriptor 449 | pDescr = DevDesc; // Send the device descriptor to the buffer to be sent 450 | len = sizeof(DevDesc); 451 | break; 452 | case USB_DESCR_TYP_CONFIG: // Configuration descriptor 453 | pDescr = CfgDesc; // Send the device descriptor to the buffer to be sent 454 | len = sizeof(CfgDesc); 455 | break; 456 | case USB_DESCR_TYP_STRING: 457 | if(UsbSetupBuf->wValueL == 0) { 458 | pDescr = LangDes; 459 | len = sizeof(LangDes); 460 | } else if(UsbSetupBuf->wValueL == 1) { 461 | pDescr = Manuf_Des; 462 | len = sizeof(Manuf_Des); 463 | } else if(UsbSetupBuf->wValueL == 2) { 464 | pDescr = Prod_Des; 465 | len = sizeof(Prod_Des); 466 | } else if(UsbSetupBuf->wValueL == 4) { 467 | pDescr = Jtag_Des; 468 | len = sizeof(Jtag_Des); 469 | } else { 470 | pDescr = (__code uint8_t *)0xffff; 471 | len = 22; /* 10-bit ASCII serial number */ 472 | } 473 | break; 474 | case USB_DESCR_TYP_QUALIF: 475 | // pDescr = QualifierDesc; 476 | // len = sizeof(QualifierDesc); 477 | len = 0xff; 478 | break; 479 | default: 480 | len = 0xff; // unsupported command or error 481 | break; 482 | } 483 | 484 | if ( SetupLen > len ) { 485 | SetupLen = len; // Limit the total length 486 | } 487 | if (len != 0xff) { 488 | len = SetupLen >= DEFAULT_ENDP0_SIZE ? DEFAULT_ENDP0_SIZE : SetupLen; // This transmission length 489 | 490 | if(pDescr == (__code uint8_t *) 0xffff) { /*If you take the serial number */ 491 | uuidcpy(Ep0Buffer, 0, len); 492 | } else { 493 | memcpy(Ep0Buffer, pDescr, len); // Load upload data 494 | } 495 | SetupLen -= len; 496 | pDescr_Index = len; 497 | } 498 | break; 499 | case USB_SET_ADDRESS: 500 | SetupLen = UsbSetupBuf->wValueL; // temporarily store the USB device address 501 | break; 502 | case USB_GET_CONFIGURATION: 503 | Ep0Buffer[0] = UsbConfig; 504 | if ( SetupLen >= 1 ) { 505 | len = 1; 506 | } 507 | break; 508 | case USB_SET_CONFIGURATION: 509 | UsbConfig = UsbSetupBuf->wValueL; 510 | break; 511 | case USB_GET_INTERFACE: 512 | break; 513 | case USB_CLEAR_FEATURE: // Clear Feature 514 | if( ( UsbSetupBuf->bRequestType & 0x1F ) == USB_REQ_RECIP_DEVICE ) { /* Clear device */ 515 | if( ( ( ( uint16_t )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x01 ) { 516 | if( CfgDesc[ 7 ] & 0x20 ) { 517 | /* Wake up */ 518 | } else { 519 | len = 0xFF; /*The operation failed */ 520 | } 521 | } else { 522 | len = 0xFF; /*The operation failed */ 523 | } 524 | } else if ( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { // Endpoint 525 | switch( UsbSetupBuf->wIndexL ) { 526 | case 0x83: 527 | UEP3_CTRL = UEP3_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK; 528 | break; 529 | case 0x03: 530 | UEP3_CTRL = UEP3_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK; 531 | break; 532 | case 0x82: 533 | UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK; 534 | break; 535 | case 0x02: 536 | UEP2_CTRL = UEP2_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK; 537 | break; 538 | case 0x81: 539 | UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_T_TOG | MASK_UEP_T_RES ) | UEP_T_RES_NAK; 540 | break; 541 | case 0x01: 542 | UEP1_CTRL = UEP1_CTRL & ~ ( bUEP_R_TOG | MASK_UEP_R_RES ) | UEP_R_RES_ACK; 543 | break; 544 | default: 545 | len = 0xFF; // Unsupported endpoint 546 | break; 547 | } 548 | UpPoint1_Busy = 0; 549 | UpPoint3_Busy = 0; 550 | } else { 551 | len = 0xFF; //It is not that the endpoint does not support 552 | } 553 | break; 554 | case USB_SET_FEATURE: /* Set Feature */ 555 | if( ( UsbSetupBuf->bRequestType & 0x1F ) == USB_REQ_RECIP_DEVICE ) { /* Set up the device */ 556 | if( ( ( ( uint16_t )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x01 ) { 557 | if( CfgDesc[ 7 ] & 0x20 ) { 558 | /* Sleep */ 559 | dbg_printf( "suspend\n" ); // sleep state 560 | #ifdef DE_PRINTF 561 | while ( XBUS_AUX & bUART0_TX ) {}; // Wait for sending completion 562 | #endif 563 | #if 0 564 | SAFE_MOD = 0x55; 565 | SAFE_MOD = 0xAA; 566 | WAKE_CTRL = bWAK_BY_USB | bWAK_RXD0_LO | bWAK_RXD1_LO; //USB or RXD0/1 can be woken up when there is a signal 567 | PCON |= PD; //sleep 568 | SAFE_MOD = 0x55; 569 | SAFE_MOD = 0xAA; 570 | WAKE_CTRL = 0x00; 571 | #endif 572 | } else { 573 | len = 0xFF; /*The operation failed */ 574 | } 575 | } else { 576 | len = 0xFF; /*The operation failed */ 577 | } 578 | } else if( ( UsbSetupBuf->bRequestType & 0x1F ) == USB_REQ_RECIP_ENDP ) { /* Set the endpoint */ 579 | if( ( ( ( uint16_t )UsbSetupBuf->wValueH << 8 ) | UsbSetupBuf->wValueL ) == 0x00 ) { 580 | switch( ( ( uint16_t )UsbSetupBuf->wIndexH << 8 ) | UsbSetupBuf->wIndexL ) { 581 | case 0x83: 582 | UEP3_CTRL = UEP3_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* Set endpoint 3 IN STALL */ 583 | break; 584 | case 0x03: 585 | UEP3_CTRL = UEP3_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL;/* Set endpoint 3 OUT Stall */ 586 | break; 587 | case 0x82: 588 | UEP2_CTRL = UEP2_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* Set endpoint 2 IN STALL */ 589 | break; 590 | case 0x02: 591 | UEP2_CTRL = UEP2_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL;/* Set endpoint 2 OUT Stall */ 592 | break; 593 | case 0x81: 594 | UEP1_CTRL = UEP1_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL;/* Set endpoint 1 IN STALL */ 595 | break; 596 | case 0x01: 597 | UEP1_CTRL = UEP1_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL;/* Set endpoint 1 OUT Stall */ 598 | default: 599 | len = 0xFF; /*The operation failed */ 600 | break; 601 | } 602 | } else { 603 | len = 0xFF; /*The operation failed */ 604 | } 605 | } else { 606 | len = 0xFF; /*The operation failed */ 607 | } 608 | break; 609 | case USB_GET_STATUS: 610 | Ep0Buffer[0] = 0x00; 611 | Ep0Buffer[1] = 0x00; 612 | if ( SetupLen >= 2 ) { 613 | len = 2; 614 | } else { 615 | len = SetupLen; 616 | } 617 | break; 618 | default: 619 | len = 0xff; //The operation failed 620 | break; 621 | } 622 | } 623 | } else { 624 | len = 0xff; // Package length error 625 | } 626 | if(len == 0xff) { 627 | SetupReq = 0xFF; 628 | UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL;// STALL 629 | } else if(len <= DEFAULT_ENDP0_SIZE) { // Upload data or return 0 length package in status stage 630 | UEP0_T_LEN = len; 631 | UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//The default data packet is DATA1, and the response ACK is returned 632 | } else { 633 | UEP0_T_LEN = 0; // Although it has not yet reached the status stage, it is preset to upload a 0-length data packet in advance to prevent the host from entering the status stage in advance 634 | UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK;//The default data packet is DATA1, and the response ACK is returned 635 | } 636 | break; 637 | case UIS_TOKEN_IN | 0: // endpoint0 IN 638 | switch(SetupReq) { 639 | case USB_GET_DESCRIPTOR: 640 | len = SetupLen >= DEFAULT_ENDP0_SIZE ? DEFAULT_ENDP0_SIZE : SetupLen; // This transmission length 641 | if(pDescr == (__code uint8_t *)0xffff) { 642 | uuidcpy(Ep0Buffer, pDescr_Index, len); 643 | } else { 644 | memcpy( Ep0Buffer, pDescr + pDescr_Index, len ); // Load upload data 645 | } 646 | SetupLen -= len; 647 | pDescr_Index += len; 648 | UEP0_T_LEN = len; 649 | UEP0_CTRL ^= bUEP_T_TOG; // Synchronization flag bit flip 650 | break; 651 | case USB_SET_ADDRESS: 652 | if(VendorControl == 0) { 653 | USB_DEV_AD = USB_DEV_AD & bUDA_GP_BIT | SetupLen; 654 | UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 655 | } 656 | break; 657 | default: 658 | UEP0_T_LEN = 0; //The status phase is completed interrupted or a 0-length data packet is forced to upload to end the control transmission 659 | UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 660 | break; 661 | } 662 | break; 663 | case UIS_TOKEN_OUT | 0: // endpoint0 OUT 664 | if(SetupReq == 0x22) { // Set serial port properties 665 | 666 | } else { 667 | UEP0_T_LEN = 0; 668 | UEP0_CTRL |= UEP_R_RES_ACK | UEP_T_RES_NAK; //In the status phase, respond NAK to IN 669 | } 670 | break; 671 | 672 | default: 673 | break; 674 | } 675 | UIF_TRANSFER = 0; // write 0 to clear interrupt 676 | } 677 | if(UIF_BUS_RST) { // device mode USB bus reset interrupt 678 | dbg_printf( "reset\n" ); // sleep state 679 | UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 680 | UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; 681 | UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; 682 | USB_DEV_AD = 0x00; 683 | UIF_SUSPEND = 0; 684 | UIF_TRANSFER = 0; 685 | UIF_BUS_RST = 0; // Clear the interrupt flag 686 | UsbConfig = 0; // Clear configuration value 687 | UpPoint1_Busy = 0; 688 | UpPoint3_Busy = 0; 689 | 690 | USBOutLength = 0; 691 | USBOutPtr = 0; 692 | USBReceived = 0; 693 | 694 | USBOutLength_1 = 0; 695 | USBOutPtr_1 = 0; 696 | USBReceived_1 = 0; 697 | 698 | Mpsse_ShortLen = 0; 699 | Mpsse_LongLen = 0; 700 | 701 | Mpsse_Status = 0; 702 | UpPoint1_Ptr = 2; 703 | UpPoint3_Ptr = 2; 704 | 705 | Serial_Done = 0; 706 | USB_Require_Data = 0; 707 | } 708 | if (UIF_SUSPEND) { // USB bus suspend/wake up completed 709 | UIF_SUSPEND = 0; 710 | if ( USB_MIS_ST & bUMS_SUSPEND ) { // suspend 711 | #ifdef USB_SLEEP 712 | dbg_printf( "suspend\n" ); // sleep state 713 | while ( XBUS_AUX & bUART0_TX ) { 714 | ; // Wait for sending completion 715 | } 716 | SAFE_MOD = 0x55; 717 | SAFE_MOD = 0xAA; 718 | WAKE_CTRL = bWAK_BY_USB | bWAK_RXD0_LO | bWAK_RXD1_LO; // USB or RXD0/1 can be woken up when there is a signal 719 | PCON |= PD; // sleep 720 | SAFE_MOD = 0x55; 721 | SAFE_MOD = 0xAA; 722 | WAKE_CTRL = 0x00; 723 | #endif 724 | } 725 | } else { // Unexpected interruption, impossible situation 726 | USB_INT_FG = 0xFF; // Clear interrupt flag 727 | 728 | } 729 | } 730 | 731 | 732 | // #define FAST_COPY_2 733 | // #define FAST_COPY_1 734 | 735 | void CLKO_Enable(void) { // Turn on T2 output 736 | ET2 = 0; 737 | T2CON = 0; 738 | T2MOD = 0; 739 | T2MOD |= bTMR_CLK | bT2_CLK | T2OE; 740 | RCAP2H = 0xff; 741 | RCAP2L = 0xfe; 742 | TH2 = 0xff; 743 | TL2 = 0xfe; 744 | TR2 = 1; 745 | P1_MOD_OC &= ~(0x01); // P1.0 push-pull output 746 | P1_DIR_PU |= 0x01; 747 | } 748 | 749 | #define TMS T2EX 750 | #define TDI MOSI 751 | #define TDO MISO 752 | #define TCK SCK 753 | #define TCK_CONT SCS 754 | 755 | void JTAG_IO_Config(void) { 756 | P1_DIR_PU |= ((1 << 1) | (1 << 5) | (1 << 7)); 757 | P1_DIR_PU &= ~((1 << 6) | (1 << 4)); 758 | P1_MOD_OC &= ~((1 << 1) | (1 << 5) | (1 << 7) | (1 << 6) | (1 << 4)); 759 | 760 | TMS = 0; 761 | TDI = 0; 762 | TDO = 0; 763 | TCK = 0; 764 | TCK_CONT = 0; 765 | /* P1.1 TMS, P1.5 TDI(MOSI), P1.7 TCK PP */ 766 | /* P1.6 TDO(MISO) INPUT */ 767 | /* P1.4 INPUT */ 768 | } 769 | 770 | void Run_Test_Start() { 771 | /* P1.7 INPUT, P1.4 PP */ 772 | PIN_FUNC |= bT2_PIN_X; 773 | P1_DIR_PU &= ~((1 << 7)); 774 | P1_MOD_OC &= ~((1 << 7)); 775 | // TCK = 1; 776 | 777 | RCAP2L = 0xfd; 778 | 779 | P1_DIR_PU |= ((1 << 4)); 780 | P1_MOD_OC &= ~((1 << 4)); 781 | } 782 | 783 | void Run_Test_Stop() { 784 | P1_DIR_PU &= ~((1 << 4)); 785 | P1_MOD_OC &= ~((1 << 4)); // P1.4 INPUT 786 | 787 | RCAP2L = 0xfe; 788 | PIN_FUNC &= ~bT2_PIN_X; 789 | 790 | P1_DIR_PU |= ((1 << 7)); 791 | P1_MOD_OC &= ~((1 << 7)); // P1.7 OUTPUT 792 | } 793 | 794 | #define MPSSE_IDLE 0 795 | #define MPSSE_RCV_LENGTH_L 1 796 | #define MPSSE_RCV_LENGTH_H 2 797 | #define MPSSE_TRANSMIT_BYTE 3 798 | #define MPSSE_RCV_LENGTH 4 799 | #define MPSSE_TRANSMIT_BIT 5 800 | #define MPSSE_ERROR 6 801 | #define MPSSE_TRANSMIT_BIT_MSB 7 802 | #define MPSSE_TMS_OUT 8 803 | #define MPSSE_NO_OP_1 9 804 | #define MPSSE_NO_OP_2 10 805 | #define MPSSE_TRANSMIT_BYTE_MSB 11 806 | #define MPSSE_RUN_TEST 12 807 | 808 | // Main function 809 | main() { 810 | uint8_t i; 811 | uint8_t Purge_Buffer = 0; 812 | uint8_t data, rcvdata; 813 | uint8_t instr = 0; 814 | volatile uint16_t Uart_Timeout = 0; 815 | volatile uint16_t Uart_Timeout1 = 0; 816 | uint16_t Esp_Stage = 0; 817 | // int8_t size; 818 | 819 | 820 | Xtal_Enable(); // Start the oscillator 821 | CfgFsys( ); // CH552 clock selection configuration 822 | mDelaymS(5); // Modify the main frequency and wait for the internal clock to stabilize, must be added 823 | CLKO_Enable(); 824 | JTAG_IO_Config(); 825 | SerialPort_Config(); 826 | 827 | PWM2 = 1; 828 | 829 | #if MPSSE_HWSPI 830 | SPI_Init(); 831 | #endif 832 | 833 | dbg_printf("start ...\n"); 834 | USBDeviceCfg(); 835 | USBDeviceEndPointCfg(); // Endpoint configuration 836 | USBDeviceIntCfg(); // Interrupt initialization 837 | UEP0_T_LEN = 0; 838 | UEP1_T_LEN = 0; //The pre-used transmission length must be cleared 839 | UEP2_T_LEN = 0; //The pre-used transmission length must be cleared 840 | 841 | /* Pre-fill Modem Status */ 842 | Ep1Buffer[0] = 0x01; 843 | Ep1Buffer[1] = 0x60; 844 | Ep3Buffer[0] = 0x01; 845 | Ep3Buffer[1] = 0x60; 846 | UpPoint1_Ptr = 2; 847 | UpPoint3_Ptr = 2; 848 | XBUS_AUX = 0; 849 | #ifndef SOF_NO_TIMER 850 | init_timer(); // Every 1ms SOF_Count increases by 1 851 | SOF_Count = 0; 852 | #endif 853 | T1 = 0; 854 | while(1) { 855 | if(UsbConfig) { 856 | if(USBReceived == 1) { 857 | // Received a packet 858 | #if MPSSE_DEBUG 859 | if(UpPoint1_Ptr < 64 && UpPoint1_Busy == 0 && UpPoint3_Busy == 0 && UpPoint3_Ptr < 64) /* Can send */ 860 | #else 861 | if(UpPoint1_Ptr < 64 && UpPoint1_Busy == 0) 862 | #endif 863 | { 864 | PWM2 = !PWM2; 865 | switch(Mpsse_Status) { 866 | case MPSSE_IDLE: 867 | instr = Ep2Buffer[USBOutPtr]; 868 | #if MPSSE_DEBUG 869 | Ep3Buffer[UpPoint3_Ptr++] = instr; 870 | #endif 871 | switch(instr) { 872 | case 0x80: 873 | case 0x82: /* Fake Bit bang mode */ 874 | Mpsse_Status = MPSSE_NO_OP_1; 875 | USBOutPtr++; 876 | break; 877 | case 0x81: 878 | case 0x83: /* False state */ 879 | Ep1Buffer[UpPoint1_Ptr++] = Ep2Buffer[USBOutPtr] - 0x80; 880 | USBOutPtr++; 881 | break; 882 | case 0x84: 883 | case 0x85: /* Loopback */ 884 | USBOutPtr++; 885 | break; 886 | case 0x86: /* Speed adjustment, temporarily not supported */ 887 | Mpsse_Status = MPSSE_NO_OP_1; 888 | USBOutPtr++; 889 | break; 890 | case 0x87: /* Refresh the buffer immediately */ 891 | Purge_Buffer = 1; 892 | USBOutPtr++; 893 | break; 894 | case 0x19: 895 | case 0x39: 896 | case 0x11: 897 | case 0x31: 898 | SPI_ON(); 899 | Mpsse_Status = MPSSE_RCV_LENGTH_L; 900 | USBOutPtr++; 901 | break; 902 | case 0x6b: 903 | case 0x4b: 904 | case 0x3b: 905 | case 0x1b: 906 | case 0x13: 907 | SPI_OFF(); 908 | Mpsse_Status = MPSSE_RCV_LENGTH; 909 | USBOutPtr++; 910 | break; 911 | default: /* Unsupported command */ 912 | Ep1Buffer[UpPoint1_Ptr++] = 0xfa; 913 | Mpsse_Status = MPSSE_ERROR; 914 | break; 915 | } 916 | break; 917 | case MPSSE_RCV_LENGTH_L: /* Receive length */ 918 | Mpsse_LongLen = Ep2Buffer[USBOutPtr]; 919 | Mpsse_Status ++; 920 | USBOutPtr++; 921 | break; 922 | case MPSSE_RCV_LENGTH_H: 923 | Mpsse_LongLen |= (Ep2Buffer[USBOutPtr] << 8) & 0xff00; 924 | USBOutPtr++; 925 | #if GOWIN_INT_FLASH_QUIRK 926 | if((Mpsse_LongLen == 25000 || Mpsse_LongLen == 750 || Mpsse_LongLen == 2968) && (instr & (1 << 5)) == 0) { 927 | SPI_OFF(); 928 | Run_Test_Start(); 929 | Mpsse_Status = MPSSE_RUN_TEST; 930 | } else if(instr == 0x11 || instr == 0x31) 931 | #else 932 | if (instr == 0x11 || instr == 0x31) 933 | #endif 934 | { 935 | Mpsse_Status = MPSSE_TRANSMIT_BYTE_MSB; 936 | SPI_MSBFIRST(); 937 | } else { 938 | Mpsse_Status ++; 939 | SPI_LSBFIRST(); 940 | } 941 | break; 942 | case MPSSE_TRANSMIT_BYTE: 943 | data = Ep2Buffer[USBOutPtr]; 944 | #if MPSSE_HWSPI 945 | SPI0_DATA = data; 946 | while(S0_FREE == 0); 947 | rcvdata = SPI0_DATA; 948 | #else 949 | rcvdata = 0; 950 | for(i = 0; i < 8; i++) { 951 | SCK = 0; 952 | MOSI = (data & 0x01); 953 | data >>= 1; 954 | rcvdata >>= 1; 955 | __asm nop __endasm; 956 | __asm nop __endasm; 957 | SCK = 1; 958 | if(MISO == 1) 959 | rcvdata |= 0x80; 960 | __asm nop __endasm; 961 | __asm nop __endasm; 962 | } 963 | SCK = 0; 964 | #endif 965 | if(instr == 0x39) 966 | Ep1Buffer[UpPoint1_Ptr++] = rcvdata; 967 | USBOutPtr++; 968 | if(Mpsse_LongLen == 0) 969 | Mpsse_Status = MPSSE_IDLE; 970 | Mpsse_LongLen --; 971 | break; 972 | case MPSSE_TRANSMIT_BYTE_MSB: 973 | data = Ep2Buffer[USBOutPtr]; 974 | #if MPSSE_HWSPI 975 | SPI0_DATA = data; 976 | while(S0_FREE == 0); 977 | rcvdata = SPI0_DATA; 978 | #else 979 | rcvdata = 0; 980 | for(i = 0; i < 8; i++) { 981 | SCK = 0; 982 | MOSI = (data & 0x80); 983 | data <<= 1; 984 | rcvdata <<= 1; 985 | __asm nop __endasm; 986 | __asm nop __endasm; 987 | SCK = 1; 988 | if(MISO == 1) 989 | rcvdata |= 0x01; 990 | __asm nop __endasm; 991 | __asm nop __endasm; 992 | } 993 | SCK = 0; 994 | #endif 995 | if(instr == 0x31) 996 | Ep1Buffer[UpPoint1_Ptr++] = rcvdata; 997 | USBOutPtr++; 998 | if(Mpsse_LongLen == 0) 999 | Mpsse_Status = MPSSE_IDLE; 1000 | Mpsse_LongLen --; 1001 | break; 1002 | case MPSSE_RCV_LENGTH: 1003 | Mpsse_ShortLen = Ep2Buffer[USBOutPtr]; 1004 | if(instr == 0x6b || instr == 0x4b) 1005 | Mpsse_Status = MPSSE_TMS_OUT; 1006 | else if(instr == 0x13) 1007 | Mpsse_Status = MPSSE_TRANSMIT_BIT_MSB; 1008 | else 1009 | Mpsse_Status++; 1010 | USBOutPtr++; 1011 | break; 1012 | case MPSSE_TRANSMIT_BIT: 1013 | data = Ep2Buffer[USBOutPtr]; 1014 | rcvdata = 0; 1015 | do { 1016 | SCK = 0; 1017 | MOSI = (data & 0x01); 1018 | data >>= 1; 1019 | rcvdata >>= 1; 1020 | __asm nop __endasm; 1021 | __asm nop __endasm; 1022 | SCK = 1; 1023 | if(MISO) 1024 | rcvdata |= 0x80;// (1 << (Mpsse_ShortLen)); 1025 | __asm nop __endasm; 1026 | __asm nop __endasm; 1027 | } while((Mpsse_ShortLen--) > 0); 1028 | SCK = 0; 1029 | if(instr == 0x3b) 1030 | Ep1Buffer[UpPoint1_Ptr++] = rcvdata; 1031 | Mpsse_Status = MPSSE_IDLE; 1032 | USBOutPtr++; 1033 | break; 1034 | case MPSSE_TRANSMIT_BIT_MSB: 1035 | data = Ep2Buffer[USBOutPtr]; 1036 | rcvdata = 0; 1037 | do { 1038 | SCK = 0; 1039 | MOSI = (data & 0x80); 1040 | data <<= 1; 1041 | __asm nop __endasm; 1042 | __asm nop __endasm; 1043 | SCK = 1; 1044 | __asm nop __endasm; 1045 | __asm nop __endasm; 1046 | } while((Mpsse_ShortLen--) > 0); 1047 | SCK = 0; 1048 | 1049 | Mpsse_Status = MPSSE_IDLE; 1050 | USBOutPtr++; 1051 | 1052 | break; 1053 | case MPSSE_ERROR: 1054 | Ep1Buffer[UpPoint1_Ptr++] = Ep2Buffer[USBOutPtr]; 1055 | Mpsse_Status = MPSSE_IDLE; 1056 | USBOutPtr++; 1057 | break; 1058 | case MPSSE_TMS_OUT: 1059 | data = Ep2Buffer[USBOutPtr]; 1060 | if(data & 0x80) 1061 | TDI = 1; 1062 | else 1063 | TDI = 0; 1064 | rcvdata = 0; 1065 | do { 1066 | TCK = 0; 1067 | TMS = (data & 0x01); 1068 | data >>= 1; 1069 | rcvdata >>= 1; 1070 | __asm nop __endasm; 1071 | __asm nop __endasm; 1072 | SCK = 1; 1073 | if(TDO) 1074 | rcvdata |= 0x80;// (1 << (Mpsse_ShortLen)); 1075 | __asm nop __endasm; 1076 | __asm nop __endasm; 1077 | } while((Mpsse_ShortLen--) > 0); 1078 | TCK = 0; 1079 | if(instr == 0x6b) 1080 | Ep1Buffer[UpPoint1_Ptr++] = rcvdata; 1081 | Mpsse_Status = MPSSE_IDLE; 1082 | USBOutPtr++; 1083 | break; 1084 | case MPSSE_NO_OP_1: 1085 | Mpsse_Status ++; 1086 | USBOutPtr++; 1087 | break; 1088 | case MPSSE_NO_OP_2: 1089 | Mpsse_Status = MPSSE_IDLE; 1090 | USBOutPtr++; 1091 | break; 1092 | #if GOWIN_INT_FLASH_QUIRK 1093 | case MPSSE_RUN_TEST: 1094 | if(Mpsse_LongLen == 0) { 1095 | Mpsse_Status = MPSSE_IDLE; 1096 | Run_Test_Stop(); 1097 | } 1098 | 1099 | USBOutPtr++; 1100 | Mpsse_LongLen --; 1101 | break; 1102 | #endif 1103 | default: 1104 | Mpsse_Status = MPSSE_IDLE; 1105 | break; 1106 | } 1107 | 1108 | 1109 | if(USBOutPtr >= USBOutLength) { 1110 | // Received 1111 | USBReceived = 0; 1112 | UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_R_RES | UEP_R_RES_ACK; 1113 | // Open reception 1114 | } 1115 | } 1116 | } 1117 | 1118 | if(UpPoint1_Busy == 0) { 1119 | if(UpPoint1_Ptr == 64) { 1120 | UpPoint1_Busy = 1; 1121 | UEP1_T_LEN = 64; 1122 | UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; 1123 | UpPoint1_Ptr = 2; 1124 | } else if((uint16_t) (SOF_Count - Uart_Timeout) >= Latency_Timer || Purge_Buffer == 1) { // Timeout 1125 | Uart_Timeout = SOF_Count; 1126 | 1127 | UpPoint1_Busy = 1; 1128 | UEP1_T_LEN = UpPoint1_Ptr; 1129 | UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; // Response to ACK 1130 | UpPoint1_Ptr = 2; 1131 | Purge_Buffer = 0; 1132 | } 1133 | } 1134 | 1135 | if(UpPoint3_Busy == 0) { 1136 | int8_t size = WritePtr - ReadPtr; 1137 | if(size < 0) size = size + sizeof(RingBuf);// Find the remainder 1138 | 1139 | if(size >= 62) { 1140 | for(i = 0; i < 62; i++) { 1141 | Ep3Buffer[2 + i] = RingBuf[ReadPtr++]; 1142 | ReadPtr %= sizeof(RingBuf); 1143 | } 1144 | UpPoint3_Busy = 1; 1145 | UEP3_T_LEN = 64; 1146 | UEP3_CTRL = UEP3_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; 1147 | UpPoint3_Ptr = 2; 1148 | 1149 | } else if((uint16_t) (SOF_Count - Uart_Timeout1) >= Latency_Timer1) { // Timeout 1150 | Uart_Timeout1 = SOF_Count; 1151 | if(size > 62) size = 62; 1152 | for(i = 0; i < (uint8_t)size; i++) { 1153 | Ep3Buffer[2 + i] = RingBuf[ReadPtr++]; 1154 | ReadPtr %= sizeof(RingBuf); 1155 | } 1156 | UpPoint3_Busy = 1; 1157 | // UEP3_T_LEN = UpPoint3_Ptr; 1158 | UEP3_T_LEN = 2 + size; 1159 | UpPoint3_Ptr = 2; 1160 | UEP3_CTRL = UEP3_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; // Response to ACK 1161 | } 1162 | } 1163 | 1164 | if(USBReceived_1) { // IDLE status 1165 | if(Serial_Done == 0) { // Serial port IDLE 1166 | Serial_Done = 2; // Serial port sending 1167 | TI = 1; 1168 | } 1169 | if(UEP4_CTRL & MASK_UEP_R_RES != UEP_R_RES_ACK) 1170 | UEP4_CTRL = UEP4_CTRL & ~ MASK_UEP_R_RES | UEP_R_RES_ACK; 1171 | USBReceived_1 = 0; 1172 | } 1173 | 1174 | if(Serial_Done == 1) { 1175 | Serial_Done = 2; // Serial port sending 1176 | TI = 1; 1177 | 1178 | Serial_Done = 0; 1179 | // if(UEP4_CTRL & MASK_UEP_R_RES != UEP_R_RES_ACK) 1180 | UEP4_CTRL = UEP4_CTRL & ~ MASK_UEP_R_RES | UEP_R_RES_ACK; 1181 | } 1182 | 1183 | if(Require_DFU) { 1184 | Require_DFU = 0; 1185 | Jump_to_BL(); 1186 | } 1187 | } 1188 | } 1189 | } 1190 | 1191 | /******************************************************************************* 1192 | * Function Name : mTimer0Interrupt() 1193 | * Description : CH554 timer counter 0 timer counter interrupt processing function 1194 | *******************************************************************************/ 1195 | void mTimer0Interrupt(void) __interrupt (INT_NO_TMR0) { //timer0 interrupt service routine 1196 | mTimer_x_SetData(0, 1000); //For non-auto reload mode, TH0 and TL0 need to be re-assigned, 1MHz/1000=1000Hz, 1ms 1197 | SOF_Count ++; 1198 | if(Modem_Count) 1199 | Modem_Count --; 1200 | if(Modem_Count == 1) { 1201 | if(soft_dtr == 0 && soft_rts == 1) { 1202 | INTF1_RTS = 1; 1203 | INTF1_DTR = 0; 1204 | } 1205 | if(soft_dtr == 1 && soft_rts == 0) { 1206 | INTF1_RTS = 0; 1207 | INTF1_DTR = 1; 1208 | } 1209 | if(soft_dtr == soft_rts) { 1210 | INTF1_DTR = 1; 1211 | INTF1_RTS = 0; 1212 | INTF1_RTS = 1; 1213 | } 1214 | } 1215 | if(SOF_Count % 16 == 0) 1216 | PWM2 = 1; 1217 | } 1218 | 1219 | -------------------------------------------------------------------------------- /src/spi.c: -------------------------------------------------------------------------------- 1 | #include "hal.h" 2 | 3 | void SPI_Init() { 4 | SPI0_CK_SE = 0x06; 5 | } 6 | -------------------------------------------------------------------------------- /src/uart.c: -------------------------------------------------------------------------------- 1 | 2 | /******************************************************************************* 3 | * Function Name : Uart0_ISR() 4 | * Description : Serial port receive interrupt function to achieve circular buffer reception 5 | *******************************************************************************/ 6 | #include "hal.h" 7 | 8 | // Ring Buf 9 | 10 | volatile __idata uint8_t WritePtr = 0; 11 | volatile __idata uint8_t ReadPtr = 0; 12 | 13 | #ifndef HARD_ESP_CTRL 14 | volatile __idata uint8_t Esp_Boot_Chk = 0; 15 | volatile __idata uint8_t Esp_Require_Reset = 0; 16 | #endif 17 | 18 | #ifndef HARD_ESP_CTRL 19 | __code uint8_t ESP_Boot_Sequence[] = { 20 | 0x07, 0x07, 0x12, 0x20, 21 | 0x55, 0x55, 0x55, 0x55, 22 | 0x55, 0x55, 0x55, 0x55, 23 | 0x55, 0x55, 0x55, 0x55, 24 | 0x55, 0x55, 0x55, 0x55 25 | }; 26 | #endif 27 | 28 | #ifndef FAST_RECEIVE /* Old disrepair code, don't maintain it anymore */ 29 | void Uart0_ISR(void) __interrupt (INT_NO_UART0) __using 1 { 30 | if(RI) { // Receive data 31 | if((WritePtr + 1) % sizeof(RingBuf) != ReadPtr) { 32 | // Ring buffer write 33 | RingBuf[WritePtr++] = SBUF; 34 | WritePtr %= sizeof(RingBuf); 35 | } 36 | RI = 0; 37 | } 38 | if (TI) { 39 | if(USBOutPtr_1 >= USBOutLength_1) { 40 | UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_R_RES | UEP_R_RES_ACK; 41 | TI = 0; 42 | } else { 43 | uint8_t ch = Ep2Buffer[USBOutPtr_1]; 44 | SBUF = ch; 45 | TI = 0; 46 | #ifndef HARD_ESP_CTRL 47 | if(ESP_Boot_Sequence[Esp_Boot_Chk] == ch) 48 | Esp_Boot_Chk ++; 49 | else 50 | Esp_Boot_Chk = 0; 51 | 52 | if(Esp_Boot_Chk >= (sizeof(ESP_Boot_Sequence) - 1)) { 53 | if(Esp_Require_Reset == 0) 54 | Esp_Require_Reset = 1; 55 | Esp_Boot_Chk = 0; 56 | } 57 | #endif 58 | USBOutPtr_1++; 59 | } 60 | } 61 | 62 | } 63 | #else 64 | 65 | // Assemble receive data, select register group 1, DPTR1 1.5M~150kHz~160 cycles 66 | void Uart0_ISR(void) __interrupt (INT_NO_UART0) __using 1 __naked { 67 | __asm 68 | push psw ; 2 69 | push a 70 | push dph 71 | push dpl 72 | 73 | ReadFromSerial: 74 | jnb _RI, SendToSerial ; 7 75 | 76 | mov a, _WritePtr ; 2 77 | mov dpl, _ReadPtr 78 | 79 | inc a ; 1 80 | anl dpl, #0x7f 81 | anl a, #0x7f ; 2 82 | 83 | xrl a, dpl 84 | jz SendToSerial 85 | 86 | mov dph, #(_RingBuf >> 8) ; 3 87 | mov dpl, _WritePtr ; 3 88 | mov a, _SBUF ; 2 89 | movx @dptr, a ; 1 90 | 91 | inc _WritePtr ; 1 92 | anl _WritePtr, #0x7f ; 2 93 | 94 | SendToSerial: 95 | clr _RI ; 2 96 | 97 | jnb _TI, ISR_End 98 | 99 | clr c 100 | mov a, _USBOutPtr_1 101 | subb a, _USBOutLength_1 102 | jc SerialTx 103 | 104 | UsbEpAck: 105 | mov _Serial_Done, #1 106 | sjmp Tx_End 107 | SerialTx: 108 | mov dph, #(_Ep4Buffer >> 8) 109 | mov dpl, _USBOutPtr_1 110 | movx a, @dptr 111 | mov _SBUF, a 112 | inc _USBOutPtr_1 113 | 114 | Tx_End: 115 | clr _TI 116 | 117 | ISR_End: 118 | 119 | pop dpl 120 | pop dph 121 | pop a 122 | pop psw 123 | reti 124 | __endasm; 125 | } 126 | #endif 127 | 128 | void SerialPort_Config() { 129 | volatile uint32_t x; 130 | volatile uint8_t x2; 131 | 132 | /* P3.0 input */ 133 | P3_DIR_PU &= ~((1 << 0)); 134 | P3_MOD_OC &= ~((1 << 0)); 135 | 136 | /* P3.1 output */ 137 | P3_DIR_PU &= ((1 << 1)); 138 | P3_MOD_OC |= ~((1 << 1)); 139 | 140 | SM0 = 0; 141 | SM1 = 1; 142 | SM2 = 0; // Serial port 0 use mode 1 143 | // Use Timer1 as baud rate generator 144 | RCLK = 0; // UART0 receive clock 145 | TCLK = 0; // UART0 sending clock 146 | PCON |= SMOD; 147 | x = 10 * FREQ_SYS / SBAUD_SET / 16; // Calculation of baud rate: 16M/16/baud rate 148 | // If you change the main frequency, pay attention to the value of x not to overflow 149 | x2 = x % 10; 150 | x /= 10; 151 | if ( x2 >= 5 ) x ++; // rounding 152 | 153 | TMOD = TMOD & ~ bT1_GATE & ~ bT1_CT & ~ MASK_T1_MOD | bT1_M1; // 0X20, Timer1 as an 8-bit automatic reload timer 154 | T2MOD = T2MOD | bTMR_CLK | bT1_CLK; // Timer1 clock selection 155 | TH1 = 0 - x; // 12MHz crystal oscillator, buad/12 is the actual baud rate that needs to be set 156 | TR1 = 1; // Start timer 1 157 | TI = 0; 158 | REN = 1; // Serial port 0 receiving enable 159 | ES = 1; // Open serial port interrupt 160 | PS = 1; // Interrupt priority is the highest 161 | } 162 | --------------------------------------------------------------------------------