Commit 0df40144 authored by Martin Vítek's avatar Martin Vítek

Ported ENC28J60, fixes

parent a670ec55
......@@ -36,8 +36,8 @@ class Button
{
if (EIC->INTFLAG.reg & (1UL<<extint))
{
if (button.is_set()) { uart.send("Button "); uart.send_dec(extint); uart.send(" is set\n\r"); }
else { uart.send("Button "); uart.send_dec(extint); uart.send(" is not set\n\r"); }
if (button.is_set()) { }
else { }
EIC->INTFLAG.reg = (1UL<<extint);
}
......
......@@ -6,8 +6,8 @@
#include "SPI.h"
#include "SPI_select.h"
EEPROM_25AA02E48::EEPROM_25AA02E48(SPI& spi, SPI_select& cs): spi(spi),
cs(cs)
EEPROM_25AA02E48::EEPROM_25AA02E48(SPI& spi, volatile PortGroup& cs_port, const uint8_t cs_bit): spi(spi),
cs(cs_port, cs_bit)
{
}
......
......@@ -41,7 +41,7 @@ class EEPROM_25AA02E48
SPI_select cs;
public:
EEPROM_25AA02E48(SPI& spi, SPI_select& cs);
EEPROM_25AA02E48(SPI& spi, volatile PortGroup& cs_port, const uint8_t cs_bit);
//Read data from EEPROM
uint8_t read(const uint8_t address);
......
This diff is collapsed.
#pragma once
#include <cstdint>
#include <cstddef>
#include "SPI.h"
#include "GPIO.h"
#include "ENC28J60_registers.h"
#include "ENC28J60_SPI.h"
#include "ethernet_frame.h"
namespace ENC28J60_namespace
{
class ENC28J60: public ENC28J60_SPI
{
private:
uint16_t eth_rx_buffer_start;
uint16_t eth_rx_buffer_end;
uint16_t eth_tx_buffer_start;
uint16_t eth_tx_buffer_end;
uint16_t eth_rx_packet_start;
const uint8_t (&mac)[6];
ethernet_frame frame;
public:
ENC28J60(SPI &spi,
volatile PortGroup& cs_port, const uint8_t cs_bit,
volatile PortGroup& irq_port, const uint8_t irq_bit,
const uint8_t (&mac)[6]);
//Initialization
void init();
void set_eth_rx_buffer_size(uint16_t size);
//RX & TX
void tx_frame_blocking(const ethernet_frame &frame);
bool rx_frame_blocking(ethernet_frame &frame);
//For testing
void print_connection_status();
void print_device_info();
void test_RXEN_corruption();
};
}
This diff is collapsed.
#pragma once
#include <cstdint>
#include "SPI.h"
#include "SPI_select.h"
#include "GPIO.h"
#include "ENC28J60_registers.h"
//TODO: write_control_register for 16bit variables
//TODO: read_control_register for 16bit variables
//TODO: write & read buffer memory for single variable
namespace ENC28J60_namespace
{
enum instructions
{
// NAME OPTCODE ARGUMENT
READ_CONTROL_REGISTER = (0x00<<5),
READ_BUFFER_MEMORY = (0x01<<5) | 0x1A,
WRITE_CONTROL_REGISTER = (0x02<<5),
WRITE_BUFFER_MEMORY = (0x03<<5) | 0x1A,
BIT_FIELD_SET = (0x04<<5),
BIT_FIELD_CLEAR = (0x05<<5),
SYSTEM_RESET = (0x07<<5) | 0x1F
};
enum constants
{
BANK_SIZE = 0x1F
};
enum silicon_revisions
{
B1 = 0b00000010,
B4 = 0b00000100,
B5 = 0b00000101,
B7 = 0b00000110
};
class ENC28J60_SPI
{
private:
SPI& spi;
SPI_select cs;
Input irq;
uint8_t current_bank; //TODO: volatile if used in IRQ
public:
ENC28J60_SPI(SPI &spi,
volatile PortGroup& cs_port, const uint8_t cs_bit,
volatile PortGroup& irq_port, const uint8_t irq_bit);
//Read control register
uint8_t read_control_register(const uint8_t address);
uint8_t read_control_register(const common_registers address);
uint8_t read_control_register(const bank0_registers address);
uint8_t read_control_register(const bank1_registers address);
uint8_t read_control_register(const bank2_registers address);
uint8_t read_control_register(const bank3_registers address);
//Read buffer memory
void read_buffer_memory(uint8_t buffer[], const uint16_t size);
void read_buffer_memory(uint8_t &value);
void read_buffer_memory(uint16_t &value);
void read_buffer_memory(uint32_t &value);
//Write control register
void write_control_register(const uint8_t address, const uint8_t data);
void write_control_register(const common_registers address, const uint8_t data);
void write_control_register(const bank0_registers address, const uint8_t data);
void write_control_register(const bank1_registers address, const uint8_t data);
void write_control_register(const bank2_registers address, const uint8_t data);
void write_control_register(const bank3_registers address, const uint8_t data);
//Write buffer memory
void write_buffer_memory(const uint8_t buffer[], const uint16_t size);
//Bit field set
void bit_field_set_in_register(const uint8_t address, const uint8_t mask);
void bit_field_set_in_register(const common_registers address, const uint8_t mask);
void bit_field_set_in_register(const bank0_registers address, const uint8_t mask);
void bit_field_set_in_register(const bank1_registers address, const uint8_t mask);
void bit_field_set_in_register(const bank2_registers address, const uint8_t mask);
void bit_field_set_in_register(const bank3_registers address, const uint8_t mask);
//Bit field clear
void bit_field_clear_in_register(const uint8_t address, const uint8_t mask);
void bit_field_clear_in_register(const common_registers address, const uint8_t mask);
void bit_field_clear_in_register(const bank0_registers address, const uint8_t mask);
void bit_field_clear_in_register(const bank1_registers address, const uint8_t mask);
void bit_field_clear_in_register(const bank2_registers address, const uint8_t mask);
void bit_field_clear_in_register(const bank3_registers address, const uint8_t mask);
//System reset
void system_reset();
//Read PHY register
uint16_t read_PHY_register(const uint8_t address);
uint16_t read_PHY_register(const PHY_registers address);
//Write PHY register
void write_PHY_register(const uint8_t address, uint16_t data);
void write_PHY_register(const PHY_registers address, uint16_t data);
//Bit field set on PHY register
void bit_field_set_in_PHY_register(const uint8_t address, const uint16_t mask);
void bit_field_set_in_PHY_register(const PHY_registers address, const uint16_t mask);
//Bit field clear on PHY register
void bit_field_clear_in_PHY_register(const uint8_t address, const uint16_t mask);
void bit_field_clear_in_PHY_register(const PHY_registers address, const uint16_t mask);
//Start scanning PHY register
void start_scanning_in_PHY_register(const uint8_t address);
void start_scanning_in_PHY_register(const PHY_registers address);
//Stop scanning PHY register
void stop_scanning_in_PHY_register();
};
}
This diff is collapsed.
......@@ -2,6 +2,7 @@
#include <cstdint>
#include <ctime>
#include <cstdio>
#include "ADC_class.h"
#include "BoostConverter.h"
......@@ -9,10 +10,18 @@
#include "NixieDisplay.h"
#include "Separator.h"
#include "Time.h"
#include "ENC28J60.h"
#include "EEPROM_25AA02E48.h"
using namespace ENC28J60_namespace;
uint8_t mac[6];
adc_class adc;
BoostConverter boost(TC2->COUNT8, adc);
SPI spi(SERCOM0->SPI, 5'000'000);
SPI spi(SERCOM0->SPI, 11'800'000);
ENC28J60 eth(spi, PORT->Group[0], PIN_PA09, PORT->Group[1], PIN_PA10, mac);
EEPROM_25AA02E48 eeprom(spi, PORT->Group[1], PIN_PA11);
Button button_hour(PORT->Group[0], PIN_PA07, 7);
Button button_min(PORT->Group[0], PIN_PA12, 12);
......@@ -81,3 +90,43 @@ void NixieClock::display_handler()
}
}
}
void NixieClock::get_mac()
{
eeprom.read_EUI(mac);
char buffer[200];
sprintf(buffer, "Obtained MAC: %02X %02X %02X %02X %02X %02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
debug.info(buffer);
}
void NixieClock::print_eeprom()
{
uint8_t buffer[256];
eeprom.read(0, buffer, 256);
debug.info("EEPROM:");
uart.send("\t\t");
for (uint16_t i=0; i<256; i++)
{
if (i%16)
{
debug.uart.send_hex8(buffer[i]);
debug.uart.send(' ');
}
else
{
debug.uart.send_new_line();
debug.uart.send("\t\t0x");
debug.uart.send_hex8(i);
debug.uart.send(": ");
}
}
debug.uart.send_new_line();
debug.uart.send_new_line();
}
......@@ -11,6 +11,12 @@
#include "Separator.h"
#include "Button.h"
#include "Time.h"
#include "ENC28J60.h"
#include "EEPROM_25AA02E48.h"
using namespace ENC28J60_namespace;
extern uint8_t mac[6];
class NixieClock
{
......@@ -31,6 +37,8 @@ class NixieClock
tm time_date;
display_states state;
//uint8_t mac[6];
public:
NixieClock();
......@@ -41,12 +49,16 @@ class NixieClock
void display_handler();
void get_mac();
void print_eeprom();
};
extern adc_class adc;
extern BoostConverter boost;
extern SPI spi;
extern ENC28J60 eth;
extern EEPROM_25AA02E48 eeprom;
extern Button button_hour;
extern Button button_min;
......
......@@ -95,7 +95,7 @@ class USART
{
DRE_enabled = true;
usart.INTENSET.reg = SERCOM_USART_INTENSET_DRE;
usart.DATA.reg = c;
send_blocking(c);
}
else tx_buffer.add(c);
......
#pragma once
#include <stdint.h>
enum ETHERNET_FRAME_TYPE
{
IPV4 = 0x0800,
ARP = 0x0806,
WOL = 0x0842,
TRILL = 0x22F3,
DECNET = 0x6003,
REVERSE_ARP = 0x8035,
APPLE_TALK = 0x809B,
VLAN_TAGGED_FRAME = 0x8100,
IPX = 0x8137,
QNX_QNET = 0x8204,
IPV6 = 0x86DD,
ETHERNET_FLOW_CONTROL = 0x8808,
COBRA_NET = 0x8819,
MPLS_UNICAST = 0x8847,
MPLS_MULTICAST = 0x8848,
PPPOE_DISCOVERY_STAGE = 0x8863,
PPPOE_SESSION_STAGE = 0x8864,
//TODO: others ethernet frame types
};
struct ethernet_payload
{
uint8_t data[500];
uint16_t length;
};
struct ethernet_frame
{
uint8_t dest_address[6];
uint8_t src_address[6];
uint16_t type_length;
ethernet_payload payload;
uint32_t crc;
};
struct ethernet_802_1Q_header
{
uint16_t TPID;
uint16_t TCI;
};
struct ethernet_tagged_frame
{
uint8_t dest_address[6];
uint8_t src_address[6];
ethernet_802_1Q_header header_802_11Q;
uint16_t type_length;
ethernet_payload payload;
uint32_t crc;
};
......@@ -23,8 +23,10 @@
#include "NixieClock.h"
#include "BoostConverter.h"
#include "EEPROM_25AA02E48.h"
#include "ENC28J60.h"
#include "Debug.h"
using namespace ENC28J60_namespace;
Output led(PORT->Group[0], PIN_PA06);
......@@ -52,70 +54,25 @@ int main(void)
nixie.display.init();
nixie.separator.init();
boost.init();
boost.set_duty(120);
debug.uart.init();
uart.init();
uart.send("\n\rNixie clock v2.0\n\r");
uart.send("Martin Vitek - 2017\n\r");
SPI_select eeprom_cs(PORT->Group[1], 11);
eth.init();
EEPROM_25AA02E48 eeprom(spi, eeprom_cs);
uart.send("\n\rNixie clock v2.0\n\r");
uart.send("Martin Vitek - 2017\n\r\n\r");
/*
eeprom_cs.select(true);
for (int i=0; i<800; i++);
eeprom_cs.select(false);
for (int i=0; i<800; i++);
eeprom_cs.select(true);
for (int i=0; i<800; i++);
eeprom_cs.select(false);
for (int i=0; i<800; i++);
*/
eth.print_device_info();
//uint8_t to_write[] = {0xDE, 0xAD, 0xBE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB};
//eeprom.write(1, to_write, 16);
//while (!eeprom.is_ready()) ;;
nixie.print_eeprom();
nixie.get_mac();
/*
debug.uart.send("Status: 0b");
debug.uart.send_binary8(eeprom.read_status_register());
debug.uart.send_new_line();
uint8_t MAC[256];
//eeprom.read_EUI(MAC);
eeprom.read(0, MAC, 256);
for (uint16_t i=0; i<256; i++)
{
//uart.send("0x");
if (i%16)
{
debug.uart.send_hex8(MAC[i]);
debug.uart.send(' ');
}
else
{
debug.uart.send_new_line();
debug.uart.send("0x");
debug.uart.send_hex8(i);
debug.uart.send(": ");
}
//uart.send_new_line();
}
debug.uart.send_new_line();
*/
uint8_t i = 0;
time_t old = 0;
bool up = true;
while (1)
while (true)
{
nixie.display_handler();
nixie.separator.pulsing_handler();
......@@ -169,6 +126,9 @@ int main(void)
if ((clock() % 1000) == 0 )
{
eth.print_connection_status();
/*
uart.send("Voltage 12V:\t");
uart.send_dec(adc.value[adc.VOLTAGE_12V]/1000);uart.send('.');uart.send_dec(adc.value[adc.VOLTAGE_12V]%1000);
uart.send_new_line();
......@@ -202,6 +162,7 @@ int main(void)
uart.send_new_line();
uart.send_new_line();
*/
//clock.display.set(i++);
//if (i>99) i=0;
......
......@@ -220,6 +220,24 @@
<Compile Include="EEPROM_25AA02E48.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="ENC28J60.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="ENC28J60.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="ENC28J60_registers.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="ENC28J60_SPI.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="ENC28J60_SPI.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="ethernet_frame.h">
<SubType>compile</SubType>
</Compile>
<Compile Include="fifo.h">
<SubType>compile</SubType>
</Compile>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment