Commit 3b8b5cff authored by Martin Vítek's avatar Martin Vítek

Same code as yesterday, but working

parent 39312f32
......@@ -34,12 +34,7 @@ class Button
void interrupt_handler()
{
if (EIC->INTFLAG.reg & (1UL<<extint))
{
if (button.is_set()) { }
else { }
EIC->INTFLAG.reg = (1UL<<extint);
}
if (button.is_set()) { }
else { }
}
};
\ No newline at end of file
};
......@@ -44,8 +44,8 @@ class Debug
void reg(const char* name, const uint8_t value);
void reg(const char* name, const uint16_t value);
void frame(const ethernet_frame &frame);
void tx_status(const ENC28J60_namespace::tx_status_vector& status, bool simple= true);
void rx_status(const ENC28J60_namespace::rx_status_vector& status, bool simple= true);
void tx_status(const ENC28J60_namespace::tx_status_vector& status, bool simple=true);
void rx_status(const ENC28J60_namespace::rx_status_vector& status, bool simple=true);
void adc();
};
......
......@@ -11,27 +11,27 @@
//#include "nixie_clock.h"
#include "Debug.h"
#include "ethernet_frame.h"
#include "NetworkTypes.h"
namespace ENC28J60_namespace
{
ENC28J60::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]
): ENC28J60_SPI(spi, cs_port, cs_bit, irq_port, irq_bit),
mac(mac)
{
//test_RXEN_corruption();
ENC28J60::ENC28J60(SPI &spi,
volatile PortGroup& cs_port, const uint8_t cs_bit,
volatile PortGroup& irq_port, const uint8_t irq_bit): ENC28J60_SPI(spi, cs_port, cs_bit, irq_port, irq_bit)
{
test_RXEN_corruption();
}
void ENC28J60::init()
{
void ENC28J60::init(const MAC& mac)
{
system_reset();
irq.set_pull_up();
irq.enable_peripheral_multiplexing();
//Wait for oscillator start-up timer (access to MAC and PHY)
//This isn't working - errata issue 2
/*
/* This isn't working - errata issue 2
uint8_t delay = 0;
while (!(read_control_register(ESTAT) & CLKRDY_bm))
......@@ -52,10 +52,14 @@ namespace ENC28J60_namespace
//Set-up RX & TX buffer - RX=6001B, TX=2190B
set_eth_rx_buffer_size(6001);
//TODO: Pattern Match Filter to accept ARP multicast packets (and more?)
//TODO: DHCP needs multicast to be enabled
//Set-up receive filters
write_control_register(ERXFCON, 0/*UCEN_bm | CRCEN_bm*/);
//Set-up receive filters - accept only if CRC is OK, unicast, match pattern
write_control_register(ERXFCON, UCEN_bm | CRCEN_bm | PMEN_bm);
//Set-up pattern match (ARP to ff:ff:ff:ff:ff:ff)
write_control_register(EPMM0, 0x3F);
write_control_register(EPMM1, 0x30);
write_control_register(EPMCSL, 0xF9);
write_control_register(EPMCSH, 0xF7);
//Set-up MAC
write_control_register(MACON1, MARXEN_bm | TXPAUS_bm | RXPAUS_bm); //Enable RX, IEEE pause control frames
......@@ -82,9 +86,11 @@ namespace ENC28J60_namespace
bit_field_set_in_PHY_register(PHCON2, HDLDIS_bm); //Fix for errata issue 9???
bit_field_clear_in_PHY_register(PHCON1, PDPXMD_bm); //Force half-duplex
//write_PHY_register(PHLCON, (1<<13) | (1<<12) | LACFG2_bm | LBCFG2_bm | LBCFG1_bm | LBCFG0_bm | STRCH_bm); //LEDA (green) link status, LEDB (orange) rx & tx activity
write_PHY_register(PHLCON, (1<<13) | (1<<12) | LACFG2_bm | LACFG1_bm | LACFG0_bm | LBCFG2_bm | LBCFG1_bm | LBCFG0_bm | STRCH_bm);
write_PHY_register(PHLCON, (1<<13) | (1<<12) | LACFG2_bm | LACFG1_bm | LACFG0_bm | LBCFG2_bm | LBCFG1_bm | LBCFG0_bm | STRCH_bm); //Both LEDs indicates rx/tx activity
write_PHY_register(PHIE, PLNKIE_bm | PGEIE_bm); //Enable interrupt from PHY
//TODO: Enable interrupts
//Enable interrupts - global enable, RX packet, link change, TX packet
bit_field_set_in_register(EIE, INTIE_bm | PKTIE_bm | LINKIE_bm | TXIE_bm);
//Enable reception
bit_field_set_in_register(ECON1, RXEN_bm);
......@@ -144,6 +150,9 @@ namespace ENC28J60_namespace
bool ENC28J60::check_link()
{
//Clear LINKIF flag
read_PHY_register(PHIR);
return (read_PHY_register(PHSTAT2) & LSTAT_bm);
}
......@@ -396,8 +405,15 @@ namespace ENC28J60_namespace
}
}
void ENC28J60::print_interrupt_flags(const interrupt_flags& flags)
{
uart.send_binary8(flags.value);
uart.send_new_line();
}
void ENC28J60::test_RXEN_corruption()
{
//This test is only valid with avr-gcc
if (RXEN_bm != (1<<0x02)) debug.error("RXEN is corrupted!!!\n\r");
}
}
......@@ -9,6 +9,7 @@
#include "ENC28J60_registers.h"
#include "ENC28J60_SPI.h"
#include "ethernet_frame.h"
#include "NetworkTypes.h"
namespace ENC28J60_namespace
{
......@@ -67,6 +68,23 @@ namespace ENC28J60_namespace
bool zero :1;
} bit;
};
union interrupt_flags
{
uint8_t value;
struct
{
uint8_t rxerif :1;
uint8_t txerif :1;
uint8_t reserved :1;
uint8_t txif :1;
uint8_t linkif :1;
uint8_t dmaif :1;
uint8_t pktif :1;
uint8_t unimplemented :1;
} bit;
};
#pragma pack(pop)
class ENC28J60: public ENC28J60_SPI
......@@ -78,18 +96,16 @@ namespace ENC28J60_namespace
uint16_t eth_tx_buffer_end;
uint16_t eth_rx_packet_start;
const uint8_t (&mac)[6];
ethernet_frame frame;
public:
volatile bool tx_was_successful;
volatile bool link_changed;
volatile bool pending_packet;
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]);
ENC28J60(SPI &spi, volatile PortGroup& cs_port, const uint8_t cs_bit, volatile PortGroup& irq_port, const uint8_t irq_bit);
//Initialization
void init();
void init(const MAC& mac);
void set_eth_rx_buffer_size(uint16_t size);
bool check_link();
......@@ -97,10 +113,75 @@ namespace ENC28J60_namespace
void tx_frame_blocking(const ethernet_frame &frame);
bool rx_frame_blocking(ethernet_frame &frame);
//Interrupt handler
inline void interrupt_handler();
//For testing
void print_connection_status();
void print_device_info();
void print_interrupt_flags(const interrupt_flags& flags);
void test_RXEN_corruption();
};
inline void ENC28J60::interrupt_handler()
{
//TODO: Maybe just set a flag and check interrupt source in main loop
//Disable interrupts
bit_field_clear_in_register(EIE, INTIE_bm);
interrupt_flags flags;
flags.value = read_control_register(EIR);
uint8_t flags_to_clear = 0;
print_interrupt_flags(flags);
if (flags.bit.rxerif)
{
flags_to_clear |= RXERIF_bm;
}
if (flags.bit.txerif)
{
flags_to_clear |= TXERIF_bm;
}
if (flags.bit.txif)
{
tx_was_successful = true;
flags_to_clear |= TXIF_bm;
}
if (flags.bit.linkif)
{
link_changed = true;
//Cleared by reading PHIR PHY register
}
if (flags.bit.dmaif)
{
flags_to_clear |= DMAIF_bm;
}
if (flags.bit.pktif)
{
pending_packet = true;
//Cleared if EPKTCNT is zero
}
if (flags_to_clear) bit_field_clear_in_register(EIR, flags_to_clear);
//Enable interrupts
bit_field_set_in_register(EIE, INTIE_bm);
}
}
......@@ -43,7 +43,7 @@ namespace ENC28J60_namespace
class ENC28J60_SPI
{
private:
protected:
SPI& spi;
SPI_select cs;
Input irq;
......
......@@ -20,7 +20,7 @@ uint8_t mac[6];
adc_class adc;
BoostConverter boost(TC2->COUNT8, adc);
SPI spi(SERCOM0->SPI, 11'800'000);
ENC28J60 eth(spi, PORT->Group[0], PIN_PA09, PORT->Group[1], PIN_PA10, mac);
ENC28J60 eth(spi, PORT->Group[0], PIN_PA09, PORT->Group[1], PIN_PA10);
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);
......
......@@ -136,12 +136,15 @@ void System::init_eic()
{
//EXTINT[7] both edges, filter enabled
EIC->CONFIG[0].reg = EIC_CONFIG_SENSE7_BOTH | EIC_CONFIG_FILTEN7;
//EXTINT[10] falling edge, filter enabled
EIC->CONFIG[1].reg = EIC_CONFIG_SENSE2_FALL | EIC_CONFIG_FILTEN2;
//EXTINT[12] both edges, filter enabled
EIC->CONFIG[1].reg = EIC_CONFIG_SENSE4_BOTH | EIC_CONFIG_FILTEN4;
//Enable interrupts EXTINT[7], EXTINT[12]
EIC->INTENSET.reg = EIC_INTENSET_EXTINT7 | EIC_INTENSET_EXTINT12;
EIC->INTENSET.reg = EIC_INTENSET_EXTINT7 | EIC_INTENSET_EXTINT10 | EIC_INTENSET_EXTINT12;
//Enable EIC
EIC->CTRL.bit.ENABLE = 1;
......
......@@ -15,8 +15,26 @@ void ADC_Handler()
void EIC_Handler()
{
button_hour.interrupt_handler();
button_min.interrupt_handler();
if (EIC->INTFLAG.bit.EXTINT10)
{
eth.interrupt_handler();
EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT10;
}
if (EIC->INTFLAG.bit.EXTINT7)
{
button_hour.interrupt_handler();
EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT7;
}
if (EIC->INTFLAG.bit.EXTINT12)
{
button_min.interrupt_handler();
EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT12;
}
}
void TC0_Handler()
......
......@@ -69,7 +69,7 @@ int main(void)
boost.disable();
uart.init();
eth.init();
eth.init(MAC({0x54, 0x10, 0xEC, 0x20, 0xE5, 0xBD}));
uart.send("\n\rNixie clock v2.0\n\r");
uart.send("Martin Vitek - 2017\n\r\n\r");
......@@ -114,6 +114,18 @@ int main(void)
}
}
if (eth.link_changed)
{
if (eth.check_link())
{
debug.info("Link up");
}
else debug.info("Link down");
eth.link_changed = false;
}
/*
if (clock() > old)
{
......
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