Skip to content

Commit

Permalink
ethernet support
Browse files Browse the repository at this point in the history
  • Loading branch information
mvladic committed Jul 16, 2019
1 parent 51fdc19 commit a237ff3
Show file tree
Hide file tree
Showing 9 changed files with 389 additions and 324 deletions.
3 changes: 1 addition & 2 deletions src/eez/apps/psu/conf_user.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,4 @@ Use this header file to override anything from conf.h or conf_advanced.h.

#pragma once

#define ETHERNET_MAC_ADDRESS \
{ 0x74, 0x69, 0x69, 0x2D, 0x30, 0x00 }
#define ETHERNET_MAC_ADDRESS { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x00 }
134 changes: 41 additions & 93 deletions src/eez/apps/psu/ethernet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#define CONF_CHECK_DHCP_LEASE_SEC 60

namespace eez {

using namespace scpi;

namespace psu {

using namespace scpi;
Expand All @@ -42,29 +45,23 @@ namespace ethernet {

TestResult g_testResult = TEST_FAILED;

using namespace eez::mcu::ethernet;

static EthernetServer g_server;

static bool g_isConnected = false;
static EthernetClient g_activeClient;
// static uint32_t g_lastCheckDhcpLeaseTime;

////////////////////////////////////////////////////////////////////////////////

size_t ethernet_client_write(EthernetClient &client, const char *data, size_t len) {
size_t size = client.write(data, len);
size_t ethernet_client_write(const char *data, size_t len) {
size_t size = eez::mcu::ethernet::writeBuffer(data, len);
return size;
}

size_t ethernet_client_write_str(EthernetClient &client, const char *str) {
return ethernet_client_write(client, str, strlen(str));
size_t ethernet_client_write_str(const char *str) {
return ethernet_client_write(str, strlen(str));
}

////////////////////////////////////////////////////////////////////////////////

size_t SCPI_Write(scpi_t *context, const char *data, size_t len) {
return ethernet_client_write(g_activeClient, data, len);
return ethernet_client_write(data, len);
}

scpi_result_t SCPI_Flush(scpi_t *context) {
Expand All @@ -76,7 +73,7 @@ int SCPI_Error(scpi_t *context, int_fast16_t err) {
char errorOutputBuffer[256];
sprintf(errorOutputBuffer, "**ERROR: %d,\"%s\"\r\n", (int16_t)err,
SCPI_ErrorTranslate(err));
ethernet_client_write(g_activeClient, errorOutputBuffer, strlen(errorOutputBuffer));
ethernet_client_write(errorOutputBuffer, strlen(errorOutputBuffer));

if (err == SCPI_ERROR_INPUT_BUFFER_OVERRUN) {
scpi::onBufferOverrun(*context);
Expand All @@ -94,15 +91,15 @@ scpi_result_t SCPI_Control(scpi_t *context, scpi_ctrl_name_t ctrl, scpi_reg_val_
sprintf(outputBuffer, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val);
}

ethernet_client_write(g_activeClient, outputBuffer, strlen(outputBuffer));
ethernet_client_write(outputBuffer, strlen(outputBuffer));

return SCPI_RES_OK;
}

scpi_result_t SCPI_Reset(scpi_t *context) {
char errorOutputBuffer[256];
strcpy(errorOutputBuffer, "**Reset\r\n");
ethernet_client_write(g_activeClient, errorOutputBuffer, strlen(errorOutputBuffer));
ethernet_client_write(errorOutputBuffer, strlen(errorOutputBuffer));

return reset() ? SCPI_RES_OK : SCPI_RES_ERR;
}
Expand All @@ -129,9 +126,8 @@ void init() {
return;
}

bool result;
if (persist_conf::isEthernetDhcpEnabled()) {
result = Ethernet.begin(persist_conf::devConf2.ethernetMacAddress);
eez::mcu::ethernet::begin(persist_conf::devConf2.ethernetMacAddress);
} else {
uint8_t ipAddress[4];
ipAddressToArray(persist_conf::devConf2.ethernetIpAddress, ipAddress);
Expand All @@ -145,31 +141,10 @@ void init() {
uint8_t subnetMask[4];
ipAddressToArray(persist_conf::devConf2.ethernetIpAddress, ipAddress);

Ethernet.begin(persist_conf::devConf2.ethernetMacAddress, ipAddress, dns, gateway, subnetMask);

result = 1;
eez::mcu::ethernet::begin(persist_conf::devConf2.ethernetMacAddress, ipAddress, dns, gateway, subnetMask);
}

if (!result) {
g_testResult = TEST_WARNING;
DebugTrace("Ethernet not connected!");
event_queue::pushEvent(event_queue::EVENT_WARNING_ETHERNET_NOT_CONNECTED);

return;
}

g_server.init(persist_conf::devConf2.ethernetScpiPort);

g_server.begin();

g_testResult = TEST_OK;

DebugTrace("Listening on port %d", (int)persist_conf::devConf2.ethernetScpiPort);

scpi::init(g_scpiContext, g_scpiPsuContext, &g_scpiInterface, g_scpiInputBuffer,
SCPI_PARSER_INPUT_BUFFER_LENGTH, g_errorQueueData, SCPI_PARSER_ERROR_QUEUE_SIZE + 1);

// g_lastCheckDhcpLeaseTime = micros();
g_testResult = TEST_CONNECTING;
}

bool test() {
Expand All @@ -180,75 +155,48 @@ bool test() {
return g_testResult != TEST_FAILED;
}

void tick(uint32_t tick_usec) {
if (g_testResult != TEST_OK) {
return;
}

// This code is commented because DHCP lease renewal blocks main thread for 5 or more seconds.
// if (persist_conf::devConf2.flags.ethernetDhcpEnabled) {
// int32_t diff = tick_usec - g_lastCheckDhcpLeaseTime;
// if (diff > CONF_CHECK_DHCP_LEASE_SEC * 1000000L) {
// // DebugTrace("DHCP lease check");
// g_lastCheckDhcpLeaseTime = tick_usec;
// watchdog::disable();
// Ethernet.maintain();
// watchdog::enable();
// }
//}

if (g_isConnected) {
if (!g_activeClient.connected()) {
g_isConnected = false;
g_activeClient = EthernetClient();
DebugTrace("Ethernet client lost!");
void onQueueMessage(uint32_t type, uint32_t param) {
if (type == ETHERNET_CONNECTED) {
bool isConnected = param ? true : false;
if (!isConnected) {
g_testResult = TEST_WARNING;
DebugTrace("Ethernet not connected!");
event_queue::pushEvent(event_queue::EVENT_WARNING_ETHERNET_NOT_CONNECTED);
return;
}
}

EthernetClient client = g_server.available();
g_testResult = TEST_OK;

if (client) {
if (!g_isConnected) {
client.flush();
g_activeClient = client;
g_isConnected = true;
scpi::emptyBuffer(g_scpiContext);
DebugTrace("A new ethernet client detected!");
}

size_t size;
while ((size = client.available()) > 0) {
uint8_t *msg = (uint8_t *)malloc(size);
size = client.read(msg, size);
if (client == g_activeClient) {
input(g_scpiContext, (const char *)msg, size);
} else {
ethernet_client_write_str(client, "**ERROR: another client already connected\r\n");
DebugTrace("Another client detected and ignored!");
}
free(msg);
eez::mcu::ethernet::beginServer(persist_conf::devConf2.ethernetScpiPort);
DebugTrace("Listening on port %d", (int)persist_conf::devConf2.ethernetScpiPort);
scpi::init(g_scpiContext, g_scpiPsuContext, &g_scpiInterface, g_scpiInputBuffer,
SCPI_PARSER_INPUT_BUFFER_LENGTH, g_errorQueueData, SCPI_PARSER_ERROR_QUEUE_SIZE + 1);
} else if (type == ETHERNET_CLIENT_CONNECTED) {
g_isConnected = true;
scpi::emptyBuffer(g_scpiContext);
} else if (type == ETHERNET_CLIENT_DISCONNECTED) {
g_isConnected = false;
} else if (type == ETHERNET_INPUT_AVAILABLE) {
char *buffer;
uint32_t length;
eez::mcu::ethernet::getInputBuffer(param, &buffer, &length);
if (buffer && length) {
input(g_scpiContext, (const char *)buffer, length);
eez::mcu::ethernet::releaseInputBuffer();
}
}
}

uint32_t getIpAddress() {
return Ethernet.localIP();
return eez::mcu::ethernet::localIP();
}

bool isConnected() {
return g_isConnected;
}

void update() {
if (g_isConnected) {
if (g_activeClient.connected()) {
g_activeClient.stop();
g_activeClient = EthernetClient();
}
g_isConnected = false;
}

g_testResult = TEST_WARNING;
// TODO
}

} // namespace ethernet
Expand Down
9 changes: 8 additions & 1 deletion src/eez/apps/psu/ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,19 @@ extern scpi_t g_scpiContext;
void init();
bool test();

void tick(uint32_t tick_usec);
#define ETHERNET_CONNECTED 1
#define ETHERNET_CLIENT_CONNECTED 2
#define ETHERNET_CLIENT_DISCONNECTED 3
#define ETHERNET_INPUT_AVAILABLE 4

void onQueueMessage(uint32_t type, uint32_t param);

uint32_t getIpAddress();

bool isConnected();

// this function is called when ethernet settings are changed,
// and it should reconnect to the ethernet with these settings
void update();

} // namespace ethernet
Expand Down
4 changes: 4 additions & 0 deletions src/eez/apps/psu/persist_conf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,3 +1040,7 @@ bool isSdLocked() {
} // namespace persist_conf
} // namespace psu
} // namespace eez

extern "C" void getMacAddress(uint8_t macAddress[]) {
memcpy(macAddress, eez::psu::persist_conf::devConf2.ethernetMacAddress, 6);
}
2 changes: 2 additions & 0 deletions src/eez/apps/psu/persist_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,5 @@ bool isSdLocked();
} // namespace persist_conf
} // namespace psu
} // namespace eez

extern "C" void getMacAddress(uint8_t macAddress[]);
69 changes: 19 additions & 50 deletions src/eez/modules/mcu/ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,70 +24,38 @@ namespace ethernet {

bool onSystemStateChanged();

class IPAddress {
private:
struct IPAddress {
IPAddress() {
_address.dword = 0;
}

IPAddress(uint32_t dwordAddress) {
_address.dword = dwordAddress;
}

union {
uint8_t bytes[4]; // IPv4 address
uint32_t dword;
} _address;

public:
operator uint32_t() const {
return _address.dword;
};
};

/// Arduino Ethernet object simulator
class EthernetModule {
public:
bool begin(uint8_t *mac, uint8_t *ipAddress = 0, uint8_t *dns = 0, uint8_t *gateway = 0,
uint8_t *subnetMask = 0);
uint8_t maintain();

IPAddress localIP();
IPAddress subnetMask();
IPAddress gatewayIP();
IPAddress dnsServerIP();
};

extern EthernetModule Ethernet;

class EthernetClient {
public:
EthernetClient();
EthernetClient(bool valid);

operator bool();
bool operator==(EthernetClient &other) {
return true;
}

bool connected();
void begin(uint8_t *mac, uint8_t *ipAddress = 0, uint8_t *dns = 0, uint8_t *gateway = 0, uint8_t *subnetMask = 0);

size_t available();
size_t read(uint8_t *, size_t);
size_t write(const char *data, size_t len);
void flush();
IPAddress localIP();
IPAddress subnetMask();
IPAddress gatewayIP();
IPAddress dnsServerIP();

void stop();

private:
bool valid;
};
void beginServer(uint16_t port);

class EthernetServer {
public:
void init(int port);

void begin();
EthernetClient available();

private:
bool bind_result;
int port;
EthernetClient client;
};
void getInputBuffer(int bufferPosition, char **buffer, uint32_t *length);
void releaseInputBuffer();

int writeBuffer(const char *buffer, uint32_t length);

class EthernetUDP {
public:
Expand All @@ -99,6 +67,7 @@ class EthernetUDP {
int read(unsigned char* buffer, size_t len);
int parsePacket();
};

}
}
} // namespace eez::mcu::ethernet
Loading

0 comments on commit a237ff3

Please sign in to comment.