summaryrefslogtreecommitdiffstats
path: root/servers/fpga_server_lin/src/fpga_conn.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-01-10 02:58:09 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-01-10 02:58:09 -0600
commit4436bddc8ceecb5277de73de6c929a3bb6722143 (patch)
tree1fc6dde36e5339cd3d1e2f669facc01c9bdaede5 /servers/fpga_server_lin/src/fpga_conn.cpp
parent4123289a7a118ab922a815e3c216e3d6fe306d88 (diff)
downloadulab-4436bddc8ceecb5277de73de6c929a3bb6722143.tar.gz
ulab-4436bddc8ceecb5277de73de6c929a3bb6722143.zip
Add GPMC interface to FPGA server
Diffstat (limited to 'servers/fpga_server_lin/src/fpga_conn.cpp')
-rw-r--r--servers/fpga_server_lin/src/fpga_conn.cpp213
1 files changed, 183 insertions, 30 deletions
diff --git a/servers/fpga_server_lin/src/fpga_conn.cpp b/servers/fpga_server_lin/src/fpga_conn.cpp
index fdd54fd..a20cad9 100644
--- a/servers/fpga_server_lin/src/fpga_conn.cpp
+++ b/servers/fpga_server_lin/src/fpga_conn.cpp
@@ -35,6 +35,7 @@
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <math.h>
#include <tqtimer.h>
@@ -42,6 +43,8 @@
#include "fpga_conn.h"
+#include "bbb-gpmc-init.h"
+
#define FLUSH_IN 0
#define FLUSH_OUT 1
#define FLUSH_BOTH 2
@@ -137,9 +140,29 @@ void FPGASocket::finishKerberosHandshake() {
close();
return;
}
- if (setupSerial() != 0) {
+ m_config->setGroup("FPGA");
+ m_interfaceType = m_config->readEntry("interface", "serial");
+ if (m_interfaceType == "serial") {
+ if (setupSerial() != 0) {
+ if (enableDebug) {
+ printf("[DEBUG] Connection from %s closed due to serial port initialization failure\n\r", m_remoteHost.ascii()); fflush(stdout);
+ }
+ close();
+ return;
+ }
+ }
+ else if (m_interfaceType == "gpmc") {
+ if (setupGPMC() != 0) {
+ if (enableDebug) {
+ printf("[DEBUG] Connection from %s closed due to GPMC initialization failure\n\r", m_remoteHost.ascii()); fflush(stdout);
+ }
+ close();
+ return;
+ }
+ }
+ else {
if (enableDebug) {
- printf("[DEBUG] Connection from %s closed due to serial port initialization failure\n\r", m_remoteHost.ascii()); fflush(stdout);
+ printf("[DEBUG] Connection from %s closed due to incorrect interface type specification in configuration file\n\r", m_remoteHost.ascii()); fflush(stdout);
}
close();
return;
@@ -212,6 +235,40 @@ int FPGASocket::setupSerial() {
return 0;
}
+int FPGASocket::setupGPMC() {
+ int i;
+ int ret;
+
+ m_stateTXRequested = false;
+ m_stateImageRXRequested = false;
+ m_stateImageTXRequested = false;
+
+ ret = setup_gpmc_bbb();
+ if (ret == 0) {
+ // Verify attached uLab hardware model and version
+ unsigned char model = read_gpmc(0x00);
+ unsigned char version = read_gpmc(0x01);
+ if ((model != 0x42) || (version < 1)) {
+ printf("A compatible uLab hardware debug interface was not detected! Please verify your configuration.\n");
+ return -1;
+ }
+ printf("[DEBUG] Detected a compatible uLab hardware debug interface (model number 0x%02x, firmware version 0x%02x)\n", model, version);
+
+ // Clear out DSP and LCD RAM
+ unsigned char dsp_ram_bits = read_gpmc(0x0b);
+ unsigned int dsp_ram_offset = (1 << dsp_ram_bits);
+ unsigned int dsp_ram_size = (1 << dsp_ram_bits);
+ for (i=0; i<dsp_ram_size; i++) {
+ write_gpmc(dsp_ram_offset + i, 0x00);
+ }
+ for (i=0; i<32; i++) {
+ write_gpmc(0x20 + i, 0x00);
+ }
+ }
+
+ return 0;
+}
+
void FPGASocket::commandLoop() {
int cc;
int ret;
@@ -222,39 +279,135 @@ void FPGASocket::commandLoop() {
try {
transferred_data = false;
if (state() == TQSocket::Connected) {
- cc = read(m_fd_tty, buffer, 1024);
- if (cc > 0) {
- writeBlock(buffer, cc);
- flush();
- transferred_data = true;
- if (enableDebug) {
- printf("[DEBUG] Got %d bytes from the serial port\n\r", cc); fflush(stdout);
- }
- }
- if (canReadData()) {
- cc = readBlock(buffer, 1024);
+ if (m_interfaceType == "serial") {
+ cc = read(m_fd_tty, buffer, 1024);
if (cc > 0) {
- ret = write(m_fd_tty, buffer, cc);
-
- // HACK
- // This works around a buffer overflow on FTDI serial devices
- // It may not be sufficient for baudrates less than 115200!
- if (cc > 128) {
- usleep(100000);
+ writeBlock(buffer, cc);
+ flush();
+ transferred_data = true;
+ if (enableDebug) {
+ printf("[DEBUG] Got %d bytes from the serial port\n\r", cc); fflush(stdout);
}
-
- while ((ret < 0) && (errno == EAGAIN)) {
- usleep(1000);
+ }
+ if (canReadData()) {
+ cc = readBlock(buffer, 1024);
+ if (cc > 0) {
ret = write(m_fd_tty, buffer, cc);
+
+ // HACK
+ // This works around a buffer overflow on FTDI serial devices
+ // It may not be sufficient for baudrates less than 115200!
+ if (cc > 128) {
+ usleep(100000);
+ }
+
+ while ((ret < 0) && (errno == EAGAIN)) {
+ usleep(1000);
+ ret = write(m_fd_tty, buffer, cc);
+ }
+ if (ret < 0) {
+ // ERROR
+ printf("[ERROR] Failed to transmit data to serial port (%s, code %d)! Continuing, but data was likely lost\n\r", strerror(errno), errno); fflush(stdout);
+ }
+ ioctl(m_fd_tty, TCFLSH, FLUSH_OUT);
+ transferred_data = true;
+ if (enableDebug) {
+ printf("[DEBUG] Got %d bytes from the network interface\n\r", cc); fflush(stdout);
+ }
}
- if (ret < 0) {
- // ERROR
- printf("[ERROR] Failed to transmit data to serial port (%s, code %d)! Continuing, but data was likely lost\n\r", strerror(errno), errno); fflush(stdout);
+ }
+ }
+ else if (m_interfaceType == "gpmc") {
+ if (m_stateImageTXRequested) {
+ if (read_gpmc(0x0a) & 0x02) {
+ m_stateImageTXRequested = false;
+
+ // Transmit image back to client
+ unsigned char dsp_ram_bits = read_gpmc(0x0b);
+ unsigned int dsp_ram_size = (1 << dsp_ram_bits);
+ unsigned int dsp_ram_offset = (1 << dsp_ram_bits);
+ TQByteArray dataToSend(dsp_ram_size);
+ memcpy_from_gpmc(dataToSend.data(), dsp_ram_offset, dsp_ram_size);
+ int offset = 0;
+ while (offset <= dsp_ram_size) {
+ writeBlock(dataToSend.data()+offset, 1024);
+ writeBufferedData();
+ offset = offset + 1024;
+ }
}
- ioctl(m_fd_tty, TCFLSH, FLUSH_OUT);
- transferred_data = true;
- if (enableDebug) {
- printf("[DEBUG] Got %d bytes from the network interface\n\r", cc); fflush(stdout);
+ }
+ else if (m_stateTXRequested) {
+ m_stateTXRequested = false;
+
+ char data[42];
+
+ // Read state data from memory map and assemble a reply
+ memcpy_from_gpmc(data+0, 0x20, 0x1f); // LCD display
+ data[32] = 1; // Input mode (locked to Remote)
+ data[33] = read_gpmc(0x0b); // Number of address bits of DSP RAM
+ data[34] = read_gpmc(0x02); // 4-bit LEDs
+ data[35] = read_gpmc(0x03); // 8-bit LEDs
+ data[36] = read_gpmc(0x04); // 16-bit LEDs (upper byte)
+ data[37] = read_gpmc(0x05); // 16-bit LEDs (lower byte)
+ memcpy_from_gpmc(data+38, 0x06, 0x04); // 7-segment LED display
+
+ writeBlock(data, 42);
+ writeBufferedData();
+ }
+ if (canReadData()) {
+ int read_offset = 0;
+ cc = readBlock(buffer, 1024);
+ if (cc > 0) {
+ if (m_stateImageRXRequested) {
+ unsigned char dsp_ram_bits = read_gpmc(0x0b);
+ unsigned int dsp_ram_offset = (1 << dsp_ram_bits);
+ unsigned int dsp_ram_size = (1 << dsp_ram_bits);
+
+ memcpy_to_gpmc(buffer, (dsp_ram_offset + m_stateImageRXCounter), cc);
+
+ m_stateImageRXCounter = m_stateImageRXCounter + cc;
+ if (m_stateImageRXCounter >= dsp_ram_size) {
+ m_stateImageRXRequested = false;
+ m_stateImageTXRequested = true;
+ }
+ }
+ else {
+ // Parse and write state data to the memory map
+ while (read_offset < cc) {
+ if (buffer[read_offset+0] == 'M') {
+ // Receive image data and store in FPGA memory
+ m_stateImageRXRequested = true;
+ m_stateImageTXRequested = false;
+ m_stateImageRXCounter = 0;
+ read_offset = read_offset + 2;
+ }
+ else if (buffer[read_offset+0] == 'L') {
+ m_stateTXRequested = true;
+ read_offset = read_offset + 2;
+ }
+ else if (buffer[read_offset+0] == 'I') {
+ write_gpmc(0x02, buffer[read_offset+2]);
+ read_offset = read_offset + 4;
+ }
+ else if (buffer[read_offset+0] == 'B') {
+ write_gpmc(0x03, buffer[read_offset+2]);
+ read_offset = read_offset + 4;
+ }
+ else if (buffer[read_offset+0] == 'C') {
+ write_gpmc(0x04, buffer[read_offset+2]);
+ write_gpmc(0x05, buffer[read_offset+4]);
+ read_offset = read_offset + 6;
+ }
+ }
+ if (m_stateImageTXRequested) {
+ m_stateImageTXRequested = false;
+ }
+ }
+
+ transferred_data = true;
+ if (enableDebug) {
+ printf("[DEBUG] Got %d bytes from the network interface\n\r", cc); fflush(stdout);
+ }
}
}
}