/*!
|
/*!
|
ZTEX Firmware Kit for EZ-USB FX2 Microcontrollers
|
ZTEX Firmware Kit for EZ-USB FX2 Microcontrollers
|
Copyright (C) 2009-2011 ZTEX GmbH.
|
Copyright (C) 2009-2011 ZTEX GmbH.
|
http://www.ztex.de
|
http://www.ztex.de
|
|
|
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
it under the terms of the GNU General Public License version 3 as
|
it under the terms of the GNU General Public License version 3 as
|
published by the Free Software Foundation.
|
published by the Free Software Foundation.
|
|
|
This program is distributed in the hope that it will be useful, but
|
This program is distributed in the hope that it will be useful, but
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
General Public License for more details.
|
General Public License for more details.
|
|
|
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
along with this program; if not, see http://www.gnu.org/licenses/.
|
along with this program; if not, see http://www.gnu.org/licenses/.
|
!*/
|
!*/
|
|
|
/*
|
/*
|
FPGA support for ZTEX USB FPGA Modules 1.11
|
FPGA support for ZTEX USB FPGA Modules 1.11
|
*/
|
*/
|
|
|
#ifndef[ZTEX_FPGA_H]
|
#ifndef[ZTEX_FPGA_H]
|
#define[ZTEX_FPGA_H]
|
#define[ZTEX_FPGA_H]
|
|
|
#define[@CAPABILITY_FPGA;]
|
#define[@CAPABILITY_FPGA;]
|
|
|
__xdata BYTE fpga_checksum; // checksum
|
__xdata BYTE fpga_checksum; // checksum
|
__xdata DWORD fpga_bytes; // transfered bytes
|
__xdata DWORD fpga_bytes; // transfered bytes
|
__xdata BYTE fpga_init_b; // init_b state (should be 222 after configuration)
|
__xdata BYTE fpga_init_b; // init_b state (should be 222 after configuration)
|
__xdata BYTE fpga_flash_result; // result of automatic fpga configuarion from Flash
|
__xdata BYTE fpga_flash_result; // result of automatic fpga configuarion from Flash
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** reset_fpga ****************************************************
|
***** reset_fpga ****************************************************
|
********************************************************************* */
|
********************************************************************* */
|
static void reset_fpga_int (BYTE mode) { // reset FPGA
|
static void reset_fpga_int (BYTE mode) { // reset FPGA
|
unsigned short k;
|
unsigned short k;
|
IFCONFIG = bmBIT7;
|
IFCONFIG = bmBIT7;
|
SYNCDELAY;
|
SYNCDELAY;
|
PORTACFG = 0;
|
PORTACFG = 0;
|
PORTCCFG = 0;
|
PORTCCFG = 0;
|
|
|
OEA = (OEA & 5 ) | bmBIT1 | bmBIT3 | bmBIT4 | bmBIT5 | bmBIT6 | bmBIT7;
|
OEA = (OEA & 5 ) | bmBIT1 | bmBIT3 | bmBIT4 | bmBIT5 | bmBIT6 | bmBIT7;
|
IOA = bmBIT7 | mode;
|
IOA = bmBIT7 | mode;
|
wait(10);
|
wait(10);
|
|
|
OEC &= ~bmBIT3;
|
OEC &= ~bmBIT3;
|
|
|
IOA = bmBIT1 | mode; // ready for configuration
|
IOA = bmBIT1 | mode; // ready for configuration
|
k=0;
|
k=0;
|
while (!IOA0 && k<65535)
|
while (!IOA0 && k<65535)
|
k++;
|
k++;
|
|
|
fpga_init_b = IOA0 ? 200 : 100;
|
fpga_init_b = IOA0 ? 200 : 100;
|
fpga_bytes = 0;
|
fpga_bytes = 0;
|
fpga_checksum = 0;
|
fpga_checksum = 0;
|
}
|
}
|
|
|
static void reset_fpga () {
|
static void reset_fpga () {
|
reset_fpga_int(bmBIT5);
|
reset_fpga_int(bmBIT5);
|
}
|
}
|
|
|
static void reset_fpga_flash () {
|
static void reset_fpga_flash () {
|
reset_fpga_int(bmBIT5 | bmBIT6);
|
reset_fpga_int(bmBIT5 | bmBIT6);
|
}
|
}
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** init_fpga_configuration ***************************************
|
***** init_fpga_configuration ***************************************
|
********************************************************************* */
|
********************************************************************* */
|
static void init_fpga_configuration () {
|
static void init_fpga_configuration () {
|
{
|
{
|
PRE_FPGA_RESET
|
PRE_FPGA_RESET
|
}
|
}
|
reset_fpga(); // reset FPGA
|
reset_fpga(); // reset FPGA
|
}
|
}
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** post_fpga_confog **********************************************
|
***** post_fpga_confog **********************************************
|
********************************************************************* */
|
********************************************************************* */
|
static void post_fpga_config () {
|
static void post_fpga_config () {
|
POST_FPGA_CONFIG
|
POST_FPGA_CONFIG
|
}
|
}
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** finish_fpga_configuration *************************************
|
***** finish_fpga_configuration *************************************
|
********************************************************************* */
|
********************************************************************* */
|
static void finish_fpga_configuration () {
|
static void finish_fpga_configuration () {
|
WORD w;
|
BYTE w;
|
fpga_init_b += IOA0 ? 20 : 10;
|
fpga_init_b += IOA0 ? 20 : 10;
|
|
|
for ( w=0; w<64; w++ ) {
|
for ( w=0; w<64; w++ ) {
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
}
|
}
|
IOA7 = 1;
|
IOA7 = 1;
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
IOA3 = 1; IOA3 = 0;
|
|
|
OEA = OEA & 5;
|
OEA = OEA & 5;
|
fpga_init_b += IOA0 ? 2 : 1;
|
fpga_init_b += IOA0 ? 2 : 1;
|
if ( IOA1 ) {
|
if ( IOA1 ) {
|
IOA1 = 1;
|
IOA1 = 1;
|
post_fpga_config();
|
post_fpga_config();
|
}
|
}
|
|
|
IOA1 = 1;
|
IOA1 = 1;
|
OEA |= bmBIT1;
|
OEA |= bmBIT1;
|
}
|
}
|
|
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** EP0 vendor request 0x30 ***************************************
|
***** EP0 vendor request 0x30 ***************************************
|
********************************************************************* */
|
********************************************************************* */
|
ADD_EP0_VENDOR_REQUEST((0x30,, // get FPGA state
|
ADD_EP0_VENDOR_REQUEST((0x30,, // get FPGA state
|
MEM_COPY1(fpga_checksum,EP0BUF+1,7);
|
MEM_COPY1(fpga_checksum,EP0BUF+1,7);
|
OEA &= ~bmBIT1;
|
OEA &= ~bmBIT1;
|
if ( IOA1 ) {
|
if ( IOA1 ) {
|
EP0BUF[0] = 0; // FPGA configured
|
EP0BUF[0] = 0; // FPGA configured
|
IOA1 = 1;
|
IOA1 = 1;
|
OEA |= bmBIT1;
|
OEA |= bmBIT1;
|
}
|
}
|
else {
|
else {
|
EP0BUF[0] = 1; // FPGA unconfigured
|
EP0BUF[0] = 1; // FPGA unconfigured
|
reset_fpga(); // prepare FPGA for configuration
|
reset_fpga(); // prepare FPGA for configuration
|
}
|
}
|
EP0BUF[8] = 1; // bit order for bitstream in Flash memory: swapped
|
EP0BUF[8] = 1; // bit order for bitstream in Flash memory: swapped
|
|
|
EP0BCH = 0;
|
EP0BCH = 0;
|
EP0BCL = 9;
|
EP0BCL = 9;
|
,,));;
|
,,));;
|
|
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** EP0 vendor command 0x31 ***************************************
|
***** EP0 vendor command 0x31 ***************************************
|
********************************************************************* */
|
********************************************************************* */
|
ADD_EP0_VENDOR_COMMAND((0x31,,init_fpga_configuration();,,));; // reset FPGA
|
ADD_EP0_VENDOR_COMMAND((0x31,,init_fpga_configuration();,,));; // reset FPGA
|
|
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** EP0 vendor command 0x32 ***************************************
|
***** EP0 vendor command 0x32 ***************************************
|
********************************************************************* */
|
********************************************************************* */
|
void fpga_send_ep0() {
|
void fpga_send_ep0() {
|
BYTE oOED;
|
BYTE oOED;
|
oOED = OED;
|
oOED = OED;
|
OED = 255;
|
OED = 255;
|
fpga_bytes += ep0_payload_transfer;
|
fpga_bytes += ep0_payload_transfer;
|
__asm
|
__asm
|
mov dptr,#_EP0BCL
|
mov dptr,#_EP0BCL
|
movx a,@dptr
|
movx a,@dptr
|
jz 010000$
|
jz 010000$
|
mov r2,a
|
mov r2,a
|
mov _AUTOPTRL1,#(_EP0BUF)
|
mov _AUTOPTRL1,#(_EP0BUF)
|
mov _AUTOPTRH1,#(_EP0BUF >> 8)
|
mov _AUTOPTRH1,#(_EP0BUF >> 8)
|
mov _AUTOPTRSETUP,#0x07
|
mov _AUTOPTRSETUP,#0x07
|
mov dptr,#_fpga_checksum
|
mov dptr,#_fpga_checksum
|
movx a,@dptr
|
movx a,@dptr
|
mov r1,a
|
mov r1,a
|
mov dptr,#_XAUTODAT1
|
mov dptr,#_XAUTODAT1
|
010001$:
|
010001$:
|
movx a,@dptr // 2
|
movx a,@dptr // 2
|
mov _IOD,a // 2
|
mov _IOD,a // 2
|
setb _IOA3 // 2
|
setb _IOA3 // 2
|
add a,r1 // 1
|
add a,r1 // 1
|
mov r1,a // 1
|
mov r1,a // 1
|
clr _IOA3 // 2
|
clr _IOA3 // 2
|
djnz r2, 010001$ // 4
|
djnz r2, 010001$ // 4
|
|
|
mov dptr,#_fpga_checksum
|
mov dptr,#_fpga_checksum
|
mov a,r1
|
mov a,r1
|
movx @dptr,a
|
movx @dptr,a
|
|
|
010000$:
|
010000$:
|
__endasm;
|
__endasm;
|
OED = oOED;
|
OED = oOED;
|
if ( EP0BCL<64 ) {
|
if ( EP0BCL<64 ) {
|
finish_fpga_configuration();
|
finish_fpga_configuration();
|
}
|
}
|
}
|
}
|
|
|
ADD_EP0_VENDOR_COMMAND((0x32,, // send FPGA configuration data
|
ADD_EP0_VENDOR_COMMAND((0x32,, // send FPGA configuration data
|
,,
|
,,
|
fpga_send_ep0();
|
fpga_send_ep0();
|
));;
|
));;
|
|
|
|
|
#ifeq[FLASH_BITSTREAM_ENABLED][1]
|
#ifeq[FLASH_BITSTREAM_ENABLED][1]
|
#ifeq[FLASH_ENABLED][1]
|
#ifeq[FLASH_ENABLED][1]
|
|
|
/* *********************************************************************
|
/* *********************************************************************
|
***** fpga_send_bitstream_from_flash ********************************
|
***** fpga_send_bitstream_from_flash ********************************
|
********************************************************************* */
|
********************************************************************* */
|
void fpga_send_bitstream_from_flash (WORD size) {
|
void fpga_send_bitstream_from_flash (WORD size) {
|
size; // this avoids stupid warnings
|
size; // this avoids stupid warnings
|
__asm
|
__asm
|
push _OED
|
push _OED
|
mov _OED,#0
|
mov _OED,#0
|
|
|
mov r5,dpl // = size
|
mov r5,dpl // = size
|
mov r6,dph
|
mov r6,dph
|
|
|
// fpga_bytes+=size
|
// fpga_bytes+=size
|
mov dptr,#_fpga_bytes
|
mov dptr,#_fpga_bytes
|
movx a,@dptr
|
movx a,@dptr
|
mov r1,a
|
mov r1,a
|
inc dptr
|
inc dptr
|
movx a,@dptr
|
movx a,@dptr
|
mov r2,a
|
mov r2,a
|
inc dptr
|
inc dptr
|
movx a,@dptr
|
movx a,@dptr
|
mov r3,a
|
mov r3,a
|
inc dptr
|
inc dptr
|
movx a,@dptr
|
movx a,@dptr
|
mov r4,a
|
mov r4,a
|
|
|
mov dptr,#_fpga_bytes
|
mov dptr,#_fpga_bytes
|
mov a,r5
|
mov a,r5
|
add a,r1
|
add a,r1
|
movx @dptr,a
|
movx @dptr,a
|
mov a,r6
|
mov a,r6
|
addc a,r2
|
addc a,r2
|
inc dptr
|
inc dptr
|
movx @dptr,a
|
movx @dptr,a
|
mov a,#0
|
mov a,#0
|
addc a,r3
|
addc a,r3
|
inc dptr
|
inc dptr
|
movx @dptr,a
|
movx @dptr,a
|
mov a,#0
|
mov a,#0
|
addc a,r4
|
addc a,r4
|
inc dptr
|
inc dptr
|
movx @dptr,a
|
movx @dptr,a
|
|
|
010003$:
|
010003$:
|
cjne r5,#0x00,010002$ // 4
|
cjne r5,#0x00,010002$ // 4
|
cjne r6,#0x00,010002$
|
cjne r6,#0x00,010002$
|
pop _OED
|
pop _OED
|
ret
|
ret
|
010002$: // approx 73 cycles per byte
|
010002$: // approx 73 cycles per byte
|
setb _IOA3 // 2
|
setb _IOA3 // 2
|
setb _IOC6 // 2
|
setb _IOC6 // 2
|
clr _IOA3 // 2
|
clr _IOA3 // 2
|
clr _IOC6 // 2
|
clr _IOC6 // 2
|
|
|
setb _IOA3
|
setb _IOA3
|
setb _IOC6
|
setb _IOC6
|
clr _IOA3
|
clr _IOA3
|
clr _IOC6
|
clr _IOC6
|
|
|
setb _IOA3
|
setb _IOA3
|
setb _IOC6
|
setb _IOC6
|
clr _IOA3
|
clr _IOA3
|
clr _IOC6
|
clr _IOC6
|
|
|
setb _IOA3
|
setb _IOA3
|
setb _IOC6
|
setb _IOC6
|
clr _IOA3
|
clr _IOA3
|
clr _IOC6
|
clr _IOC6
|
|
|
setb _IOA3
|
setb _IOA3
|
setb _IOC6
|
setb _IOC6
|
clr _IOA3
|
clr _IOA3
|
clr _IOC6
|
clr _IOC6
|
|
|
setb _IOA3
|
setb _IOA3
|
setb _IOC6
|
setb _IOC6
|
clr _IOA3
|
clr _IOA3
|
clr _IOC6
|
clr _IOC6
|
|
|
setb _IOA3
|
setb _IOA3
|
setb _IOC6
|
setb _IOC6
|
clr _IOA3
|
clr _IOA3
|
clr _IOC6
|
clr _IOC6
|
|
|
setb _IOA3
|
setb _IOA3
|
setb _IOC6
|
setb _IOC6
|
clr _IOA3
|
clr _IOA3
|
clr _IOC6
|
clr _IOC6
|
|
|
dec r5 // 1
|
dec r5 // 1
|
cjne r5,#0xff,010003$ // 4
|
cjne r5,#0xff,010003$ // 4
|
dec r6
|
dec r6
|
sjmp 010003$
|
sjmp 010003$
|
__endasm;
|
__endasm;
|
}
|
}
|
|
|
#include[ztex-fpga-flash.h]
|
#include[ztex-fpga-flash.h]
|
|
|
#else
|
#else
|
#warning[Flash interface is not enabled but required for FPGA configuration using a bitstream from Flash meomory]
|
#warning[Flash interface is not enabled but required for FPGA configuration using a bitstream from Flash meomory]
|
#define[FLASH_BITSTREAM_ENABLED][0]
|
#define[FLASH_BITSTREAM_ENABLED][0]
|
#endif
|
#endif
|
#endif
|
#endif
|
|
|
#endif /*ZTEX_FPGA_H*/
|
#endif /*ZTEX_FPGA_H*/
|
|
|