Skip to content

Commit

Permalink
Set single segment on 7 Segment displays (#295)
Browse files Browse the repository at this point in the history
  • Loading branch information
elral authored Sep 4, 2024
1 parent 0c564d2 commit 52dba44
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 12 deletions.
Empty file added CustomDevices
Empty file.
1 change: 1 addition & 0 deletions src/CommandMessenger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void attachCommandCallbacks()
cmdMessenger.attach(kInitModule, LedSegment::OnInitModule);
cmdMessenger.attach(kSetModule, LedSegment::OnSetModule);
cmdMessenger.attach(kSetModuleBrightness, LedSegment::OnSetModuleBrightness);
cmdMessenger.attach(kSetModuleSingleSegment, LedSegment::OnSetModuleSingleSegment);
#endif

cmdMessenger.attach(kSetPin, Output::OnSet);
Expand Down
53 changes: 50 additions & 3 deletions src/MF_Segment/LedControl_dual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//

#include "LedControl_dual.h"
#include "allocateMem.h"

// Segments to be switched on for characters and digits on 7-Segment Displays
// bit/segment sequence: dABCDEFG
Expand Down Expand Up @@ -73,7 +74,7 @@ enum {
};

#ifdef LEDCONTROL_NO_BUF
uint8_t LedControl::rawdata[16] = {0};
uint8_t *LedControl::rawdata;
#endif

// =======================================================================
Expand Down Expand Up @@ -132,15 +133,24 @@ uint8_t LedControl::rawdata[16] = {0};
// Digit sequence map for 6 digit displays
const uint8_t digitmap[] = {2, 1, 0, 5, 4, 3};

void LedControl::begin(uint8_t type, uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t numDevices)
bool LedControl::begin(uint8_t type, uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t numDevices)
{
_type = type;
_dataPin = dataPin;
_clkPin = clkPin;
_csPin = csPin;

if (!FitInMemory(sizeof(uint8_t) * numDevices * 2))
return false;
rawdata = new (allocateMemory(sizeof(uint8_t) * numDevices * 2)) uint8_t;

if (isMAX()) {
if ((numDevices - 1) > 7) numDevices = 8;
// make sure we have max 8 chips in the daisy chain
if (numDevices > 8) numDevices = 8;

if (!FitInMemory(sizeof(uint8_t) * numDevices * 8))
return false;
digitBuffer = new (allocateMemory(sizeof(uint8_t) * numDevices * 8)) uint8_t;
maxUnits = numDevices;
pinMode(_dataPin, OUTPUT);
pinMode(_clkPin, OUTPUT);
Expand All @@ -165,6 +175,8 @@ void LedControl::begin(uint8_t type, uint8_t dataPin, uint8_t clkPin, uint8_t cs
brightness = MAX_BRIGHTNESS;
shutdown(0, true);
}

return true;
}

void LedControl::shutdown(uint8_t addr, bool b)
Expand Down Expand Up @@ -238,13 +250,48 @@ void LedControl::setChar(uint8_t addr, uint8_t digit, char value, bool dp, bool
setPattern(addr, digit, v, sendNow);
}

void LedControl::setSingleSegment(uint8_t subModule, uint8_t segment, uint8_t value, bool sendNow)
{
uint8_t digit = segment >> 3;
uint8_t bitPosition = segment % 8;
uint8_t offset = subModule * 8;

if (isMAX()) {
if (subModule >= maxUnits) return;
if (segment > 63) return;
if (value) {
digitBuffer[offset + digit] |= (1 << bitPosition);
} else {
digitBuffer[offset + digit] &= ~(1 << bitPosition);
}
spiTransfer(subModule, digit + 1, digitBuffer[offset + digit]);
} else {
if (subModule >= maxUnits) return;
if (segment >= maxUnits * 8) return;
// Same order as MAX72XX
// MAX72XX order is: dABCDEFG
// TM1637 order required: ABCDEFGd
bitPosition++;
if (bitPosition == 8)
bitPosition = 0;
if (value) {
rawdata[(maxUnits - 1) - digit] |= (1 << bitPosition);
} else {
rawdata[(maxUnits - 1) - digit] &= ~(1 << bitPosition);
}
if (sendNow) writeDigits(digit, 1);
}
}

void LedControl::setPattern(uint8_t addr, uint8_t digit, uint8_t value, bool sendNow)
{
if (digit > getDigitCount() - 1) return;
uint8_t v;
v = pgm_read_byte_near(charTable + (value & 0x7F));
if (isMAX()) {
uint8_t offset = addr * 8;
if (value & 0x80) v |= 0x80;
digitBuffer[offset + digit] = v;
spiTransfer(addr, digit + 1, v); // Always send immediately for MAX
} else {
// Original data for MAX has the bit sequence: dABCDEFG
Expand Down
19 changes: 14 additions & 5 deletions src/MF_Segment/LedControl_dual.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,21 @@ class LedControl
uint8_t _dataPin = TYPE_UNDEFINED;
uint8_t _clkPin = TYPE_UNDEFINED;
uint8_t _csPin = TYPE_UNDEFINED;
// MAX: Number of chained units
// TM: Number of digits (4 or 6)
#ifdef LEDCONTROL_NO_BUF
// For TM, buffer can't be static (= shared): either we are building
// the extended version (which adds a per-unit buffer instead of the static one)
// or we are forced to resort to digit-by-digit output
static uint8_t rawdata[16];
static uint8_t *rawdata;
#else
uint8_t rawdata[16];
uint8_t *rawdata;
#endif

uint8_t maxUnits = 0; // MAX: N. of chained units; TM: N. of digits
uint8_t brightness = MAX_BRIGHTNESS;
void setPattern(uint8_t addr, uint8_t digit, uint8_t value, bool sendNow = true);

// MAX-specific
uint8_t *digitBuffer; // each digit must be stored in a buffer to be able to set single segments
void setScanLimit(uint8_t addr, uint8_t limit);
void spiTransfer(uint8_t addr, uint8_t opcode, uint8_t data);

Expand All @@ -103,7 +102,7 @@ class LedControl
public:
LedControl(){};

void begin(uint8_t type, uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t numDevices = 1);
bool begin(uint8_t type, uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t numDevices = 1);

bool isMAX(void) { return _type == LedSegment::TYPE_MAX72XX; }
uint8_t getDeviceCount(void) { return (isMAX() ? maxUnits : 1); };
Expand Down Expand Up @@ -139,6 +138,16 @@ class LedControl
// Ignored for MAX, or if LEDCONTROL_NO_BUF is defined.
void setChar(uint8_t addr, uint8_t digit, char value, bool dp = false, bool sendNow = true);

// Display a Single Segment.
// Params:
// addr address of the display (ignored for TM)
// segment the segment to be set or unset
// value set or unset the Segment
// sendnow If false, buffers chars rather than sending them immediately (TM only;
// requires a sendAll() afterwards).
// Ignored for MAX, or if LEDCONTROL_NO_BUF is defined.
void setSingleSegment(uint8_t addr, uint8_t segment, uint8_t value, bool sendNow = true);

#ifndef LEDCONTROL_NO_BUF
// Sends the whole (previously filled) buffer content.
void sendAll(void) { writeBuffer(); };
Expand Down
25 changes: 24 additions & 1 deletion src/MF_Segment/LedSegment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ namespace LedSegment
{
if (ledSegmentsRegistered == ledSegmentsRegistereds)
return;

ledSegments[ledSegmentsRegistered] = MFSegments();
ledSegments[ledSegmentsRegistered].attach(type, dataPin, csPin, clkPin, numDevices, brightness);

if (!ledSegments[ledSegmentsRegistered].attach(type, dataPin, csPin, clkPin, numDevices, brightness))
{
cmdMessenger.sendCmd(kStatus, F("Led Segment array does not fit into Memory"));
return;
}

ledSegmentsRegistered++;
#ifdef DEBUG2CMDMESSENGER
cmdMessenger.sendCmd(kDebug, F("Added Led Segment"));
Expand Down Expand Up @@ -78,6 +85,22 @@ namespace LedSegment
int brightness = cmdMessenger.readInt16Arg();
ledSegments[module].setBrightness(subModule, brightness);
}

void OnSetModuleSingleSegment()
{
uint8_t module = (uint8_t)cmdMessenger.readInt16Arg();
uint8_t subModule = (uint8_t)cmdMessenger.readInt16Arg();
char *segment = cmdMessenger.readStringArg(); // 0 to 63, multiple segments deliminited by '|'
uint8_t on_off = (uint8_t)cmdMessenger.readInt16Arg(); // 0 or 1

char *pinTokens = strtok(segment, "|");
while (pinTokens != 0) {
uint8_t num = (uint8_t)atoi(pinTokens);
ledSegments[module].setSingleSegment(subModule, num, on_off);
pinTokens = strtok(0, "|");
}
}

} // namespace

// LedSegment.cpp
1 change: 1 addition & 0 deletions src/MF_Segment/LedSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace LedSegment
void OnInitModule();
void OnSetModule();
void OnSetModuleBrightness();
void OnSetModuleSingleSegment();
}

// LedSegment.h
20 changes: 18 additions & 2 deletions src/MF_Segment/MFSegments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//

#include "MFSegments.h"
#include "commandmessenger.h"

MFSegments::MFSegments()
{
Expand All @@ -26,10 +27,20 @@ void MFSegments::display(uint8_t module, char *string, uint8_t points, uint8_t m
}
}

void MFSegments::setSingleSegment(uint8_t module, uint8_t segment, uint8_t on_off)
{
if (_moduleCount == 0)
return;

_ledControl.setSingleSegment(module, segment, on_off);

}

void MFSegments::setBrightness(uint8_t module, uint8_t value)
{
if (_moduleCount == 0)
return;

if (module < _moduleCount) {
if (value) {
_ledControl.setIntensity(module, value - 1);
Expand All @@ -40,15 +51,20 @@ void MFSegments::setBrightness(uint8_t module, uint8_t value)
}
}

void MFSegments::attach(uint8_t type, uint8_t dataPin, uint8_t csPin, uint8_t clkPin, uint8_t moduleCount, uint8_t brightness)
bool MFSegments::attach(uint8_t type, uint8_t dataPin, uint8_t csPin, uint8_t clkPin, uint8_t moduleCount, uint8_t brightness)
{
_ledControl.begin(type, dataPin, clkPin, csPin, moduleCount);
if (!_ledControl.begin(type, dataPin, clkPin, csPin, moduleCount))
return false;

_moduleCount = moduleCount;

for (uint8_t i = 0; i < _moduleCount; ++i) {
setBrightness(i, brightness);
_ledControl.shutdown(i, false);
_ledControl.clearDisplay(i);
}

return true;
}

void MFSegments::detach()
Expand Down
3 changes: 2 additions & 1 deletion src/MF_Segment/MFSegments.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ class MFSegments
public:
MFSegments();
void display(uint8_t module, char *string, uint8_t points, uint8_t mask, bool convertPoints = false);
void attach(uint8_t type, uint8_t dataPin, uint8_t csPin, uint8_t clkPin, uint8_t moduleCount, uint8_t brightness);
bool attach(uint8_t type, uint8_t dataPin, uint8_t csPin, uint8_t clkPin, uint8_t moduleCount, uint8_t brightness);
void detach();
void test();
void powerSavingMode(bool state);
void setBrightness(uint8_t module, uint8_t value);
void setSingleSegment(uint8_t module, uint8_t segment, uint8_t on_off);

private:
LedControl _ledControl;
Expand Down
1 change: 1 addition & 0 deletions src/commandmessenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ enum {
kDigInMuxChange, // 30
kSetStepperSpeedAccel, // 31
kSetCustomDevice, // 32
kSetModuleSingleSegment, // 33
kDebug = 0xFF // 255
};

Expand Down

0 comments on commit 52dba44

Please sign in to comment.