Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM
Diff: i2c_bit_banged.cpp
- 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");