From 5935aeec6bdcb5f3f2bc6436f75861872e88fdc6 Mon Sep 17 00:00:00 2001
From: Neil Gershenfeld <gersh@cba.mit.edu>
Date: Sun, 30 Mar 2025 19:37:51 -0400
Subject: [PATCH] wip

---
 input_devices/index.html                      |   3 +-
 .../mag/TLE493D/hello.TLE493D.t412.nowire.ino | 278 ++++++++++++++++++
 .../TLE493D/hello.TLE493D.t412.softwire.ino   |  97 ++++++
 .../mag/TLE493D/hello.TLE493D.t412.wire.ino   |  87 ++++++
 4 files changed, 463 insertions(+), 2 deletions(-)
 create mode 100644 input_devices/mag/TLE493D/hello.TLE493D.t412.nowire.ino
 create mode 100644 input_devices/mag/TLE493D/hello.TLE493D.t412.softwire.ino
 create mode 100644 input_devices/mag/TLE493D/hello.TLE493D.t412.wire.ino

diff --git a/input_devices/index.html b/input_devices/index.html
index 2100a046..95ad3ecf 100755
--- a/input_devices/index.html
+++ b/input_devices/index.html
@@ -38,8 +38,7 @@
          <a href=mag/hello.mag.USB.ino>hello.mag.USB.ino</a> <a href=mag/hello.mag.D11C.ino>hello.mag.D11C.ino</a>
    <a href=https://www.digikey.com/en/products/detail/infineon-technologies/TLE493DA2B6HTSA1/9808570>vector</a> <a href=https://www.infineon.com/dgdl/Infineon-3D_Magnetic_Sensors-ProductBrief-v05_00-EN.pdf?fileId=5546d46261d5e6820161e7571b2b3dd0>applications</a> <a href=https://design.infineon.com/3dsim/>simulation</a>
       <a href=mag/TLE493D/hello.TLE493D.t412>hello.TLE493D.t412</a> <a href=mag/TLE493D/hello.TLE493D.t412.png>board</a> <a href=mag/TLE493D/hello.TLE493D.t412.jpg>components</a> <a href=mag/TLE493D/hello.TLE493D.t412.traces.png>traces</a> <a href=mag/TLE493D/hello.TLE493D.t412.traces_exterior.png>traces+exterior</a> <a href=mag/TLE493D/hello.TLE493D.t412.interior.png>interior</a>
-         <a href=mag/TLE493D/hello.TLE493D.t412.ino>hello.TLE493D.t412.ino</a> <a href=mag/TLE493D/hello.TLE493D.t412.c>.c</a> <a href=mag/TLE493D/hello.TLE493D.t412.make>.make</a> <a href=mag/TLE493D/hello.TLE493D.t412.py>.py</a> <a href=mag/TLE493D/hello.TLE493D.t412.mp4>video</a>
-
+         <a href=mag/TLE493D/hello.TLE493D.t412.wire.ino>hello.TLE493D.t412.wire.ino</a> <a href=mag/TLE493D/hello.TLE493D.t412.softwire.ino>softwire.ino</a> <a href=mag/TLE493D/hello.TLE493D.t412.nowire.ino>nowire.ino</a> <a href=mag/TLE493D/hello.TLE493D.t412.c>.c</a> <a href=mag/TLE493D/hello.TLE493D.t412.make>.make</a> <a href=mag/TLE493D/hello.TLE493D.t412.py>.py</a> <a href=mag/TLE493D/hello.TLE493D.t412.mp4>video</a>
 <b><a href=https://www.digikey.com/en/products/detail/nidec-copal-electronics/ST4ETB103/738213>potentiometer</a></b>
    <a href=http://academy.cba.mit.edu/classes/output_devices/DRV8428/hello.DRV8428-D11C-NEMA17.jpg>hello.DRV8428-D11C-NEMA17</a>
 
diff --git a/input_devices/mag/TLE493D/hello.TLE493D.t412.nowire.ino b/input_devices/mag/TLE493D/hello.TLE493D.t412.nowire.ino
new file mode 100644
index 00000000..f50945c5
--- /dev/null
+++ b/input_devices/mag/TLE493D/hello.TLE493D.t412.nowire.ino
@@ -0,0 +1,278 @@
+//
+// hello.TLE493D.t412.nowire.ino
+//    TLE493D vector magnetometer tiny412 hello-world
+//    no I2C library version
+//
+// Neil Gershenfeld 3/29/25
+//
+// This work may be reproduced, modified, distributed,
+// performed, and displayed for any purpose, but must
+// acknowledge this project. Copyright is retained and
+// must be preserved. The work is provided as is; no
+// warranty is provided, and users accept all liability.
+//
+
+#define address 0x35
+#define SDA PIN_PA1
+#define SCL PIN_PA2
+#define I2C_delay() delayMicroseconds(5)
+
+unsigned char ret,data[10];
+
+void SCL_write(unsigned char bit, unsigned char SCL_pin) {
+   //
+   // write SCL bit
+   //
+   if (bit == 0) {
+      pinMode(SCL_pin,OUTPUT);
+      digitalWrite(SCL_pin,LOW);
+      }
+   else {
+      pinMode(SCL_pin,INPUT);
+      while (digitalRead(SCL_pin) == LOW); // check for clock stretching
+      }
+   }
+
+void SDA_write(unsigned char bit, unsigned char SDA_pin) {
+   //
+   // write SDA bit
+   //
+   if (bit == 0) {
+      pinMode(SDA_pin,OUTPUT);
+      digitalWrite(SDA_pin,LOW);
+      }
+   else
+      pinMode(SDA_pin,INPUT);
+   }
+
+void I2C_init(unsigned char SCL_pin, unsigned char SDA_pin) {
+   //
+   // initialize I2C lines
+   //
+   SDA_write(1,SDA_pin);
+   SCL_write(1,SCL_pin);
+   } 
+
+unsigned char I2C_master_write_byte(unsigned char byte,
+   unsigned char SCL_pin, unsigned char SDA_pin) {
+   //
+   // master write I2C byte
+   //
+   unsigned char bit;
+   unsigned char ret = 0;
+   //
+   // loop over bits
+   //
+   for (bit = 0; bit < 8; ++bit) {
+      if ((byte & 0x80) == 0)
+         SDA_write(0,SDA);
+      else
+         SDA_write(1,SDA);
+      I2C_delay();
+      SCL_write(1,SCL);
+      I2C_delay();
+      SCL_write(0,SCL);
+      byte <<= 1;
+      }
+   //
+   // check for ACK
+   //
+   I2C_delay();
+   SDA_write(1,SDA);
+   SCL_write(1,SCL);
+   I2C_delay();
+   if (digitalRead(SDA) != LOW) {
+      //
+      // no ACK, return 1
+      //
+      ret = 1;	
+      }
+   //
+   // yes ACK, return 0
+   //
+   SCL_write(0,SCL);
+   I2C_delay();
+   return ret;
+   }	
+
+unsigned char I2C_master_write(unsigned char* data, unsigned char nbytes, unsigned char secondary_address,
+   unsigned char SCL_pin, unsigned char SDA_pin) {
+   //
+   // I2C master write
+   //
+   unsigned char index,secondary_address_write;
+   unsigned char ret = 0;
+   //
+   // send start
+   //
+   SDA_write(0,SDA);
+   I2C_delay();
+   SCL_write(0,SCL);	
+   //
+   // send secondary address
+   //
+   secondary_address_write = secondary_address << 1;
+   if (I2C_master_write_byte(secondary_address_write, SCL_pin, SDA_pin) != 0)
+      //
+      // no ACK, return 1
+      //
+      ret = 1;
+   //
+   // loop over bytes
+   //
+   for (index = 0; index < nbytes; ++index) {
+      ret = I2C_master_write_byte(data[index], SCL_pin, SDA_pin);
+      if (ret != 0)
+         //
+         // no ACK, return 1
+         //
+         ret = 1;
+      //
+      // yes ACK, continue
+      //	
+      }
+   //
+   // send stop
+   //
+   SDA_write(0,SDA);
+   I2C_delay();
+   SCL_write(1,SCL);
+   I2C_delay();
+   SDA_write(1,SDA);
+   I2C_delay();
+   return ret;
+   }
+
+void I2C_master_read_byte(unsigned char* data, unsigned char index, unsigned char nbytes,
+   unsigned char SCL_pin, unsigned char SDA_pin) {
+   //
+   // master read I2C byte
+   //
+   unsigned char byte,bit;
+   SDA_write(1,SDA);
+   byte = 0;
+   //
+   // loop over bits
+   //
+   for (bit = 0; bit < 8; ++bit)  {
+      I2C_delay();
+      SCL_write(1,SCL);
+      I2C_delay();
+      if (digitalRead(SDA) != LOW)
+         byte |= (1 << (7-bit));
+      SCL_write(0,SCL);
+      }
+   data[index] = byte;
+   if (index < (nbytes-1)) {
+      //
+      // not done, send ACK
+      //
+      SDA_write(0,SDA);
+      I2C_delay();
+      SCL_write(1,SCL);
+      I2C_delay();
+      SCL_write(0,SCL);
+      SDA_write(1,SDA);
+      }
+   else {
+      //
+      // done, send NACK
+      //
+      SDA_write(1,SDA);
+      I2C_delay();
+      SCL_write(1,SCL);
+      I2C_delay();
+      SCL_write(0,SCL);
+      I2C_delay();
+      }
+   }	
+
+unsigned char I2C_master_read(unsigned char* data, unsigned char nbytes, unsigned char secondary_address,
+   unsigned char SCL_pin, unsigned char SDA_pin) {
+   //
+   // I2C master read
+   //
+   unsigned char index,secondary_address_read;
+   unsigned char ret = 0;
+   //
+   // send start
+   //
+   SDA_write(0,SDA);
+   I2C_delay();
+   SCL_write(0,SCL);	
+   I2C_delay();
+   //
+   // send secondary address
+   //
+   secondary_address_read = (secondary_address << 1) + 1;
+   if (I2C_master_write_byte(secondary_address_read, SCL_pin, SDA_pin) == 1)
+      //
+      // no ACK, return 1
+      //
+      ret = 1;
+   //
+   // loop over bytes
+   //
+   for (index = 0; index < nbytes; ++index)
+      I2C_master_read_byte(data, index, nbytes, SCL_pin, SDA_pin);
+   //
+   // send stop
+   //
+   SCL_write(1,SCL);
+   I2C_delay();
+   SDA_write(1,SDA);
+   I2C_delay();
+   return ret;
+   }	
+
+void setup() {
+   //
+   // start serial and I2C
+   //
+   Serial.begin(115200);
+   I2C_init(SCL,SDA);
+   //
+   // reset TLE493D
+   //
+   data[0] = 0xFF;
+   ret = I2C_master_write(data,1,address,SCL,SDA);
+   data[0] = 0xFF;
+   ret = I2C_master_write(data,1,address,SCL,SDA);
+   data[0] = 0x00;
+   ret = I2C_master_write(data,1,address,SCL,SDA);
+   data[0] = 0x00;
+   ret = I2C_master_write(data,1,address,SCL,SDA);
+   //
+   // configure TLE493D
+   //
+   data[0] = 0x10;
+   data[1] = 0x28;
+      // config register 0x10
+      // ADC trigger on read after register 0x05
+      // short-range sensitivity
+   data[2] = 0x15;
+      // mode register 0x11
+      // 1-byte read protocol
+      // interrupt disabled
+      // master controlled mode
+   ret = I2C_master_write(data,3,address,SCL,SDA);
+   }
+
+void loop() {
+   //
+   // read registers 0x00-0x05
+   //
+   ret = I2C_master_write(data,0,address,SCL,SDA);
+   ret = I2C_master_read(data,6,address,SCL,SDA);
+   //
+   // send framing
+   //
+   Serial.write(1);
+   Serial.write(2);
+   Serial.write(3);
+   Serial.write(4);
+   //
+   // send data
+   //
+   Serial.write(data,6);
+   }
diff --git a/input_devices/mag/TLE493D/hello.TLE493D.t412.softwire.ino b/input_devices/mag/TLE493D/hello.TLE493D.t412.softwire.ino
new file mode 100644
index 00000000..dda2c3c7
--- /dev/null
+++ b/input_devices/mag/TLE493D/hello.TLE493D.t412.softwire.ino
@@ -0,0 +1,97 @@
+//
+// hello.TLE493D.t412.softwire.ino
+//    TLE493D vector magnetometer tiny412 hello-world
+//    SoftWire I2C library version
+//
+// Neil Gershenfeld 3/29/25
+//
+// This work may be reproduced, modified, distributed,
+// performed, and displayed for any purpose, but must
+// acknowledge this project. Copyright is retained and
+// must be preserved. The work is provided as is; no
+// warranty is provided, and users accept all liability.
+//
+
+#include <SoftWire.h>
+
+#define address 0x35
+#define SDA PIN_PA1
+#define SCL PIN_PA2
+
+char Tx[16];
+char Rx[16];
+
+SoftWire SWire(SDA,SCL);
+
+void setup() {
+   //
+   // start serial and I2C
+   //
+   Serial.begin(115200);
+   SWire.setTxBuffer(Tx,sizeof(Tx));
+   SWire.setRxBuffer(Rx,sizeof(Rx));
+   SWire.setDelay_us(5);
+   SWire.setTimeout(1000);
+   SWire.begin();
+   //
+   // reset TLE493D
+   //
+   SWire.beginTransmission(0);
+   SWire.write(0xFF);
+   SWire.endTransmission();
+   SWire.beginTransmission(0);
+   SWire.write(0xFF);
+   SWire.endTransmission();
+   SWire.beginTransmission(0);
+   SWire.write(0x00);
+   SWire.endTransmission();
+   SWire.beginTransmission(0);
+   SWire.write(0x00);
+   SWire.endTransmission();
+   delayMicroseconds(50);
+   //
+   // configure TLE493D
+   //
+   SWire.beginTransmission(address);
+   SWire.write(0x10);
+   SWire.write(0x28);
+      // config register 0x10
+      // ADC trigger on read after register 0x05
+      // short-range sensitivity
+   SWire.write(0x15);
+      // mode register 0x11
+      // 1-byte read protocol
+      // interrupt disabled
+      // master controlled mode
+   SWire.endTransmission();
+   }
+
+void loop() {
+   uint8_t v0,v1,v2,v3,v4,v5;
+   //
+   // read data
+   //
+   SWire.requestFrom(address,6);
+   v0 = SWire.read();
+   v1 = SWire.read();
+   v2 = SWire.read();
+   v3 = SWire.read();
+   v4 = SWire.read();
+   v5 = SWire.read();
+   //
+   // send framing
+   //
+   Serial.write(1);
+   Serial.write(2);
+   Serial.write(3);
+   Serial.write(4);
+   //
+   // send data
+   //
+   Serial.write(v0);
+   Serial.write(v1);
+   Serial.write(v2);
+   Serial.write(v3);
+   Serial.write(v4);
+   Serial.write(v5);
+   }
diff --git a/input_devices/mag/TLE493D/hello.TLE493D.t412.wire.ino b/input_devices/mag/TLE493D/hello.TLE493D.t412.wire.ino
new file mode 100644
index 00000000..95044fea
--- /dev/null
+++ b/input_devices/mag/TLE493D/hello.TLE493D.t412.wire.ino
@@ -0,0 +1,87 @@
+//
+// hello.TLE493D.t412.wire.ino
+//    TLE493D vector magnetometer tiny412 hello-world
+//    Wire I2C library version
+//
+// Neil Gershenfeld 3/29/25
+//
+// This work may be reproduced, modified, distributed,
+// performed, and displayed for any purpose, but must
+// acknowledge this project. Copyright is retained and
+// must be preserved. The work is provided as is; no
+// warranty is provided, and users accept all liability.
+//
+
+#include <Wire.h>
+
+#define address 0x35
+
+void setup() {
+   //
+   // start serial and I2C
+   //
+   Serial.begin(115200);
+   Wire.begin();
+   Wire.setClock(400000);
+   //
+   // reset TLE493D
+   //
+   Wire.beginTransmission(0);
+   Wire.write(0xFF);
+   Wire.endTransmission();
+   Wire.beginTransmission(0);
+   Wire.write(0xFF);
+   Wire.endTransmission();
+   Wire.beginTransmission(0);
+   Wire.write(0x00);
+   Wire.endTransmission();
+   Wire.beginTransmission(0);
+   Wire.write(0x00);
+   Wire.endTransmission();
+   delayMicroseconds(50);
+   //
+   // configure TLE493D
+   //
+   Wire.beginTransmission(address);
+   Wire.write(0x10);
+   Wire.write(0x28);
+      // config register 0x10
+      // ADC trigger on read after register 0x05
+      // short-range sensitivity
+   Wire.write(0x15);
+      // mode register 0x11
+      // 1-byte read protocol
+      // interrupt disabled
+      // master controlled mode
+   Wire.endTransmission();
+   }
+
+void loop() {
+   uint8_t v0,v1,v2,v3,v4,v5;
+   //
+   // read data
+   //
+   Wire.requestFrom(address,6);
+   v0 = Wire.read();
+   v1 = Wire.read();
+   v2 = Wire.read();
+   v3 = Wire.read();
+   v4 = Wire.read();
+   v5 = Wire.read();
+   //
+   // send framing
+   //
+   Serial.write(1);
+   Serial.write(2);
+   Serial.write(3);
+   Serial.write(4);
+   //
+   // send data
+   //
+   Serial.write(v0);
+   Serial.write(v1);
+   Serial.write(v2);
+   Serial.write(v3);
+   Serial.write(v4);
+   Serial.write(v5);
+   }
-- 
GitLab