//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(ð_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> |