Skip to content

Commit

Permalink
Merge pull request #1479 from ledvinap/test-gpio-retry
Browse files Browse the repository at this point in the history
Pi4 gpio timing experiment
  • Loading branch information
hzeller authored Jul 29, 2024
2 parents 816d982 + 4edddfa commit a0ea844
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
2 changes: 1 addition & 1 deletion examples-api-use/minimal-example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void DrawOnCanvas(Canvas *canvas) {
float angle_step = 1.0 / 360;
for (float a = 0, r = 0; r < radius_max; a += angle_step, r += angle_step) {
if (interrupt_received)
return;
return;
float dot_x = cos(a * 2 * M_PI) * r;
float dot_y = sin(a * 2 * M_PI) * r;
canvas->SetPixel(center_x + dot_x, center_y + dot_y,
Expand Down
27 changes: 19 additions & 8 deletions lib/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,23 @@ class GPIO {
inline void SetBits(gpio_bits_t value) {
if (!value) return;
WriteSetBits(value);
for (int i = 0; i < slowdown_; ++i) {
WriteSetBits(value);
}
delay();
}

// Clear the bits that are '1' in the output. Leave the rest untouched.
inline void ClearBits(gpio_bits_t value) {
if (!value) return;
WriteClrBits(value);
for (int i = 0; i < slowdown_; ++i) {
WriteClrBits(value);
}
delay();
}

// Write all the bits of "value" mentioned in "mask". Leave the rest untouched.
inline void WriteMaskedBits(gpio_bits_t value, gpio_bits_t mask) {
// Writing a word is two operations. The IO is actually pretty slow, so
// this should probably be unnoticable.
ClearBits(~value & mask);
SetBits(value & mask);
WriteClrBits(~value & mask);
WriteSetBits(value & mask);
delay();
}

inline gpio_bits_t Read() const { return ReadRegisters() & input_bits_; }
Expand All @@ -75,6 +72,20 @@ class GPIO {
static bool IsPi4();

private:
inline void delay() const {
switch(slowdown_) {
case -1:
#if __ARM_ARCH >= 7
asm volatile("dsb\tst");
#endif
break;
case 0:
break;
default:
for (int n = 0; n < slowdown_; n++)
*gpio_clr_bits_low_ = 0;
}
}
inline gpio_bits_t ReadRegisters() const {
return (static_cast<gpio_bits_t>(*gpio_read_bits_low_)
#ifdef ENABLE_WIDE_GPIO_COMPUTE_MODULE
Expand Down
4 changes: 3 additions & 1 deletion lib/led-matrix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,9 @@ RGBMatrix *RGBMatrix::CreateFromOptions(const RGBMatrix::Options &options,
}

// For the Pi4, we might need 2, maybe up to 4. Let's open up to 5.
if (runtime_options.gpio_slowdown < 0 || runtime_options.gpio_slowdown > 5) {
// on supproted architectures, -1 will emit memory barier (DSB ST) after GPIO write
if (runtime_options.gpio_slowdown < (__ARM_ARCH >= 7 ? -1 : 0)
|| runtime_options.gpio_slowdown > 5) {
fprintf(stderr, "--led-slowdown-gpio=%d is outside usable range\n",
runtime_options.gpio_slowdown);
return NULL;
Expand Down

0 comments on commit a0ea844

Please sign in to comment.