lgpio 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/examples/{i2c_bitbang_search.rb → i2c_bb_search.rb} +2 -3
- data/examples/pwm_hw_bench.rb +20 -0
- data/ext/lgpio/lgpio.c +123 -290
- data/lib/lgpio/version.rb +1 -1
- metadata +26 -27
- data/examples/i2c_bitbang_aht10.rb +0 -40
- data/examples/i2c_bitbang_ssd1306_bench.rb +0 -35
- /data/examples/{bench_in.rb → gpio_bench_in.rb} +0 -0
- /data/examples/{bench_out.rb → gpio_bench_out.rb} +0 -0
- /data/examples/{blink.rb → gpio_blink.rb} +0 -0
- /data/examples/{group_in.rb → gpio_group_in.rb} +0 -0
- /data/examples/{group_out.rb → gpio_group_out.rb} +0 -0
- /data/examples/{momentary.rb → gpio_momentary.rb} +0 -0
- /data/examples/{reports.rb → gpio_reports.rb} +0 -0
- /data/examples/{rotary_encoder.rb → gpio_rotary_encoder.rb} +0 -0
- /data/examples/{rotary_encoder_led.rb → gpio_rotary_encoder_led.rb} +0 -0
- /data/examples/{wave.rb → gpio_wave.rb} +0 -0
- /data/examples/{i2c_bitbang-rb_aht10.rb → i2c_bb_aht10.rb} +0 -0
- /data/examples/{i2c_bitbang-rb_ssd1306_bench.rb → i2c_bb_ssd1306_bench.rb} +0 -0
- /data/examples/{i2c_aht10.rb → i2c_hw_aht10.rb} +0 -0
- /data/examples/{i2c_aht10_zip.rb → i2c_hw_aht10_zip.rb} +0 -0
- /data/examples/{i2c_ssd1306_bench.rb → i2c_hw_ssd1306_bench.rb} +0 -0
- /data/examples/{servo.rb → pwm_hw_servo.rb} +0 -0
- /data/examples/{pwm.rb → pwm_sw.rb} +0 -0
- /data/examples/{spi_bitbang_loopback.rb → spi_bb_loopback.rb} +0 -0
- /data/examples/{spi_bitbang_ssd1306_sim_bench.rb → spi_bb_sim_bench.rb} +0 -0
- /data/examples/{spi_bitbang_ssd1306_bench.rb → spi_bb_ssd1306_bench.rb} +0 -0
- /data/examples/{spi_loopback.rb → spi_hw_loopback.rb} +0 -0
- /data/examples/{spi_ws2812.rb → spi_hw_ws2812.rb} +0 -0
- /data/examples/{spi_ws2812_bounce.rb → spi_hw_ws2812_bounce.rb} +0 -0
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 175af29acc6f0bb362dc017458e1ca9948f5d0c73ac0693f4a06b2e4e64f2842
         | 
| 4 | 
            +
              data.tar.gz: c7eebe2b025a40e98c3e7fc7574eb1f7572e7c147a88a32d7b4a9bfdb0cb0882
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: e3f5bfc169dfeb319fdfc06c4de1058682e9bee1f547a9eebecc1eb9ad2d50403bda912a67aef171e66b828d22740b04925b83c0e3494204c73c0b32dbbe7931
         | 
| 7 | 
            +
              data.tar.gz: f3d17767bf96c7af4631945ac0a7812628698cb483634fc0c1a45513a8ac5107bc613799be32b95b2c4b251e51a4c95c253f107691767d5351b8b1e073f5d965
         | 
| @@ -5,9 +5,8 @@ SCL_PIN   = 228 | |
| 5 5 | 
             
            SDA_PIN   = 270
         | 
| 6 6 |  | 
| 7 7 | 
             
            chip_handle = LGPIO.chip_open(GPIO_CHIP)
         | 
| 8 | 
            -
            LGPIO. | 
| 9 | 
            -
             | 
| 10 | 
            -
            devices = LGPIO.i2c_bb_search(chip_handle, SCL_PIN, SDA_PIN)
         | 
| 8 | 
            +
            i2c_bb = LGPIO::I2CBitBang.new(chip_handle, SCL_PIN, SDA_PIN)
         | 
| 9 | 
            +
            devices = i2c_bb.search
         | 
| 11 10 |  | 
| 12 11 | 
             
            if devices.empty?
         | 
| 13 12 | 
             
              puts "No devices found on I2C bus"
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require 'lgpio'
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Writing directly to a hardware PWM channel.
         | 
| 4 | 
            +
            # Arguments in order are:
         | 
| 5 | 
            +
            #   pwmchip index (X in /sys/class/pwm/pwmchipX/)
         | 
| 6 | 
            +
            #   PWM channel on the chip (Y in /sys/class/pwm/pwmchipX/pwmY)
         | 
| 7 | 
            +
            #   period: given in nanoseconds
         | 
| 8 | 
            +
            #   OR frequency: given in Hz
         | 
| 9 | 
            +
            #
         | 
| 10 | 
            +
            pwm_out = LGPIO::HardwarePWM.new(0, 1, period: 20_000_000)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            RUNS = 250_000
         | 
| 13 | 
            +
            start = Time.now
         | 
| 14 | 
            +
            RUNS.times do
         | 
| 15 | 
            +
              pwm_out.duty_us = 1000
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
            finish = Time.now
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            wps = RUNS / (finish - start)
         | 
| 20 | 
            +
            puts "Hardware PWM writes per second: #{wps.round(2)}"
         | 
    
        data/ext/lgpio/lgpio.c
    CHANGED
    
    | @@ -3,13 +3,19 @@ | |
| 3 3 | 
             
            #include <stdio.h>
         | 
| 4 4 | 
             
            #include <time.h>
         | 
| 5 5 |  | 
| 6 | 
            -
             | 
| 6 | 
            +
            /*****************************************************************************/
         | 
| 7 | 
            +
            /*                           GPIO REPORT QUEUE                               */
         | 
| 8 | 
            +
            /*****************************************************************************/
         | 
| 7 9 | 
             
            static pthread_mutex_t queueLock;
         | 
| 10 | 
            +
            // Set up a queue for up to 2**16 GPIO reports.
         | 
| 8 11 | 
             
            #define QUEUE_LENGTH UINT16_MAX + 1
         | 
| 9 12 | 
             
            static lgGpioReport_t reportQueue[QUEUE_LENGTH];
         | 
| 10 13 | 
             
            static uint16_t qWritePos = 1;
         | 
| 11 14 | 
             
            static uint16_t qReadPos  = 0;
         | 
| 12 15 |  | 
| 16 | 
            +
            /*****************************************************************************/
         | 
| 17 | 
            +
            /*                             TIMING HELPERS                                */
         | 
| 18 | 
            +
            /*****************************************************************************/
         | 
| 13 19 | 
             
            static uint64_t nanoDiff(const struct timespec *event2, const struct timespec *event1) {
         | 
| 14 20 | 
             
              uint64_t event2_ns = (uint64_t)event2->tv_sec * 1000000000LL + event2->tv_nsec;
         | 
| 15 21 | 
             
              uint64_t event1_ns = (uint64_t)event1->tv_sec * 1000000000LL + event1->tv_nsec;
         | 
| @@ -36,6 +42,9 @@ static void microDelay(uint64_t micros) { | |
| 36 42 | 
             
              nanoDelay(micros * 1000);
         | 
| 37 43 | 
             
            }
         | 
| 38 44 |  | 
| 45 | 
            +
            /*****************************************************************************/
         | 
| 46 | 
            +
            /*                              CHIP & GPIO                                 */
         | 
| 47 | 
            +
            /*****************************************************************************/
         | 
| 39 48 | 
             
            static VALUE chip_open(VALUE self, VALUE gpio_dev) {
         | 
| 40 49 | 
             
              int result = lgGpiochipOpen(NUM2INT(gpio_dev));
         | 
| 41 50 | 
             
              return INT2NUM(result);
         | 
| @@ -162,103 +171,9 @@ static VALUE gpio_get_report(VALUE self){ | |
| 162 171 | 
             
              return (popped) ? hash : Qnil;
         | 
| 163 172 | 
             
            }
         | 
| 164 173 |  | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
              int echo              = NUM2UINT(rbEcho);
         | 
| 169 | 
            -
              uint32_t triggerTime  = NUM2UINT(rbTriggerTime);
         | 
| 170 | 
            -
              struct timespec start;
         | 
| 171 | 
            -
              struct timespec now;
         | 
| 172 | 
            -
              bool echoSeen = false;
         | 
| 173 | 
            -
             | 
| 174 | 
            -
              // Pull down avoids false readings if disconnected.
         | 
| 175 | 
            -
              lgGpioClaimInput(handle, LG_SET_PULL_DOWN, echo);
         | 
| 176 | 
            -
             | 
| 177 | 
            -
              // Initial pulse on the triger pin.
         | 
| 178 | 
            -
              lgGpioClaimOutput(handle, LG_SET_PULL_NONE, trigger, 0);
         | 
| 179 | 
            -
              microDelay(5);
         | 
| 180 | 
            -
              lgGpioWrite(handle, trigger, 1);
         | 
| 181 | 
            -
              microDelay(triggerTime);
         | 
| 182 | 
            -
              lgGpioWrite(handle, trigger, 0);
         | 
| 183 | 
            -
             | 
| 184 | 
            -
              clock_gettime(CLOCK_MONOTONIC, &start);
         | 
| 185 | 
            -
              now = start;
         | 
| 186 | 
            -
             | 
| 187 | 
            -
              // Wait for echo to go high, up to 25,000 us after trigger.
         | 
| 188 | 
            -
              while(nanoDiff(&now, &start) < 25000000){
         | 
| 189 | 
            -
                clock_gettime(CLOCK_MONOTONIC, &now);
         | 
| 190 | 
            -
                if (lgGpioRead(handle, echo) == 1) {
         | 
| 191 | 
            -
                  echoSeen = true;
         | 
| 192 | 
            -
                  start = now;
         | 
| 193 | 
            -
                  break;
         | 
| 194 | 
            -
                }
         | 
| 195 | 
            -
              }
         | 
| 196 | 
            -
              if (!echoSeen) return Qnil;
         | 
| 197 | 
            -
             | 
| 198 | 
            -
              // Wait for echo to go low again, up to 25,000 us after echo start.
         | 
| 199 | 
            -
              while(nanoDiff(&now, &start) < 25000000){
         | 
| 200 | 
            -
                clock_gettime(CLOCK_MONOTONIC, &now);
         | 
| 201 | 
            -
                if (lgGpioRead(handle, echo) == 0) break;
         | 
| 202 | 
            -
              }
         | 
| 203 | 
            -
             | 
| 204 | 
            -
              // High pulse time in microseconds.
         | 
| 205 | 
            -
              return INT2NUM(round(nanoDiff(&now, &start) / 1000.0));
         | 
| 206 | 
            -
            }
         | 
| 207 | 
            -
             | 
| 208 | 
            -
            static VALUE gpio_read_pulses_us(VALUE self, VALUE rbHandle, VALUE rbGPIO, VALUE rbReset_us, VALUE rbResetLevel, VALUE rbLimit, VALUE rbTimeout_ms) {
         | 
| 209 | 
            -
              // C values
         | 
| 210 | 
            -
              int handle          = NUM2INT(rbHandle);
         | 
| 211 | 
            -
              int gpio            = NUM2INT(rbGPIO);
         | 
| 212 | 
            -
              uint32_t reset_us   = NUM2UINT(rbReset_us);
         | 
| 213 | 
            -
              uint8_t  resetLevel = NUM2UINT(rbResetLevel);
         | 
| 214 | 
            -
              uint32_t limit      = NUM2UINT(rbLimit);
         | 
| 215 | 
            -
              uint64_t timeout_ns = NUM2UINT(rbTimeout_ms) * 1000000;
         | 
| 216 | 
            -
             | 
| 217 | 
            -
              // State setup
         | 
| 218 | 
            -
              uint64_t pulses_ns[limit];
         | 
| 219 | 
            -
              uint32_t pulseIndex = 0;
         | 
| 220 | 
            -
              int      gpioState;
         | 
| 221 | 
            -
              struct timespec start;
         | 
| 222 | 
            -
              struct timespec lastPulse;
         | 
| 223 | 
            -
              struct timespec now;
         | 
| 224 | 
            -
             | 
| 225 | 
            -
              // Perform reset
         | 
| 226 | 
            -
              if (reset_us > 0) {
         | 
| 227 | 
            -
                int result = lgGpioClaimOutput(handle, LG_SET_PULL_NONE, gpio, resetLevel);
         | 
| 228 | 
            -
                if (result < 0) return NUM2INT(result);
         | 
| 229 | 
            -
                microDelay(reset_us);
         | 
| 230 | 
            -
              }
         | 
| 231 | 
            -
             | 
| 232 | 
            -
              // Initialize timing
         | 
| 233 | 
            -
              clock_gettime(CLOCK_MONOTONIC, &start);
         | 
| 234 | 
            -
              lastPulse = start;
         | 
| 235 | 
            -
              now       = start;
         | 
| 236 | 
            -
             | 
| 237 | 
            -
              // Switch to input and read initial state
         | 
| 238 | 
            -
              lgGpioClaimInput(handle, LG_SET_PULL_NONE, gpio);
         | 
| 239 | 
            -
              gpioState = lgGpioRead(handle, gpio);
         | 
| 240 | 
            -
             | 
| 241 | 
            -
              // Read pulses in nanoseconds
         | 
| 242 | 
            -
              while ((nanoDiff(&now, &start) < timeout_ns) && (pulseIndex < limit)) {
         | 
| 243 | 
            -
                clock_gettime(CLOCK_MONOTONIC, &now);
         | 
| 244 | 
            -
                if (lgGpioRead(handle, gpio) != gpioState) {
         | 
| 245 | 
            -
                  pulses_ns[pulseIndex] = nanoDiff(&now, &lastPulse);
         | 
| 246 | 
            -
                  lastPulse = now;
         | 
| 247 | 
            -
                  gpioState = gpioState ^ 0b1;
         | 
| 248 | 
            -
                  pulseIndex++;
         | 
| 249 | 
            -
                }
         | 
| 250 | 
            -
              }
         | 
| 251 | 
            -
             | 
| 252 | 
            -
              // Return Ruby array of pulse as microseconds
         | 
| 253 | 
            -
              if (pulseIndex == 0) return Qnil;
         | 
| 254 | 
            -
              VALUE retArray = rb_ary_new2(pulseIndex);
         | 
| 255 | 
            -
              for(int i=0; i<pulseIndex; i++){
         | 
| 256 | 
            -
                uint32_t pulse_us = round(pulses_ns[i] / 1000.0);
         | 
| 257 | 
            -
                rb_ary_store(retArray, i, UINT2NUM(pulse_us));
         | 
| 258 | 
            -
              }
         | 
| 259 | 
            -
              return retArray;
         | 
| 260 | 
            -
            }
         | 
| 261 | 
            -
             | 
| 174 | 
            +
            /*****************************************************************************/
         | 
| 175 | 
            +
            /*                          SOFTWARE PWM & WAVE                              */
         | 
| 176 | 
            +
            /*****************************************************************************/
         | 
| 262 177 | 
             
            static VALUE tx_busy(VALUE self, VALUE handle, VALUE gpio, VALUE kind) {
         | 
| 263 178 | 
             
              int result = lgTxBusy(NUM2INT(handle), NUM2INT(gpio), NUM2INT(kind));
         | 
| 264 179 | 
             
              return INT2NUM(result);
         | 
| @@ -302,6 +217,9 @@ static VALUE tx_wave(VALUE self, VALUE handle, VALUE lead_gpio, VALUE pulses) { | |
| 302 217 | 
             
              return INT2NUM(result);
         | 
| 303 218 | 
             
            }
         | 
| 304 219 |  | 
| 220 | 
            +
            /*****************************************************************************/
         | 
| 221 | 
            +
            /*                        HARDWARE PWM OOK WAVE                              */
         | 
| 222 | 
            +
            /*****************************************************************************/
         | 
| 305 223 | 
             
            static VALUE tx_wave_ook(VALUE self, VALUE dutyPath, VALUE dutyString, VALUE pulses) {
         | 
| 306 224 | 
             
              // NOTE: This uses hardware PWM, NOT the lgpio software PWM/wave interface.
         | 
| 307 225 | 
             
              // The Ruby class LGPIO::HardwarePWM should have already set the PWM carrier frequency.
         | 
| @@ -343,6 +261,9 @@ static VALUE tx_wave_ook(VALUE self, VALUE dutyPath, VALUE dutyString, VALUE pul | |
| 343 261 | 
             
              fclose(dutyFile);
         | 
| 344 262 | 
             
            }
         | 
| 345 263 |  | 
| 264 | 
            +
            /*****************************************************************************/
         | 
| 265 | 
            +
            /*                             HARDWARE I2C                                  */
         | 
| 266 | 
            +
            /*****************************************************************************/
         | 
| 346 267 | 
             
            static VALUE i2c_open(VALUE self, VALUE i2cDev, VALUE i2cAddr, VALUE i2cFlags){
         | 
| 347 268 | 
             
              int handle = lgI2cOpen(NUM2INT(i2cDev), NUM2INT(i2cAddr), NUM2INT(i2cFlags));
         | 
| 348 269 | 
             
              return INT2NUM(handle);
         | 
| @@ -406,6 +327,9 @@ static VALUE i2c_zip(VALUE self, VALUE handle, VALUE txArray, VALUE rb_rxCount){ | |
| 406 327 | 
             
              return retArray;
         | 
| 407 328 | 
             
            }
         | 
| 408 329 |  | 
| 330 | 
            +
            /*****************************************************************************/
         | 
| 331 | 
            +
            /*                             HARDWARE SPI                                  */
         | 
| 332 | 
            +
            /*****************************************************************************/
         | 
| 409 333 | 
             
            static VALUE spi_open(VALUE self, VALUE spiDev, VALUE spiChan, VALUE spiBaud, VALUE spiFlags){
         | 
| 410 334 | 
             
              int handle = lgSpiOpen(NUM2INT(spiDev), NUM2INT(spiChan), NUM2INT(spiBaud), NUM2INT(spiFlags));
         | 
| 411 335 | 
             
              return INT2NUM(handle);
         | 
| @@ -506,32 +430,108 @@ static VALUE spi_ws2812_write(VALUE self, VALUE handle, VALUE pixelArray){ | |
| 506 430 | 
             
            }
         | 
| 507 431 |  | 
| 508 432 | 
             
            /*****************************************************************************/
         | 
| 509 | 
            -
            /* | 
| 433 | 
            +
            /*                           BIT-BANG PULSE INPUT                            */
         | 
| 510 434 | 
             
            /*****************************************************************************/
         | 
| 511 | 
            -
            static  | 
| 512 | 
            -
               | 
| 513 | 
            -
             | 
| 435 | 
            +
            static VALUE gpio_read_ultrasonic(VALUE self, VALUE rbHandle, VALUE rbTrigger, VALUE rbEcho, VALUE rbTriggerTime) {
         | 
| 436 | 
            +
              int handle            = NUM2UINT(rbHandle);
         | 
| 437 | 
            +
              int trigger           = NUM2UINT(rbTrigger);
         | 
| 438 | 
            +
              int echo              = NUM2UINT(rbEcho);
         | 
| 439 | 
            +
              uint32_t triggerTime  = NUM2UINT(rbTriggerTime);
         | 
| 440 | 
            +
              struct timespec start;
         | 
| 441 | 
            +
              struct timespec now;
         | 
| 442 | 
            +
              bool echoSeen = false;
         | 
| 514 443 |  | 
| 515 | 
            -
             | 
| 516 | 
            -
               | 
| 517 | 
            -
             | 
| 518 | 
            -
               | 
| 519 | 
            -
             | 
| 444 | 
            +
              // Pull down avoids false readings if disconnected.
         | 
| 445 | 
            +
              lgGpioClaimInput(handle, LG_SET_PULL_DOWN, echo);
         | 
| 446 | 
            +
             | 
| 447 | 
            +
              // Initial pulse on the triger pin.
         | 
| 448 | 
            +
              lgGpioClaimOutput(handle, LG_SET_PULL_NONE, trigger, 0);
         | 
| 449 | 
            +
              microDelay(5);
         | 
| 450 | 
            +
              lgGpioWrite(handle, trigger, 1);
         | 
| 451 | 
            +
              microDelay(triggerTime);
         | 
| 452 | 
            +
              lgGpioWrite(handle, trigger, 0);
         | 
| 453 | 
            +
             | 
| 454 | 
            +
              clock_gettime(CLOCK_MONOTONIC, &start);
         | 
| 455 | 
            +
              now = start;
         | 
| 456 | 
            +
             | 
| 457 | 
            +
              // Wait for echo to go high, up to 25,000 us after trigger.
         | 
| 458 | 
            +
              while(nanoDiff(&now, &start) < 25000000){
         | 
| 459 | 
            +
                clock_gettime(CLOCK_MONOTONIC, &now);
         | 
| 460 | 
            +
                if (lgGpioRead(handle, echo) == 1) {
         | 
| 461 | 
            +
                  echoSeen = true;
         | 
| 462 | 
            +
                  start = now;
         | 
| 463 | 
            +
                  break;
         | 
| 464 | 
            +
                }
         | 
| 465 | 
            +
              }
         | 
| 466 | 
            +
              if (!echoSeen) return Qnil;
         | 
| 467 | 
            +
             | 
| 468 | 
            +
              // Wait for echo to go low again, up to 25,000 us after echo start.
         | 
| 469 | 
            +
              while(nanoDiff(&now, &start) < 25000000){
         | 
| 470 | 
            +
                clock_gettime(CLOCK_MONOTONIC, &now);
         | 
| 471 | 
            +
                if (lgGpioRead(handle, echo) == 0) break;
         | 
| 520 472 | 
             
              }
         | 
| 521 | 
            -
            }
         | 
| 522 473 |  | 
| 523 | 
            -
             | 
| 524 | 
            -
              return ( | 
| 474 | 
            +
              // High pulse time in microseconds.
         | 
| 475 | 
            +
              return INT2NUM(round(nanoDiff(&now, &start) / 1000.0));
         | 
| 525 476 | 
             
            }
         | 
| 526 477 |  | 
| 527 | 
            -
            static  | 
| 528 | 
            -
               | 
| 529 | 
            -
             | 
| 530 | 
            -
               | 
| 531 | 
            -
             | 
| 478 | 
            +
            static VALUE gpio_read_pulses_us(VALUE self, VALUE rbHandle, VALUE rbGPIO, VALUE rbReset_us, VALUE rbResetLevel, VALUE rbLimit, VALUE rbTimeout_ms) {
         | 
| 479 | 
            +
              // C values
         | 
| 480 | 
            +
              int handle          = NUM2INT(rbHandle);
         | 
| 481 | 
            +
              int gpio            = NUM2INT(rbGPIO);
         | 
| 482 | 
            +
              uint32_t reset_us   = NUM2UINT(rbReset_us);
         | 
| 483 | 
            +
              uint8_t  resetLevel = NUM2UINT(rbResetLevel);
         | 
| 484 | 
            +
              uint32_t limit      = NUM2UINT(rbLimit);
         | 
| 485 | 
            +
              uint64_t timeout_ns = NUM2UINT(rbTimeout_ms) * 1000000;
         | 
| 486 | 
            +
             | 
| 487 | 
            +
              // State setup
         | 
| 488 | 
            +
              uint64_t pulses_ns[limit];
         | 
| 489 | 
            +
              uint32_t pulseIndex = 0;
         | 
| 490 | 
            +
              int      gpioState;
         | 
| 491 | 
            +
              struct timespec start;
         | 
| 492 | 
            +
              struct timespec lastPulse;
         | 
| 493 | 
            +
              struct timespec now;
         | 
| 494 | 
            +
             | 
| 495 | 
            +
              // Perform reset
         | 
| 496 | 
            +
              if (reset_us > 0) {
         | 
| 497 | 
            +
                int result = lgGpioClaimOutput(handle, LG_SET_PULL_NONE, gpio, resetLevel);
         | 
| 498 | 
            +
                if (result < 0) return NUM2INT(result);
         | 
| 499 | 
            +
                microDelay(reset_us);
         | 
| 500 | 
            +
              }
         | 
| 501 | 
            +
             | 
| 502 | 
            +
              // Initialize timing
         | 
| 503 | 
            +
              clock_gettime(CLOCK_MONOTONIC, &start);
         | 
| 504 | 
            +
              lastPulse = start;
         | 
| 505 | 
            +
              now       = start;
         | 
| 506 | 
            +
             | 
| 507 | 
            +
              // Switch to input and read initial state
         | 
| 508 | 
            +
              lgGpioClaimInput(handle, LG_SET_PULL_NONE, gpio);
         | 
| 509 | 
            +
              gpioState = lgGpioRead(handle, gpio);
         | 
| 510 | 
            +
             | 
| 511 | 
            +
              // Read pulses in nanoseconds
         | 
| 512 | 
            +
              while ((nanoDiff(&now, &start) < timeout_ns) && (pulseIndex < limit)) {
         | 
| 513 | 
            +
                clock_gettime(CLOCK_MONOTONIC, &now);
         | 
| 514 | 
            +
                if (lgGpioRead(handle, gpio) != gpioState) {
         | 
| 515 | 
            +
                  pulses_ns[pulseIndex] = nanoDiff(&now, &lastPulse);
         | 
| 516 | 
            +
                  lastPulse = now;
         | 
| 517 | 
            +
                  gpioState = gpioState ^ 0b1;
         | 
| 518 | 
            +
                  pulseIndex++;
         | 
| 519 | 
            +
                }
         | 
| 532 520 | 
             
              }
         | 
| 521 | 
            +
             | 
| 522 | 
            +
              // Return Ruby array of pulse as microseconds
         | 
| 523 | 
            +
              if (pulseIndex == 0) return Qnil;
         | 
| 524 | 
            +
              VALUE retArray = rb_ary_new2(pulseIndex);
         | 
| 525 | 
            +
              for(int i=0; i<pulseIndex; i++){
         | 
| 526 | 
            +
                uint32_t pulse_us = round(pulses_ns[i] / 1000.0);
         | 
| 527 | 
            +
                rb_ary_store(retArray, i, UINT2NUM(pulse_us));
         | 
| 528 | 
            +
              }
         | 
| 529 | 
            +
              return retArray;
         | 
| 533 530 | 
             
            }
         | 
| 534 531 |  | 
| 532 | 
            +
            /*****************************************************************************/
         | 
| 533 | 
            +
            /*                       BIT BANG 1-WIRE HEPERS                              */
         | 
| 534 | 
            +
            /*****************************************************************************/
         | 
| 535 535 | 
             
            static VALUE one_wire_bit_read(VALUE self, VALUE rbHandle, VALUE rbGPIO) {
         | 
| 536 536 | 
             
              int handle  = NUM2INT(rbHandle);
         | 
| 537 537 | 
             
              int gpio    = NUM2INT(rbGPIO);
         | 
| @@ -598,167 +598,6 @@ static VALUE one_wire_reset(VALUE self, VALUE rbHandle, VALUE rbGPIO) { | |
| 598 598 | 
             
              return UINT2NUM(presence);
         | 
| 599 599 | 
             
            }
         | 
| 600 600 |  | 
| 601 | 
            -
            /*****************************************************************************/
         | 
| 602 | 
            -
            /*                            BIT-BANG I2C                                   */
         | 
| 603 | 
            -
            /*****************************************************************************/
         | 
| 604 | 
            -
            static uint8_t sdaState = 1;
         | 
| 605 | 
            -
             | 
| 606 | 
            -
            static void i2c_bb_set_sda(int handle, int sda, uint8_t level) {
         | 
| 607 | 
            -
              if (level == sdaState) return;
         | 
| 608 | 
            -
              lgGpioWrite(handle, sda, level);
         | 
| 609 | 
            -
              sdaState = level;
         | 
| 610 | 
            -
            }
         | 
| 611 | 
            -
             | 
| 612 | 
            -
            // Start condition is SDA then SCL going low, from both high.
         | 
| 613 | 
            -
            static void i2c_bb_start(int handle, int scl, int sda) {
         | 
| 614 | 
            -
              lgGpioWrite(handle, sda, 0);
         | 
| 615 | 
            -
              lgGpioWrite(handle, scl, 0);
         | 
| 616 | 
            -
            }
         | 
| 617 | 
            -
             | 
| 618 | 
            -
            // Stop condition is SDA going high, while SCL is also high.
         | 
| 619 | 
            -
            static void i2c_bb_stop(int handle, int scl, int sda) {
         | 
| 620 | 
            -
              lgGpioWrite(handle, sda, 0);
         | 
| 621 | 
            -
              lgGpioWrite(handle, scl, 1);
         | 
| 622 | 
            -
              lgGpioWrite(handle, sda, 1);
         | 
| 623 | 
            -
            }
         | 
| 624 | 
            -
             | 
| 625 | 
            -
            static uint8_t i2c_bb_read_bit(int handle, int scl, int sda) {
         | 
| 626 | 
            -
              uint8_t bit;
         | 
| 627 | 
            -
              // Ensure SDA high before we pull SCL high.
         | 
| 628 | 
            -
              i2c_bb_set_sda(handle, sda, 1);
         | 
| 629 | 
            -
              lgGpioWrite(handle, scl, 1);
         | 
| 630 | 
            -
              bit = lgGpioRead(handle, sda);
         | 
| 631 | 
            -
              lgGpioWrite(handle, scl, 0);
         | 
| 632 | 
            -
              return bit;
         | 
| 633 | 
            -
            }
         | 
| 634 | 
            -
             | 
| 635 | 
            -
            static void i2c_bb_write_bit(int handle, int scl, int sda, uint8_t bit) {
         | 
| 636 | 
            -
              // Set SDA while SCL is low.
         | 
| 637 | 
            -
              i2c_bb_set_sda(handle, sda, bit);
         | 
| 638 | 
            -
              lgGpioWrite(handle, scl, 1);
         | 
| 639 | 
            -
              lgGpioWrite(handle, scl, 0);
         | 
| 640 | 
            -
            }
         | 
| 641 | 
            -
             | 
| 642 | 
            -
            static uint8_t i2c_bb_read_byte(int handle, int scl, int sda, bool ack) {
         | 
| 643 | 
            -
              uint8_t b;
         | 
| 644 | 
            -
             | 
| 645 | 
            -
              // Receive MSB first.
         | 
| 646 | 
            -
              for (int i=7; i>=0; i--) bitWriteU8(&b, i, i2c_bb_read_bit(handle, scl, sda));
         | 
| 647 | 
            -
             | 
| 648 | 
            -
              // Send ACK or NACK and return byte.
         | 
| 649 | 
            -
              if (ack) {
         | 
| 650 | 
            -
                i2c_bb_write_bit(handle, scl, sda, 0);
         | 
| 651 | 
            -
              } else {
         | 
| 652 | 
            -
                i2c_bb_write_bit(handle, scl, sda, 1);
         | 
| 653 | 
            -
              }
         | 
| 654 | 
            -
              return b;
         | 
| 655 | 
            -
            }
         | 
| 656 | 
            -
             | 
| 657 | 
            -
            static int i2c_bb_write_byte(int handle, int scl, int sda, uint8_t b) {
         | 
| 658 | 
            -
              // Send MSB first.
         | 
| 659 | 
            -
              for (int i=7; i>=0; i--) i2c_bb_write_bit(handle, scl, sda, bitReadU8(&b, i));
         | 
| 660 | 
            -
             | 
| 661 | 
            -
              // Return -1 for NACK, 0 for ACK.
         | 
| 662 | 
            -
              return (i2c_bb_read_bit(handle, scl, sda) == 0) ? 0 : -1;
         | 
| 663 | 
            -
            }
         | 
| 664 | 
            -
             | 
| 665 | 
            -
            static VALUE i2c_bb_claim(VALUE self, VALUE rbHandle, VALUE rbSCL, VALUE rbSDA) {
         | 
| 666 | 
            -
              int handle = NUM2INT(rbHandle);
         | 
| 667 | 
            -
              int scl    = NUM2INT(rbSCL);
         | 
| 668 | 
            -
              int sda    = NUM2INT(rbSDA);
         | 
| 669 | 
            -
             | 
| 670 | 
            -
              // SCL is a driven output. SDA is open drain with pullup enabled.
         | 
| 671 | 
            -
              lgGpioClaimOutput(handle, LG_SET_PULL_NONE, scl, 1);
         | 
| 672 | 
            -
              lgGpioClaimOutput(handle, LG_SET_OPEN_DRAIN | LG_SET_PULL_UP, sda, 1);
         | 
| 673 | 
            -
            }
         | 
| 674 | 
            -
             | 
| 675 | 
            -
            static VALUE i2c_bb_search(VALUE self, VALUE rbHandle, VALUE rbSCL, VALUE rbSDA) {
         | 
| 676 | 
            -
              int handle = NUM2INT(rbHandle);
         | 
| 677 | 
            -
              int scl    = NUM2INT(rbSCL);
         | 
| 678 | 
            -
              int sda    = NUM2INT(rbSDA);
         | 
| 679 | 
            -
              int ack;
         | 
| 680 | 
            -
              uint8_t present[128];
         | 
| 681 | 
            -
              uint8_t presentCount = 0;
         | 
| 682 | 
            -
              sdaState = 1;
         | 
| 683 | 
            -
             | 
| 684 | 
            -
              // Only addresses from 0x08 to 0x77 are usable (8 to 127).
         | 
| 685 | 
            -
              for (uint8_t addr = 0x08; addr < 0x78;  addr++) {
         | 
| 686 | 
            -
                i2c_bb_start(handle, scl, sda);
         | 
| 687 | 
            -
                ack = i2c_bb_write_byte(handle, scl, sda, ((addr << 1) & 0b11111110));
         | 
| 688 | 
            -
                i2c_bb_stop(handle, scl, sda);
         | 
| 689 | 
            -
                if (ack == 0){
         | 
| 690 | 
            -
                  present[addr] = 1;
         | 
| 691 | 
            -
                  presentCount++;
         | 
| 692 | 
            -
                } else {
         | 
| 693 | 
            -
                  present[addr] = 0;
         | 
| 694 | 
            -
                }
         | 
| 695 | 
            -
              }
         | 
| 696 | 
            -
              if (presentCount == 0) return Qnil;
         | 
| 697 | 
            -
             | 
| 698 | 
            -
              VALUE retArray = rb_ary_new2(presentCount);
         | 
| 699 | 
            -
              uint8_t i = 0;
         | 
| 700 | 
            -
              for (uint8_t addr = 0x08; addr < 0x78;  addr++) {
         | 
| 701 | 
            -
                if (present[addr] == 1) {
         | 
| 702 | 
            -
                  rb_ary_store(retArray, i, UINT2NUM(addr));
         | 
| 703 | 
            -
                  i++;
         | 
| 704 | 
            -
                }
         | 
| 705 | 
            -
              }
         | 
| 706 | 
            -
              return retArray;
         | 
| 707 | 
            -
            }
         | 
| 708 | 
            -
             | 
| 709 | 
            -
            static VALUE i2c_bb_write(VALUE self, VALUE rbHandle, VALUE rbSCL, VALUE rbSDA, VALUE rbAddress, VALUE txArray) {
         | 
| 710 | 
            -
              int handle = NUM2INT(rbHandle);
         | 
| 711 | 
            -
              int scl    = NUM2INT(rbSCL);
         | 
| 712 | 
            -
              int sda    = NUM2INT(rbSDA);
         | 
| 713 | 
            -
              uint8_t address      = NUM2CHR(rbAddress);
         | 
| 714 | 
            -
              uint8_t writeAddress = (address << 1);
         | 
| 715 | 
            -
              sdaState = 1;
         | 
| 716 | 
            -
             | 
| 717 | 
            -
              int count = RARRAY_LEN(txArray);
         | 
| 718 | 
            -
              uint8_t txBuf[count];
         | 
| 719 | 
            -
              VALUE currentByte;
         | 
| 720 | 
            -
              for(int i=0; i<count; i++){
         | 
| 721 | 
            -
                currentByte = rb_ary_entry(txArray, i);
         | 
| 722 | 
            -
                Check_Type(currentByte, T_FIXNUM);
         | 
| 723 | 
            -
                txBuf[i] = NUM2CHR(currentByte);
         | 
| 724 | 
            -
              }
         | 
| 725 | 
            -
             | 
| 726 | 
            -
              i2c_bb_start(handle, scl, sda);
         | 
| 727 | 
            -
              i2c_bb_write_byte(handle, scl, sda, writeAddress);
         | 
| 728 | 
            -
              for (int i=0; i<count; i++) i2c_bb_write_byte(handle, scl, sda, txBuf[i]);
         | 
| 729 | 
            -
              i2c_bb_stop(handle, scl, sda);
         | 
| 730 | 
            -
            }
         | 
| 731 | 
            -
             | 
| 732 | 
            -
            static VALUE i2c_bb_read(VALUE self, VALUE rbHandle, VALUE rbSCL, VALUE rbSDA, VALUE rbAddress, VALUE rbCount) {
         | 
| 733 | 
            -
              int handle = NUM2INT(rbHandle);
         | 
| 734 | 
            -
              int scl    = NUM2INT(rbSCL);
         | 
| 735 | 
            -
              int sda    = NUM2INT(rbSDA);
         | 
| 736 | 
            -
              uint8_t address      = NUM2CHR(rbAddress);
         | 
| 737 | 
            -
              uint8_t readAddress  = (address << 1) | 0b00000001;
         | 
| 738 | 
            -
              sdaState = 1;
         | 
| 739 | 
            -
             | 
| 740 | 
            -
              int count = NUM2INT(rbCount);
         | 
| 741 | 
            -
              uint8_t rxBuf[count];
         | 
| 742 | 
            -
             | 
| 743 | 
            -
              i2c_bb_start(handle, scl, sda);
         | 
| 744 | 
            -
              int ack = i2c_bb_write_byte(handle, scl, sda, readAddress);
         | 
| 745 | 
            -
              // Device with this address not present on the bus.
         | 
| 746 | 
            -
              if (ack != 0) return Qnil;
         | 
| 747 | 
            -
             | 
| 748 | 
            -
              // Read and ACK for all but the last byte.
         | 
| 749 | 
            -
              int pos = 0;
         | 
| 750 | 
            -
              while(pos < count-1) {
         | 
| 751 | 
            -
                rxBuf[pos] = i2c_bb_read_byte(handle, scl, sda, true);
         | 
| 752 | 
            -
                pos++;
         | 
| 753 | 
            -
              }
         | 
| 754 | 
            -
              rxBuf[pos] = i2c_bb_read_byte(handle, scl, sda, false);
         | 
| 755 | 
            -
              i2c_bb_stop(handle, scl, sda);
         | 
| 756 | 
            -
             | 
| 757 | 
            -
              VALUE retArray = rb_ary_new2(count);
         | 
| 758 | 
            -
              for(int i=0; i<count; i++) rb_ary_store(retArray, i, UINT2NUM(rxBuf[i]));
         | 
| 759 | 
            -
              return retArray;
         | 
| 760 | 
            -
            }
         | 
| 761 | 
            -
             | 
| 762 601 | 
             
            /*****************************************************************************/
         | 
| 763 602 | 
             
            /*                           EXTENSION INIT                                  */
         | 
| 764 603 | 
             
            /*****************************************************************************/
         | 
| @@ -798,10 +637,6 @@ void Init_lgpio(void) { | |
| 798 637 | 
             
              rb_define_singleton_method(mLGPIO, "gpio_start_reporting",  gpio_start_reporting,  0);
         | 
| 799 638 | 
             
              rb_define_singleton_method(mLGPIO, "gpio_get_report",       gpio_get_report,       0);
         | 
| 800 639 |  | 
| 801 | 
            -
              // Pulse Input
         | 
| 802 | 
            -
              rb_define_singleton_method(mLGPIO, "gpio_read_ultrasonic",  gpio_read_ultrasonic,  4);
         | 
| 803 | 
            -
              rb_define_singleton_method(mLGPIO, "gpio_read_pulses_us",   gpio_read_pulses_us,   6);
         | 
| 804 | 
            -
             | 
| 805 640 | 
             
              // Soft PWM / Wave
         | 
| 806 641 | 
             
              rb_define_const(mLGPIO, "TX_PWM", INT2NUM(LG_TX_PWM));
         | 
| 807 642 | 
             
              rb_define_const(mLGPIO, "TX_WAVE",INT2NUM(LG_TX_WAVE));
         | 
| @@ -813,6 +648,10 @@ void Init_lgpio(void) { | |
| 813 648 | 
             
              // Don't use this. Servo will jitter.
         | 
| 814 649 | 
             
              rb_define_singleton_method(mLGPIO, "tx_servo", tx_servo, 6);
         | 
| 815 650 |  | 
| 651 | 
            +
              // Hardware PWM waves for on-off-keying.
         | 
| 652 | 
            +
              VALUE cHardwarePWM = rb_define_class_under(mLGPIO, "HardwarePWM", rb_cObject);
         | 
| 653 | 
            +
              rb_define_method(cHardwarePWM, "tx_wave_ook", tx_wave_ook, 3);
         | 
| 654 | 
            +
             | 
| 816 655 | 
             
              // I2C
         | 
| 817 656 | 
             
              rb_define_singleton_method(mLGPIO, "i2c_open",           i2c_open,          3);
         | 
| 818 657 | 
             
              rb_define_singleton_method(mLGPIO, "i2c_close",          i2c_close,         1);
         | 
| @@ -828,18 +667,12 @@ void Init_lgpio(void) { | |
| 828 667 | 
             
              rb_define_singleton_method(mLGPIO, "spi_xfer",           spi_xfer,          2);
         | 
| 829 668 | 
             
              rb_define_singleton_method(mLGPIO, "spi_ws2812_write",   spi_ws2812_write,  2);
         | 
| 830 669 |  | 
| 831 | 
            -
              //  | 
| 832 | 
            -
               | 
| 833 | 
            -
               | 
| 670 | 
            +
              // Bit-Bang Pulse Input
         | 
| 671 | 
            +
              rb_define_singleton_method(mLGPIO, "gpio_read_ultrasonic",  gpio_read_ultrasonic,  4);
         | 
| 672 | 
            +
              rb_define_singleton_method(mLGPIO, "gpio_read_pulses_us",   gpio_read_pulses_us,   6);
         | 
| 834 673 |  | 
| 835 | 
            -
              // Bit- | 
| 674 | 
            +
              // Bit-bang 1-Wire Helpers
         | 
| 836 675 | 
             
              rb_define_singleton_method(mLGPIO, "one_wire_bit_read",   one_wire_bit_read,  2);
         | 
| 837 676 | 
             
              rb_define_singleton_method(mLGPIO, "one_wire_bit_write",  one_wire_bit_write, 3);
         | 
| 838 677 | 
             
              rb_define_singleton_method(mLGPIO, "one_wire_reset",      one_wire_reset,     2);
         | 
| 839 | 
            -
             | 
| 840 | 
            -
              // Bit-banged I2C
         | 
| 841 | 
            -
              rb_define_singleton_method(mLGPIO, "i2c_bb_claim",    i2c_bb_claim,    3);
         | 
| 842 | 
            -
              rb_define_singleton_method(mLGPIO, "i2c_bb_search",   i2c_bb_search,   3);
         | 
| 843 | 
            -
              rb_define_singleton_method(mLGPIO, "i2c_bb_write",    i2c_bb_write,    5);
         | 
| 844 | 
            -
              rb_define_singleton_method(mLGPIO, "i2c_bb_read",     i2c_bb_read,     5);
         | 
| 845 678 | 
             
            }
         | 
    
        data/lib/lgpio/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: lgpio
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.7
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - vickash
         | 
| @@ -21,37 +21,36 @@ files: | |
| 21 21 | 
             
            - LICENSE
         | 
| 22 22 | 
             
            - README.md
         | 
| 23 23 | 
             
            - Rakefile
         | 
| 24 | 
            -
            - examples/bench_in.rb
         | 
| 25 | 
            -
            - examples/bench_out.rb
         | 
| 26 | 
            -
            - examples/blink.rb
         | 
| 27 24 | 
             
            - examples/dht.rb
         | 
| 28 | 
            -
            - examples/ | 
| 29 | 
            -
            - examples/ | 
| 25 | 
            +
            - examples/gpio_bench_in.rb
         | 
| 26 | 
            +
            - examples/gpio_bench_out.rb
         | 
| 27 | 
            +
            - examples/gpio_blink.rb
         | 
| 28 | 
            +
            - examples/gpio_group_in.rb
         | 
| 29 | 
            +
            - examples/gpio_group_out.rb
         | 
| 30 | 
            +
            - examples/gpio_momentary.rb
         | 
| 31 | 
            +
            - examples/gpio_reports.rb
         | 
| 32 | 
            +
            - examples/gpio_rotary_encoder.rb
         | 
| 33 | 
            +
            - examples/gpio_rotary_encoder_led.rb
         | 
| 34 | 
            +
            - examples/gpio_wave.rb
         | 
| 30 35 | 
             
            - examples/hcsr04.rb
         | 
| 31 | 
            -
            - examples/ | 
| 32 | 
            -
            - examples/ | 
| 33 | 
            -
            - examples/ | 
| 34 | 
            -
            - examples/ | 
| 35 | 
            -
            - examples/ | 
| 36 | 
            -
            - examples/ | 
| 37 | 
            -
            - examples/i2c_bitbang_ssd1306_bench.rb
         | 
| 38 | 
            -
            - examples/i2c_ssd1306_bench.rb
         | 
| 36 | 
            +
            - examples/i2c_bb_aht10.rb
         | 
| 37 | 
            +
            - examples/i2c_bb_search.rb
         | 
| 38 | 
            +
            - examples/i2c_bb_ssd1306_bench.rb
         | 
| 39 | 
            +
            - examples/i2c_hw_aht10.rb
         | 
| 40 | 
            +
            - examples/i2c_hw_aht10_zip.rb
         | 
| 41 | 
            +
            - examples/i2c_hw_ssd1306_bench.rb
         | 
| 39 42 | 
             
            - examples/infrared.rb
         | 
| 40 | 
            -
            - examples/momentary.rb
         | 
| 41 43 | 
             
            - examples/one_wire_ds18b20.rb
         | 
| 42 44 | 
             
            - examples/one_wire_search.rb
         | 
| 43 | 
            -
            - examples/ | 
| 44 | 
            -
            - examples/ | 
| 45 | 
            -
            - examples/ | 
| 46 | 
            -
            - examples/ | 
| 47 | 
            -
            - examples/ | 
| 48 | 
            -
            - examples/ | 
| 49 | 
            -
            - examples/ | 
| 50 | 
            -
            - examples/ | 
| 51 | 
            -
            - examples/ | 
| 52 | 
            -
            - examples/spi_ws2812.rb
         | 
| 53 | 
            -
            - examples/spi_ws2812_bounce.rb
         | 
| 54 | 
            -
            - examples/wave.rb
         | 
| 45 | 
            +
            - examples/pwm_hw_bench.rb
         | 
| 46 | 
            +
            - examples/pwm_hw_servo.rb
         | 
| 47 | 
            +
            - examples/pwm_sw.rb
         | 
| 48 | 
            +
            - examples/spi_bb_loopback.rb
         | 
| 49 | 
            +
            - examples/spi_bb_sim_bench.rb
         | 
| 50 | 
            +
            - examples/spi_bb_ssd1306_bench.rb
         | 
| 51 | 
            +
            - examples/spi_hw_loopback.rb
         | 
| 52 | 
            +
            - examples/spi_hw_ws2812.rb
         | 
| 53 | 
            +
            - examples/spi_hw_ws2812_bounce.rb
         | 
| 55 54 | 
             
            - ext/lgpio/extconf.rb
         | 
| 56 55 | 
             
            - ext/lgpio/lgpio.c
         | 
| 57 56 | 
             
            - lgpio.gemspec
         | 
| @@ -1,40 +0,0 @@ | |
| 1 | 
            -
            require 'lgpio'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            POWER_ON_DELAY      = 0.100
         | 
| 4 | 
            -
            RESET_DELAY         = 0.020
         | 
| 5 | 
            -
            COMMAND_DELAY       = 0.010
         | 
| 6 | 
            -
            MEASURE_DELAY       = 0.080
         | 
| 7 | 
            -
            DATA_LENGTH         = 6
         | 
| 8 | 
            -
            SOFT_RESET          = [0xBA]
         | 
| 9 | 
            -
            INIT_AND_CALIBRATE  = [0xE1, 0x08, 0x00]
         | 
| 10 | 
            -
            START_MEASUREMENT   = [0xAC, 0x33, 0x00]
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            GPIO_CHIP = 0
         | 
| 13 | 
            -
            SCL_PIN   = 228
         | 
| 14 | 
            -
            SDA_PIN   = 270
         | 
| 15 | 
            -
            ADDRESS   = 0x38
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            chip_handle = LGPIO.chip_open(GPIO_CHIP)
         | 
| 18 | 
            -
            LGPIO.i2c_bb_claim(chip_handle, SCL_PIN, SDA_PIN)
         | 
| 19 | 
            -
             | 
| 20 | 
            -
            # Startup sequence
         | 
| 21 | 
            -
            sleep(POWER_ON_DELAY)
         | 
| 22 | 
            -
            LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, SOFT_RESET)
         | 
| 23 | 
            -
            sleep(RESET_DELAY)
         | 
| 24 | 
            -
            LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, INIT_AND_CALIBRATE)
         | 
| 25 | 
            -
            sleep(COMMAND_DELAY)
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            # Read and close
         | 
| 28 | 
            -
            LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, START_MEASUREMENT)
         | 
| 29 | 
            -
            sleep(MEASURE_DELAY)
         | 
| 30 | 
            -
            bytes = LGPIO.i2c_bb_read(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, DATA_LENGTH)
         | 
| 31 | 
            -
             | 
| 32 | 
            -
            # Humidity uses the upper 4 bits of the shared byte as its lowest 4 bits.
         | 
| 33 | 
            -
            h_raw = ((bytes[1] << 16) | (bytes[2] << 8) | (bytes[3])) >> 4
         | 
| 34 | 
            -
            humidity = (h_raw.to_f / 2**20) * 100
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            # Temperature uses the lower 4 bits of the shared byte as its highest 4 bits.
         | 
| 37 | 
            -
            t_raw = ((bytes[3] & 0x0F) << 16) | (bytes[4] << 8) | bytes[5]
         | 
| 38 | 
            -
            temperature = (t_raw.to_f / 2**20) * 200 - 50
         | 
| 39 | 
            -
             | 
| 40 | 
            -
            puts "#{Time.now.strftime '%Y-%m-%d %H:%M:%S'} - Temperature: #{temperature.round(2)} \xC2\xB0C | Humidity: #{humidity.round(2)} %"
         | 
| @@ -1,35 +0,0 @@ | |
| 1 | 
            -
            require 'lgpio'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            INIT_ARRAY  = [0, 168, 63, 211, 0, 64, 161, 200, 218, 18, 164, 166, 213, 128, 219, 32, 217, 241, 141, 20, 32, 0, 175]
         | 
| 4 | 
            -
            START_ARRAY = [0, 33, 0, 127, 34, 0, 7]
         | 
| 5 | 
            -
            PATTERN_1   = [64] + Array.new(1024) { 0b00110011 }
         | 
| 6 | 
            -
            PATTERN_2   = [64] + Array.new(1024) { 0b11001100 }
         | 
| 7 | 
            -
             | 
| 8 | 
            -
            GPIO_CHIP = 0
         | 
| 9 | 
            -
            SCL_PIN   = 228
         | 
| 10 | 
            -
            SDA_PIN   = 270
         | 
| 11 | 
            -
            ADDRESS   = 0x3C
         | 
| 12 | 
            -
             | 
| 13 | 
            -
            chip_handle = LGPIO.chip_open(GPIO_CHIP)
         | 
| 14 | 
            -
            LGPIO.i2c_bb_claim(chip_handle, SCL_PIN, SDA_PIN)
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, INIT_ARRAY)
         | 
| 17 | 
            -
            FRAME_COUNT = 400
         | 
| 18 | 
            -
             | 
| 19 | 
            -
            start = Time.now
         | 
| 20 | 
            -
            (FRAME_COUNT / 2).times do
         | 
| 21 | 
            -
              LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, START_ARRAY)
         | 
| 22 | 
            -
              LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, PATTERN_1)
         | 
| 23 | 
            -
              LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, START_ARRAY)
         | 
| 24 | 
            -
              LGPIO.i2c_bb_write(chip_handle, SCL_PIN, SDA_PIN, ADDRESS, PATTERN_2)
         | 
| 25 | 
            -
            end
         | 
| 26 | 
            -
            finish = Time.now
         | 
| 27 | 
            -
             | 
| 28 | 
            -
            LGPIO.chip_close(chip_handle)
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            fps = FRAME_COUNT / (finish - start)
         | 
| 31 | 
            -
            # Also calculate C calls per second, using roughly 23 calls per byte written.
         | 
| 32 | 
            -
            cps = (START_ARRAY.length + ((PATTERN_1.length + PATTERN_2.length) / 2) + 2) * 23 * fps
         | 
| 33 | 
            -
            cps = (cps / 1000.0).round
         | 
| 34 | 
            -
             | 
| 35 | 
            -
            puts "SSD1306 benchmark result: #{fps.round(2)} fps | #{cps}k C calls/s"
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |