Browse Source

SPIDriver port running

James Bowman 1 year ago
parent
commit
d85a0679d5
7 changed files with 366 additions and 7 deletions
  1. 7 3
      GD2.cpp
  2. 5 2
      GD2.h
  3. 5 2
      pc/SPI.h
  4. 15 0
      pc/main.cpp
  5. 173 0
      pc/spidriver.cpp
  6. 27 0
      pc/spidriver.h
  7. 134 0
      transports/tr-spidriver.h

+ 7 - 3
GD2.cpp

@@ -27,7 +27,7 @@
 #define CALIBRATION   1                 // Want touchscreen?
 
 // FTDI boards do not have storage
-#if (BOARD == BOARD_FTDI_80x)
+#if (BOARD == BOARD_FTDI_80x) || defined(RASPBERRY_PI) || defined(DUMPDEV) || defined(SPIDRIVER)
 #undef STORAGE
 #define STORAGE 0
 #endif
@@ -59,6 +59,10 @@ byte ft8xx_model;
 #include "transports/wiring.h"
 #endif
 
+#if defined(SPIDRIVER)
+#include "transports/tr-spidriver.h"
+#endif
+
 ////////////////////////////////////////////////////////////////////////
 
 void xy::set(int _x, int _y)
@@ -511,7 +515,7 @@ void GDClass::tune(void)
 }
 
 void GDClass::begin(uint8_t options) {
-#if defined(ARDUINO) || defined(ESP8266)
+#if defined(ARDUINO) || defined(ESP8266) || defined(SPIDRIVER)
   GDTR.begin0();
 
   if (STORAGE && (options & GD_STORAGE)) {
@@ -1494,7 +1498,7 @@ void GDClass::reset() {
 
 byte GDClass::load(const char *filename, void (*progress)(long, long))
 {
-#if defined(RASPBERRY_PI) || defined(DUMPDEV)
+#if defined(RASPBERRY_PI) || defined(DUMPDEV) || defined(SPIDRIVER)
   char full_name[2048]  = "sdcard/";
   strcat(full_name, filename);
   FILE *f = fopen(full_name, "rb");

+ 5 - 2
GD2.h

@@ -1072,8 +1072,11 @@ typedef struct {
 #define REG_VSYNC1            (ft8xx_model ? 0x302050UL : 0x10244cUL)
 #define FONT_ROOT             (ft8xx_model ? 0x2ffffcUL : 0x0ffffcUL)
 
-#define REG_MEDIAFIFO_READ    0x309014
-#define REG_MEDIAFIFO_WRITE   0x309018
+// FT81x only registers
+#define REG_CMDB_SPACE                       0x302574UL
+#define REG_CMDB_WRITE                       0x302578UL
+#define REG_MEDIAFIFO_READ                   0x309014UL
+#define REG_MEDIAFIFO_WRITE                  0x309018UL
 
 #define VERTEX2II(x, y, handle, cell) \
         ((2UL << 30) | (((x) & 511UL) << 21) | (((y) & 511UL) << 12) | (((handle) & 31) << 7) | (((cell) & 127) << 0))

+ 5 - 2
pc/SPI.h

@@ -70,8 +70,9 @@ class _SPI {
     void begin() {
     }
     uint8_t transfer(uint8_t c) {
-      uint8_t r = spix(c);
-      return r;
+      assert(0);
+      // uint8_t r = spix(c);
+      return 0;
     }
     uint8_t transfer(uint8_t *m, size_t c) {
       assert(0);
@@ -150,4 +151,6 @@ typedef const unsigned long prog_uint32_t;
 
 #define highByte(x) ((x) >> 8)
 #define lowByte(x) ((x) & 255)
+#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
 
+long map(long x, long in_min, long in_max, long out_min, long out_max);

+ 15 - 0
pc/main.cpp

@@ -0,0 +1,15 @@
+long map(long x, long in_min, long in_max, long out_min, long out_max)
+{
+  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+extern void setup(void);
+extern void loop(void);
+
+int main()
+{
+   setup();
+   for (;;)
+     loop();
+   return 0;
+}

+ 173 - 0
pc/spidriver.cpp

@@ -0,0 +1,173 @@
+#include <stdio.h>
+#include <assert.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+#include <errno.h>
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
+#include "spidriver.h"
+
+// ****************************   Serial port  ********************************
+
+int openSerialPort(const char *portname)
+{
+  int fd = open(portname, O_RDWR | O_NOCTTY);
+  if (fd == -1)
+    perror(portname);
+
+  struct termios Settings;
+
+  tcgetattr(fd, &Settings);
+
+  cfsetispeed(&Settings, B460800);
+  cfsetospeed(&Settings, B460800);
+
+  Settings.c_cflag &= ~PARENB;
+  Settings.c_cflag &= ~CSTOPB;
+  Settings.c_cflag &= ~CSIZE;
+  Settings.c_cflag &= ~CRTSCTS;
+  Settings.c_cflag |=  CS8;
+  Settings.c_cflag |=  CREAD | CLOCAL;
+
+  Settings.c_iflag &= ~(IXON | IXOFF | IXANY);
+  Settings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+
+  Settings.c_oflag &= ~OPOST;
+
+  Settings.c_cc[VMIN] = 1;
+
+  if (tcsetattr(fd, TCSANOW, &Settings) != 0)
+    perror("Serial settings");
+
+  return fd;
+}
+
+size_t readFromSerialPort(int fd, char *b, size_t s)
+{
+  size_t n, t;
+  t = 0;
+  while (t < s) {
+    n = read(fd, b + t, s);
+    t += n;
+  }
+#ifdef VERBOSE
+  printf(" READ %d %d: ", (int)s, int(n));
+  for (int i = 0; i < s; i++)
+    printf("%02x ", 0xff & b[i]);
+  printf("\n");
+#endif
+  return s;
+}
+
+void writeToSerialPort(int fd, const char *b, size_t s)
+{
+  write(fd, b, s);
+#ifdef VERBOSE
+  printf("WRITE %u: ", (int)s);
+  for (int i = 0; i < s; i++)
+    printf("%02x ", 0xff & b[i]);
+  printf("\n");
+#endif
+}
+
+// ******************************  SPIDriver  *********************************
+
+void spi_connect(SPIDriver *sd, const char* portname)
+{
+  sd->port = openSerialPort(portname);
+  writeToSerialPort(sd->port, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", 64);
+  for (int i = 0; i < 256; i++) {
+    char tx[2] = {'e', i};
+    writeToSerialPort(sd->port, tx, 2);
+    char rx[1];
+    readFromSerialPort(sd->port, rx, 1);
+    if ((rx[0] & 0xff) != i)
+      assert(0);
+  }
+  printf("\n");
+  spi_getstatus(sd);
+}
+
+void spi_getstatus(SPIDriver *sd)
+{
+  char readbuffer[100];
+  int bytesRead;
+
+  writeToSerialPort(sd->port, "?", 1);
+  bytesRead = readFromSerialPort(sd->port, readbuffer, 80);
+  readbuffer[bytesRead] = 0;
+  // printf("%d Bytes were read: %.*s\n", bytesRead, bytesRead, readbuffer);
+  sscanf(readbuffer, "[%15s %8s %" SCNu64 " %f %f %f %d %d %d %x ]",
+    sd->model,
+    sd->serial,
+    &sd->uptime,
+    &sd->voltage_v,
+    &sd->current_ma,
+    &sd->temp_celsius,
+    &sd->a,
+    &sd->b,
+    &sd->cs,
+    &sd->debug
+    );
+}
+
+void spi_sel(SPIDriver *sd)
+{
+  writeToSerialPort(sd->port, "s", 1);
+  sd->cs = 0;
+}
+
+void spi_unsel(SPIDriver *sd)
+{
+  writeToSerialPort(sd->port, "u", 1);
+  sd->cs = 1;
+}
+
+void spi_seta(SPIDriver *sd, char v)
+{
+  char cmd[2] = {'a', v};
+  writeToSerialPort(sd->port, cmd, 2);
+  sd->a = v;
+}
+
+void spi_setb(SPIDriver *sd, char v)
+{
+  char cmd[2] = {'b', v};
+  writeToSerialPort(sd->port, cmd, 2);
+  sd->b = v;
+}
+
+void spi_write(SPIDriver *sd, size_t nn, const char bytes[])
+{
+  for (size_t i = 0; i < nn; i += 64) {
+    size_t len = ((nn - i) < 64) ? (nn - i) : 64;
+    char cmd[65] = {(char)(0xc0 + len - 1)};
+    memcpy(cmd + 1, bytes + i, len);
+    writeToSerialPort(sd->port, cmd, 1 + len);
+  }
+}
+
+void spi_read(SPIDriver *sd, size_t nn, char bytes[])
+{
+  for (size_t i = 0; i < nn; i += 64) {
+    size_t len = ((nn - i) < 64) ? (nn - i) : 64;
+    char cmd[65] = {(char)(0x80 + len - 1), 0};
+    writeToSerialPort(sd->port, cmd, 1 + len);
+    readFromSerialPort(sd->port, bytes + i, len);
+  }
+}
+
+void spi_writeread(SPIDriver *sd, size_t nn, char bytes[])
+{
+  for (size_t i = 0; i < nn; i += 64) {
+    size_t len = ((nn - i) < 64) ? (nn - i) : 64;
+    char cmd[65] = {(char)(0x80 + len - 1)};
+    memcpy(cmd + 1, bytes + i, len);
+    writeToSerialPort(sd->port, cmd, 1 + len);
+    readFromSerialPort(sd->port, bytes + i, len);
+  }
+}
+

+ 27 - 0
pc/spidriver.h

@@ -0,0 +1,27 @@
+#ifndef SPIDRIVER_H
+#define SPIDRIVER_H
+
+#include <stdint.h>
+
+#define HANDLE int
+
+typedef struct {
+  HANDLE port;
+  char model[16], serial[9];
+  uint64_t uptime;
+  float voltage_v, current_ma, temp_celsius;
+  unsigned int a, b, cs;
+  unsigned int debug;
+} SPIDriver;
+
+void spi_connect(SPIDriver *sd, const char* portname);
+void spi_getstatus(SPIDriver *sd);
+void spi_sel(SPIDriver *sd);
+void spi_unsel(SPIDriver *sd);
+void spi_seta(SPIDriver *sd, char v);
+void spi_setb(SPIDriver *sd, char v);
+void spi_write(SPIDriver *sd, size_t nn, const char bytes[]);
+void spi_read(SPIDriver *sd, size_t nn, char bytes[]);
+void spi_writeread(SPIDriver *sd, size_t nn, char bytes[]);
+
+#endif

+ 134 - 0
transports/tr-spidriver.h

@@ -0,0 +1,134 @@
+#include "spidriver.h"
+
+class GDTransport {
+  SPIDriver sd;
+  uint16_t space;
+
+public:
+  void begin0(void) {
+    spi_connect(&sd, "/dev/ttyUSB0");
+
+    hostcmd(0x42);    // SLEEP
+    hostcmd(0x61);    // CLKSEL default
+    hostcmd(0x00);    // ACTIVE
+    hostcmd(0x48);    // CLKINT
+    hostcmd(0x49);    // PD_ROMS all up
+    hostcmd(0x68);    // RST_PULSE
+    ft8xx_model = 1;
+  }
+  void begin1(void) {
+    while ((__rd16(0xc0000UL) & 0xff) != 0x08)
+      ;
+    stream();
+  }
+  void ios(void) {}
+  void external_crystal() {
+    __end();
+    hostcmd(0x44);
+  }
+  void cmdbyte(char x) {
+    getspace(1);
+    spi_write(&sd, 1, &x);
+  }
+  void cmd32(uint32_t x) {
+    getspace(4);
+    spi_write(&sd, 4, (char*)&x);
+  }
+  void cmd_n(byte *s, size_t n) {
+    getspace(n);
+    spi_write(&sd, n, (char*)s);
+  }
+  void hostcmd(uint8_t a)
+  {
+    char buf[3] = {a, 0, 0};
+    spi_sel(&sd);
+    spi_write(&sd, 3, buf);
+    spi_unsel(&sd);
+  }
+
+  uint16_t rd16(uint32_t a) {
+    __end();
+    uint16_t r = __rd16(a);
+    stream();
+    return r;
+  }
+  void wr16(uint32_t a, uint16_t v) {
+    __end();
+    __wr16(a, v);
+    stream();
+  }
+  uint8_t rd(uint32_t a) {
+    return rd16(a);
+  }
+  void wr(uint32_t a, byte v)
+  {
+    __end();
+    char buf[4] = {(a >> 16) | 0x80, a >> 8, a, v};
+    spi_sel(&sd);
+    spi_write(&sd, sizeof(buf), buf);
+    spi_unsel(&sd);
+    stream();
+  }
+
+  void __end() {
+    spi_unsel(&sd);
+  }
+  void stream(void) {
+    __end();
+    space = __rd16(REG_CMDB_SPACE);
+    __wstart(REG_CMDB_WRITE);
+  }
+  void resume(void) {
+    stream();
+  }
+  void getspace(uint16_t n) {
+    while (space < n) {
+      __end();
+      stream();
+    }
+    space -= n;
+  }
+  uint32_t getwp(void) {
+    assert(0);
+  }
+  uint32_t rd32(uint32_t a) { return 0xff; }
+  void rd_n(byte *dst, uint32_t a, uint16_t n) {
+    __end();
+    char buf[4] = {a >> 16, a >> 8, a, 0xff};
+    spi_sel(&sd);
+    spi_write(&sd, sizeof(buf), buf);
+    spi_read(&sd, n, (char*)dst);
+    spi_unsel(&sd);
+    stream();
+  }
+  void wr32(uint32_t a, uint32_t v) { }
+  void flush() {
+  }
+  void finish() {
+    getspace(4092);
+  }
+  void bulk(uint32_t addr) {}
+
+  unsigned int __wstart(uint32_t a) {
+    char buf[3] = {0x80 | (a >> 16), a >> 8, a};
+    spi_sel(&sd);
+    spi_write(&sd, sizeof(buf), buf);
+  }
+
+  unsigned int __rd16(uint32_t a) {
+    char buf[6] = {a >> 16, a >> 8, a, 0xff, 0xff, 0xff};
+    spi_sel(&sd);
+    spi_writeread(&sd, sizeof(buf), buf);
+    spi_unsel(&sd);
+    return *(uint16_t*)&buf[4];
+  }
+
+  void __wr16(uint32_t a, unsigned int v) {
+    char buf[5] = {(a >> 16) | 0x80, a >> 8, a, v, v >> 8};
+    spi_sel(&sd);
+    spi_write(&sd, sizeof(buf), buf);
+    spi_unsel(&sd);
+  }
+  void stop() {} // end the SPI transaction
+  void wr_n(uint32_t addr, byte *src, uint16_t n) {}
+};