BOOL DR_LED1(void) //×Ô¶¨ÒåÇëÇó { EP0BUF[0]=0xA1; EP0BCH=0; EP0BCL=2; EZUSB_Delay(100); IOE=EP0BUF[1]; EP0CS |= bmHSNAK; return(TRUE); }
void EZUSB_Discon(BOOL renum) { if(renum) // If renumerate (i.e. 8051 will handle SETUP commands) USBCS |= (bmDISCON | bmRENUM); // disconnect from USB and set the renumerate bit else USBCS |= bmDISCON; // just disconnect from USB EZUSB_Delay(1500); // Wait 1500 ms USBIRQ = 0xff; // Clear any pending USB interrupt requests. They're for our old life. EPIRQ = 0xff; EZUSB_IRQ_CLEAR(); USBCS &=~bmDISCON; // reconnect USB }
/* ******************************************************************** */ void Check_Bootloader(void) { // reinit all chip TD_Init(); // just to allow send/receive from midi and usb inputs z8_board_fully_updated_from_ez0_bit = 1; // Init i2c bus for eeprom ez upgrade //EZUSB_InitI2C(); // update bootloading flags and state bootloader_state = SEND_IDENTITY_SYSEX; // First send the Bootloader identity sysex acknoledge to midi & usb out SendIdentityBootLoader(); must_program_z8 = FALSE; // The data firmware upgrade starts here bootloader_state = WAIT_EZ_FW_DATA; // Now Wait for the ez firmware data sysexs WaitNextBootLoaderState(bootloader_state); if(must_program_z8) { // Release Z8 board reset line Z8_RESET_PORT_OUT |= Z8_RESET_PIN; // wait por EZUSB_Delay(200); // disable rx1 SCON1 = 0x40; /* SCON1: mode 1, 8-bit UART, disable rcvr */ // tx1 is now dedicated to z8 dbg pin OCD_EN_PORT_OUT |= OCD_EN_PIN; // set z8 dbg pin low TX1_TO_Z8_DBG_PORT_OUT &= ~TX1_TO_Z8_DBG_PIN; // wait 2sec EZUSB_Delay(2000); // set z8 dbg pin high TX1_TO_Z8_DBG_PORT_OUT |= TX1_TO_Z8_DBG_PIN; // turn on tx1 and rx1 (serial to/from z8) PORTBCFG |= 0x0C; // send ocd first byte so the z8 autobaudrate the serial line Send_To_Serial_Z8(OCD_FIRST_BYTE); EZUSB_Delay1ms(); // place the z8 chip in ocd mode Send_To_Serial_Z8(OCD_WRITE_CTR_REG_CMD); Send_To_Serial_Z8(OCD_CTR_REG_DBGMODE); EZUSB_Delay(100); InitFlashFrqAndUnlock(); // selet flash page 0 WriteSingleRegOCD(OCD_FLASH_SELECT_PAGE, 0x00); // launch a mass erase WriteSingleRegOCD(OCD_FLASH_CTR_REG_ADD, OCD_FLASH_MASS_ERASE); EZUSB_Delay(Z8_ERASING_TIME); InitFlashFrqAndUnlock(); // Now Wait for the z8 firmware data sysexs WaitNextBootLoaderState(bootloader_state); EZUSB_Delay(50); // relock the flash controller WriteSingleRegOCD(OCD_FLASH_CTR_REG_ADD, OCD_FLASH_CTR_REG_RESET); /* ///////////////////// Z8 CRC CHECKS ///////////////////////////////// // V1.4 it is now time to verify Z8 programmed flash bootloader_state = VERIFY_Z8_CRC; // V1.4 Read the Z8 memory CRC and compare to calculated CRC Send_To_Serial_Z8(OCD_READ_FLASH_CRC); // V1.4 required time is 65536 * 1/(20MHz) EZUSB_Delay(50); // V1.4 the serial port should now have received the z8 internal CRC in buffer 0 to 3 // Send this CRC to host Serial_In_From_Z8.buffer[7] = Serial_In_From_Z8.buffer[0]; Serial_In_From_Z8.buffer[8] = Serial_In_From_Z8.buffer[1]; Serial_In_From_Z8.end_index = WID_SYX_HEADER_SIZE + 3 + 1; AssignWidSysexHeader(); // send ack firmware Serial_In_From_Z8.buffer[6] = FRAME_IS_FIRMWARE_OR_PURE_MIDI | sysex_direction_sysxid0 | prog_upload_sysxid0; // send eox Serial_In_From_Z8.buffer[9] = MIDI_EOX; SendDispatchFwSysex(); ///////////////////// END Z8 CRC CHECKS ///////////////////////////////// */ // exit z8 ocd mode OCD_EN_PORT_OUT &= ~OCD_EN_PIN; // exit z8 ocd mode Z8_RESET_PORT_OUT &= ~Z8_RESET_PIN; } // Now finish with a soft reset // SoftReset(); while(1) { Check_Usb(); Ep2out_Function(); } }
// *************************************************************************** // Routine : DecodeFirmwareSysex() // Input : // Output : must send ack bool // Process : decode the sysex dedicated to firmware // *************************************************************************** void DecodeFirmwareSysex(Midi_In_Struct *midi_struct) { BYTE SYSXID0; WORD Address; BYTE i, j, tmp1, tmp2, tmp3, lenght_div_2; BYTE result = 0; bit must_send_ack = FALSE; BYTE fw_checksum = 0; SYSXID0 = midi_struct->buffer[6]; // check the received sysex is dedicated to firmware otherwise return // also check it is a programming sysex : ack request must be set for firmware programming if((SYSXID0 & (FRAME_TO_Z8_TYPE_MSK | acknoledge_sysxid0)) == (/*v1.1 FRAME_IS_FIRMWARE*/FRAME_IS_FIRMWARE_OR_PURE_MIDI | acknoledge_sysxid0)) { must_send_ack = TRUE; // must finish firmware upgrade ? if(SYSXID0 & fw_znext_finish_sysxid0) { // bootloader_state = TERMINATE_FW_UPGRADE; bootloader_state++; result = acknoledge_sysxid0; // pass to z8 programming ? if(SYSXID0 & prog_ez_z8_sysxid0) { must_program_z8 = TRUE; // reset crc z8 // z8_flash_crc = 0; } } else { // here we have to program EZ or Z8 firmware data // extract address from sysex Address = midi_struct->buffer[8] << 14; Address += (midi_struct->buffer[9] << 7); Address += (midi_struct->buffer[10]); // un nibble data, decode it, calculate checksum fw_checksum = 0; j= FW_SYSX_DATA_START; for(i=0; i < midi_struct->buffer[7]; i=i+2) { tmp1 = midi_struct->buffer[FW_SYSX_DATA_START+i]; tmp2 = midi_struct->buffer[FW_SYSX_DATA_START+i+1]; fw_checksum = (fw_checksum + tmp1) & 0x7F; fw_checksum = (fw_checksum + tmp2) & 0x7F; midi_struct->buffer[j] = ( (tmp1 << 4) + (tmp2 & 0x0F)) ^ 0x55; j++; } // compare checksum if(fw_checksum == midi_struct->buffer[FW_SYSX_DATA_START+i]) { lenght_div_2 = midi_struct->buffer[7] >> 1; // NEED TO PROGRAM EZ USB EEPROM ? if(!(SYSXID0 & prog_ez_z8_sysxid0)) { if(Address < EE24C64_SIZE) //if(!(LSB(Address) % 32)) { EZUSB_IRQ_DISABLE(); CKCON |= 0x07; // Set stretch to Non zero when accessing I2C (insert 7 wait states) // write and verify eeprom result=0 if error result = EEPROMWriteVerify(Address, lenght_div_2, &midi_struct->buffer[FW_SYSX_DATA_START]); CKCON &= 0xF8; // Set stretch to 0 after i2c access (required if using paired endpoints : see chip errata) EZUSB_IRQ_ENABLE(); } } // OR NEED TO PROGRAM Z8 ? else { // calculated checksum is ok to start result = acknoledge_sysxid0; // ///////////////// PROGRAM Z8 ///////////////// // Send write command Send_To_Serial_Z8(OCD_WRITE_PRG_MEM_CMD); // Send address msb to write Send_To_Serial_Z8(Address >> 8); // Send address msb to write Send_To_Serial_Z8(Address & 0xFF); // Send data_lenght msb to write Send_To_Serial_Z8(0x00); // Send data_lenght lsb to write Send_To_Serial_Z8(lenght_div_2); // Now send datas for(i=0; i < lenght_div_2; i++) { Send_To_Serial_Z8(midi_struct->buffer[FW_SYSX_DATA_START+i]); } // V1.4 Wait for the transmit buffer being empty (everything sent to Z8) while(tx_to_serial_z8_busy); // wait raw time write EZUSB_Delay(50); // V1.4 10 // V1.4 ///////////////// READ BACK Z8 AND CHECK IF SAME ///////////////// // Send write command Send_To_Serial_Z8(OCD_READ_PRG_MEM_CMD); // Send address msb to write Send_To_Serial_Z8(Address >> 8); // Send address msb to write Send_To_Serial_Z8(Address & 0xFF); // Send data_lenght msb to write Send_To_Serial_Z8(0x00); // Send data_lenght lsb to write Send_To_Serial_Z8(lenght_div_2); // V1.4 Wait for the transmit buffer being empty (everything sent to Z8) while(tx_to_serial_z8_busy); // V1.4 enable rx1 for reading back datas from z8 SCON1 |= 0x50; /* SCON1: mode 1, 8-bit UART, enable rcvr */ // V1.4 wait for all data being received from Z8 while(Serial_In_From_Z8.current_index < lenght_div_2); // EZUSB_Delay(50); // Send_To_Midi_Out_Con(0xF0); // Send_To_Midi_Out_Con(lenght_div_2); // Send_To_Midi_Out_Con(Serial_In_From_Z8.start_index); // Send_To_Midi_Out_Con(Serial_In_From_Z8.current_index); // Send_To_Midi_Out_Con(Serial_In_From_Z8.end_index); // Send_To_Midi_Out_Con(00); // Send_To_Midi_Out_Con(00); // Send_To_Midi_Out_Con(0xF7); // V1.4 Now read datas from serial_in_from_z8 input buffer for(i=0; i < lenght_div_2; i++) { // read data received from serial port buffer tmp3 = Serial_In_From_Z8.buffer[i]; // Send_To_Midi_Out_Con(0xF0); // Send_To_Midi_Out_Con(midi_struct->buffer[FW_SYSX_DATA_START+i] >> 4); // Send_To_Midi_Out_Con(midi_struct->buffer[FW_SYSX_DATA_START+i] & 0x0F); // Send_To_Midi_Out_Con(tmp3 >> 4); // Send_To_Midi_Out_Con(tmp3 & 0x0F); // Send_To_Midi_Out_Con(0xF7); // compare data read back with data written if(tmp3 != midi_struct->buffer[FW_SYSX_DATA_START+i]) { // a byte doesnt correspond to what was programmed : send ack error result = 0; break; } } // V1.4 disable rx1 SCON1 &= 0xEF; /* SCON1: mode 1, 8-bit UART, disable rcvr */ } // end prog z8 // 10ms delay after ez or z8 programming //EZUSB_Delay(10); } // end checksum ok } // end program instead of terminate
void TD_Init(void) // Called once at startup { WORD tmp; Running = FALSE; /* The following code depends on your actual circuit design. Make required changes _before_ you try the code! */ // set the CPU clock to 48MHz, enable clock output to FPGA CPUCS = bmCLKOE | bmCLKSPD1; #ifndef FTDEMU // Use internal 48 MHz, enable output, use "Port" mode for all pins IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE; #else // Use internal 48 MHz, enable output, asynchronous slave FIFO mode IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmASYNC | bmIFCFG1 | bmIFCFG0; PINFLAGSAB = 0; FIFOPINPOLAR = 0; /* SLRD, SLOE == RD# Input: Enables the current FIFO data byte on D0...D7 when low. Fetched the next FIFO data byte (if available) from the receive FIFO buffer when RD# goes from high to low. */ FIFOPINPOLAR &= ~(1<<5); // PKTEND: active low FIFOPINPOLAR &= ~(1<<4); // SLOE: active low FIFOPINPOLAR &= ~(1<<3); // SLRD: active low /* FLAGA == RXF# Output: When high, do not read data from the FIFO. When low, there is data available in the FIFO which can be read by strobing RD# low, then high again. */ PINFLAGSAB |= 0x08; // FLAGA is EP2 EMPTY FLAG FIFOPINPOLAR |= (1<<1); // active high /* SLWR == WR Input: Writes the data byte on the D0...D7 pins into the transmit FIFO buffer when WR goes from high to low. */ FIFOPINPOLAR |= (1<<2); // active high /* FLAGB == TXE# Output: When high, do not write data into the FIFO. When low, data can be written into the FIFO by strobing WR high, then low. */ PINFLAGSAB |= 0xE0; // FLAGB is EP6 FULL FLAG FIFOPINPOLAR |= (1<<0); // active high #endif #ifdef DEBUG UART230 |= 2; SCON1 = 0x52; SMOD1 = 0; printf("Debug active\n"); #endif // power on the FPGA and all other VCCs, assert RESETN IOE = 0x1F & ~(1<<4); OEE = 0x1F; EZUSB_Delay(500); // wait for supply to come up // The remainder of the code however should be left unchanged... // Make Timer2 reload at 100 Hz to trigger Keepalive packets tmp = 65536 - ( 48000000 / 12 / 100 ); RCAP2H = tmp >> 8; RCAP2L = tmp & 0xFF; CKCON = 0; // Default Clock T2CON = 0x04; // Auto-reload mode using internal clock, no baud clock. // Enable Autopointer EXTACC = 1; // Enable APTR1FZ = 1; // Don't freeze APTR2FZ = 1; // Don't freeze // define endpoint configuration REVCTL = 3; SYNCDELAY; // Allow FW access to FIFO buffer EP1OUTCFG = 0xA0; SYNCDELAY; EP1INCFG = 0xA0; SYNCDELAY; EP2CFG = 0xA2; SYNCDELAY; EP4CFG = 0xA0; SYNCDELAY; EP6CFG = 0xE2; SYNCDELAY; EP8CFG = 0xE0; SYNCDELAY; EP4FIFOCFG = 0x00; SYNCDELAY; EP8FIFOCFG = 0x00; SYNCDELAY; FIFORESET = 0x80; SYNCDELAY; // From now on, NAK all FIFORESET = 0x04; SYNCDELAY; FIFORESET = 0x08; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; // Restore normal behaviour OUTPKTEND = 0x84; SYNCDELAY; OUTPKTEND = 0x84; SYNCDELAY; VC_Reset_IN(); VC_Reset_OUT(); VC_Reset_FPGA(); }
void VC_Reset_FPGA(void) { IOE &= ~(1<<4); EZUSB_Delay(50); IOE |= (1<<4); }
// // If a breakout command is received // We must go back to loading the FPGA // static int I2cEP1Data(void) { xdata const unsigned char *src = EP1OUTBUF; xdata unsigned char *dest = EP1INBUF; unsigned int len = EP1OUTBC; unsigned int i; unsigned int add; int resends; BYTE rl; BYTE buffer[40]; if( len > 40 ) { // Fault EP1OUTBC=0xff; // re-arm endpoint 1 return 1; } for(i=0; i<len; i++,src++) { buffer[i] = *src; } // // Send or receive it depending on the LSBit of the Address field. // if(buffer[0]&0x01) { // Receive // ADD - LEN - PAYLOAD // Calculate the response message length rl = buffer[1] + len; if( rl > 40 ) { // Fault EP1OUTBC=0xff; // re-arm EP1 return 1; } // Receive operation add = buffer[2]; add <<= 8; add |= buffer[3]; i2c_receive_flash( buffer[0], add, &buffer[4], buffer[1] ); // Send message back to host via EP1 // We assume the endpoint is ready and don't // test the status. for(i=0; i<rl; i++,dest++) { *dest = buffer[i];// Load data } EP1INBC = rl;// Trigger send } else { // transmit operation //re-transmit up to 3 times with delay resends = 3; rl = buffer[1]+2;//2 is the address field while( resends > 0 ) { resends--; if( i2_send( buffer[0], &buffer[2], rl ) == 0 ) resends = 0; else EZUSB_Delay(4000); } } EP1OUTBC=0xff; // re-arm EP1 return 0; }