summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-08-07 17:31:59 +0200
committerDaniel Friesel <derf@finalrewind.org>2018-08-07 17:31:59 +0200
commit178835c160940772341615dab7a239c45a875807 (patch)
treec732f59d48c41453cd8c28603ee61f3365fac773 /src
parent8579b2a1023211c86cb1221eb2b44b9221034478 (diff)
Add AM2320 driver
Diffstat (limited to 'src')
-rw-r--r--src/app/i2cdetect/main.cc14
-rw-r--r--src/driver/am2320.cc61
2 files changed, 75 insertions, 0 deletions
diff --git a/src/app/i2cdetect/main.cc b/src/app/i2cdetect/main.cc
index 141c65a..5094fd5 100644
--- a/src/app/i2cdetect/main.cc
+++ b/src/app/i2cdetect/main.cc
@@ -9,6 +9,9 @@
#ifdef DRIVER_LM75
#include "driver/lm75.h"
#endif
+#ifdef DRIVER_AM2320
+#include "driver/am2320.h"
+#endif
#ifdef DRIVER_MAX44009
#include "driver/max44009.h"
#endif
@@ -22,6 +25,17 @@ void loop(void)
kout.printf_float(lm75.getTemp());
kout << endl;
#endif
+#ifdef DRIVER_AM2320
+ am2320.read();
+ if (am2320.getStatus() == 0) {
+ kout.printf_float(am2320.getTemp());
+ kout << " degC @ ";
+ kout.printf_float(am2320.getHumidity());
+ kout << " rel%" << endl;
+ } else {
+ kout << "AM2320 error " << dec << am2320.getStatus() << endl;
+ }
+#endif
#ifdef DRIVER_MAX44009
kout.printf_float(max44009.getLux());
kout << endl;
diff --git a/src/driver/am2320.cc b/src/driver/am2320.cc
new file mode 100644
index 0000000..25e2ffe
--- /dev/null
+++ b/src/driver/am2320.cc
@@ -0,0 +1,61 @@
+#include "driver/am2320.h"
+#if defined(MULTIPASS_ARCH_HAS_I2C) && !defined(DRIVER_SOFTI2C)
+#include "driver/i2c.h"
+#else
+#include "driver/soft_i2c.h"
+#endif
+#include "arch.h"
+
+void AM2320::read()
+{
+ txbuf[0] = 0;
+ i2c.xmit(address, 1, txbuf, 0, rxbuf);
+ arch.delay_ms(1);
+ txbuf[0] = 3;
+ txbuf[1] = 0;
+ txbuf[2] = 4;
+ rxbuf[3] = rxbuf[4] = rxbuf[5] = rxbuf[6] = 0;
+ i2c.xmit(address, 3, txbuf, 0, rxbuf);
+ arch.delay_ms(3);
+ i2c.xmit(address, 0, txbuf, 8, rxbuf);
+}
+
+unsigned char AM2320::getStatus()
+{
+ if (rxbuf[0] != 3) {
+ return 1;
+ }
+ if (rxbuf[1] != 4) {
+ return 2;
+ }
+ unsigned short checksum = 0xffff;
+ for (unsigned char i = 0; i < 6; i++) {
+ checksum ^= rxbuf[i] & 0x00ff;
+ for (unsigned char j = 0; j < 8; j++) {
+ if (checksum & 0x0001) {
+ checksum = (checksum >> 1) ^ 0xa001;
+ } else {
+ checksum >>= 1;
+ }
+ }
+ }
+ if ((rxbuf[6] != (checksum & 0x00ff)) || (rxbuf[7] != (checksum >> 8) & 0x00ff)) {
+ return 3;
+ }
+ return 0;
+}
+
+float AM2320::getTemp()
+{
+ if (txbuf[5] & 0x80) {
+ return (-256 * (rxbuf[4] & 0x7f) + rxbuf[5]) / 10.;
+ }
+ return (256 * rxbuf[4] + rxbuf[5]) / 10.;
+}
+
+float AM2320::getHumidity()
+{
+ return (rxbuf[2] * 256 + rxbuf[3]) / 10.;
+}
+
+AM2320 am2320(0x5c);