Jon Freeman / Mbed 2 deprecated Alternator2020_06

Dependencies:   mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM

Revision:
1:450090bdb6f4
Parent:
0:77803b3ee157
Child:
2:8e7b51353f32
diff -r 77803b3ee157 -r 450090bdb6f4 i2c_bit_banged.cpp
--- a/i2c_bit_banged.cpp	Fri Jun 28 19:32:51 2019 +0000
+++ b/i2c_bit_banged.cpp	Sat Apr 25 15:35:58 2020 +0000
@@ -1,14 +1,20 @@
 #include "mbed.h"
 #include "Alternator.h"
+#ifdef  TARGET_NUCLEO_L432KC    //
 extern  Serial  pc;
 DigitalInOut    SDA (D4);       //  Horrible bodge to get i2c working using bit banging.
 DigitalInOut    SCL (D5);       //  DigitalInOut do not work as you might expect. Fine if used only as OpenDrain opuputs though!
 DigitalIn       SDA_IN  (A4);   //  That means paralleling up with two other pins as inputs
 DigitalIn       SCL_IN  (A5);   //  This works but is a pain. Inbuilt I2C should have worked but never does on small boards with 32 pin cpu.
-
+const int ACK     = 0;  //  but acknowledge is 0, NAK is 1
+#endif
+#ifdef  TARGET_NUCLEO_F401RE    //
+extern  BufferedSerial  pc;
+extern  I2C i2c;
+const int ACK     = 1;  //  but acknowledge is 0, NAK is 1
+#endif
 const int _24LC_rd = 0xa1;  //  set bit 0 for read, clear bit 0 for write
 const int _24LC_wr = 0xa0;  //  set bit 0 for read, clear bit 0 for write
-const int ACK     = 0;  //  but acknowledge is 0, NAK is 1
 
 
 /*struct  optpar  {
@@ -39,7 +45,7 @@
 
 
 
-eeprom_settings mode  ;
+eeprom_settings user_settings  ;
 
 eeprom_settings::eeprom_settings    ()  {}
 
@@ -57,16 +63,25 @@
     return  settings[i];
 }
 
-bool    eeprom_settings::wr  (char c, uint32_t i)  {           //  Read one setup char value from private buffer 'settings'
+bool    eeprom_settings::rd  (char * c, uint32_t i)  {           //  Read one setup char value from private buffer 'settings'
+    if  (i > 31)    {
+        pc.printf   ("ERROR Attempt to read setting %d\r\n", i);
+        return  false;
+    }
+    *c = settings[i];
+    return  true;
+}
+
+bool    eeprom_settings::wr  (char c, uint32_t i)  {           //  Write one setup char value to private buffer 'settings'
     if  (i > 31)
         return  false;
     settings[i] = c;
     return  true;
 }
 
-int     eeprom_settings::get_pwm (int rpm)   {
+double  eeprom_settings::get_pwm (int rpm)   {
     int p = rpm * lut_size;
-    p /= 8000;  //  8000 is upper RPM limit
+    p /= 8000;  //  8000 is upper RPM limit, p now scaled to sizeof lut
     if  (p < 0) p = 0;                    //  point to first
     if  (p >= lut_size) p = lut_size - 1; //  point to last
 //    pc.printf   ("In get_pwm, rpm = %d, lut entry = %d, pwm = %d\r\n", rpm, p, max_pwm_lut[p]);
@@ -76,33 +91,29 @@
 void    eeprom_settings::build_lut   ()  {
     int ptr = 0;
     int range, i;
-    int base = mode.rd(RPM0) * PWM_PERIOD_US;
-    double  acc, incr;
-    base /= 100;    //  got pwm_pulsewidth of 0 RPM
-    acc = (double) base;
-    pc.printf   ("pwm_period_us ar 0 RPM = %d\r\n", base);
+    double  acc = 0.0, incr = 0.0;
     for (i = 0; i < 8; i++) {
-        range = mode.rd(i+1) - mode.rd(i);  //  range now change in percent between two 'n'000 RPMs
-        range *= mode.rd(PWM_SCALE);        //  range now 10000 times factor due to percentage twice
-        range *= PWM_PERIOD_US;
+        range = user_settings.rd(i+1) - user_settings.rd(i);  //  range now change in percent between two 'n'000 RPMs
         incr = (double)range;
-        incr /= 10000.0;
+        incr /= 100.0;  //  percent
         incr /= lut_seg_size;
         for(int j = 0; j < lut_seg_size; j++)   {
-            max_pwm_lut[ptr++] = (int)acc;
+            max_pwm_lut[ptr++] = acc;
             acc += incr;
         }
     }
     max_pwm_lut[ptr] = (int)acc;
     pc.printf   ("At end of build_lut ptr=%d\r\n", ptr);
     range = 0;
-//    while   (range < ptr)   {
-//        for (i = 0; i < 10; i++)    {
-//            pc.printf   ("%d\t", max_pwm_lut[range++]);
-//        }
-//        pc.printf   ("\r\n");
-//    }
+
+    while   (range < ptr)   {
+        for (i = 0; i < 8; i++)    {
+            pc.printf   ("%.3f\t", max_pwm_lut[range++]);
+        }
+        pc.printf   ("\r\n");
+    }
     pc.printf   ("lut_size = %d\r\n", lut_size);
+
 }
 
 bool    eeprom_settings::load    ()  {               //  Get 'settings' buffer from EEPROM
@@ -117,6 +128,7 @@
 }
 
 
+//#ifdef  TARGET_NUCLEO_L432KC    //
 
 /**
 *   bool    i2c_init(void) {
@@ -126,6 +138,7 @@
 *   a I2C bus lockup or that the lines are not pulled up.
 */
 bool    i2c_init(void) {
+#ifdef  TARGET_NUCLEO_L432KC    //
     SDA.output();
     SCL.output();
     SDA.mode(OpenDrain);
@@ -139,6 +152,11 @@
     wait_us (1);
     if  (SCL_IN == 0 || SDA_IN == 0)    return  false;
   return true;
+#endif
+#ifdef  TARGET_NUCLEO_F401RE    //
+//    return  i2c.init    ()  ; //  class has no member "init"
+    return  true;
+#endif
 }
 
 /**
@@ -152,6 +170,7 @@
 *   commands must be preceded by a Start condition.
 */
 int i2c_start  ()  {   // Should be Both hi, start takes SDA low
+#ifdef  TARGET_NUCLEO_L432KC    //
     int    rv = 0;
     if  (SDA_IN == 0 )  {
         rv |= 1;    //  Fault - SDA was lo on entry
@@ -168,6 +187,11 @@
     SCL = 0;
     wait_us (1);
     return  rv;     //  Returns 0 on success, 1 with SDA fault, 2 with SCL fault, 3 with SDA and SCL fault
+#endif
+#ifdef  TARGET_NUCLEO_F401RE    //
+    i2c.start   ()  ;
+    return  0;
+#endif
 }
 
 /**
@@ -181,6 +205,7 @@
 *   operations must be ended with a Stop condition.
 */
 int i2c_stop  ()  {   //  Should be SDA=0, SCL=1, start takes SDA hi
+#ifdef  TARGET_NUCLEO_L432KC    //
     int    rv = 0;
     SDA = 0;    //  Pull SDA to 0
     wait_us (1);
@@ -198,8 +223,14 @@
     if  (SDA_IN == 0)
         pc.printf   ("SDA stuck lo in stop\r\n");
     return  rv;     //  Returns 0 on success, 1 with SDA fault, 2 with SCL fault, 3 with SDA and SCL fault
+#endif
+#ifdef  TARGET_NUCLEO_F401RE    //
+    i2c.stop    ()  ;
+    return  0;
+#endif
 }
 
+#ifdef  TARGET_NUCLEO_L432KC    //
 void    jclk    (int bit)   {
     SCL = bit;
     wait_us (1);
@@ -212,8 +243,10 @@
     SCL = 0;
     wait_us (1);
 }
+#endif
 
 int i2c_write (int    d)  {
+#ifdef  TARGET_NUCLEO_L432KC    //
     int ackbit = 0;
     if  (SCL_IN != 0)   {
         pc.printf   ("SCL hi on entry to write\r\n");
@@ -230,12 +263,17 @@
     jclk    (0);    //  SCL = 0
 //    pc.printf   ("wr 0x%x %s\r\n", d, ackbit == 0 ? "ACK" : "nak");
     return  ackbit; //      0 for acknowledged ACK, 1 for NAK
+#endif
+#ifdef  TARGET_NUCLEO_F401RE    //
+    return  i2c.write   (d);
+#endif
 }
 
 
 
 
 int i2c_read    (int acknak)  {     //  acknak  indicates if the byte is to be acknowledged (0 = acknowledge)
+#ifdef  TARGET_NUCLEO_L432KC    //
     int result = 0;                 //  SCL should be 1 on entry
     SDA = 1;        //  Master released SDA
     if  (SCL_IN != 0)   pc.printf   ("SCL hi arriving at read\r\n");
@@ -253,6 +291,10 @@
     jclkout ();    //  clock out the ACK bit __--__
 //    pc.printf   ("rd 0x%x %s\r\n", result, acknak == 0 ? "ACK" : "nak");
     return  result;             //  Always ? nah
+#endif
+#ifdef  TARGET_NUCLEO_F401RE    //
+    return  i2c.read    (acknak)    ;
+#endif
 }
 
 int check_24LC64   ()  {     //  Call from near top of main() to init i2c bus
@@ -323,13 +365,15 @@
         pc.printf   ("Length out of range %d in wr_24LC64\r\n", length);
         return  false;
     }
+    ack_poll    ();
     if  (!set_24LC64_internal_address   (start_addr))   {
         pc.printf   ("In wr_24LC64, Believe Device present, failed in writing 2 mem addr bytes %d\r\n", err);
         return  false;
     }
-    while(length--) {
-        err += i2c_write(*source++);
-    }
+    while(length--) 
+        if  (i2c_write(*source++) != ACK)
+            err++;
+//        err += i2c_write(*source++);
     i2c_stop();
     if  (err)   {
         pc.printf   ("in wr_24LC64, device thought good, mem addr write worked, failed writing string\r\n");