summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2019-01-27 11:13:14 -0500
committerSolomon Peachy <pizza@shaftnet.org>2019-01-27 11:13:14 -0500
commit12b88b73c32f7bd46bad21a2dd901f06589b0358 (patch)
tree9bd0072d687346df4777f0245a4ece90000d92c1
downloadaldl_pi-12b88b73c32f7bd46bad21a2dd901f06589b0358.tar.gz
aldl_pi-12b88b73c32f7bd46bad21a2dd901f06589b0358.tar.bz2
aldl_pi-12b88b73c32f7bd46bad21a2dd901f06589b0358.zip
Initial commit of WIP code
-rw-r--r--Makefile11
-rw-r--r--a179.c101
-rw-r--r--aldl.c48
-rw-r--r--aldl.h55
-rw-r--r--sdldash.c97
-rw-r--r--testpi.c49
6 files changed, 361 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f5bea60
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+FILES := $(wildcard *.c)
+#LDFLAGS := /usr/lib/libwiringPi.so.2
+CFLAGS := -Wall -lSDL2 -lSDL2_ttf
+
+all: testpi
+
+testpi: $(FILES)
+ gcc -o $@ $? $(LDFLAGS) $(CFLAGS)
+
+clean:
+ rm -f testpi
diff --git a/a179.c b/a179.c
new file mode 100644
index 0000000..e72f1ea
--- /dev/null
+++ b/a179.c
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "aldl.h"
+
+#define STREAM A179
+#define STREAM_WORDS 23
+#define VERSION 0
+
+static const int8_t A179_coolant_temp_table[] = {
+ [0] = 200,
+ [12] = 150,
+ [13] = 145,
+ [14] = 140,
+ [16] = 135,
+ [18] = 130,
+ [21] = 125,
+ [23] = 120,
+ [26] = 115,
+ [30] = 110,
+ [34] = 105,
+ [39] = 100,
+ [44] = 95,
+ [50] = 90,
+ [56] = 85,
+ [64] = 80,
+ [72] = 75,
+ [81] = 70,
+ [92] = 65,
+ [102] = 60,
+ [114] = 55,
+ [126] = 50,
+ [139] = 45,
+ [152] = 40,
+ [165] = 35,
+ [177] = 30,
+ [189] = 25,
+ [199] = 20,
+ [209] = 15,
+ [218] = 10,
+ [225] = 5,
+ [231] = 0,
+ [237] = -5,
+ [241] = -10,
+ [245] = -15,
+ [247] = -20,
+ [250] = -25,
+ [251] = -30,
+ [253] = -40,
+};
+
+void aldl_a179_callback(uint8_t *data, int datalen)
+{
+ printf("! %d\n", datalen); // XXX indicate!
+
+ /* Decode */
+ decoded.heartbeat = !decoded.heartbeat;
+
+// data[0]; // MW2
+ decoded.idling = data[0] & 0x80 ? (data[0] & 0x40 ? 1 : 2 ) : 0;
+ decoded.running = data[0] & 0x04;
+ decoded.driving = data[0] & 0x01;
+
+ decoded.prom_id = data[1] | (data[2] << 8);
+
+ decoded.iac_steps = data[3];
+ decoded.coolant_temp_c = A179_coolant_temp_table[data[4]];
+ decoded.mph = data[5];
+ decoded.map_v = (float)((int)data[6] * 5) / 255;
+ decoded.rpm = data[7] * 25;
+ decoded.tps_v = (float)((int)data[8] * 5) / 255;
+ decoded.base_fuel = data[9];
+ decoded.o2_v = (float)((int)data[10] * 1000) / 226 / 1000;
+
+ decoded.mil = data[11] | (data[12] << 8) | (data[13] << 16);
+
+// data[14]; // MWAF
+ decoded.learn_req = data[14] & 0x02;
+ decoded.closed_loop = data[14] & 0x80;
+ decoded.closed_loop_idle = data[14] & 0x10;
+ decoded.rich_lean = data[14] & 0x40;
+
+ decoded.battery_v = (float)data[15] / 10;
+
+// data[16]; // MCU2IO
+
+ decoded.overspeed = data[6] & 0x04;
+ decoded.shift_req = data[6] & 0x08;
+ decoded.neutral = data[6] & 0x10;
+ decoded.top_gear = data[6] & 0x20;
+ decoded.ac_request = data[6] & 0x80;
+
+ decoded.knock_count = data[17];
+ decoded.corr_fuel = data[18];
+ decoded.o2_transitions = data[19];
+ decoded.fuelp_v = (float)data[20] / 10;
+ decoded.idle_tgt = (float)data[21] * 12.5;
+ decoded.tp = (float)data[22] / 2.55;
+
+}
diff --git a/aldl.c b/aldl.c
new file mode 100644
index 0000000..ef38d97
--- /dev/null
+++ b/aldl.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "aldl.h"
+
+/* shift register & sync word */
+#define SYNC_WORD 0x1ff
+#define MAX_STREAM_WORDS 255
+static uint16_t ALDLSR = 0;
+static uint8_t bits = 0;
+static int datalen = 0;
+static uint8_t data[MAX_STREAM_WORDS];
+
+int gotsync = 0;
+
+struct stream_common decoded = { 0 };
+
+void (*aldl_callback)(uint8_t *data, int datalen) = NULL;
+
+void isrfn(void)
+{
+ int val;
+ delayfn(1); // To handle both variations, minimum of 0.5, max of 1.8
+ val = readbit();
+ ALDLSR <<= 1;
+ ALDLSR |= (val & 1);
+
+ /* Wait for initial sync. */
+ if (!gotsync) {
+ if ((ALDLSR & SYNC_WORD) == SYNC_WORD) {
+ gotsync = 1;
+ }
+ return; /* No sync, drop everything */
+ }
+
+ if ((ALDLSR & SYNC_WORD) == SYNC_WORD) {
+ /* New sync word, we've finished a sequence */
+ if (aldl_callback)
+ aldl_callback(data, datalen);
+ bits = 0;
+ datalen = 0;
+ } else if (++bits == 9) {
+ /* Just latch in the word */
+ data[datalen++] = ALDLSR & 0xff;
+ bits = 0;
+ }
+}
diff --git a/aldl.h b/aldl.h
new file mode 100644
index 0000000..6367605
--- /dev/null
+++ b/aldl.h
@@ -0,0 +1,55 @@
+/* API */
+void isrfn(void);
+int readbit(void);
+void delayfn(int ms);
+
+extern int gotsync;
+extern void (*aldl_callback)(uint8_t *data, int datalen);
+
+/* Decoded data stream */
+struct stream_common {
+ uint16_t heartbeat;
+
+ uint16_t prom_id; /* PROM ID */
+
+ /* Raw data */
+ uint16_t mph; /* Miles per hour */
+ uint16_t rpm; /* Revolutions per minute */
+ int16_t coolant_temp_c; /* Coolant temperature */
+ uint16_t tp; /* Throttle Position, percent */
+ uint16_t iac_steps;
+ uint16_t idle_tgt; /* Idle target RPM */
+ uint16_t base_fuel; /* Base fuel correction */
+ uint16_t knock_count; /* Knock counter */
+ uint16_t corr_fuel; /* Corrective fuel multiplier */
+ uint16_t o2_transitions; /* O2 sensors transitions */
+
+ float battery_v; /* Battery voltage */
+ float fuelp_v; /* Fuel Pump Voltage */
+ float map_v; /* Manifold Absolute Pressure Voltage */
+ float tps_v; /* Throttle Position, Voltage */
+ float o2_v; /* O2 sensor, Voltage */
+
+ /* Derived data */
+
+ uint16_t running; /* non-zero if engine running */
+ uint16_t driving; /* non-zero if moving */
+ uint16_t idling; /* 1 = first idle, 2 = regular */
+ uint32_t mil; /* Aka Check Engine Light */
+ uint16_t closed_loop; /* Runining in closed loop mode */
+ uint16_t closed_loop_idle; /* Idle in closed loop mode */
+ uint16_t rich_lean; /* 1 if rich, 0 for lean */
+ uint16_t ac_request; /* True if AC requested */
+ uint16_t learn_req; /* Learning Requested */
+ uint16_t shift_req; /* Shift requested */
+ uint16_t top_gear; /* In top gear */
+ uint16_t neutral; /* Neutral or Park */
+ uint16_t overspeed; /* Overspeed */
+
+};
+
+extern struct stream_common decoded;
+
+/* Examples */
+void aldl_a179_callback(uint8_t *data, int datalen);
+
diff --git a/sdldash.c b/sdldash.c
new file mode 100644
index 0000000..7bedc8b
--- /dev/null
+++ b/sdldash.c
@@ -0,0 +1,97 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "aldl.h"
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+
+/* Dimensions and basic stuff */
+
+#define SCREEN_W 320
+#define SCREEN_H 240
+#define FONT "/usr/share/fonts/levien-inconsolata/Inconsolata-Regular.ttf"
+#define FONT_SZ 12
+#define VIDEODRIVER NULL
+#define WINDOW_NAME "ALDL Dashboard"
+
+/* State */
+static SDL_bool videoinit = SDL_FALSE;
+static SDL_Window *window = NULL;
+static TTF_Font *font = NULL;
+static SDL_Renderer *renderer = NULL;
+static SDL_Surface *surface = NULL;;
+
+/* Cleanup */
+void OnQuit(void) {
+ if (videoinit) {
+ SDL_VideoQuit();
+ }
+ SDL_Quit();
+}
+
+
+/* Initialize */
+int init_dash(void) {
+ if (SDL_Init(0)) {
+ printf("fail to init SDL\n");
+ return 1;
+ }
+
+ /* Clean up on exit */
+ atexit(OnQuit);
+
+ if (SDL_VideoInit(VIDEODRIVER)) {
+ printf("fail to init SDL_Video\n");
+ return 2;
+ }
+ videoinit = SDL_TRUE;
+
+ /* Init font subsystem */
+ if (TTF_Init()) {
+ printf("fail to init TTF\n");
+ return 3;
+ }
+
+ /* Load up a font */
+ font = TTF_OpenFont(FONT, FONT_SZ);
+ if (!font) {
+ printf("Can't open font '%s'\n", FONT);
+ return 4;
+ }
+
+ /* Set up display */
+ window = SDL_CreateWindow(WINDOW_NAME,
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ SCREEN_W, SCREEN_H, 0);
+ if (!window) {
+ printf("fail to create window\n");
+ return 5;
+ }
+
+ /* Set up drawing surface */
+ surface = SDL_CreateRGBSurface(0, SCREEN_W, SCREEN_H,
+ 8, 0, 0, 0, 0);
+ if (!surface) {
+ printf("Fail to create drawing surface");
+ return 6;
+ }
+
+ /* Set up renderer */
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
+ if (!renderer) {
+ printf("Fail to create renderer");
+ return 7;
+ }
+
+ return 0;
+}
+
+int render_dash(void) {
+ // draw border, 1px around the edge.
+ // draw some text.
+
+ return 0;
+}
diff --git a/testpi.c b/testpi.c
new file mode 100644
index 0000000..a2a2395
--- /dev/null
+++ b/testpi.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "aldl.h"
+
+#include <wiringPi/wiringPi.h>
+
+/* What pin? */
+#define ALDL_PIN_IN 5
+
+int readbit(void)
+{
+ return digitalRead(ALDL_PIN_IN);
+}
+void delayfn(int ms)
+{
+ delay(1);
+}
+
+int main (int argc, char **argv)
+{
+ void *dash_ctx;
+ /* Set up RPi GPIO */
+ wiringPiSetup();
+
+ pinMode(ALDL_PIN_IN, INPUT);
+ pullUpDnControl(ALDL_PIN_IN, PUD_DOWN);
+
+ wiringPiISR (ALDL_PIN_IN, INT_EDGE_FALLING, &isrfn);
+
+ aldl_callback = aldl_a179_callback;
+
+ if (init_dash())
+ return -1;
+
+ while(1) {
+ sleep(1);
+
+ if (!gotsync) {
+ // No sync, we're off.
+ continue;
+ }
+
+ render_dash();
+ }
+
+ return 0;
+}