This wiki has been archived and made read-only.
For up-to-date information about TkkrLab and it's projects please visit our main website at tkkrlab.nl.

Difference between revisions of "Ledboard"

From

Jump to: navigation, search
(Replaced content with "{{Project |ProjectName=Ledboard |Owner=jawsper |Skillz=Arduino, soldering, ethernet }} == Sauce == https://github.com/jawsper/ledboard")
Line 6: Line 6:
  
  
== Segment sauce ==
+
== Sauce ==
 
https://github.com/jawsper/ledboard
 
https://github.com/jawsper/ledboard
 
== Controller sauce ==
 
<pre>
 
#include "EtherCard.h"
 
#include "IPAddress.h"
 
#include "EEPROMAnything.h"
 
#include <avr/io.h>
 
 
#define DEBUG 0
 
 
#define SIZE (96*48)
 
 
byte calculate_config_checksum(byte* data);
 
void udpReceive(word port, byte ip[4], const char *data, word len);
 
void ethernet_setup();
 
void eeprom_read_config();
 
void eeprom_write_config();
 
 
// ethernet interface default settings
 
static byte permitted_source_address[4] = { 10, 42, 2, 104 };
 
static byte default_ip[4] = { 10, 42, 3, 12 };
 
static byte default_gateway[4] = { 10, 42, 1, 1 };
 
static byte default_netmask[4] = { 255, 255, 0, 0 };
 
 
 
struct config_t {
 
byte ip[4];
 
byte gateway[4];
 
byte netmask[4];
 
} config;
 
 
 
// ethernet mac address - must be unique on your network
 
static byte mymac[] = { 0x70, 0x69, 0x69, 0xCA, 0xFE, 0x00 };
 
 
byte Ethernet::buffer[1536]; // tcp/ip send and receive buffer
 
 
byte calculate_config_checksum(byte* data)
 
{
 
byte checksum = 0xAA;
 
for(int i = 0; i < sizeof(config); i++) checksum ^= *data++;
 
return checksum;
 
}
 
 
#define SERIAL_WAIT() while(!(UCSR0A & (1<<UDRE0)))
 
#define SERIAL_WRITE(x) SERIAL_WAIT(); UDR0 = x
 
 
byte pixels_per_byte = 1;
 
 
void udpReceive(word port, byte ip[4], const char *chr_data, word len)
 
{
 
byte* data = (byte*)chr_data;
 
 
switch(port)
 
{
 
case 1337:
 
{
 
#if DEBUG
 
Serial.println("I FAILED YOU MY MASTER");
 
#else
 
if(pixels_per_byte != 1 && pixels_per_byte != 7)
 
{
 
SERIAL_WRITE(0x80);
 
for(int i = 0; i < pixels_per_byte; i++)
 
{
 
SERIAL_WRITE(0x7f);
 
}
 
break;
 
}
 
for(int i = 0; i < len; i++)
 
{
 
byte val = *data++;
 
 
if((val & 0x80) == 0)
 
{
 
val &= 0x7f;
 
switch(pixels_per_byte)
 
{
 
case 0:
 
case 1:
 
SERIAL_WRITE(val);
 
break;
 
case 7:
 
for(int i = 1; i < 7; i++)
 
{
 
SERIAL_WRITE((val & 0x01) ? 0x7f : 0x00);
 
val >>= 1;
 
}
 
break;
 
}
 
}
 
else
 
{
 
if(val != 0x80)
 
{
 
pixels_per_byte = val & 0x0f;
 
continue;
 
}
 
pixels_per_byte = 1;
 
SERIAL_WRITE(val & 0x80);
 
}
 
}
 
#endif
 
// Serial.write((const uint8_t*)data, len);
 
break;
 
}
 
case 4242:
 
{
 
int _size = sizeof(config) + 1;
 
if(len == _size)
 
{
 
byte checksum = *data++;
 
 
byte* cfg = (byte*)&config;
 
byte config_checksum = calculate_config_checksum((byte*)data);
 
 
if(checksum == config_checksum)
 
{
 
memcpy(&config, data, sizeof(config));
 
eeprom_write_config();
 
 
ethernet_setup();
 
}
 
}
 
break;
 
}
 
}
 
}
 
 
void ethernet_setup()
 
{
 
  ether.staticSetup(config.ip, config.gateway, 0, config.netmask);
 
 
ether.udpServerListenOnPort(&udpReceive, 1337);
 
ether.udpServerListenOnPort(&udpReceive, 4242);
 
}
 
 
void eeprom_read_config()
 
{
 
byte checksum = EEPROM.read(0);
 
EEPROM_readAnything(1, config);
 
byte config_checksum = calculate_config_checksum((byte*)&config);
 
if(config_checksum != checksum)
 
{
 
EtherCard::copyIp(config.ip, default_ip);
 
EtherCard::copyIp(config.gateway, default_gateway);
 
EtherCard::copyIp(config.netmask, default_netmask);
 
eeprom_write_config();
 
}
 
}
 
 
void eeprom_write_config()
 
{
 
byte checksum = calculate_config_checksum((byte*)&config);
 
EEPROM.write(0, checksum);
 
EEPROM_writeAnything(1, config);
 
}
 
 
void setup()
 
{
 
#if DEBUG
 
Serial.begin(115200);
 
Serial.println("DEBUG");
 
#else
 
Serial.begin(500000);
 
#endif
 
 
eeprom_read_config();
 
 
if (ether.begin(sizeof Ethernet::buffer, mymac, 8) == 0)
 
{
 
// for(int i = 0; i < 5; i++) Serial.write(0x80);
 
// for(int i = 0; i < 100; i++)
 
// {
 
// Serial.write(0x7f);
 
// Serial.write(0x01);
 
// }
 
while(1);
 
}
 
 
ethernet_setup();
 
 
 
#if DEBUG
 
Serial.println("Init completed");
 
#else
 
delay(3000);
 
for(int i = 0; i < 5; i++)
 
Serial.write(0x80);
 
for(int i = 0; i < 96*48; i++)
 
{
 
Serial.write(0);
 
}
 
#endif
 
 
}
 
 
static bool eth_type_is_ip(byte* packet, uint16_t len)
 
{
 
return
 
packet[ETH_TYPE_H_P] == ETHTYPE_IP_H_V &&
 
packet[ETH_TYPE_L_P] == ETHTYPE_IP_L_V &&
 
packet[IP_HEADER_LEN_VER_P] == 0x45;
 
}
 
 
 
bool isMySpecialPacket(byte* header, uint16_t len)
 
{
 
    bool is_ip = eth_type_is_ip(header, len);
 
    bool is_udp = header[IP_PROTO_P] == IP_PROTO_UDP_V;
 
    uint16_t port = (header[UDP_DST_PORT_H_P] << 8) | (header[UDP_DST_PORT_L_P] & 0xFF);
 
return is_ip && is_udp && port == 1337 && memcmp(config.ip, header + IP_DST_P, 4) == 0;
 
// && memcmp(permitted_source_address, header + IP_SRC_P, 4) == 0;
 
}
 
void specialPacketReceive(byte b)
 
{
 
while(!(UCSR0A & (1<<UDRE0)));
 
UDR0 = b;
 
}
 
 
void loop()
 
{
 
//this must be called for ethercard functions to work.
 
 
// packetLoop in tcpip.cpp
 
// packetReceive in enc28j60.cpp
 
#if DEBUG
 
ether.packetLoop(ether.specialPacketReceive(&isMySpecialPacket, &specialPacketReceive));
 
#else
 
ether.packetLoop(ether.packetReceive());
 
#endif
 
}
 
</pre>
 

Revision as of 16:00, 4 January 2015

Project: Ledboard
360x360px
Name Ledboard
Initiator jawsper
Status {{{Status}}}
Skills Arduino, soldering, ethernet
Summary {{{Summary}}}


Sauce

https://github.com/jawsper/ledboard