encoder and tachometer class for EW3XX single board computer

Revision:
0:1d5bf13d7dbb
Child:
1:b33d4964669b
diff -r 000000000000 -r 1d5bf13d7dbb EW305sbc.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EW305sbc.cpp	Thu Aug 15 19:21:44 2019 +0000
@@ -0,0 +1,208 @@
+//#include "mbed.h"
+#include "EW305sbc.h"
+
+
+EW305sbc::EW305sbc(int ch, int pulsesPerRev) 
+    : ch_(ch), pulsesPerRev_(pulsesPerRev), spi(p5, p6, p7), ls7166_cs1(p19,1), ls7166_cs2(p20,1)
+{
+    init();
+}
+
+void EW305sbc::init()
+{
+    dt_ = 0.00625; // 125 Hz
+    speed_ = 0.0; // initial distance
+    countp_ = 0;
+    count_ = 0;
+    /** configure the rising edge to start the timer */
+    updater.attach(callback(this, &EW305sbc::recalc), 0.00625); // 125 Hz, syntax from https://os.mbed.com/forum/mbed/topic/1964/?page=1
+    wait(.2);   //delay at beginning for voltage settle purposes
+
+    // initialize channel 1 encoder by 
+    LS7366_reset_counter(ch_);
+    LS7366_quad_mode_x4(ch_);
+    LS7366_write_DTR(ch_,0);
+}
+
+
+void EW305sbc::recalc()
+{
+    // Read encoder
+    count_ = -LS7366_read_counter(ch_); // input is the encoder channel
+
+    // Estimate speed (counts/sec)
+    speed_ = (count_-countp_)/0.00625*2.0*3.14159/(4.0*pulsesPerRev_);
+
+    // Age variable
+    countp_ = count_;
+}
+
+
+int EW305sbc::getCount(void)
+{
+    return count_;
+}
+
+float EW305sbc::getSpeed(void)
+{
+    return speed_;
+}
+
+
+
+
+
+
+//---- Function Listing -------------------------------
+
+//----- LS7366 Encoder/Counter Routines --------------------
+void EW305sbc::LS7366_cmd(int inst,  int reg)
+{
+    char cmd;
+    spi.format(8, 0);
+    spi.frequency(2000000);
+    cmd = (inst << 6) | (reg << 3);
+//    printf("\r\ncmd=0X%2X", cmd);
+    spi.write(cmd);
+}
+
+long EW305sbc::LS7366_read_counter(int chan_num)
+{
+    union bytes {
+        char byte_enc[4];
+        long long_enc;
+    } counter;
+
+    counter.long_enc = 0;
+    spi.format(8, 0);
+    spi.frequency(2000000);
+
+    if(chan_num!=2) {
+        ls7166_cs1 = 0;
+        wait_us(1);
+        LS7366_cmd(LOAD,OTR);//cmd = 0xe8, LOAD to OTR
+        ls7166_cs1 = 1;
+        wait_us(1);
+        ls7166_cs1 = 0;
+    } else {
+        ls7166_cs2 = 0;
+        wait_us(1);
+        LS7366_cmd(LOAD,OTR);//cmd = 0xe8, LOAD to OTR
+        ls7166_cs2 = 1;
+        wait_us(1);
+        ls7166_cs2 = 0;
+    }
+    wait_us(1);
+    LS7366_cmd(RD,CNTR);  //cmd = 0x60, READ from CNTR
+    counter.byte_enc[3] = spi.write(0x00);
+    counter.byte_enc[2] = spi.write(0x00);
+    counter.byte_enc[1] = spi.write(0x00);
+    counter.byte_enc[0] = spi.write(0x00);
+
+    if(chan_num!=2) {
+        ls7166_cs1 = 1;
+    } else {
+        ls7166_cs2 = 1;
+    }
+
+    return counter.long_enc;  //return count
+}
+
+void EW305sbc::LS7366_quad_mode_x4(int chan_num)
+{
+
+    spi.format(8, 0);
+    spi.frequency(2000000);
+
+    if(chan_num!=2) {
+        ls7166_cs1 = 0;
+    } else {
+        ls7166_cs2 = 0;
+    }
+    wait_us(1);
+    LS7366_cmd(WR,MDR0);// Write to the MDR0 register
+    wait_us(1);
+    spi.write(0x03); // X4 quadrature count mode
+    if(chan_num!=2) {
+        ls7166_cs1 = 1;
+    } else {
+        ls7166_cs2 = 1;
+    }
+}
+
+void EW305sbc::LS7366_reset_counter(int chan_num)
+{
+    spi.format(8, 0);           // set up SPI for 8 data bits, mode 0
+    spi.frequency(2000000);     // 2MHz SPI clock
+
+    if(chan_num!=2) {           // activate chip select
+        ls7166_cs1 = 0;
+    } else {
+        ls7166_cs2 = 0;
+    }
+    wait_us(1);                 // short delay
+    LS7366_cmd(CLR,CNTR);       // Clear the counter register
+    if(chan_num!=2) {           // de-activate chip select
+        ls7166_cs1 = 1;
+    } else {
+        ls7166_cs2 = 1;
+    }
+    wait_us(1);                 // short delay
+
+    if(chan_num!=2) {           // activate chip select
+        ls7166_cs1 = 0;
+    } else {
+        ls7166_cs2 = 0;
+    }
+    wait_us(1);                 // short delay
+    LS7366_cmd(LOAD,CNTR);      // load counter reg
+    if(chan_num!=2) {           // de-activate chip select
+        ls7166_cs1 = 1;
+    } else {
+        ls7166_cs2 = 1;
+    }
+}
+
+void EW305sbc::LS7366_write_DTR(int chan_num, long enc_value)
+{
+    union bytes {              // Union to speed up byte writes
+        char byte_enc[4];
+        long long_enc;
+    } counter;
+
+    spi.format(8, 0);           // set up SPI for 8 data bits, mode 0
+    spi.frequency(2000000);     // 2MHz SPI clock
+
+    counter.long_enc = enc_value; // pass enc_value to Union
+
+    if(chan_num!=2) {             // activate chip select
+        ls7166_cs1 = 0;
+    } else {
+        ls7166_cs2 = 0;
+    }
+    wait_us(1);                 // short delay
+    LS7366_cmd(WR,DTR);         // Write to the Data Transfer Register
+    spi.write(counter.byte_enc[3]); // Write the 32-bit encoder value
+    spi.write(counter.byte_enc[2]);
+    spi.write(counter.byte_enc[1]);
+    spi.write(counter.byte_enc[0]);
+    if(chan_num!=2) {           // de-activate the chip select
+        ls7166_cs1 = 1;
+    } else {
+        ls7166_cs2 = 1;
+    }
+
+    wait_us(1);                 // short delay
+    if(chan_num!=2) {           // activate chip select
+        ls7166_cs1 = 0;
+    } else {
+        ls7166_cs2 = 0;
+    }
+    wait_us(1);                 // short delay
+    LS7366_cmd(LOAD,CNTR);      // load command to the counter register from DTR
+    if(chan_num!=2) {           // de-activate chip select
+        ls7166_cs1 = 1;
+    } else {
+        ls7166_cs2 = 1;
+    }
+}
\ No newline at end of file