A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/hzeller/rpi-rgb-led-matrix/commit/829d40e9ff00dd315b8315e5647088fbd4d74a7f below:

Provide initial support for displays with AB line. Works for LED display · hzeller/rpi-rgb-led-matrix@829d40e · GitHub

@@ -60,7 +60,95 @@ PixelMapper::~PixelMapper() {

60 60

delete [] buffer_;

61 61

}

62 62 63 +

// Different panel types use different techniques to set the row address.

64 +

// We abstract that away with different implementations of RowAddressSetter

65 +

class RowAddressSetter {

66 +

public:

67 +

virtual ~RowAddressSetter() {}

68 +

virtual gpio_bits_t need_bits() const = 0;

69 +

virtual void SetRowAddress(GPIO *io, int row) = 0;

70 +

};

71 + 72 +

namespace {

73 + 74 +

// The default DirectRowAddressSetter just sets the address in parallel

75 +

// output lines ABCDE with A the LSB and E the MSB.

76 +

class DirectRowAddressSetter : public RowAddressSetter {

77 +

public:

78 +

DirectRowAddressSetter(int double_rows, const HardwareMapping &h)

79 +

: row_mask_(0), last_row_(-1) {

80 +

assert(double_rows <= 32); // need to resize row_lookup_

81 +

if (double_rows >= 32) row_mask_ |= h.e;

82 +

if (double_rows >= 16) row_mask_ |= h.d;

83 +

if (double_rows >= 8) row_mask_ |= h.c;

84 +

if (double_rows >= 4) row_mask_ |= h.b;

85 +

row_mask_ |= h.a;

86 +

for (int i = 0; i < double_rows; ++i) {

87 +

// To avoid the bit-fiddle in the critical path, utilize

88 +

// a lookup-table for all possible rows.

89 +

gpio_bits_t row_address = (i & 0x01) ? h.a : 0;

90 +

row_address |= (i & 0x02) ? h.b : 0;

91 +

row_address |= (i & 0x04) ? h.c : 0;

92 +

row_address |= (i & 0x08) ? h.d : 0;

93 +

row_address |= (i & 0x10) ? h.e : 0;

94 +

row_lookup_[i] = row_address;

95 +

}

96 +

}

97 + 98 +

virtual gpio_bits_t need_bits() const { return row_mask_; }

99 + 100 +

virtual void SetRowAddress(GPIO *io, int row) {

101 +

if (row == last_row_) return;

102 +

io->WriteMaskedBits(row_lookup_[row], row_mask_);

103 +

last_row_ = row;

104 +

}

105 + 106 +

private:

107 +

gpio_bits_t row_mask_;

108 +

gpio_bits_t row_lookup_[32];

109 +

int last_row_;

110 +

};

111 + 112 +

// This is mostly experimental at this point. It works with the one panel I have

113 +

// seen that does AB, but might need smallish tweaks to work with all panels

114 +

// that do this.

115 +

class ShiftRegisterRowAddressSetter : public RowAddressSetter {

116 +

public:

117 +

ShiftRegisterRowAddressSetter(int double_rows, const HardwareMapping &h)

118 +

: double_rows_(double_rows),

119 +

row_mask_(h.a | h.b), clock_(h.a), data_(h.b),

120 +

last_row_(-1) {

121 +

}

122 +

virtual gpio_bits_t need_bits() const { return row_mask_; }

123 + 124 +

virtual void SetRowAddress(GPIO *io, int row) {

125 +

if (row == last_row_) return;

126 +

for (int activate = 0; activate < double_rows_; ++activate) {

127 +

io->ClearBits(clock_);

128 +

if (activate == double_rows_ - 1 - row) {

129 +

io->ClearBits(data_);

130 +

} else {

131 +

io->SetBits(data_);

132 +

}

133 +

io->SetBits(clock_);

134 +

}

135 +

io->ClearBits(clock_);

136 +

io->SetBits(clock_);

137 +

last_row_ = row;

138 +

}

139 + 140 +

private:

141 +

const int double_rows_;

142 +

const gpio_bits_t row_mask_;

143 +

const gpio_bits_t clock_;

144 +

const gpio_bits_t data_;

145 +

int last_row_;

146 +

};

147 + 148 +

}

149 + 63 150

const struct HardwareMapping *Framebuffer::hardware_mapping_ = NULL;

151 +

RowAddressSetter *Framebuffer::row_setter_ = NULL;

64 152 65 153

Framebuffer::Framebuffer(int rows, int columns, int parallel,

66 154

int scan_mode,

@@ -155,7 +243,8 @@ Framebuffer::~Framebuffer() {

155 243 156 244

/* static */ void Framebuffer::InitGPIO(GPIO *io, int rows, int parallel,

157 245

bool allow_hardware_pulsing,

158 -

int pwm_lsb_nanoseconds) {

246 +

int pwm_lsb_nanoseconds,

247 +

int row_address_type) {

159 248

if (sOutputEnablePulser != NULL)

160 249

return; // already initialized.

161 250

@@ -174,11 +263,18 @@ Framebuffer::~Framebuffer() {

174 263

}

175 264 176 265

const int double_rows = rows / SUB_PANELS_;

177 -

if (double_rows >= 32) all_used_bits |= h.e;

178 -

if (double_rows >= 16) all_used_bits |= h.d;

179 -

if (double_rows >= 8) all_used_bits |= h.c;

180 -

if (double_rows >= 4) all_used_bits |= h.b;

181 -

all_used_bits |= h.a;

266 +

switch (row_address_type) {

267 +

case 0:

268 +

row_setter_ = new DirectRowAddressSetter(double_rows, h);

269 +

break;

270 +

case 1:

271 +

row_setter_ = new ShiftRegisterRowAddressSetter(double_rows, h);

272 +

break;

273 +

default:

274 +

assert(0); // unexpected type.

275 +

}

276 + 277 +

all_used_bits |= row_setter_->need_bits();

182 278 183 279

// Initialize outputs, make sure that all of these are supported bits.

184 280

const uint32_t result = io->InitOutputs(all_used_bits);

@@ -415,10 +511,6 @@ void Framebuffer::DumpToMatrix(GPIO *io) {

415 511 416 512

color_clk_mask |= h.clock;

417 513 418 -

const gpio_bits_t row_mask = h.a | h.b | h.c | h.d | h.e;

419 - 420 -

gpio_bits_t row_address;

421 - 422 514

// info needed for interlace mode.

423 515

uint8_t rot_bits = 0;

424 516

switch (double_rows_) {

@@ -441,12 +533,6 @@ void Framebuffer::DumpToMatrix(GPIO *io) {

441 533

d_row = ((row_loop << 1) | (row_loop >> rot_bits)) & row_mask_;

442 534

}

443 535 444 -

row_address = (d_row & 0x01) ? h.a : 0;

445 -

row_address |= (d_row & 0x02) ? h.b : 0;

446 -

row_address |= (d_row & 0x04) ? h.c : 0;

447 -

row_address |= (d_row & 0x08) ? h.d : 0;

448 -

row_address |= (d_row & 0x10) ? h.e : 0;

449 - 450 536

// Rows can't be switched very quickly without ghosting, so we do the

451 537

// full PWM of one row before switching rows.

452 538

for (int b = kBitPlanes - pwm_to_show; b < kBitPlanes; ++b) {

@@ -464,7 +550,8 @@ void Framebuffer::DumpToMatrix(GPIO *io) {

464 550

sOutputEnablePulser->WaitPulseFinished();

465 551 466 552

// Setting address and strobing needs to happen in dark time.

467 -

io->WriteMaskedBits(row_address, row_mask); // Set row address

553 +

row_setter_->SetRowAddress(io, d_row);

554 + 468 555

io->SetBits(h.strobe); // Strobe in the previously clocked in row.

469 556

io->ClearBits(h.strobe);

470 557

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4