PiDP-8/I Software

Check-in Differences
Log In

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From d10da9f38617cb2b To 1eee47198175cfc1

2020-05-20
04:58
Merged trunk changes into pi4-gpio-clean. check-in: 4d51e218ef user: tangent tags: pi4-gpio-clean
2019-08-18
00:57
Tightened up the Fossil vs Git stuff in HACKERS.md, added a bit more Fossil help, added some links to external help, and reorganized the top level sections to flow better. check-in: ce1fca0017 user: tangent tags: trunk
2019-08-17
23:15
Merged the use of libbcm_host from trunk with Oscar's new GPIO pull up/down setup code to get the best of both worlds. This requires a version of libbcm_host that was only just released: https://github.com/raspberrypi/firmware/issues/1161 check-in: 1eee471981 user: tangent tags: pi4-gpio-clean
2019-08-16
00:50
Changed all references to "FOCAL 69" to "FOCAL,1969", and linked to the new "[Running FOCAL,1969]" wiki article which explains why this naming difference matters. check-in: d10da9f386 user: tangent tags: trunk
2019-08-15
22:49
Updated the docs talking about Fossil 2.x binaries now that Buster is out, shipping Fossil 2.9. check-in: 062d059f8a user: tangent tags: trunk
00:22
Added support for Pi 4 GPIO, based on code the Raspberry Pi Foundation published: https://github.com/RPi-Distro/raspi-gpio/commit/80fa7d04eafb3ea34fc6f2d32de5f1873b5fb369 This check-in is based on a version of gpio-common.c.in posted to the PiDP-8 Google Group by Oscar Vermeulen, which is why we're giving him credit for this check-in, even though I (tangent) have done quite a lot of changes to that code, mainly to match the existing code style. This is a branch because it conflicts with the current tip-of-trunk and because it's not yet tested on a Pi 4. It is unknown whether this branch will end up overriding the method we're using on trunk for Pi 0-3 or if we will instead wait for the Foundation to publish a new libbcm_host that obviates some of what this check-in does. Closed-Leaf check-in: bd10d4dde2 user: vermeulen.oscar tags: pi4-gpio-hack

Changes to src/pidp8i/gpio-common.c.in.

1
2
3
4
5
6
7
8
9
10
11
/*
 * gpio-common.c: functions common to both gpio.c and gpio-nls.c
 *
 * Copyright © 2015 Oscar Vermeulen, © 2016-2019 by Warren Young
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:



|







1
2
3
4
5
6
7
8
9
10
11
/*
 * gpio-common.c: functions common to both gpio.c and gpio-nls.c
 *
 * Copyright © 2015, 2019 Oscar Vermeulen, © 2016-2019 by Warren Young
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
578
579
580
581
582
583
584
585








586




587






588




589
590






591





592
593
594
595



596




597






598




599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634

































635
636
637
638
639
640
641
    }
    for (size_t row = 0; row < NLEDROWS; ++row) {
        INP_GPIO (ledrows[row]);
    }
}


//// init_pidp8i_gpio //////////////////////////////////////////////////








// Initialize the GPIO pins to the initial states required by




// gpio_thread().   It's a separate exported function so that scanswitch






// can also use it.





void init_pidp8i_gpio (void)






{





    // Set GPIO pins to their starting state
    turn_on_pidp8i_leds ();
    for (size_t i = 0; i < NROWS; i++) {       // Define rows as input
        INP_GPIO (rows[i]);



    }











    // BCM2835 ARM Peripherals PDF p 101 & elinux.org/RPi_Low-level_peripherals#Internal_Pull-Ups_.26_Pull-Downs




    GPIO_PULL = 2;  // pull-up
    usleep(1);  // must wait 150 cycles
#if defined(PCB_SERIAL_MOD_OV) || defined(PCB_SERIAL_MOD_JLW)
    // The Oscar Vermeulen and James L-W serial mods rearrange the PiDP-8/I
    // GPIO matrix to use Pi GPIO pins 2..13, freeing up the hardware
    // serial port on GPIO pins 14 & 15.
    GPIO_PULLCLK0 = 0x03ffc;
#else
    // The standard PiDP-8/I board drive scheme uses Pi GPIO pins 4..15.
    GPIO_PULLCLK0 = 0x0fff0;
#endif
    usleep(1);
    GPIO_PULL = 0; // reset GPPUD register
    usleep(1);
    GPIO_PULLCLK0 = 0; // remove clock
    usleep(1); // probably unnecessary

    // BCM2835 ARM Peripherals PDF p 101 & elinux.org/RPi_Low-level_peripherals#Internal_Pull-Ups_.26_Pull-Downs
    GPIO_PULL = 1;  // pull-down to avoid ghosting (dec2015)
    usleep(1);  // must wait 150 cycles
    GPIO_PULLCLK0 = 0x0ff00000; // selects GPIO pins 20..27
    usleep(1);
    GPIO_PULL = 0; // reset GPPUD register
    usleep(1);
    GPIO_PULLCLK0 = 0; // remove clock
    usleep(1); // probably unnecessary

    // BCM2835 ARM Peripherals PDF p 101 & elinux.org/RPi_Low-level_peripherals#Internal_Pull-Ups_.26_Pull-Downs
    GPIO_PULL = 0;  // no pull-up no pull down just float
    usleep(1);  // must wait 150 cycles
    GPIO_PULLCLK0 = 0x070000; // selects GPIO pins 16..18
    usleep(1);
    GPIO_PULL = 0; // reset GPPUD register
    usleep(1);
    GPIO_PULLCLK0 = 0; // remove clock
    usleep(1); // probably unnecessary

































}


//// gpio_thread ///////////////////////////////////////////////////////
// The GPIO thread entry point: initializes GPIO and then calls
// the gpio_core () implementation linked to this program.








|
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>
|
|
>
>
>
>
>
>
|
>
>
>
>
>
|
|
|
|
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
|
>
>
>
>

















<
<
<
<
<
<
<
<
<
|
<








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665









666

667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
    }
    for (size_t row = 0; row < NLEDROWS; ++row) {
        INP_GPIO (ledrows[row]);
    }
}


//// init_bcm2711_gpio /////////////////////////////////////////////////
// Called from init_pidp8i_gpio() when it sees that it's running on a Pi
// 4 which uses the BCM 2711 GPIO peripheral, which behaves differently
// than GPIO was done in all prior Pi models.  This code is based on
// https://github.com/RPi-Distro/raspi-gpio/blob/master/raspi-gpio.c
//
// Note that there is no "serial mod" handling here: no one has come up
// with such a hardware hack for the Pi 4 yet, and no one has verified
// that you can do one of the existing ones atop the Pi 4.

static void init_bcm2711_gpio (void)
{
    int gpiox, pullreg, pullshift;
    unsigned int pullbits, pull;

    // Configure "columns" GPIO pins
    for (size_t i = 0; i < 12; ++i) {
        gpiox = cols[i];
        pullreg = GPPUPPDN0 + (gpiox>>4);
        pullshift = (gpiox & 0xf) << 1;
        pull = 1;

        pullbits = *(gpio.addr + pullreg);
        pullbits &= ~(3 << pullshift);
        pullbits |= (pull << pullshift);
        *(gpio.addr + pullreg) = pullbits;
    }

    // Configure "rows" GPIO pins
    for (size_t i = 0; i < 3; ++i) {
        gpiox = rows[i];
        pullreg = GPPUPPDN0 + (gpiox>>4);
        pullshift = (gpiox & 0xf) << 1;
        pull = 0;

        pullbits = *(gpio.addr + pullreg);
        pullbits &= ~(3 << pullshift);
        pullbits |= (pull << pullshift);
        *(gpio.addr + pullreg) = pullbits;
    }

    // Configure "ledrows" GPIO pins
    for (size_t i = 0; i < 6; ++i) {
        gpiox = ledrows[i];
        pullreg = GPPUPPDN0 + (gpiox>>4);
        pullshift = (gpiox & 0xf) << 1;
        pull = 0;

        pullbits = *(gpio.addr + pullreg);
        pullbits &= ~(3 << pullshift);
        pullbits |= (pull << pullshift);
        *(gpio.addr + pullreg) = pullbits;
    }
}


//// init_bcm2835_gpio /////////////////////////////////////////////////
// Called from init_pidp8i_gpio() when it sees that it's running on a Pi
// 3 or older.  This is the "classic" Pi GPIO mode.  See page 101 in the
// peripheral's datasheet and // http://elinux.org/RPi_Low-level_peripherals#Internal_Pull-Ups_.26_Pull-Downs

static void init_bcm2835_gpio (void)
{
    // Configure "columns" GPIO pins
    GPIO_PULL = 2;  // pull-up
    usleep(1);  // must wait 150 cycles
#if defined(PCB_SERIAL_MOD_OV) || defined(PCB_SERIAL_MOD_JLW)
    // The Oscar Vermeulen and James L-W serial mods rearrange the PiDP-8/I
    // GPIO matrix to use Pi GPIO pins 2..13, freeing up the hardware
    // serial port on GPIO pins 14 & 15.
    GPIO_PULLCLK0 = 0x03ffc;
#else
    // The standard PiDP-8/I board drive scheme uses Pi GPIO pins 4..15.
    GPIO_PULLCLK0 = 0x0fff0;
#endif
    usleep(1);
    GPIO_PULL = 0; // reset GPPUD register
    usleep(1);
    GPIO_PULLCLK0 = 0; // remove clock
    usleep(1); // probably unnecessary










    // Configure "rows" GPIO pins

    GPIO_PULL = 0;  // no pull-up no pull down just float
    usleep(1);  // must wait 150 cycles
    GPIO_PULLCLK0 = 0x070000; // selects GPIO pins 16..18
    usleep(1);
    GPIO_PULL = 0; // reset GPPUD register
    usleep(1);
    GPIO_PULLCLK0 = 0; // remove clock
    usleep(1); // probably unnecessary

    // Configure "ledrows" GPIO pins
    GPIO_PULL = 1;  // pull-down to avoid ghosting
    usleep(1);  // must wait 150 cycles
    GPIO_PULLCLK0 = 0x0ff00000; // selects GPIO pins 20..27
    usleep(1);
    GPIO_PULL = 0; // reset GPPUD register
    usleep(1);
    GPIO_PULLCLK0 = 0; // remove clock
    usleep(1); // probably unnecessary
}


//// init_pidp8i_gpio //////////////////////////////////////////////////
// Initialize the GPIO pins to the initial states required by
// gpio_thread().   It's a separate exported function so that scanswitch
// can also use it.

void init_pidp8i_gpio (void)
{
    // Set GPIO pins to their starting state
    turn_on_pidp8i_leds ();
    for (size_t i = 0; i < NROWS; i++) {       // Define rows as input
        INP_GPIO (rows[i]);
    }

    // Configure GPIO pin pull-ups
    if (gpio.addr_p == 0xfe200000) {
        init_bcm2711_gpio();
    }
    else {
        init_bcm2835_gpio();
    }
}


//// gpio_thread ///////////////////////////////////////////////////////
// The GPIO thread entry point: initializes GPIO and then calls
// the gpio_core () implementation linked to this program.

Changes to src/pidp8i/gpio-common.h.

1
2
3
4
5
6
7
8
9
10
11
/*
 * gpio-common.h: public interface for the PiDP-8/I's GPIO module
 *
 * Copyright © 2015-2017 Oscar Vermeulen and Warren Young
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:



|







1
2
3
4
5
6
7
8
9
10
11
/*
 * gpio-common.h: public interface for the PiDP-8/I's GPIO module
 *
 * Copyright © 2015, 2019 by Oscar Vermeulen, © 2016-2019 by Warren Young
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
49
50
51
52
53
54
55






56
57
58
59
60
61
62
#define GPIO_CLR  *(pgpio->addr + 10) // clears bits which are 1 ignores bits which are 0

#define GPIO_READ(g)  *(pgpio->addr + 13) &= (1<<(g))

#define GPIO_PULL *(pgpio->addr + 37) // pull up/pull down
#define GPIO_PULLCLK0 *(pgpio->addr + 38) // pull up/pull down clock








// Switch masks, SSn, used against switchstatus[n]
#define SS0_SR_B11 04000
#define SS0_SR_B10 02000
#define SS0_SR_B09 01000
#define SS0_SR_B08 00400
#define SS0_SR_B07 00200







>
>
>
>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#define GPIO_CLR  *(pgpio->addr + 10) // clears bits which are 1 ignores bits which are 0

#define GPIO_READ(g)  *(pgpio->addr + 13) &= (1<<(g))

#define GPIO_PULL *(pgpio->addr + 37) // pull up/pull down
#define GPIO_PULLCLK0 *(pgpio->addr + 38) // pull up/pull down clock

// Pi 4 GPIO pull up/down peripheral I/O offsets.  Based on
// https://github.com/RPi-Distro/raspi-gpio/blob/master/raspi-gpio.c
#define GPPUPPDN0 57        // pins 15:0
#define GPPUPPDN1 58        // pins 31:16
#define GPPUPPDN2 59        // pins 47:32
#define GPPUPPDN3 60        // pins 57:48

// Switch masks, SSn, used against switchstatus[n]
#define SS0_SR_B11 04000
#define SS0_SR_B10 02000
#define SS0_SR_B09 01000
#define SS0_SR_B08 00400
#define SS0_SR_B07 00200