Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 254 → Rev 255

/PIC Stuff/Cerebot_32MX7_LED_Cube/CUBE.c
3,6 → 3,7
#include "SPI1.h"
#include "glcdfont.h"
#include "UART1.h"
#include "ETHERNET.h"
 
static CUBE_DATA *cube_data_ptr;
 
843,4 → 844,34
 
void Cube_Data_Direct_Write_All(uint8_t *buffer) {
memcpy(cube_data_ptr->GCS, buffer, CUBE_LAYER_COUNT * GCS_LAYER_SIZE);
}
 
void Cube_Ethernet_Frame_In(void) {
uint8_t i,j,k;
uint8_t buffer[2048];
uint16_t length;
uint16_t index = 1;
 
// Read and process the ethernet packet
if (ETH_Read_Packet(buffer, &length)) {
// Check the first byte to determine what to do
if (buffer[0] == 0x1) {
Reset_Board(BOARD_MODE_ETHERNET);
}
if (buffer[0] == 0x2) {
Reset_Board(BOARD_MODE_IDLE);
}
if (buffer[0] == 0xA) {
ClearWDT();
// Update the cube
for (i = 0; i < CUBE_LAYER_COUNT; i++) {
for (j = 0; j < CUBE_COLUMN_COUNT; j++) {
for (k = 0; k < CUBE_ROW_COUNT; k++) {
Cube_Set_Pixel(i, k, j, buffer[index], buffer[index+1], buffer[index+2]);
index += 3;
}
}
}
}
}
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/CUBE.h
122,6 → 122,7
void Cube_Data_In(uint8_t c);
void Cube_Data_In_Process_Frame(void);
void Cube_Data_Direct_Write_All(uint8_t *buffer);
void Cube_Ethernet_Frame_In(void);
 
#endif /* CUBE_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/ETHERNET.c
0,0 → 1,348
#include "defines.h"
#include "ETHERNET.h"
 
static ETH_DATA *eth_data;
 
/* Function to convert from virtual address to physical address
See 3.4.1 in reference manual for explanation */
uint32_t VA_TO_PA(uint32_t ptr) {
uint32_t ret = ptr & 0x1FFFFFFF;
return ret;
}
 
void ETH_Init(ETH_DATA *data, void(*tx_callback)(void), void(*rx_callback)(void)) {
// Save a pointer to the descriptor tables
eth_data = data;
eth_data->tx_callback = tx_callback;
eth_data->rx_callback = rx_callback;
 
// Bring the PHY reset line high to initialize the PHY
PHY_RESET_TRIS = 0;
PHY_RESET_LAT = 0;
Delay_US(100);
PHY_RESET_LAT = 1;
 
INTDisableInterrupts();
 
// Initialize the I/O lines (dont actually need this)
ETH_MDC_TRIS = 0;
ETH_MDIO_TRIS = 1;
ETH_TXEN_TRIS = 0;
ETH_TXD0_TRIS = 0;
ETH_TXD1_TRIS = 0;
ETH_RXCLK_TRIS = 1;
ETH_RXDV_TRIS = 1;
ETH_RXD0_TRIS = 1;
ETH_RXD1_TRIS = 1;
ETH_RXERR_TRIS = 1;
 
eth_data->TX_descriptor_index = 0;
eth_data->RX_descriptor_index = 0;
 
// Initialize values in the descriptor tables
uint8_t i;
for (i = 0; i < ETH_TX_DESCRIPTOR_COUNT; i++) {
// Set the NPV values for each descriptor (linear list)
eth_data->TX_ED_table.descriptor[i].NPV = 0;
// Set the EOWN values for each descriptor
eth_data->TX_ED_table.descriptor[i].EOWN = 0;
 
// Assign a data buffer to each descriptor
eth_data->TX_ED_table.descriptor[i].BUFFER_ADDR = VA_TO_PA((uint32_t)eth_data->TX_ED_buffer[i]);
}
for (i = 0; i < ETH_RX_DESCRIPTOR_COUNT; i++) {
// Set the NPV values for each descriptor (linear list)
eth_data->RX_ED_table.descriptor[i].NPV = 0;
 
// Set the EOWN values for each descriptor
eth_data->RX_ED_table.descriptor[i].EOWN = 1;
 
// Assign a data buffer to each descriptor
eth_data->RX_ED_table.descriptor[i].BUFFER_ADDR = VA_TO_PA((uint32_t)eth_data->RX_ED_buffer[i]);
}
 
// On the last descriptor, save the address to the beginning of the list
eth_data->TX_ED_table.descriptor[ETH_TX_DESCRIPTOR_COUNT-1].NPV = 1;
eth_data->RX_ED_table.descriptor[ETH_RX_DESCRIPTOR_COUNT-1].NPV = 1;
 
// Set the last RX descriptor EOWN to software, thus using list configuration
// eth_data->TX_ED_table.descriptor[ETH_TX_DESCRIPTOR_COUNT-1].EOWN = 0;
// eth_data->RX_ED_table.descriptor[ETH_RX_DESCRIPTOR_COUNT-1].EOWN = 0;
 
// Loop the end of the descriptor table to the beginning (ring configuration)
eth_data->TX_ED_table.next_ED = VA_TO_PA((uint32_t)eth_data->TX_ED_table.descriptor);
eth_data->RX_ED_table.next_ED = VA_TO_PA((uint32_t)eth_data->RX_ED_table.descriptor);
 
// Save the head of the table to the corresponding ETH register
ETHTXST = VA_TO_PA((uint32_t)eth_data->TX_ED_table.descriptor);
ETHRXST = VA_TO_PA((uint32_t)eth_data->RX_ED_table.descriptor);
 
// Ethernet Initialization Sequence: see section 35.4.10 in the PIC32 Family Reference Manual
// Part 1. Ethernet Controller Initialization
IEC1bits.ETHIE = 0; // Disable ethernet interrupts
ETHCON1bits.ON = 0; // Disable the ethernet module
ETHCON1bits.TXRTS = 0; // Stop transmit logic
ETHCON1bits.RXEN = 0; // Stop receive logic
ETHCON1bits.AUTOFC = 0;
ETHCON1bits.MANFC = 0;
while (ETHSTATbits.ETHBUSY);
IFS1bits.ETHIF = 0; // Clear interrupt flags
ETHIENCLR = 0xFFFF; // Clear the ETHIEN register (interrupt enable)
 
// Part 2. MAC Init
EMAC1CFG1bits.SOFTRESET = 1; // Put the MACMII in reset
EMAC1CFG1bits.SOFTRESET = 0;
// Default I/O configuration, RMII operating mode
EMAC1SUPPbits.RESETRMII = 1; // Reset the MAC RMII module
EMAC1MCFGbits.RESETMGMT = 1; // Reset the MII management module
EMAC1MCFGbits.RESETMGMT = 0;
EMAC1MCFGbits.CLKSEL = 0x8; // Set the MIIM PHY clock to SYSCLK/40
while(EMAC1MINDbits.MIIMBUSY);
 
// Part 3. PHY Init
// Contrary to the ref manual, the ETH module needs to be enabled for the MIIM to work
 
ETHCON1bits.ON = 1; // Enable the ethernet module
uint16_t value;
// Reset the PHY chip
ETH_PHY_Write(PHY_ADDRESS, 0x0, 0x8000);
do {
value = ETH_PHY_Read(PHY_ADDRESS, 0x0);
} while (value & 0x8000 != 0);
 
// Delay to wait for the link to be established
Delay_MS(5000);
// Wait for auto-negotiation to finish
do {
value = ETH_PHY_Read(PHY_ADDRESS, 0x1F); // Acquire link status
} while (value & 0x1000 == 0);
 
ETHCON1bits.ON = 0; // Disable the ethernet module before changing other settings
// Part 4. MAC Configuration
EMAC1CFG1bits.RXENABLE = 1; // Enable the MAC receiving of frames
EMAC1CFG1bits.TXPAUSE = 1; // Enable PAUSE flow control frames
EMAC1CFG1bits.RXPAUSE = 1; // Enable processing of PAUSE control frames
EMAC1CFG2bits.AUTOPAD = 0; // No auto-detection for VLAN padding
EMAC1CFG2bits.VLANPAD = 0; // MAC does not perform padding of short frames
EMAC1CFG2bits.PADENABLE = 1; // Pad all short frames
EMAC1CFG2bits.CRCENABLE = 1; // Append a CRC to every frame
EMAC1CFG2bits.HUGEFRM = 1; // Allow frames of any length
EMAC1CFG2bits.LENGTHCK = 0; // Check the frame lengths to the length/type field
if ((value & 0x14) || (value & 0x18)) {
EMAC1CFG2bits.FULLDPLX = 1; // Operate in full-duplex mode
EMAC1IPGT = 0x15; // Back-to-back interpacket gap @ 0.96us/9.6us
// LED1_LAT = 1;
} else {
EMAC1CFG2bits.FULLDPLX = 0; // Operate in half-duplex mode
EMAC1IPGT = 0x12; // Back-to-back interpacket gap @ 0.96us/9.6us
// LED2_LAT = 1;
}
if ((value & 0x08) || (value & 0x18)) {
EMAC1SUPPbits.SPEEDRMII = 1; // 100Mbps mode
// LED3_LAT = 1;
} else {
EMAC1SUPPbits.SPEEDRMII = 0; // 10Mbps mode
// LED4_LAT = 1;
}
EMAC1IPGRbits.NB2BIPKTGP1 = 0xC; // Set some other delay gap values
EMAC1IPGRbits.NB2BIPKTGP2 = 0x12;
EMAC1CLRTbits.CWINDOW = 0x37; // Set collision window to count of frame bytes
EMAC1CLRTbits.RETX = 0xF; // Set number of retransmission attempts
EMAC1MAXF = 0x7F4; // Set the maximum frame length to 2046 bits
// Default MAC address is 00-04-A3-1A-4C-FC
// Set MAC address to 00-18-3E-00-D7-EB
EMAC1SA0 = 0xEBD7;
EMAC1SA1 = 0x003E;
EMAC1SA2 = 0x1800;
 
// Part 5. Ethernet Controller Initialization cont.
// Flow control is off by default!
ETHRXFCbits.HTEN = 0; // Disable hash table filtering
ETHRXFCbits.MPEN = 0; // Disable magic packet filtering
ETHRXFCbits.PMMODE = 0; // Disable pattern matching
ETHRXFCbits.CRCERREN = 0; // Disable CRC error collection filtering
ETHRXFCbits.CRCOKEN = 0; // Disable CRC filtering
ETHRXFCbits.RUNTERREN = 0; // Disable runt error collection filtering
ETHRXFCbits.RUNTEN = 0; // Disable runt filtering
ETHRXFCbits.UCEN = 1; // Enable unicast filtering
ETHRXFCbits.NOTMEEN = 0; // Disable acceptance of packets to other destinations
ETHRXFCbits.MCEN = 0; // Disable multicast filtering
ETHRXFCbits.BCEN = 0; // Disable broadcast filtering
 
ETHCON2bits.RXBUF_SZ = 0x7F; // Set RX data buffer size to 2032 bytes
 
ETHIENbits.TXBUSEIE = 1; // Enable interrupt on transmit BVCI bus error
ETHIENbits.RXBUSEIE = 1; // Enable interrupt on receive BVCI bus error
// ETHIENbits.RXDONEIE = 1; // Enable interrupt on packet received
ETHIENbits.PKTPENDIE = 1; // Enable interrupt on packet pending
// ETHIENbits.RXACTIE = 1;
ETHIENbits.TXDONEIE = 1; // Enable interrupt on packet sent
ETHIENbits.TXABORTIE = 1; // Enable interrupt on packet send aborted
 
IPC12bits.ETHIP = 2; // Set interrupt priority to 2
IPC12bits.ETHIS = 2; // Set intererupt sub-priority to 2
IEC1bits.ETHIE = 1; // Enable ethernet interrupts
 
EMAC1SUPPbits.RESETRMII = 0; // Bring the RMII module out of reset
ETHCON1bits.RXEN = 1; // Start receive logic
ETHCON1bits.ON = 1; // Enable the ethernet module
 
INTEnableInterrupts();
}
 
/* Reads from the specified register on the PHY chip */
uint16_t ETH_PHY_Read(uint8_t address, uint8_t reg) {
EMAC1MADR = reg | (address << 8);
EMAC1MCMDbits.READ = 1;
Nop();Nop();Nop();
while (EMAC1MINDbits.MIIMBUSY);
EMAC1MCMDbits.READ = 0;
return EMAC1MRDD;
}
 
/* Write to the specified register on the PHY chip */
void ETH_PHY_Write(uint8_t address, uint8_t reg, uint16_t value) {
EMAC1MADR = reg | (address << 8);
EMAC1MWTD = value;
Nop();Nop();Nop();
while (EMAC1MINDbits.MIIMBUSY);
}
 
/* Queries the number of pending packets */
uint8_t ETH_Recv_Queue(void) {
return ETHSTATbits.BUFCNT;
}
 
/* Function to read a single packet (<2014 bytes) */
uint8_t ETH_Read_Packet(uint8_t *buffer, uint16_t *length) {
uint16_t i, j;
uint16_t size;
uint8_t descriptor_index = eth_data->RX_descriptor_index;
 
// Look for the first descriptor where EOWN is cleared and SOP/EOP is set
for (i = 0; i < ETH_RX_DESCRIPTOR_COUNT; i++) {
if ((eth_data->RX_ED_table.descriptor[descriptor_index].EOWN == 0) &&
(eth_data->RX_ED_table.descriptor[descriptor_index].SOP == 1) &&
(eth_data->RX_ED_table.descriptor[descriptor_index].EOP == 1)) {
 
// Read the packet data values into the buffer
size = eth_data->RX_ED_table.descriptor[descriptor_index].BYTE_COUNT - 18;
*length = size;
for (j = 0; j < size - 18; j++) {
buffer[j] = eth_data->RX_ED_buffer[descriptor_index][j+14];
}
 
// Reset the descriptors
eth_data->RX_ED_table.descriptor[descriptor_index].SOP = 0;
eth_data->RX_ED_table.descriptor[descriptor_index].EOP = 0;
eth_data->RX_ED_table.descriptor[descriptor_index].EOWN = 1;
 
eth_data->RX_descriptor_index = (descriptor_index == ETH_RX_DESCRIPTOR_COUNT - 1) ? 0 : descriptor_index + 1;
 
ETHCON1bits.BUFCDEC = 1;
return 0;
 
} else {
descriptor_index = (descriptor_index == ETH_RX_DESCRIPTOR_COUNT - 1) ? 0 : descriptor_index + 1;
}
}
 
return 1;
}
 
/* Function to send a single packet (<2018 bytes) */
uint8_t ETH_Write_Packet(ETH_MAC_ADDRESS dest, ETH_MAC_ADDRESS src, uint16_t length, uint8_t *buffer) {
uint16_t i;
uint16_t write_index = 0;
uint16_t read_index = 0;
uint16_t descriptor_index = eth_data->TX_descriptor_index;
 
// Do a quick sanity check to ensure that we have enough memory to send the message
if (length > ETH_TX_ED_BUFFER_SIZE - 14)
return 1;
 
// Fill the descriptor
eth_data->TX_ED_table.descriptor[descriptor_index].TSV.registers[0] = 0;
eth_data->TX_ED_table.descriptor[descriptor_index].TSV.registers[1] = 0;
eth_data->TX_ED_table.descriptor[descriptor_index].EOWN = 1;
eth_data->TX_ED_table.descriptor[descriptor_index].SOP = 1;
eth_data->TX_ED_table.descriptor[descriptor_index].EOP = 1;
 
for (i = 0; i < 6; i++) {
eth_data->TX_ED_buffer[descriptor_index][write_index] = dest.bytes[i];
write_index++;
}
for (i = 0; i < 6; i++) {
eth_data->TX_ED_buffer[descriptor_index][write_index] = src.bytes[i];
write_index++;
}
eth_data->TX_ED_buffer[descriptor_index][write_index] = length >> 8;
eth_data->TX_ED_buffer[descriptor_index][write_index+1] = length;
write_index += 2;
 
 
eth_data->TX_ED_table.descriptor[descriptor_index].BYTE_COUNT = length + 14;
 
for (i = 0; i < length; i++) {
eth_data->TX_ED_buffer[descriptor_index][write_index] = buffer[read_index];
write_index++;
read_index++;
}
 
// Wait for any previous transmits to finish before sending
while (ETHSTATbits.TXBUSY);
ETHCON1bits.TXRTS = 1;
while (ETHSTATbits.TXBUSY);
 
eth_data->TX_descriptor_index = (descriptor_index == ETH_TX_DESCRIPTOR_COUNT - 1) ? 0 : descriptor_index + 1;
return 0;
}
 
void __ISR(_ETH_VECTOR, ipl1) __ETH_Interrupt_Handler(void) {
uint32_t value = ETHIRQ;
if (ETHIRQbits.TXBUSE) {
 
ETHIRQbits.TXBUSE = 0;
}
if (ETHIRQbits.RXBUSE) {
 
ETHIRQbits.RXBUSE = 0;
}
// if (ETHIRQbits.RXDONE) {
// ETHIRQbits.RXDONE = 0;
// }
if (ETHIRQbits.PKTPEND) {
if (eth_data->rx_callback != NULL)
(*eth_data->rx_callback)();
ETHIRQbits.PKTPEND = 0;
}
if (ETHIRQbits.TXDONE) {
if (eth_data->tx_callback != NULL)
(*eth_data->tx_callback)();
ETHIRQbits.TXDONE = 0;
}
if (ETHIRQbits.TXABORT) {
 
ETHIRQbits.TXABORT = 0;
}
if (ETHIRQbits.RXBUFNA) {
// This is a serious error!
 
ETHIRQbits.RXBUFNA = 0;
}
if (ETHIRQbits.RXOVFLW) {
// This is a serious error!
 
ETHIRQbits.RXOVFLW = 0;
}
 
IFS1bits.ETHIF = 0;
}
/PIC Stuff/Cerebot_32MX7_LED_Cube/ETHERNET.h
0,0 → 1,162
#ifndef ETHERNET_H
#define ETHERNET_H
 
#define ETH_TX_DESCRIPTOR_COUNT 2
#define ETH_RX_DESCRIPTOR_COUNT 2
#define ETH_TX_ED_BUFFER_SIZE 2032
#define ETH_RX_ED_BUFFER_SIZE 2032
 
#ifdef CEREBOT_MX7CK
#define PHY_RESET_TRIS TRISAbits.TRISA6
#define PHY_RESET_LAT LATAbits.LATA6
#endif
#ifdef CEREBOT_32MX7
#define PHY_RESET_TRIS TRISEbits.TRISE9
#define PHY_RESET_LAT LATEbits.LATE9
#endif
#define ETH_MDC_TRIS TRISDbits.TRISD11
#define ETH_MDIO_TRIS TRISDbits.TRISD8
#define ETH_TXEN_TRIS TRISDbits.TRISD6
#define ETH_TXD0_TRIS TRISFbits.TRISF1
#define ETH_TXD1_TRIS TRISFbits.TRISF0
#define ETH_RXCLK_TRIS TRISGbits.TRISG9
#define ETH_RXDV_TRIS TRISGbits.TRISG8
#define ETH_RXD0_TRIS TRISBbits.TRISB12
#define ETH_RXD1_TRIS TRISBbits.TRISB13
#define ETH_RXERR_TRIS TRISBbits.TRISB11
 
#define PHY_ADDRESS 0x0
 
typedef union {
struct {
uint8_t BYTE_0;
uint8_t BYTE_1;
uint8_t BYTE_2;
uint8_t BYTE_3;
uint8_t BYTE_4;
uint8_t BYTE_5;
};
uint8_t bytes[6];
} ETH_MAC_ADDRESS;
 
typedef union {
struct {
// Bits 31:0
unsigned BYTE_COUNT : 16; // Total bytes in frame not counting collided bytes
unsigned COLLISION_COUNT : 4; // Number of collisions current packet incurred durrent transmit attempts
unsigned CRC_ERROR : 1; // Attached CRC did not match the internal generated CRC
unsigned LENGTH_CHECK_ERROR : 1; // Frame length field value in packet does not match actual data byte length and is not a Type field
unsigned LENGTH_OUT_OF_RANGE : 1; // Frame type/length field was larger than 1500 bytes
unsigned DONE : 1; // Transmit of packet was completed
unsigned MULTICASE : 1; // Destination address was a multicast address
unsigned BROADCAST : 1; // Destination address was a broadcast address
unsigned PACKET_DEFER : 1; // Packet was deferred for at least one attempt
unsigned EXCESSIVE_DEFER : 1; // Packet was defered in excess of 6071/24287 nibble(100Mbps)/bit(10Mbps) times
unsigned MAXIMUM_COLLISION : 1; // Packet aborted, number of collisions exceeded RETX
unsigned LATE_COLLISION : 1; // Collision occurred beyond the collision window (512 bit times)
unsigned GIANT : 1; // Frame byte count greater than MACMAXF
unsigned UNDERRUN : 1; // Failed to transfer complete packet to the transmit MAC module
// Bits 63:32
unsigned BYTES_TRANSMITTED : 16; // Total bytes transmitted on wire (including collisions)
unsigned CONTROL_FRAME : 1; // Frame transmitted was a control frame
unsigned PAUSE_CONTROL_FRAME : 1; // Frame transmitted was a control frame with a valid PAUSE Op code
unsigned BACKPRESSURE : 1; // Carrier-sense method backpressure was previously applied
unsigned VLAN_TAGGED : 1; // Frame length/type field contained 0x8100 (VLAN protocol identifier)
unsigned : 12;
};
uint32_t registers[2];
} ETH_TRANSMIT_STATUS_VECTOR;
 
typedef union {
struct {
// Bits 31:0
unsigned BYTE_COUNT : 16; // Length of received frame
unsigned LONG_DROP_EVENT : 1; // Packet over 50000 bit times occured or packet since last RSV was dropped
unsigned RXDV_EVENT : 1; // Last receive event seen not long enough to be a valid packet
unsigned CARRIER_EVENT : 1; // Carrier event detected, noted, and reported
unsigned CODE_VIOLATION : 1; // MII data does not represent a valid data code when MRXER asserted
unsigned CRC_ERROR : 1; // Frame CRC does not match the CRC calculated by the receiver MAC
unsigned LENGTH_CHECK_ERROR : 1; // Frame length field value doe snot match the actual data byte length
unsigned LENGTH_OUT_OF_RANGE : 1; // Frame type/length field was larger than 1500 bytes
unsigned RECEIVE_OK : 1; // Packet has a valid CRC and no symbol errors
unsigned MULTICAST : 1; // Packet had a valid multicast address
unsigned BROADCAST : 1; // Packet had a valid broadcast address
unsigned DRIBBLE_NIBBLE : 1; // An additional 1-7 bits received after packet
unsigned CONTROL_FRAME : 1; // Frame recognized as a control frame
unsigned PAUSE_CONTROL_FRAME : 1; // Frame recognized as a control frame with a valid PAUSE Op code
unsigned UNKNOWN_OP_CODE : 1; // Frame recognized as a control frame but with an unknown Op code
unsigned VLAN_TAGGED : 1; // Frame recognized as a VLAN tagged frame
unsigned : 1;
// Bits 63:32;
unsigned PKT_CHECKSUM : 16; // RX packet payload checksum of this descriptor's packet
unsigned : 8;
unsigned RUNT_PACKET : 1; // Runt packet
unsigned BROADCAST_OR_NOT_DEST : 1; // NOT unicast match AND NOT multicast match
unsigned HASH_TABLE_MATCH : 1; // Hash table match
unsigned MAGIC_PACKET_MATCH : 1; // Magic packet match
unsigned PATTERN_MATCH : 1; // Pattern match
unsigned UNICAST_MATCH : 1; // Unicast match
unsigned BROADCAST_MATCH : 1; // Broadcast match
unsigned MULTICAST_MATCH : 1; // Multicast match
};
uint32_t registers[2];
} ETH_RECEIVE_STATUS_VECTOR;
 
typedef struct {
unsigned : 7;
unsigned EOWN : 1; // Ethernet controller own bit (1 = ED owned by controller, do not modify)
unsigned NPV : 1; // Next ED pointer valid enable bit (1 = NEXT_ED field exists)
unsigned : 7;
unsigned BYTE_COUNT : 11; // Number of bytes to be transmited for this descriptor (1-2047)
unsigned : 3;
unsigned EOP : 1; // End of packet enable bit (1 = transmit end of packet delimiter)
unsigned SOP : 1; // Start of packet enable bit (1 = transmit start of packet delimiter)
uint32_t BUFFER_ADDR; // Starting point address of the data buffer
ETH_TRANSMIT_STATUS_VECTOR TSV; // Transmit status vector bits
} ETH_TX_ETHERNET_DESCRIPTOR;
 
typedef struct {
unsigned : 7;
unsigned EOWN : 1; // Ethernet controller own bit (1 = ED owned by controller, do not modify)
unsigned NPV : 1; // Next ED pointer valid enable bit (1 = NEXT_ED field exists)
unsigned : 7;
unsigned BYTE_COUNT : 11; // Number of bytes to be transmited for this descriptor (1-2047)
unsigned : 3;
unsigned EOP : 1; // End of packet enable bit (1 = transmit end of packet delimiter)
unsigned SOP : 1; // Start of packet enable bit (1 = transmit start of packet delimiter)
uint32_t BUFFER_ADDR; // Starting point address of the data buffer
ETH_RECEIVE_STATUS_VECTOR RSV; // Transmit status vector bits
} ETH_RX_ETHERNET_DESCRIPTOR;
 
typedef struct {
ETH_TX_ETHERNET_DESCRIPTOR descriptor[ETH_TX_DESCRIPTOR_COUNT];
uint32_t next_ED;
} ETH_TX_DESCRIPTOR_TABLE;
 
typedef struct {
ETH_RX_ETHERNET_DESCRIPTOR descriptor[ETH_RX_DESCRIPTOR_COUNT];
uint32_t next_ED;
} ETH_RX_DESCRIPTOR_TABLE;
 
typedef struct {
ETH_TX_DESCRIPTOR_TABLE TX_ED_table;
ETH_RX_DESCRIPTOR_TABLE RX_ED_table;
uint8_t TX_ED_buffer[ETH_TX_DESCRIPTOR_COUNT][ETH_TX_ED_BUFFER_SIZE];
uint8_t RX_ED_buffer[ETH_RX_DESCRIPTOR_COUNT][ETH_RX_ED_BUFFER_SIZE];
uint8_t TX_descriptor_index;
uint8_t RX_descriptor_index;
void (*tx_callback)(void);
void (*rx_callback)(void);
} ETH_DATA;
 
void ETH_Init(ETH_DATA *data, void(*tx_callback)(void), void(*rx_callback)(void));
 
uint16_t ETH_PHY_Read(uint8_t address, uint8_t reg);
void ETH_PHY_Write(uint8_t address, uint8_t reg, uint16_t value);
 
uint8_t ETH_Recv_Queue(void);
uint8_t ETH_Read_Packet(uint8_t *buffer, uint16_t *length);
uint8_t ETH_Write_Packet(ETH_MAC_ADDRESS dest, ETH_MAC_ADDRESS src, uint16_t length, uint8_t *buffer);
 
#endif /* ETHERNET_H */
 
/PIC Stuff/Cerebot_32MX7_LED_Cube/README.txt
13,6 → 13,7
TIMER5 - Used by the cube code for the update layer interrupt
UART1 - Used by the cube code for reading in frame data
PWM2 - Generates a constant ~20MHz output, uses TIMER2
ETHERNET - Used to remote-update the cube
 
PERIPHERAL INTERRUPT PRIORITY LEVELS:
IPL1 = lowest, IPL7 = highest priority
22,6 → 23,7
TIMER5 - Priority 3, Subpriority 1
TIMER4 - Priority 1, Subpriority 1
UART1 - Priority 2, Subpriority 1
ETHERNET - Priority 2, Subpriority 2
 
 
PIN I/Os:
/PIC Stuff/Cerebot_32MX7_LED_Cube/TRON.c
34,6 → 34,7
void Tron_Main(void) {
// Main function, loops and delays while updating the frame every x milliseconds
Tron_Update_Direction(0x04,0x04);
Controller_Set_Leds(0x01,0x01);
Delay_MS(2000);
while (1) {
Tron_Update_Frame();
/PIC Stuff/Cerebot_32MX7_LED_Cube/defines.h
8,8 → 8,8
#include <stdint.h>
 
// Uncomment ONE of the following:
//#define CEREBOT_32MX7
#define CEREBOT_MX7CK
#define CEREBOT_32MX7
// #define CEREBOT_MX7CK
 
// Power supply must be 5V for proper operation of the board!
 
42,9 → 42,10
#define RESET_CFG 0x06 // Config mismatch reset
 
// Board 'modes' (idle/games/etc)
#define BOARD_MODE_IDLE 0x01
#define BOARD_MODE_SNAKE 0x02
#define BOARD_MODE_TRON 0x03
#define BOARD_MODE_IDLE 0x01
#define BOARD_MODE_SNAKE 0x02
#define BOARD_MODE_TRON 0x03
#define BOARD_MODE_ETHERNET 0x04
 
typedef struct {
uint8_t cube_mode;
/PIC Stuff/Cerebot_32MX7_LED_Cube/main.c
40,6 → 40,7
#include "SPI1.h"
#include "SPI4.h"
#include "I2C1.h"
#include "ETHERNET.h"
#include "TIMER4.h"
#include "TIMER5.h"
#include "CUBE.h"
142,6 → 143,10
LED3_LAT = 0;
LED4_LAT = 0;
 
// Initialize the Ethernet module
ETH_DATA eth_data;
ETH_Init(&eth_data, NULL, &Cube_Ethernet_Frame_In);
 
// Initialize the SPI1 module
SPI1_DATA spi_1_data;
SPI1_Init(&spi_1_data, NULL);
212,6 → 217,9
Tron_Init(&tron_data);
Tron_Main();
break;
case BOARD_MODE_ETHERNET:
while(1);
break;
case BOARD_MODE_IDLE:
default:
Idle_Animation_Sequence();
245,7 → 253,7
// UART1_Write(start_text, 18);
 
// Set the overlay text
uint8_t text_string[] = "Welcome to the AMP Lab ";
uint8_t text_string[] = "Welcome to the CCM Lab ";
Cube_Text_Init(text_string, 27, 0xFF, 0xFF, 0xFF);
 
// Loop through some preset animations
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-default.mk
45,17 → 45,17
DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE}
 
# Source Files Quoted if spaced
SOURCEFILES_QUOTED_IF_SPACED=main.c SPI1.c TIMER5.c CUBE.c PWM2.c BTN.c TIMER4.c UART1.c SPI4.c ANIMATIONS.c I2C1.c CONTROLLERS.c SNAKE.c TRON.c
SOURCEFILES_QUOTED_IF_SPACED=main.c SPI1.c TIMER5.c CUBE.c PWM2.c BTN.c TIMER4.c UART1.c SPI4.c ANIMATIONS.c I2C1.c CONTROLLERS.c SNAKE.c TRON.c ETHERNET.c
 
# Object Files Quoted if spaced
OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/main.o ${OBJECTDIR}/SPI1.o ${OBJECTDIR}/TIMER5.o ${OBJECTDIR}/CUBE.o ${OBJECTDIR}/PWM2.o ${OBJECTDIR}/BTN.o ${OBJECTDIR}/TIMER4.o ${OBJECTDIR}/UART1.o ${OBJECTDIR}/SPI4.o ${OBJECTDIR}/ANIMATIONS.o ${OBJECTDIR}/I2C1.o ${OBJECTDIR}/CONTROLLERS.o ${OBJECTDIR}/SNAKE.o ${OBJECTDIR}/TRON.o
POSSIBLE_DEPFILES=${OBJECTDIR}/main.o.d ${OBJECTDIR}/SPI1.o.d ${OBJECTDIR}/TIMER5.o.d ${OBJECTDIR}/CUBE.o.d ${OBJECTDIR}/PWM2.o.d ${OBJECTDIR}/BTN.o.d ${OBJECTDIR}/TIMER4.o.d ${OBJECTDIR}/UART1.o.d ${OBJECTDIR}/SPI4.o.d ${OBJECTDIR}/ANIMATIONS.o.d ${OBJECTDIR}/I2C1.o.d ${OBJECTDIR}/CONTROLLERS.o.d ${OBJECTDIR}/SNAKE.o.d ${OBJECTDIR}/TRON.o.d
OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/main.o ${OBJECTDIR}/SPI1.o ${OBJECTDIR}/TIMER5.o ${OBJECTDIR}/CUBE.o ${OBJECTDIR}/PWM2.o ${OBJECTDIR}/BTN.o ${OBJECTDIR}/TIMER4.o ${OBJECTDIR}/UART1.o ${OBJECTDIR}/SPI4.o ${OBJECTDIR}/ANIMATIONS.o ${OBJECTDIR}/I2C1.o ${OBJECTDIR}/CONTROLLERS.o ${OBJECTDIR}/SNAKE.o ${OBJECTDIR}/TRON.o ${OBJECTDIR}/ETHERNET.o
POSSIBLE_DEPFILES=${OBJECTDIR}/main.o.d ${OBJECTDIR}/SPI1.o.d ${OBJECTDIR}/TIMER5.o.d ${OBJECTDIR}/CUBE.o.d ${OBJECTDIR}/PWM2.o.d ${OBJECTDIR}/BTN.o.d ${OBJECTDIR}/TIMER4.o.d ${OBJECTDIR}/UART1.o.d ${OBJECTDIR}/SPI4.o.d ${OBJECTDIR}/ANIMATIONS.o.d ${OBJECTDIR}/I2C1.o.d ${OBJECTDIR}/CONTROLLERS.o.d ${OBJECTDIR}/SNAKE.o.d ${OBJECTDIR}/TRON.o.d ${OBJECTDIR}/ETHERNET.o.d
 
# Object Files
OBJECTFILES=${OBJECTDIR}/main.o ${OBJECTDIR}/SPI1.o ${OBJECTDIR}/TIMER5.o ${OBJECTDIR}/CUBE.o ${OBJECTDIR}/PWM2.o ${OBJECTDIR}/BTN.o ${OBJECTDIR}/TIMER4.o ${OBJECTDIR}/UART1.o ${OBJECTDIR}/SPI4.o ${OBJECTDIR}/ANIMATIONS.o ${OBJECTDIR}/I2C1.o ${OBJECTDIR}/CONTROLLERS.o ${OBJECTDIR}/SNAKE.o ${OBJECTDIR}/TRON.o
OBJECTFILES=${OBJECTDIR}/main.o ${OBJECTDIR}/SPI1.o ${OBJECTDIR}/TIMER5.o ${OBJECTDIR}/CUBE.o ${OBJECTDIR}/PWM2.o ${OBJECTDIR}/BTN.o ${OBJECTDIR}/TIMER4.o ${OBJECTDIR}/UART1.o ${OBJECTDIR}/SPI4.o ${OBJECTDIR}/ANIMATIONS.o ${OBJECTDIR}/I2C1.o ${OBJECTDIR}/CONTROLLERS.o ${OBJECTDIR}/SNAKE.o ${OBJECTDIR}/TRON.o ${OBJECTDIR}/ETHERNET.o
 
# Source Files
SOURCEFILES=main.c SPI1.c TIMER5.c CUBE.c PWM2.c BTN.c TIMER4.c UART1.c SPI4.c ANIMATIONS.c I2C1.c CONTROLLERS.c SNAKE.c TRON.c
SOURCEFILES=main.c SPI1.c TIMER5.c CUBE.c PWM2.c BTN.c TIMER4.c UART1.c SPI4.c ANIMATIONS.c I2C1.c CONTROLLERS.c SNAKE.c TRON.c ETHERNET.c
 
 
CFLAGS=
175,6 → 175,12
@${RM} ${OBJECTDIR}/TRON.o
@${FIXDEPS} "${OBJECTDIR}/TRON.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TRON.o.d" -o ${OBJECTDIR}/TRON.o TRON.c
${OBJECTDIR}/ETHERNET.o: ETHERNET.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/ETHERNET.o.d
@${RM} ${OBJECTDIR}/ETHERNET.o
@${FIXDEPS} "${OBJECTDIR}/ETHERNET.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/ETHERNET.o.d" -o ${OBJECTDIR}/ETHERNET.o ETHERNET.c
else
${OBJECTDIR}/main.o: main.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
260,6 → 266,12
@${RM} ${OBJECTDIR}/TRON.o
@${FIXDEPS} "${OBJECTDIR}/TRON.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/TRON.o.d" -o ${OBJECTDIR}/TRON.o TRON.c
${OBJECTDIR}/ETHERNET.o: ETHERNET.c nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} ${OBJECTDIR}
@${RM} ${OBJECTDIR}/ETHERNET.o.d
@${RM} ${OBJECTDIR}/ETHERNET.o
@${FIXDEPS} "${OBJECTDIR}/ETHERNET.o.d" $(SILENT) -rsi ${MP_CC_DIR}../ -c ${MP_CC} $(MP_EXTRA_CC_PRE) -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION) -O1 -funroll-loops -MMD -MF "${OBJECTDIR}/ETHERNET.o.d" -o ${OBJECTDIR}/ETHERNET.o ETHERNET.c
endif
 
# ------------------------------------------------------------------------------------
273,7 → 285,7
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk
@${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE}
${MP_CC} $(MP_EXTRA_LD_PRE) -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__ICD2RAM=1,--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,--defsym=__MPLAB_DEBUGGER_PK3=1,--report-mem
${MP_CC} $(MP_EXTRA_LD_PRE) -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION) -o dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC02000:0x1FC02FEF -mreserve=boot@0x1FC02000:0x1FC024FF -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,--defsym=__MPLAB_DEBUGGER_PK3=1,--report-mem
else
dist/${CND_CONF}/${IMAGE_TYPE}/Cerebot_32MX7_LED_Cube.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-genesis.properties
1,8 → 1,8
#
#Thu Dec 12 23:31:57 EST 2013
default.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=a7430524a414be59f5ce2a8f8797db6d
default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc32\\v1.21\\bin
com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=0d2b1469ad71adb787c711a416386331
default.languagetoolchain.version=1.21
#Sat Jan 25 17:19:01 EST 2014
default.com-microchip-mplab-nbide-toolchainXC32-XC32LanguageToolchain.md5=83f4565fa27ad9b8015f63d69ef74f66
default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc32\\v1.31\\bin
com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=1f98a0eed69cb2a45c12981fa9470927
default.languagetoolchain.version=1.31
host.platform=windows
conf.ids=default
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/Makefile-local-default.mk
19,19 → 19,19
# Adding MPLAB X bin directory to path.
PATH:=C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/:$(PATH)
# Path to java used to run MPLAB X when this makefile was created
MP_JAVA_PATH="C:\Program Files (x86)\Microchip\MPLABX\sys\java\jre1.7.0_17/bin/"
MP_JAVA_PATH="C:\Program Files (x86)\Microchip\MPLABX\sys\java\jre1.7.0_25-windows-x64\java-windows/bin/"
OS_CURRENT="$(shell uname -s)"
MP_CC="C:\Program Files (x86)\Microchip\xc32\v1.21\bin\xc32-gcc.exe"
MP_CPPC="C:\Program Files (x86)\Microchip\xc32\v1.21\bin\xc32-g++.exe"
MP_CC="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-gcc.exe"
MP_CPPC="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-g++.exe"
# MP_BC is not defined
MP_AS="C:\Program Files (x86)\Microchip\xc32\v1.21\bin\xc32-as.exe"
MP_LD="C:\Program Files (x86)\Microchip\xc32\v1.21\bin\xc32-ld.exe"
MP_AR="C:\Program Files (x86)\Microchip\xc32\v1.21\bin\xc32-ar.exe"
MP_AS="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-as.exe"
MP_LD="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-ld.exe"
MP_AR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin\xc32-ar.exe"
DEP_GEN=${MP_JAVA_PATH}java -jar "C:/Program Files (x86)/Microchip/MPLABX/mplab_ide/mplab_ide/modules/../../bin/extractobjectdependencies.jar"
MP_CC_DIR="C:\Program Files (x86)\Microchip\xc32\v1.21\bin"
MP_CPPC_DIR="C:\Program Files (x86)\Microchip\xc32\v1.21\bin"
MP_CC_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
MP_CPPC_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
# MP_BC_DIR is not defined
MP_AS_DIR="C:\Program Files (x86)\Microchip\xc32\v1.21\bin"
MP_LD_DIR="C:\Program Files (x86)\Microchip\xc32\v1.21\bin"
MP_AR_DIR="C:\Program Files (x86)\Microchip\xc32\v1.21\bin"
MP_AS_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
MP_LD_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
MP_AR_DIR="C:\Program Files (x86)\Microchip\xc32\v1.31\bin"
# MP_BC_DIR is not defined
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/configurations.xml
19,6 → 19,7
<itemPath>CONTROLLERS.h</itemPath>
<itemPath>SNAKE.h</itemPath>
<itemPath>TRON.h</itemPath>
<itemPath>ETHERNET.h</itemPath>
</logicalFolder>
<logicalFolder name="LinkerScript"
displayName="Linker Files"
41,6 → 42,7
<itemPath>CONTROLLERS.c</itemPath>
<itemPath>SNAKE.c</itemPath>
<itemPath>TRON.c</itemPath>
<itemPath>ETHERNET.c</itemPath>
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
59,7 → 61,7
<targetPluginBoard></targetPluginBoard>
<platformTool>PK3OBPlatformTool</platformTool>
<languageToolchain>XC32</languageToolchain>
<languageToolchainVersion>1.21</languageToolchainVersion>
<languageToolchainVersion>1.31</languageToolchainVersion>
<platform>3</platform>
</toolsSet>
<compileType>
180,6 → 182,7
<property key="ToolFirmwareFilePath"
value="Press to browse for a specific firmware version"/>
<property key="ToolFirmwareOption.UseLatestFirmware" value="true"/>
<property key="firmware.download.all" value="false"/>
<property key="memories.bootflash" value="false"/>
<property key="memories.configurationmemory" value="false"/>
<property key="memories.eeprom" value="false"/>
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/private/configurations.xml
4,8 → 4,8
<defaultConf>0</defaultConf>
<confs>
<conf name="default" type="2">
<platformToolSN>:=MPLABCommUSB:=04D8:=8108:=0002:=Digilent:=CerebotMX7CK:=D459520:=x:=en</platformToolSN>
<languageToolchainDir>C:\Program Files (x86)\Microchip\xc32\v1.21\bin</languageToolchainDir>
<platformToolSN>:=MPLABCommUSB:=04D8:=8108:=0002:=Digilent:=Cerebot 32MX7:=D370400:=x:=en</platformToolSN>
<languageToolchainDir>C:\Program Files (x86)\Microchip\xc32\v1.31\bin</languageToolchainDir>
<mdbdebugger version="1">
<placeholder1>place holder 1</placeholder1>
<placeholder2>place holder 2</placeholder2>
/PIC Stuff/Cerebot_32MX7_LED_Cube/nbproject/project.xml
9,6 → 9,7
<cpp-extensions/>
<header-extensions>h</header-extensions>
<sourceEncoding>ISO-8859-1</sourceEncoding>
<asminc-extensions/>
<make-dep-projects/>
</data>
</configuration>