temperature stuff actually working now
This commit is contained in:
parent
9f3802627a
commit
d5484cf38f
14
README.md
14
README.md
|
@ -138,12 +138,19 @@ sensor (the exact sensor emulated is the Microchip MCP9808). To have it show
|
|||
up in `sensors`, do the following (with `BUSNUM` the number from the above
|
||||
`i2cdetect -l` output):
|
||||
```
|
||||
$ ./dmctl.py /dev/ttyACM1 --i2ctemp 0x18 # need to give it an address first
|
||||
$ sudo modprobe jc42
|
||||
$ # now tell the jc42 module that the device can be found at this address
|
||||
$ echo "jc42 0x18" | sudo tee /sys/bus/i2c/device/i2c-BUSNUM/new_device
|
||||
$ sudo sensors
|
||||
$ sudo sensors # it should show up now:
|
||||
jc42-i2c-BUSNUM-18
|
||||
Adapter: i2c-tiny-usb at bus 001 device 032
|
||||
temp1: +23.1°C (low = -20.0°C)
|
||||
(high = +75.0°C, hyst = +75.0°C)
|
||||
(crit = +80.0°C, hyst = +80.0°C)
|
||||
```
|
||||
|
||||
Temperature readout is currently not really working.
|
||||
Temperature readout may be a bit higher than the ambient temperature.
|
||||
|
||||
### Runtime configuration
|
||||
|
||||
|
@ -156,6 +163,7 @@ The currently implemented options are:
|
|||
- `i2ctemp`: Get or set the I2C address of the fake I2C device of the temperature
|
||||
sensor. Use 0 for getting the value, 0xff for disabling, and any
|
||||
other for setting the address. The I2C device emulated is an MCP9808.
|
||||
When setting a value, the old value is printed.
|
||||
|
||||
```
|
||||
usage: dmctl [-h] [-v] [--ctsrts [CTSRTS]] tty
|
||||
|
@ -201,7 +209,7 @@ libco is licensed under the [ISC license](https://opensource.org/licenses/ISC)
|
|||
to use the UART interface as a loopback thing.
|
||||
- [ ] Second UART port for when stdio UART is disabled?
|
||||
- [x] I2C support by emulating the I2C Tiny USB
|
||||
- [ ] Expose RP2040-internal temperature ADC on I2C-over-USB bus?
|
||||
- [x] Expose RP2040-internal temperature ADC on I2C-over-USB bus?
|
||||
- [ ] ~~Does SMBus stuff need special treatment here?~~ ~~No.~~ Actually, some
|
||||
parts do, but, laziness.
|
||||
- [x] 10-bit I2C address support (Needs poking at the Pico SDK, as it only
|
||||
|
|
|
@ -28,9 +28,20 @@ void tempsense_dev_init(void) {
|
|||
int16_t tempsense_dev_get_temp(void) {
|
||||
adc_select_input(4); // select temp sensor
|
||||
uint16_t result = adc_read();
|
||||
int temperature = float2fix(T_OFF - T_BIAS / T_SLOPE)
|
||||
+ (int)result * float2fix(V_MAX / (D_RANGE * T_SLOPE));
|
||||
|
||||
return trunc_8fix4(temperature);
|
||||
float voltage = result * (V_MAX / D_RANGE);
|
||||
|
||||
float tempf = T_OFF + (voltage - T_BIAS) / T_SLOPE;
|
||||
|
||||
// FIXME: use fixed point instead! but something's wrong with the formula below
|
||||
/*int temperature = float2fix(T_OFF - T_BIAS / T_SLOPE)
|
||||
+ (int)result * float2fix(V_MAX / (D_RANGE * T_SLOPE));*/
|
||||
|
||||
return trunc_8fix4(/*temperature*/float2fix(tempf));
|
||||
}
|
||||
|
||||
// RP2040 absolute min/max are -20/85
|
||||
int16_t tempsense_dev_get_lower(void) { return trunc_8fix4(float2fix(-15)); }
|
||||
int16_t tempsense_dev_get_upper(void) { return trunc_8fix4(float2fix( 75)); }
|
||||
int16_t tempsense_dev_get_crit (void) { return trunc_8fix4(float2fix( 80)); }
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
tstest
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
#define DBOARD_HAS_TEMPSENSOR
|
||||
#define VERY_FAKE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline void tempsense_dev_init(void) { }
|
||||
static inline int16_t tempsense_dev_get_temp(void) { return 42 << 4; }
|
||||
|
||||
static inline int16_t tempsense_dev_get_lower(void) { return 0 << 4; }
|
||||
static inline int16_t tempsense_dev_get_upper(void) { return 75 << 4; }
|
||||
static inline int16_t tempsense_dev_get_crit (void) { return 80 << 4; }
|
||||
|
||||
#include "../tempsensor.c"
|
||||
|
||||
static int do_pkt(uint8_t cmd, bool read, uint16_t addr, uint16_t len, uint8_t* buf) {
|
||||
int rv;
|
||||
|
||||
if (cmd & 1) tempsense_do_start();
|
||||
|
||||
if (read) {
|
||||
rv = tempsense_do_read(len, buf);
|
||||
} else {
|
||||
rv = tempsense_do_write(len, buf);
|
||||
}
|
||||
|
||||
if (cmd & 2) tempsense_do_stop();
|
||||
|
||||
printf("-> %d: %s\n", rv, (rv < 0 || rv != len) ? "nak" : "ack");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void pbuf(size_t len, const uint8_t* buf) {
|
||||
printf("--> ");
|
||||
size_t i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
printf("%02x ", buf[i]);
|
||||
if ((i & 0xf) == 0xf) printf("%c", '\n');
|
||||
}
|
||||
if ((i & 0xf) != 0x0) printf("%c", '\n');
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
tempsense_init();
|
||||
|
||||
tempsense_set_addr(0x18);
|
||||
|
||||
// initial probe
|
||||
uint8_t pk1[1] = {0}; do_pkt(0x05, false, 0x18, 1, pk1);
|
||||
uint8_t pk2[2]; do_pkt(0x06, true , 0x18, 2, pk2); pbuf(2, pk2);
|
||||
|
||||
uint8_t pk3[1] = {1}; do_pkt(0x05, false, 0x18, 1, pk3);
|
||||
uint8_t pk4[2]; do_pkt(0x06, true , 0x18, 2, pk4); pbuf(2, pk4);
|
||||
|
||||
// sensor data get
|
||||
|
||||
// out 0x05 cmd5
|
||||
// in 2byte cmd6
|
||||
// out 0x04 cmd5
|
||||
// in 2byte cmd6
|
||||
// out 0x03 cmd5
|
||||
// in 2byte cmd6
|
||||
// out 0x02 cmd5
|
||||
// in 2byte cmd6
|
||||
}
|
||||
|
|
@ -4,7 +4,10 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef VERY_FAKE
|
||||
#include "protocfg.h"
|
||||
#define printf(fmt, ...) do{}while(0)
|
||||
#endif
|
||||
|
||||
#ifdef DBOARD_HAS_TEMPSENSOR
|
||||
|
||||
|
@ -17,7 +20,8 @@ static size_t index;
|
|||
static bool instartstop, hasreg;
|
||||
|
||||
enum regid {
|
||||
config = 1,
|
||||
cap = 0,
|
||||
config,
|
||||
t_upper,
|
||||
t_lower,
|
||||
t_crit,
|
||||
|
@ -36,6 +40,13 @@ struct {
|
|||
uint8_t reso;
|
||||
} mcp9808;
|
||||
|
||||
#define float2fix(x) (int)((x)*(1<<4))
|
||||
__attribute__((__const__))
|
||||
inline static int16_t trunc_8fix4(int fix) {
|
||||
if (fix > 4095) fix = 4095;
|
||||
if (fix < -4096) fix = -4096;
|
||||
return fix;
|
||||
}
|
||||
void tempsense_init(void) {
|
||||
active = false;
|
||||
addr = 0xff;
|
||||
|
@ -45,6 +56,10 @@ void tempsense_init(void) {
|
|||
hasreg = false;
|
||||
|
||||
tempsense_dev_init();
|
||||
|
||||
mcp9808.t_lower = tempsense_dev_get_lower();
|
||||
mcp9808.t_upper = tempsense_dev_get_upper();
|
||||
mcp9808.t_crit = tempsense_dev_get_crit ();
|
||||
}
|
||||
|
||||
bool tempsense_get_active(void) { return active; }
|
||||
|
@ -57,16 +72,20 @@ void tempsense_set_addr(uint8_t a) {
|
|||
}
|
||||
|
||||
void tempsense_do_start(void) {
|
||||
printf("ts start\n");
|
||||
//reg = 0;
|
||||
index = 0;
|
||||
instartstop = true;
|
||||
hasreg = false;
|
||||
}
|
||||
void tempsense_do_stop(void) {
|
||||
printf("ts stop\n");
|
||||
instartstop = false;
|
||||
}
|
||||
|
||||
int tempsense_do_read(int length, uint8_t* buf) {
|
||||
printf("read l=%d reg=%02x ", length, reg);
|
||||
|
||||
if (!instartstop || length < 0) return -1; // nak
|
||||
if (length == 0) return 0; // ack
|
||||
//if (!hasreg) return -1; // nak
|
||||
|
@ -75,22 +94,29 @@ int tempsense_do_read(int length, uint8_t* buf) {
|
|||
for (i = 0; i < length; ++i, ++index) {
|
||||
switch (reg) {
|
||||
// TODO: big or little endian? seems to be big
|
||||
case cap:
|
||||
buf[index] = 0;
|
||||
break;
|
||||
case config:
|
||||
if (index == 0) buf[0] = (mcp9808.config >> 8) & 0xff;
|
||||
else if (index == 1) buf[1] = (mcp9808.config >> 0) & 0xff;
|
||||
else return index;
|
||||
break;
|
||||
case t_upper:
|
||||
if (index == 0) buf[0] = (mcp9808.t_upper >> 8) & 0xff;
|
||||
else if (index == 1) buf[1] = (mcp9808.t_upper >> 0) & 0xff;
|
||||
else return index;
|
||||
break;
|
||||
case t_lower:
|
||||
if (index == 0) buf[0] = (mcp9808.t_lower >> 8) & 0xff;
|
||||
else if (index == 1) buf[1] = (mcp9808.t_lower >> 0) & 0xff;
|
||||
else return index;
|
||||
break;
|
||||
case t_crit:
|
||||
if (index == 0) buf[0] = (mcp9808.t_crit >> 8) & 0xff;
|
||||
else if (index == 1) buf[1] = (mcp9808.t_crit >> 0) & 0xff;
|
||||
else return index;
|
||||
break;
|
||||
case t_a: {
|
||||
static uint16_t temp;
|
||||
if (index == 0) {
|
||||
|
@ -113,17 +139,21 @@ int tempsense_do_read(int length, uint8_t* buf) {
|
|||
} else if (index == 1) buf[1] = (temp>>0) & 0xff;
|
||||
else return index;
|
||||
}
|
||||
break;
|
||||
case manuf_id:
|
||||
if (index == 0) buf[0] = (MANUF_ID >> 8) & 0xff;
|
||||
else if (index == 1) buf[1] = (MANUF_ID>>0)&0xff;
|
||||
else return index;
|
||||
break;
|
||||
case dev_idrev:
|
||||
if (index == 0) buf[0] = (DEV_IDREV >> 8) & 0xff;
|
||||
else if (index == 1) buf[1] = (DEV_IDREV>>0)&0xff;
|
||||
else return index;
|
||||
break;
|
||||
case reso:
|
||||
if (index == 0) buf[0] = mcp9808.reso;
|
||||
else return index;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
@ -131,10 +161,14 @@ int tempsense_do_read(int length, uint8_t* buf) {
|
|||
return i;
|
||||
}
|
||||
int tempsense_do_write(int length, const uint8_t* buf) {
|
||||
printf("write l=%d reg=%02x iss=%c ", length, reg, instartstop?'t':'f');
|
||||
|
||||
if (!instartstop || length < 0) return -1; // nak
|
||||
if (length == 0) return 0; // ack
|
||||
|
||||
if (!hasreg) {
|
||||
printf("get reg %02x ", reg);
|
||||
|
||||
reg = *buf & 0xf;
|
||||
++buf;
|
||||
--length;
|
||||
|
@ -152,27 +186,34 @@ int tempsense_do_write(int length, const uint8_t* buf) {
|
|||
} else if (index == 1) {
|
||||
mcp9808.config = (mcp9808.config & 0xff00) | ((uint16_t)buf[1] << 0);
|
||||
} else return index;
|
||||
break;
|
||||
case t_upper:
|
||||
if (index == 0) {
|
||||
mcp9808.t_upper = (mcp9808.t_upper & 0x00ff) | ((uint16_t)buf[0] << 8);
|
||||
} else if (index == 1) {
|
||||
mcp9808.t_upper = (mcp9808.t_upper & 0xff00) | ((uint16_t)buf[1] << 0);
|
||||
} else return index;
|
||||
break;
|
||||
case t_lower:
|
||||
if (index == 0) {
|
||||
mcp9808.t_lower = (mcp9808.t_lower & 0x00ff) | ((uint16_t)buf[0] << 8);
|
||||
} else if (index == 1) {
|
||||
mcp9808.t_lower = (mcp9808.t_lower & 0xff00) | ((uint16_t)buf[1] << 0);
|
||||
} else return index;
|
||||
break;
|
||||
case t_crit:
|
||||
if (index == 0) {
|
||||
mcp9808.t_crit = (mcp9808.t_crit & 0x00ff) | ((uint16_t)buf[0] << 8);
|
||||
} else if (index == 1) {
|
||||
mcp9808.t_crit = (mcp9808.t_crit & 0xff00) | ((uint16_t)buf[1] << 0);
|
||||
} else return index;
|
||||
break;
|
||||
case reso:
|
||||
mcp9808.reso = buf[index];
|
||||
default: return -1;
|
||||
break;
|
||||
default:
|
||||
printf("unk reg\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ void tempsense_do_stop(void); // stop cond
|
|||
void tempsense_dev_init(void);
|
||||
// 8.4
|
||||
int16_t tempsense_dev_get_temp(void);
|
||||
|
||||
int16_t tempsense_dev_get_lower(void);
|
||||
int16_t tempsense_dev_get_upper(void);
|
||||
int16_t tempsense_dev_get_crit (void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -85,7 +85,10 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
|
|||
#ifdef DBOARD_HAS_TEMPSENSOR
|
||||
if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
|
||||
if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
|
||||
status = tempsense_do_write(cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len, rxbuf);
|
||||
// FIXME: fix status handling
|
||||
int rv = tempsense_do_write(cmd.len > sizeof rxbuf ? sizeof rxbuf : cmd.len, rxbuf);
|
||||
if (rv < 0 || rv != cmd.len) status = ITU_STATUS_ADDR_NAK;
|
||||
else status = ITU_STATUS_ADDR_ACK;
|
||||
if (cmd.cmd & ITU_CMD_I2C_IO_END_F ) tempsense_do_stop ();
|
||||
} else
|
||||
#endif
|
||||
|
@ -155,7 +158,9 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
|
|||
#ifdef DBOARD_HAS_TEMPSENSOR
|
||||
if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
|
||||
if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
|
||||
status = tempsense_do_read(cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len, txbuf);
|
||||
int rv = tempsense_do_read(cmd.len > sizeof txbuf ? sizeof txbuf : cmd.len, txbuf);
|
||||
if (rv < 0 || rv != cmd.len) status = ITU_STATUS_ADDR_NAK;
|
||||
else status = ITU_STATUS_ADDR_ACK;
|
||||
if (cmd.cmd & ITU_CMD_I2C_IO_END_F ) tempsense_do_stop ();
|
||||
} else
|
||||
#endif
|
||||
|
@ -173,7 +178,9 @@ static bool iub_ctl_req(uint8_t rhport, uint8_t stage, tusb_control_request_t co
|
|||
#ifdef DBOARD_HAS_TEMPSENSOR
|
||||
if (tempsense_get_active() && tempsense_get_addr() == cmd.addr) {
|
||||
if (cmd.cmd & ITU_CMD_I2C_IO_BEGIN_F) tempsense_do_start();
|
||||
status = tempsense_do_write(0, &bleh);
|
||||
int rv = tempsense_do_write(0, &bleh);
|
||||
if (rv < 0 || rv != cmd.len) status = ITU_STATUS_ADDR_NAK;
|
||||
else status = ITU_STATUS_ADDR_ACK;
|
||||
if (cmd.cmd & ITU_CMD_I2C_IO_END_F ) tempsense_do_stop ();
|
||||
} else
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue