Skip to content

Commit

Permalink
Changes from working on the SoMs. Mostly old.
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter O'Hanley committed May 10, 2018
1 parent f43b208 commit b6b8b81
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 25 deletions.
1 change: 1 addition & 0 deletions 99-spidev-open.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
KERNEL=="spidev0.0", OWNER="amm"
2 changes: 1 addition & 1 deletion config.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#include <stdint.h>
typedef uint16_t uint_16;
typedef uint8_t uint_8;
typedef uint8_t uint_8;
23 changes: 23 additions & 0 deletions sock_spi_bridge/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
all: sock_spi_bridge sock_spi_test_client

sock_spi_bridge: sock_spi_bridge.c
gcc -Wall -o sock_spi_bridge sock_spi_bridge.c

sock_spi_test_client: sock_spi_test_client.c libspiproto.a ../spi_proto.h
gcc -Wall -o sock_spi_test_client sock_spi_test_client.c -L. -lspiproto

clean:
rm -f sock_spi_bridge sock_spi_test_client spi_forwarding_server
rm -f libspiproto.a
rm -f spi_proto.o crc16.o

spi_proto.o: spi_proto.c spi_proto.h
gcc -c spi_proto.c

crc16.o: crc16.c
gcc -c crc16.c

libspiproto.a: spi_proto.o crc16.o
ar rc libspiproto.a spi_proto.o crc16.o
ranlib libspiproto.a

135 changes: 135 additions & 0 deletions sock_spi_bridge/sock_spi_bridge.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//spi forwarder program
//runs as root, opens a unix socket and listens on it for fixed-length messages
//opens one SPI fd, configurable (this is the only configuration, recompile to change length)

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <sys/socket.h>
#include <sys/un.h>

#define TRANSFER_SIZE 36

static const char *device = "/dev/spidev0.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 8388608U; // TODO
static uint16_t delay;

static void pabort(const char *s)
{
perror(s);
abort();
}

static void transfer(int fd, uint8_t *sendbuf, uint8_t *rcvbuf)
{
int ret;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)sendbuf,
.rx_buf = (unsigned long)rcvbuf,
.len = TRANSFER_SIZE,
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};

ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
//TODO better error handling i.e. don't just crash
if (ret < 1)
pabort("can't send spi message");

}

int
setup_spi_params(int fd)
{
int ret;
/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode");

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode");

/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word");

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word");

/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz");

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz");

printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
}

int main(int argc, char **argv)
{
int spi_fd = open(device, O_RDWR);
if (spi_fd < 0) {
pabort("unable to open SPI device"); // TODO maybe print more info like which one
}
//TODO acquire the SPI fd and do all IO settings first -- that seems more likely to fail
setup_spi_params(spi_fd);

int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); // TODO confirm param choices
if (sock_fd == -1) {
//TODO report error message and fail
}

struct sockaddr_un saddr = { AF_UNIX, "spi_forwarding_server"};
bind(sock_fd, (struct sockaddr *)&saddr, sizeof(saddr));

listen(sock_fd, 1); //only talk to one other guy. maybe should be 0?

int conn_fd = accept(sock_fd, NULL, NULL);

while (1) {
uint8_t send_msg[TRANSFER_SIZE];
uint8_t rcv_msg[TRANSFER_SIZE];
//TODO continuously read until we have the full packet in case it's not the full size
ssize_t amt_read = read(conn_fd, send_msg, TRANSFER_SIZE);
if (amt_read >= 0) {
printf("got the folling over the unix socket:\n");
for (int i = 0; i < amt_read; i++) {
printf("%02x", send_msg[i]);
}
printf("\n");
}
transfer(spi_fd, send_msg, rcv_msg);

//TODO do an SPI transaction

write(conn_fd, rcv_msg, TRANSFER_SIZE);
}

//TODO maybe write some closing logic or something
close(spi_fd);
close(conn_fd);
}
103 changes: 103 additions & 0 deletions sock_spi_bridge/sock_spi_test_client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <stdint.h>
#include <time.h>

#include "../spi_proto.h"

#define TRANSFER_SIZE 36
#define SPI_TRANSFER_LEN TRANSFER_SIZE

void
print_bytes(char *c, int n, int breaklen)
{
if (!c) return;
for (int i = 0; i < n; i++) {
printf("%02x", c[i]);
if (i % breaklen == (breaklen-1)) {
printf("\n");
} else {
printf(" ");
}
}
puts("");
}

void
linux_test_callback(struct spi_packet *p)
{
print_bytes((char *) p, sizeof(struct spi_packet), 12);
}
int
main(int argc, char *argv[])
{
int sock;
int conn;

struct sockaddr_un saddr = {AF_UNIX, "spi_forwarding_server"};

sock = socket(AF_UNIX, SOCK_STREAM, 0);

conn = connect(sock, (struct sockaddr *)&saddr, sizeof(saddr));

if (conn) {
perror("connect didn't work");
abort();
}
struct timespec time_1ms;
time_1ms.tv_sec = 0;
time_1ms.tv_nsec = 1*1000000;//1 * 1ms

char recvbuf[TRANSFER_SIZE];
char sendbuf[TRANSFER_SIZE] = {};
struct spi_state s;
spi_proto_initialize(&s);
int send_on_or_off = 0;
char on_msg[3] = {0x01, 0x01, 0x01};
int on_msg_len = 3;
char off_msg[3] = {0x01, 0x01, 0x00};
int off_msg_len = 3;
while (1) {
if (send_on_or_off) {
spi_proto_send_msg(&s, on_msg, on_msg_len);
} else {
spi_proto_send_msg(&s, off_msg, off_msg_len);
}
send_on_or_off ^= 1;

//message sending
int ret = spi_proto_prep_msg(&s, sendbuf, SPI_TRANSFER_LEN);
printf("spi_proto_prep_msg ret: %d\n", ret);

//edbug output
puts("sending");
print_bytes(sendbuf, SPI_TRANSFER_LEN,12);

//do transaction
//transfer(spi_fd);
write(sock, sendbuf, TRANSFER_SIZE);
nanosleep(&time_1ms, NULL);
int amt_read = read(sock, recvbuf, TRANSFER_SIZE);
printf("amt_read = %d\n", amt_read);

//process buffer into struct
struct spi_packet pack;
memcpy(&pack, recvbuf, SPI_TRANSFER_LEN);
//TODO maybe fixup the CRC byte order?

//process received message
spi_proto_rcv_msg(&s, &pack, linux_test_callback);

print_spi_state(&s);
puts("received the following over the socket:");
print_bytes(recvbuf, TRANSFER_SIZE, 16);
}

return 0;
}
6 changes: 6 additions & 0 deletions spi_linux_test_endpoint/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
linux_test_end: linux_test_end.c ../spi_proto.h ../spi_proto.c ../crc16.c
gcc -o linux_test_end linux_test_end.c ../spi_proto.c ../crc16.c -std=c99

clean:
rm linux_test_end

31 changes: 22 additions & 9 deletions linux_test_end.c → spi_linux_test_endpoint/linux_test_end.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <time.h>

#include <string.h>
#include "spi_proto.h"
#include "../spi_proto.h"

#define SPI_TRANSFER_LEN sizeof(struct spi_packet)

Expand Down Expand Up @@ -59,7 +60,7 @@ static void transfer(int fd)
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pabort("can't send spi message");

return;
for (ret = 0; ret < ARRAY_SIZE(spi_out_buf); ret++) {
if (!(ret % 12))
puts("");
Expand Down Expand Up @@ -201,12 +202,17 @@ int main(int argc, char *argv[])
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

//struct timespec time_100ms;
//time_100ms.tv_sec = 0;
//time_100ms.tv_nsec = 1*1000000;//10 * 1ms

//time_100ms.tv_nsec = 1*5;//10 * 1ms
struct spi_state s;
spi_proto_initialize(&s);
first_loop();
for (int i = 0; i < 3; i++) {
for (;;){//(int i = 0; i < 500; i++) {
loop(&s, fd);
sleep(1);
//nanosleep(&time_100ms, NULL);
}
//transfer(fd);

Expand All @@ -218,6 +224,12 @@ int main(int argc, char *argv[])
void
linux_test_callback(struct spi_packet *p)
{
if (!p->msg[0]) return;
char strbuf[33];
memcpy(strbuf, p->msg, 32);
strbuf[32] = 0;
printf("got msg:[ %s ]\n", strbuf);
return;
//TODO print it out or something
uint8_t *s = (uint8_t *) p;
for (int i = 0; i < sizeof(struct spi_packet);i++)
Expand Down Expand Up @@ -259,8 +271,8 @@ loop(struct spi_state *s, int spi_fd)
spi_proto_prep_msg(s, spi_out_buf, SPI_TRANSFER_LEN);

//edbug output
puts("sending");
print_bytes(spi_out_buf, SPI_TRANSFER_LEN);
//puts("sending");
// print_bytes(spi_out_buf, SPI_TRANSFER_LEN);

//do transaction
transfer(spi_fd);
Expand All @@ -271,7 +283,8 @@ loop(struct spi_state *s, int spi_fd)
//TODO maybe fixup the CRC byte order?

//process received message
//puts("before rcv_msg");
spi_proto_rcv_msg(s, &pack, linux_test_callback);

print_spi_state(s);
}
//puts("after rcv_msg");
// print_spi_state(s);
}
12 changes: 10 additions & 2 deletions spi_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
//Queue is 16 so that all seq and ack values are valid indexes
#define SPI_MSG_QUEUE_SIZE 16

#ifdef CPP
extern "C" {
#endif

struct __attribute__((packed)) spi_packet {
uint8_t magic; // includes at least a version number
uint8_t seq : 4;
Expand Down Expand Up @@ -62,11 +66,15 @@ void
print_spi_packet(struct spi_packet *p);

void
spi_proto_rcv_msg(struct spi_state *s, struct spi_packet *p, , spi_msg_callback_t cb);
spi_proto_rcv_msg(struct spi_state *s, struct spi_packet *p, spi_msg_callback_t cb);
int
spi_proto_prep_msg(struct spi_state *s, void *buf, int n);
int
spi_proto_send_msg(struct spi_state *s, void *buf, int n);

uint16_t
spi_msg_crc(struct spi_packet *p);
spi_msg_crc(struct spi_packet *p);

#ifdef CPP
} // extern C
#endif
Loading

0 comments on commit b6b8b81

Please sign in to comment.