Archived
1
0

move scan() to RowScanner_BitManipulation

This commit is contained in:
wolfv6 2016-06-05 22:00:33 -06:00
parent 11f20376b7
commit 042e099995
7 changed files with 129 additions and 99 deletions

View File

@ -15,9 +15,7 @@ void Row::process(const bool activeHigh)
uint8_t debouncedChanged; //1 means debounced changed uint8_t debouncedChanged; //1 means debounced changed
wait(); wait();
scan(activeHigh); //save column-port-pin values to portState //rowState = scanner.scan(rowEnd, activeHigh);
rowState = getRowState(rowEnd, activeHigh);
//debouncedChanged = debounce(rowState);
debouncedChanged = debouncer.debounce(rowState, debounced); debouncedChanged = debouncer.debounce(rowState, debounced);
pressRelease(rowEnd, debouncedChanged); pressRelease(rowEnd, debouncedChanged);
} }

View File

@ -2,6 +2,7 @@
#define ROW_H #define ROW_H
#include <RowBase.h> #include <RowBase.h>
#include <RowScanner_BitManipulation.h>
#include <Debouncer_4Samples.h> #include <Debouncer_4Samples.h>
/* /*
@ -17,14 +18,14 @@ Instantiation
class Row : public RowBase class Row : public RowBase
{ {
private: private:
RowScanner_BitManipulation scanner;
Debouncer_4Samples debouncer; Debouncer_4Samples debouncer;
public: public:
Row( RowPort &refRowPort, const uint8_t rowPin, Row( RowPort &refRowPort, const uint8_t rowPin,
ColPort *const ptrsColPorts[], const uint8_t colPortCount, Key *const ptrsKeys[]) ColPort *const ptrsColPorts[], const uint8_t colPortCount, Key *const ptrsKeys[])
: RowBase(refRowPort, rowPin, ptrsColPorts, colPortCount, ptrsKeys) : RowBase(ptrsKeys)
{ , RowScanner_BitManipulation scanner(refRowPort, rowPin, ptrsColPorts, colPortCount)
Debouncer_4Samples debouncer; { }
}
virtual void process(const bool activeHigh); virtual void process(const bool activeHigh);
}; };
#endif #endif

View File

@ -35,82 +35,6 @@ void RowBase::wait()
delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches
} }
/*
Strobes the row and reads the columns.
Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch.
*/
void RowBase::scan(const bool activeHigh)
{
//strobe row on
if (activeHigh)
{
refRowPort.setActivePinHigh(rowPin);
}
else //activeLow
{
refRowPort.setActivePinLow(rowPin);
}
//read all the column ports
for (uint8_t i=0; i < colPortCount; i++)
{
ptrsColPorts[i]->read();
}
//strobe row off
if (activeHigh)
{
refRowPort.setActivePinLow(rowPin);
}
else //activeLow
{
refRowPort.setActivePinHigh(rowPin);
}
}
/*
Copies column pins to rowState. Unused column pins are not copied.
Sets rowEnd and returns rowState.
rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row.
rowEnd and rowMask are larger type than portMask so that they can not overflow.
*/
uint8_t RowBase::getRowState(uint16_t& rowEnd, const bool activeHigh)
{
uint16_t rowMask = 1; //bitwise, one col per bit, active col bit is 1
uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed
for (uint8_t i=0; i < colPortCount; i++) //for each col port
{
//bitwise colPins, 1 means pin is connected to column
uint8_t colPins = ptrsColPorts[i]->getColPins();
//bitwise colPortState, pin values where set in ColPort::read(), get them now
uint8_t colPortState = ptrsColPorts[i]->getPortState();
if (activeHigh)
{
colPortState = ~colPortState;
}
for ( uint8_t portMask = 1; portMask > 0; portMask <<= 1 ) //shift portMask until overflow
{ //for each pin of col port
if (portMask & colPins) //if pin is connected to column
{
if (portMask & ~colPortState) //if pin detected a key press
{
rowState |= rowMask; //set rowState bit for that key
}
rowMask <<= 1; //shift rowMask to next key
}
}
}
rowEnd = rowMask;
return rowState;
}
/* /*
pressRelease() calls key's press() or release() function if it was pressed or released. pressRelease() calls key's press() or release() function if it was pressed or released.
Both parameters are bitwise. Both parameters are bitwise.

View File

@ -3,8 +3,6 @@
#include <Arduino.h> #include <Arduino.h>
#include <inttypes.h> #include <inttypes.h>
#include <Key.h> #include <Key.h>
#include <RowPort.h>
#include <ColPort.h>
/* RowBase is an abstract base class. /* RowBase is an abstract base class.
*/ */
@ -14,27 +12,14 @@ class RowBase
static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing
Key *const *const ptrsKeys; //array of Key pointers Key *const *const ptrsKeys; //array of Key pointers
RowPort &refRowPort; //this row's IC port
const uint8_t rowPin; //bitwise, 1 indicates IC pin connected to this row
ColPort *const *const ptrsColPorts; //array of column ports
const uint8_t colPortCount;
virtual void keyWasPressed(); virtual void keyWasPressed();
protected: protected:
uint8_t debounced; //bitwise, 1 means pressed, 0 means released uint8_t debounced; //bitwise, 1 means pressed, 0 means released
void wait(); void wait();
void scan(const bool activeHigh);
uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh);
void pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged); void pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged);
public: public:
RowBase( RowPort &refRowPort, const uint8_t rowPin, RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
ColPort *const ptrsColPorts[], const uint8_t colPortCount,
Key *const ptrsKeys[])
: ptrsKeys(ptrsKeys), refRowPort(refRowPort), rowPin(rowPin),
ptrsColPorts(ptrsColPorts), colPortCount(colPortCount),
debounced(0) { }
virtual void process(const bool activeHigh)=0; virtual void process(const bool activeHigh)=0;
}; };
#endif #endif

18
src/RowScannerInterface.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef ROWSCANNERINTERFACE_H
#define ROWSCANNERINTERFACE_H
/* RowScannerInterface is an interface class.
Sets rowEnd and returns rowState.
rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row.
rowEnd and rowMask are larger type than portMask so that they can not overflow.
*/
#include <Arduino.h>
#include <inttypes.h>
class RowScannerInterface
{
public:
virtual uint8_t scan(uint16_t& rowEnd, const bool activeHigh)=0;
};
#endif

View File

@ -0,0 +1,78 @@
#include "RowScanner_BitManipulation.h"
/*
Strobes the row and reads the columns.
Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch.
*/
uint8_t RowScanner_BitManipulation::scan(uint16_t& rowEnd, const bool activeHigh)
{
//strobe row on
if (activeHigh)
{
refRowPort.setActivePinHigh(rowPin);
}
else //activeLow
{
refRowPort.setActivePinLow(rowPin);
}
//read all the column ports
for (uint8_t i=0; i < colPortCount; i++)
{
ptrsColPorts[i]->read();
}
//strobe row off
if (activeHigh)
{
refRowPort.setActivePinLow(rowPin);
}
else //activeLow
{
refRowPort.setActivePinHigh(rowPin);
}
return getRowState(rowEnd, activeHigh);
}
/*
Copies column pins to rowState. Unused column pins are not copied.
Sets rowEnd and returns rowState.
rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row.
rowEnd and rowMask are larger type than portMask so that they can not overflow.
*/
uint8_t RowScanner_BitManipulation::getRowState(uint16_t& rowEnd, const bool activeHigh)
{
uint16_t rowMask = 1; //bitwise, one col per bit, active col bit is 1
uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed
for (uint8_t i=0; i < colPortCount; i++) //for each col port
{
//bitwise colPins, 1 means pin is connected to column
uint8_t colPins = ptrsColPorts[i]->getColPins();
//bitwise colPortState, pin values where set in ColPort::read(), get them now
uint8_t colPortState = ptrsColPorts[i]->getPortState();
if (activeHigh)
{
colPortState = ~colPortState;
}
for ( uint8_t portMask = 1; portMask > 0; portMask <<= 1 ) //shift portMask until overflow
{ //for each pin of col port
if (portMask & colPins) //if pin is connected to column
{
if (portMask & ~colPortState) //if pin detected a key press
{
rowState |= rowMask; //set rowState bit for that key
}
rowMask <<= 1; //shift rowMask to next key
}
}
}
rowEnd = rowMask;
return rowState;
}

View File

@ -0,0 +1,26 @@
#ifndef ROWSCANNER_BITMANIPULATION_H
#define ROWSCANNER_BITMANIPULATION_H
#include <Arduino.h>
#include <inttypes.h>
#include <RowScannerInterface.h>
#include <RowPort.h>
#include <ColPort.h>
class RowScanner_BitManipulation : public RowScannerInterface
{
private:
RowPort &refRowPort; //this row's IC port
const uint8_t rowPin; //bitwise, 1 indicates IC pin connected to this row
ColPort *const *const ptrsColPorts; //array of column ports
const uint8_t colPortCount;
public:
RowScanner_BitManipulation(RowPort &refRowPort, const uint8_t rowPin,
ColPort *const ptrsColPorts[], const uint8_t colPortCount)
: refRowPort(refRowPort), rowPin(rowPin),
ptrsColPorts(ptrsColPorts), colPortCount(colPortCount) {}
virtual uint8_t scan(uint16_t& rowEnd, const bool activeHigh);
uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh);
};
#endif