Im trying to interface a teensy 4.1 to a luckfox pico max using ethernet. The teensy is utlilizing the QNEthernet library and just some basic socket code on the side of the luckfox. The purpose of the setup is to use the teensy as a display driver and provide an simplified interface for the pico to draw to . . . but i also need to be able to push full framebuffers of data to the teensy as well in which the teensy should recieve the data and immediately draw the full framebuffer to the display (basically act like a passthrough to driectly write to the display). Since the teensy has 100Mbits ethernet capability i thought this should be no issue and it can handle the data load allowing the pico to send data fast enough to achieve a stable 30 frames a second. however just sending a single full buffer takes around a second even though its only 150kb of data (320 x 240 resolution rgb565). This seems like a very very very low throughput for the capabilities of teensy ethernet and would love some input on how to speed up the transfers. When writing to a null buffer where the teensy just discards the data it will go through it quickly but not when storing the data to send to the display. Please let me know if anything on top of this needs to be added in order to better help. if recieving even 150kb of data takes so long then it will also struggle with the hmi interface speeds as well as i expect that should also be transfering and parsing through 10's of kb of data over the wire and that also needs to be fast enough to be able to run at 30fps.
Teensy 4.1 code . . .
Luckfox Pico Max code
Teensy 4.1 code . . .
C++:
#include <Arduino.h>
#include <QNEthernet.h>
#include "./common.h"
namespace qn = qindesign::network;
IPAddress staticIP{192, 168, 1, 101};
IPAddress subnetMask{255, 255, 255, 0};
IPAddress gateway{0, 0, 0, 0};
qn::EthernetServer server{80};
qn::EthernetClient rvCore;
bool rvCoreConnected = false;
int fbLoc = 0;
int fbLocMax = DISPLAY_WIDTH * DISPLAY_HEIGHT * 2;
char* cfb = reinterpret_cast<char*>(fb);
void link_initialize()
{
// get mac address
//uint8_t mac[6];
//qn::Ethernet.macAddress(mac);
//printf("MAC = %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// Listen for link changes
qn::Ethernet.onLinkState([](bool state) {
// state ? ON : OFF
});
// start ethernet with static settings
if (!qn::Ethernet.begin(staticIP, subnetMask, gateway))
{
// failed to start ethernet
}
// start server
server.begin();
if (!server)
{
// failed to start server
}
//
}
void link_update()
{
if (rvCoreConnected)
{
// rvCore connected
if (rvCore.available() > 0)
{
rvCore.readBytes(cfb, DISPLAY_HEIGHT * DISPLAY_WIDTH * 2);
fbLoc = fbLocMax;
}
if (!rvCore.connected())
{
rvCore.stop();
rvCoreConnected = false;
}
}
else
{
// rvCore not connected
qn::EthernetClient client = server.accept();
if (client)
{
//IPAddress ip = client.remoteIP();
//Serial.printf("rvCore connected: %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
rvCore = client;
rvCore.setNoDelay(true);
rvCoreConnected = true;
}
}
//qn::Ethernet.loop();
}
Luckfox Pico Max code
C++:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <cerrno>
#include <netinet/tcp.h>
#define INTERFACE "eth0"
static const int fbSize = 320 * 240 * 2;
int link_send_fb(uint16_t* fb)
{
int sock = 0;
int valread;
struct sockaddr_in serv_addr;
int optval = 1;
socklen_t optlen = sizeof(optval);
char buffer[1024] = {0};
std::cout << "Creating socket . . ." << std::endl;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cerr << "Socket creation error!" << std::endl;
return -1;
}
// Set TCP_NODELAY flag
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &optval, optlen) < 0) {
std::cerr << "Error setting TCP_NODELAY option" << std::endl;
close(sock);
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(80);
std::cout << "Setting connection parameters . . ." << std::endl;
if (inet_pton(AF_INET, "192.168.1.101", &serv_addr.sin_addr) <= 0) {
std::cerr << "Invalid address/ Address not supported!" << std::endl;
return -1;
}
std::cout << "Connecting to server . . ." << std::endl;
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
std::cerr << "Connection Failed!" << std::endl;
std::cerr << errno << std::endl;
return -1;
}
// Send data
int bytes_sent = send(sock, fb, fbSize, 0);
if (bytes_sent < 0) {
perror("Send failed");
close(sock);
return -1;
} else if (bytes_sent != fbSize) {
std::cerr << "Not all bytes sent. Sent: " << bytes_sent << ", Expected: " << fbSize << std::endl;
close(sock);
} else {
std::cout << "Message sent successfully" << std::endl;
close(sock);
}
return 0;
}