IHS1.1-STM32F303K8

Dependents:   Nucleo_IHS11a

Sensor.cpp

Committer:
maro
Date:
2020-10-23
Revision:
1:ace656587248
Parent:
0:cf6cdf2e5565

File content as of revision 1:ace656587248:

#include "Sensor.h"
#include "CLED.h"
#include "mbed.h"
// ************************* Object ********************************
Timer t;
extern CLED cled;
// *************************** SPI ********************************
SPI spi(D11, D12, D13); // mosi, miso, sclk
Serial uart(USBTX, USBRX);
// *************************** GPIO ********************************
#ifdef EVERY
DigitalOut ss(D8);          // *** D8 ***
DigitalOut oe_cled(D10);     // 13:OE_CLED *** D10 ***
DigitalIn oe_cled_in(D10);   // 13:OE_CLED *** D10 ***
#else
DigitalOut ss(D10);         // *** D8 ***
DigitalOut oe_cled(D8);     // 13:OE_CLED *** D10 ***
DigitalIn oe_cled_in(D8);   // 13:OE_CLED *** D10 ***
#endif

DigitalOut abc[3] = {DigitalOut(D2),DigitalOut(D3),DigitalOut(D4)};// column
DigitalOut xyz[4] = {DigitalOut(A0),DigitalOut(A1),DigitalOut(A3),DigitalOut(A6)};// row
/*ss:   pin 10                 6:SS
  MOSI: pin 13                7:MOSI
  MISO: pin 12                8:MISO
  SCK:  pin 11                 9:CLK  */
DigitalOut sel_sen(D5);     // 10:power off while LED on
DigitalOut oe_iled(D6);     // 11:OE_ILED
DigitalOut fix_cled(D7);    // 12:FIX_CLED
PwmOut pwm_cled(D9);        // 14:PWM_CLED
// ********************** global function *******************************
void out3bit(DigitalOut ary[], int val) {
    int size = 3;
    if ((ROW_LEN == 16) && (ary == xyz)) size = 4;//(ROW_LEN == 16) &&
    for (int i=0; i < size; i++)
        ary[i] = (val >> i) & 0x01;
}

int noMinus(int n) {
  if (n < 0) return 0;
  return n;
}

// **********************************************************************
int Sensor::cri[CRI_LEN] = {90,135,195,275,390,535,720,990,1300,1750,2200,2800};
int Sensor::adAryInit[ROW_LEN][COL_LEN];
Sensor::Sensor(int correction) {
    for (int i = 0; i < CRI_LEN; i++) {
        cri[i] += correction;
    }
    spi.format(8,0);
    spi.frequency(2000000);
    uart.baud(9600);
}

void Sensor::setAd(bool bAdd) {     // bAdd:add val to adAryInit[][]
    for (int row = 0; row < ROW_LEN; row++) {
        out3bit(xyz, row);
        for (int col = 0; col < COL_LEN; col++) {
            setCol(row, col, bAdd);
        }
        if (!bAdd)                  // set CLED
            cled.set(val12, row == ROW_LEN - 1);// sensor-data, indicator
    }
}

int Sensor::getColVal(int c) {
    return val12[c];
}
int Sensor::getColAd(int c) {
    return adAry[c];
}

void Sensor::pCri() {               // print criteria
    char tStr[32];                  // temporary string
    for (int i = 0; i < CRI_LEN; i++) {
        sprintf(tStr, "\rcri:%d, val:%d:b",  i, cri[i]);
        uart.printf("%s",tStr);
    }
    uart.printf("\r");              // CRLF
}

void Sensor::set_adAryInit() {
    const int INIT_MS = 1200;
    pwm_cled.period(4e-3);          // PWM-period:4mS
    pwm_cled.write(0.1);            // duty 25% (measured value)
    int cnt = 0;
// ***************** set adAryInit[][] value ******************
    t.start();
    while (t.read_ms() < INIT_MS) {
        setAd(true);
        cnt++;
    }
    t.stop();
    t.reset();
    for (int row = 0; row < ROW_LEN; row++) {
        for (int col = 0; col < COL_LEN; col++) {
            adAryInit[row][col] = adAryInit[row][col] / cnt;
        }
    }
    if (ROW_LEN == 1) t.start();    // for ILED interval > 150uS : 1.2mS / 8
}

unsigned int Sensor::getAdc(int col) {
    ss = 0;                         //digitalWrite(ss, LOW);
    spi.write(6 | (col >> 2));//
    unsigned char r1 = spi.write(col << 6);      
    unsigned char r2 = spi.write(0);
    ss = 1;                         //digitalWrite(ss, HIGH);
    return ((r1 & 0x0f) << 8) + r2;
}

void Sensor::setCol(int row, int col, bool bAdd) {
    if ((ROW_LEN == 1) && !bAdd) set_ILED_cycle_1200uS(t, 119); // 119:actual survay 150uS
    bool ledSta = oe_cled_in;
    oe_cled = 0;                    //digitalWrite(oe_cled, LOW);
    wait_us(50);
    out3bit(abc, col);
    sel_sen = 1;                    //digitalWrite(sel_sen, HIGH);
    oe_iled = 0;                    //digitalWrite(oe_iled, LOW);     // ILED-OFF
    int vOff = getAdc(col);
    oe_iled = 1;                    //digitalWrite(oe_iled, HIGH);    // ILED-ON
    int vOn = getAdc(col);      
    sel_sen = 0;                    //digitalWrite(sel_sen, LOW);
    oe_iled = 0;                    //digitalWrite(oe_iled, LOW);     // ILED-OFF
    oe_cled = ledSta;               //digitalWrite(oe_cled, ledSta);
    if (bAdd)
        adAryInit[row][col] += vOn - vOff - (vOff >> 2) + (vOn >> 4);
    else
        adAry[col] = noMinus(vOn - vOff - (vOff >> 2) + (vOn >> 4) - adAryInit[row][col]);
    val12[col] = ad2val(adAry[col]);
}

void Sensor::set_ILED_cycle_1200uS(Timer& t0, const int COL_US) {   // COL_US:col interval:150us, cycle:1.2mS
    int us = t.read_us();
    while (us < COL_US) {
        us = t.read_us();
    }
    t.stop();
    t.reset();
    t.start();
}

int Sensor::ad2val(int ad) {  // div6 true:1~6 false:1~12
    for (int i = 0; i < CRI_LEN; i++)
        if (ad < cri[i]) return i;
    return CRI_LEN;
}