代码拉取完成,页面将自动刷新
//*********************************************************************
// Copyright (C) 2013 Hell Prototypes / www.hellprototypes.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
//
//********************************************************************
#include "USB/usb.h"
#include "USB/usb_function_generic.h"
#include "HardwareProfile.h"
#include "GenericTypeDefs.h"
#include "version.h"
#include "user.h"
#include "usbcmd.h"
#include "eeprom_flags.h"
#include "utils.h"
#include "blinker.h"
#include "spi.h"
// USB data packet definitions
typedef union DATA_PACKET
{
BYTE _byte[USBGEN_EP_SIZE]; //For byte access
WORD _word[USBGEN_EP_SIZE / 2]; //For word access(USBGEN_EP_SIZE must be even)
struct // for version - compatible to bootloader version return format
{
USBCMD cmd;
BYTE UNUSE;
BYTE ver_Byte0;
BYTE ver_Byte1;
};
struct // for SPI
{
USBCMD cmd;
BYTE len;
BYTE SPI[USBGEN_EP_SIZE - 2];
};
} DATA_PACKET;
#define MIPS 12 // Number of processor instructions per microsecond.
#define MAX_BYTE_VAL 0xFF // Maximum value that can be stored in a byte.
#define NUM_ACTIVITY_BLINKS 8 // Indicate activity by blinking the LED this many times.
#define BLINK_SCALER 10 // Make larger to stretch the time between LED blinks.
#pragma udata access my_access
static near DWORD lcntr; // Large counter for fast loops.
static near BYTE last_key;
static near BYTE fpga_app;
#pragma udata
static USB_HANDLE OutHandle[2] = {0,0}; // Handles to endpoint buffers that are receiving packets from the host.
static BYTE OutIndex = 0; // Index of endpoint buffer has received a complete packet from the host.
static DATA_PACKET *OutPacket; // Pointer to the buffer with the most-recently received packet.
static BYTE OutPacketLength = 0; // Length (in bytes) of most-recently received packet.
static USB_HANDLE InHandle[2] = {0,0}; // Handles to ping-pong endpoint buffers that are sending packets to the host.
static BYTE InIndex = 0; // Index of the endpoint buffer that is currently being filled before being sent to the host.
static DATA_PACKET *InPacket; // Pointer to the buffer that is currently being filled.
// Timer for RUNTEST command.
#pragma udata usbram2
static DATA_PACKET InBuffer[2]; // Ping-pong buffers in USB RAM for sending packets to host.
static DATA_PACKET OutBuffer[2]; // Ping-pong buffers in USB RAM for receiving packets from host.
#pragma code
BYTE ReadEeprom(BYTE address)
{
EECON1 = 0x00;
EEADR = address;
EECON1bits.RD = 1;
return EEDATA;
}
void WriteEeprom(BYTE address, BYTE data)
{
EEADR = address;
EEDATA = data;
EECON1 = 0b00000100; //Setup writes: EEPGD=0,WREN=1
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
while(EECON1bits.WR); //Wait till WR bit is clear
}
//mode:
// 1: FPGA IAP auto boot (auto boot go APP0)
// 0: FPGA IAP auto boot disable (stay in IAP mode)
BYTE Reset_FPGA(BYTE mode)
{
DWORD config_delay;
BYTE ret = 0;
FPGACLK_OFF();
FPGACLK = 0;
if(mode) {
mosi_ctrl(1);
} else {
mosi_ctrl(0);
}
// Try to configure the FPGA from the serial flash.
PROGB = 0; // Erase the FPGA.
insert_delay(1000);
PROGB = 1; // Release FPGA and let it try to configure from the serial flash.
// Now wait for a while and see if the FPGA configuration done pin goes high.
for(config_delay=0L; config_delay<500000L; config_delay++)
{
if(DONE == 1) {
ret = 1;
break;
}
}
FPGACLK_ON(); // Give the FPGA a clock whether it is configured or not.
return ret;
}
void delay(void)
{
lcntr = 0xFFFF;
for(lcntr = 0xFFFF; lcntr; lcntr--);
}
void UserInit( void )
{
// Initialize the I/O pins.
// Enable high slew-rate for the I/O pins.
SLRCON = 0;
// Initialize SPI Pins
spi_init();
// Initialize the FPGA configuration pins.
INIT_DONE();
INIT_PROGB();
// Initialize the clock to the FPGA.
INIT_FPGACLK();
// Initialize the status LED.
INIT_LED();
INIT_KEY();
InitBlinker(); // Initialize LED status blinker.
// Initialize interrupts.
RCONbits.IPEN = 1; // Enable prioritized interrupts.
INTERRUPTS_ON(); // Enable high and low-priority interrupts.
Reset_FPGA(1);
last_key = 1;
fpga_app = 0;
}
// This function is called when the device becomes initialized, which occurs after the host sends a
// SET_CONFIGURATION (wValue not = 0) request. This callback function should initialize the endpoints
// for the device's usage according to the current configuration.
void USBCBInitEP( void )
{
// Enable the endpoint.
USBEnableEndpoint( USBGEN_EP_NUM, USB_OUT_ENABLED | USB_IN_ENABLED | USB_HANDSHAKE_ENABLED | USB_DISALLOW_SETUP );
// Now begin waiting for the first packets to be received from the host via this endpoint.
OutIndex = 0;
OutHandle[0] = USBGenRead( USBGEN_EP_NUM, (BYTE *)&OutBuffer[0], USBGEN_EP_SIZE );
OutHandle[1] = USBGenRead( USBGEN_EP_NUM, (BYTE *)&OutBuffer[1], USBGEN_EP_SIZE );
// Initialize the pointer to the buffer which will return data to the host via this endpoint.
InIndex = 0;
InPacket = &InBuffer[0];
}
void ProcessIO( void )
{
if ( ( USBGetDeviceState() < CONFIGURED_STATE ) || USBIsDeviceSuspended() )
return;
ServiceRequests();
}
void ServiceRequests( void )
{
BYTE num_return_bytes; // Number of bytes to return in response to received command.
BYTE cmd; // Store the command in the received packet.
BYTE i;
// Process packets received through the primary endpoint.
if ( !USBHandleBusy( OutHandle[OutIndex] ) )
{
num_return_bytes = 0; // Initially, assume nothing needs to be returned.
// Got a packet, so start getting another packet while we process this one.
OutPacket = &OutBuffer[OutIndex]; // Store pointer to just-received packet.
OutPacketLength = USBHandleGetLength( OutHandle[OutIndex] ); // Store length of received packet.
cmd = OutPacket->cmd;
blink_counter = NUM_ACTIVITY_BLINKS; // Blink the LED whenever a USB transaction occurs.
switch ( cmd ) // Process the contents of the packet based on the command byte.
{
case READ_VERSION_CMD:
InPacket->cmd = cmd;
//InPacket->UNUSE = 0;
InPacket->ver_Byte0 = (MAJOR_VERSION << 4) | MINOR_VERSION;
InPacket->ver_Byte1 = USER_APP_FLAG;
num_return_bytes = 4;
break;
case SPI_CTRL_CMD:
//(BYTE data)
InPacket->cmd = cmd;
InPacket->len = OutPacket->len;
for(i=0; i<OutPacket->len; i++) {
InPacket->SPI[i] = spi_play_one_byte(OutPacket->SPI[i]);
}
num_return_bytes = OutPacket->len + 2;
break;
case SPI_FLASH_WR:
//Write enable
spi_play_one_byte(0xC1);
spi_play_one_byte(0x06);
//Send data
for(i=0; i<OutPacket->len; i++) {
spi_play_one_byte(OutPacket->SPI[i]);
}
//Wait
cmd = 0;
i = 50;
while(i--) {
spi_play_one_byte(0xC2);
spi_play_one_byte(0x05);
if(!(spi_play_one_byte(0xff) & 1)) {
cmd = 1;
break;
}
}
InPacket->cmd = cmd;
num_return_bytes = 1;
break;
case RESET_FPGA:
InPacket->cmd = Reset_FPGA(0);;
num_return_bytes = 1;
break;
case RESET_CMD:
// When resetting, make sure to drop the device off the bus
// for a period of time. Helps when the device is suspended.
UCONbits.USBEN = 0;
delay();
Reset();
break;
default:
num_return_bytes = 0;
break;
} /* switch */
// This command packet has been handled, so get another.
OutHandle[OutIndex] = USBGenRead( USBGEN_EP_NUM, (BYTE *)&OutBuffer[OutIndex], USBGEN_EP_SIZE );
OutIndex ^= 1; // Point to next ping-pong buffer.
// Packets of data are returned to the PC here.
// The counter indicates the number of data bytes in the outgoing packet.
if ( num_return_bytes != 0U )
{
InHandle[InIndex] = USBGenWrite( USBGEN_EP_NUM, (BYTE *)InPacket, num_return_bytes ); // Now send the packet.
InIndex ^= 1;
while ( USBHandleBusy( InHandle[InIndex] ) )
{
; // Wait until transmitter is not busy.
}
InPacket = &InBuffer[InIndex];
}
} else {
if((KEY == 0) && (last_key == 1)) {
if(fpga_app == 0) {
fpga_app = 1;
Reset_FPGA(0);
delay();
//Set Multi-Boot Address : APP1
spi_play_one_byte(0x41);
spi_play_one_byte(0x03);
spi_play_one_byte(0x04);
spi_play_one_byte(0x50);
spi_play_one_byte(0x00);
delay();
//Reconfig FPGA
spi_play_one_byte(0x40);
} else {
fpga_app = 0;
Reset_FPGA(1);
}
}
last_key = KEY;
}
} /* ServiceRequests */
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。