Library to use my Photo MOS Relays Circuit having 16 or less channels.

Fork of PMRC4ch by Akifumi Takahashi

PMRC16ch.cpp

Committer:
aktk
Date:
9 months ago
Revision:
43:03e875137433
Parent:
42:a827fe9166b5

File content as of revision 43:03e875137433:


#include "PMRC16ch.h"
const uint32_t PMRC16ch::m_statearray[] = {
    ALLGROUND, CH1, CH2, CH3, CH4, CH5, CH6, CH7, CH8, CH9,
    CH10, CH11, CH12, CH13, CH14, CH15, CH16, ALLHiZ
};
//  A constractor whose arguments have all default value
//  is a default constractor.
PMRC16ch::PMRC16ch():
    m_num_ch(16),
    m_SCK(DigitalOut(p11)),
    m_CLR(DigitalOut(p12)),
    m_RCK(DigitalOut(p13)),
    m_SER(DigitalOut(p14)),
    m_OUT(DigitalIn(p10))
{
    init();
}
PMRC16ch::PMRC16ch(
    uint8_t arg_num_ch
):
    m_num_ch(arg_num_ch),
    m_SCK(DigitalOut(p11)),
    m_CLR(DigitalOut(p12)),
    m_RCK(DigitalOut(p13)),
    m_SER(DigitalOut(p14)),
    m_OUT(DigitalIn(p10))
{
    init();
}


PMRC16ch::PMRC16ch(
    uint8_t arg_num_ch,
    PinName arg_SCK,
    PinName arg_CLR,
    PinName arg_RCK,
    PinName arg_SER,
    PinName arg_OUT
):
    m_num_ch(arg_num_ch),
    m_SCK(DigitalOut(arg_SCK)),
    m_CLR(DigitalOut(arg_CLR)),
    m_RCK(DigitalOut(arg_RCK)),
    m_SER(DigitalOut(arg_SER)),
    m_OUT(DigitalIn(arg_OUT))
{
    init();
}
//  ----------------------------------------------------------------------------
void PMRC16ch::init()
{
    m_CLR = 1;
    m_SCK = m_RCK = 0;
    allHiZ();
    m_PMRC_mode = TWIN_ELECTRODES;
    m_PMRC_POL = Cathodic;
}

void PMRC16ch::allGround()
{
    if (m_PMRC_state == ALLGROUND) return;
    sweep();
    upload();
    m_PMRC_state = ALLGROUND;
    m_pos_stim = 0;
}

void PMRC16ch::allHiZ()
{
    //reset shiftresister
    m_CLR = 0;
    update();
    //enable insertion data to SR
    m_CLR = 1;
    upload();
    m_PMRC_state = ALLHiZ;
    m_pos_stim = 0;
}
//  ----------------------------------------------------------------------------
void PMRC16ch::setTwin(char arg_stim_ch, char arg_ref_ch)
{
    m_PMRC_mode = TWIN_ELECTRODES;
    m_PMRC_state = m_statearray[arg_stim_ch] + (m_statearray[arg_ref_ch] >> 1);
    setBits(m_PMRC_state);
    upload();
    m_pos_stim = arg_stim_ch;
}

void PMRC16ch::setTrio(char arg_stim_ch, char arg_ref_ch1, char arg_ref_ch2)
{
    m_PMRC_mode = TWIN_ELECTRODES;
    m_PMRC_state = m_statearray[arg_stim_ch] 
        + (m_statearray[arg_ref_ch1] >> 1)
        + (m_statearray[arg_ref_ch2] >> 1);
    setBits(m_PMRC_state);
    upload();
    m_pos_stim = arg_stim_ch;
}

void PMRC16ch::setOvsO(char arg_ch)
{
    int8_t num_of_shift;

    num_of_shift = arg_ch - m_pos_stim;
    //  m_PMRC_mode == ONE_VS_THEOTHERS && m_pos_stim == 0
    //  => m_PMRC_state == ALLGROUND
    if( num_of_shift < 0 || m_pos_stim == 0 || m_PMRC_mode != ONE_VS_THEOTHERS) {
        sweep();
        setStimbits();
        num_of_shift = arg_ch - 1;
    }
    shiftby(num_of_shift);
    m_PMRC_mode = ONE_VS_THEOTHERS;
    m_PMRC_state = ALLGROUND + m_statearray[arg_ch];

    upload();
    m_pos_stim = arg_ch;
}

//  ----------------------------------------------------------------------------

void PMRC16ch::sweep()
{
    uint32_t num_shift;

    if(m_PMRC_mode != ONE_VS_THEOTHERS || m_PMRC_state == ALLHiZ) {
        num_shift = m_num_ch;
    } else if(m_PMRC_mode == ONE_VS_THEOTHERS) {
        num_shift = m_num_ch - (m_pos_stim - 1);
    }
    shiftby(num_shift);
}

void PMRC16ch::shiftby(int arg_num)
{
    for(int i = 0; i < arg_num; i++) {
        //  insert 1 XOR Polarity
        m_SER = 1 ^ m_PMRC_POL;
        update();
        //  insert 0 XOR Polarity
        m_SER = 0 ^ m_PMRC_POL;
        update();
    }
}

void PMRC16ch::setStimbits()
{
    //  insert 0 XOR Polarity
    m_SER = 0 ^ m_PMRC_POL;
    update();
    //  insert 1 XOR Polarity
    m_SER = 1 ^ m_PMRC_POL;
    update();
    m_PMRC_state = CH1;
}

void PMRC16ch::setBits(const uint32_t arg_bits)
{
    /*  arg_bits: 0b xx xx xx xx ... xx xx xx
     *          ch1 <-                     ->ch[m_num_ch]
     */
     
    uint8_t tmp_bit[2];
    //reset shiftresister
    m_CLR = 0;
    update();
    //enable insertion data to SR
    m_CLR = 1;
    for(int i = 0; i < m_num_ch; i++) {
        tmp_bit[0] = 0b01 & (arg_bits >> (2 * i));
        tmp_bit[1] = 0b01 & (arg_bits >> (2 * i + 1));
        //  if the chan. is not HiZ meaning Hi or Lw
        if(tmp_bit[0] + tmp_bit[1] == 1) {
            m_SER = (tmp_bit[0] ^ m_PMRC_POL); //XOR Polarity
            update();
            m_SER = (tmp_bit[1] ^ m_PMRC_POL); //XOR Polarity
            update();
        } else {
            m_SER = (tmp_bit[0]);
            update();
            m_SER = (tmp_bit[1]);
            update();
        }
    }
}
//  ----------------------------------------------------------------------------
void PMRC16ch::update()
{
    //Shift-resister Clock update
    m_SCK = 1;
    m_SCK = 1;
    m_SCK = 0;
    m_SCK = 0;
}
void PMRC16ch::upload()
{
    //FF Clock Update
    m_RCK = 1;
    m_RCK = 1;
    m_RCK = 0;
    m_RCK = 0;
}