aboutsummaryrefslogtreecommitdiff
path: root/client/i2c.cpp
blob: ee57e20c2461c967ae255ccf9c9c4fb1de4e91b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>
#include <stdlib.h>

#include "i2ctcpv1.h"
#include "sock.h"
#include "xxd.h"

#include "pb/bus.h"
#include "pb/types.h"

#include "pb/mod/main.h"

bool i2c_dump_send = false;
bool i2c_dump_recv = true;

void i2c_send(uint16_t addr, const char * data, size_t data_size) {
	i2ctcp_msg_t msg = {
		.addr = addr,
		.data = (char *) data,
		.length = data_size,
	};

	char* packed;
	size_t size;
	if (!i2ctcp_write(&msg, &packed, &size)) return;

	sock->send(packed, size);
	if (i2c_dump_send) {
		printf("[%s] addr(0x%02x) data(0x%02lx):\n", __FUNCTION__, addr, data_size);
		xxd(data, data_size);
	}

	free(packed);
}

static void i2c_handle_cmd_read(uint16_t, const char *, size_t);

void i2c_recv(uint16_t addr, const char * data, size_t data_size) {
	if (i2c_dump_recv) {
		printf("[%s] addr(0x%02x) data(0x%02lx):\n", __FUNCTION__, addr, data_size);
		xxd(data, data_size);
	}

	if (data_size == 0) return;
	enum pb_cmd cmd = (enum pb_cmd) data[0];
	data++; data_size--;

	switch (cmd) {
		case PB_CMD_READ: return i2c_handle_cmd_read(addr, data, data_size);
		default: return;
	}
}

static void i2c_handle_cmd_read(uint16_t i2c_addr, const char * buf, size_t sz) {
	if (sz < 2) return; // require data address + 1 byte of data
	pb_cmd_read_t * cmd = (pb_cmd_read_t *) buf;
	sz--; // sz now represents size of cmd->data

	if (i2c_addr == BUSADDR_MAIN && cmd->address == 0x01) {
		if (sz % 2 != 0) return; // invalid data
		for (size_t offset = 0; offset < sz; offset += sizeof(pb_mod_main_mod_t)) {
			pb_mod_main_mod_t * mod = (pb_mod_main_mod_t *) (cmd->data + offset);
			printf("module at addr 0x%02x with state %d\n", mod->addr, mod->state);
		}
	}
}