Skip to content

Instantly share code, notes, and snippets.

@DeqingSun
Created April 17, 2020 21:12
Show Gist options
  • Save DeqingSun/5205978a25bccc6246c46d3b728393f7 to your computer and use it in GitHub Desktop.
Save DeqingSun/5205978a25bccc6246c46d3b728393f7 to your computer and use it in GitHub Desktop.
5A-75B driver, tested on nanopi neo 2
#include "ofDriver5A75B.h"
ofDriver5A75B::ofDriver5A75B(){
int i;
unsigned char dataPack5500[7] = {0x7f,0x00,0x00,0x00,0xC0,0x08,0x88};
for (i=0;i<LEDHEIGHT;i++){
struct ether_header *eh = (struct ether_header *) displayData[i];
memcpy(&(eh->ether_shost[0]),macComputer,6);
memcpy(&(eh->ether_dhost[0]),macCard,6);
/* Ethertype field */
eh->ether_type = htons(0x5500);
memcpy(&(displayData[i][14]),dataPack5500,7);
displayData[i][14]=i&0xFF;
displayData[i][13]=(i>>8)&0xFF;
memset(&(displayData[i][14+7]),0,LEDWIDTH*3);
}
}
bool ofDriver5A75B::initialize(){
struct ifreq if_idx;
char ifName[IFNAMSIZ];
/* Get interface name */
strcpy(ifName, DEFAULT_IF);
/* Open RAW socket to send on */
if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) {
perror("socket");
printf("Maybe you forget sudo?\n");
return false;
}
/* Get the index of the interface to send on */
memset( & if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFINDEX, & if_idx) < 0){
perror("SIOCGIFINDEX");
return false;
}
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
return true;
}
bool ofDriver5A75B::sendAllPackets(){
bool allRight = true;
int i;
sendto(sockfd, bufEthType0101, sizeof(bufEthType0101), 0, (struct sockaddr * ) & socket_address, sizeof(struct sockaddr_ll));
sendto(sockfd, bufEthType0aff, sizeof(bufEthType0aff), 0, (struct sockaddr * ) & socket_address, sizeof(struct sockaddr_ll));
int dataLen = sizeof(displayData[0]);
for (i=0;i<LEDHEIGHT;i++){
if (sendto(sockfd, displayData[i], dataLen, 0, (struct sockaddr * ) & socket_address, sizeof(struct sockaddr_ll)) <0) allRight=false;
}
return allRight;
}
void ofDriver5A75B::updateFrame(unsigned char* pixelBuffer, int width, int height, int bytesPerPixel){
unsigned char* readPtr = pixelBuffer;
int i;
if (bytesPerPixel == 3){
for (i=0;i<LEDHEIGHT;i++){
memcpy(&(displayData[i][14+7]),readPtr,LEDWIDTH*3);
readPtr += width*3;
}
}
}
#ifndef __ofDriver5A75B_h__
#define __ofDriver5A75B_h__
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <unistd.h>
//ip link show
#ifdef __ARM_ARCH
#define DEFAULT_IF "eth0"
#else
#define DEFAULT_IF "eth1"
#endif
#define MAC_CARD 0x11,0x22,0x33,0x44,0x55,0x66
#define MAC_COMPUTER 0x22,0x22,0x33,0x44,0x55,0x66
#define LEDWIDTH 64
#define LEDHEIGHT 384
class ofDriver5A75B {
public:
ofDriver5A75B();
bool initialize();
bool sendAllPackets();
void updateFrame(unsigned char* pixelBuffer, int width, int height, int bytesPerPixel);
private:
int sockfd;
struct sockaddr_ll socket_address;
unsigned char macCard[6] = {MAC_CARD};
unsigned char macComputer[6] = {MAC_COMPUTER};
unsigned char displayData[LEDHEIGHT][14+7+LEDWIDTH*3];
unsigned char bufEthType0101[112] = {MAC_CARD,MAC_COMPUTER, 0x01,0x01};
unsigned char bufEthType0aff[77] = {MAC_CARD,MAC_COMPUTER, 0x0a,0xff, 0xff,0xff,0xff};
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment