Initial commit of WIP code
This commit is contained in:
commit
12b88b73c3
|
@ -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
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue