Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(619)

Unified Diff: pkg/gpio/lib/gpio.dart

Issue 1389573002: Refactor Raspberry Pi GPIO and add GPIO mock (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Fixed come commetns Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/gpio/lib/gpio_mock.dart » ('j') | pkg/gpio/lib/gpio_mock.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/gpio/lib/gpio.dart
diff --git a/pkg/gpio/lib/gpio.dart b/pkg/gpio/lib/gpio.dart
index fda5c109e5e924a9636e0fa5e229014a3b0a416f..a429e4e2bc00c52d241a6707e1958835cabf7ed2 100644
--- a/pkg/gpio/lib/gpio.dart
+++ b/pkg/gpio/lib/gpio.dart
@@ -27,9 +27,7 @@ import 'dart:typed_data';
import 'package:file/file.dart';
// Foreign functions used.
-final ForeignFunction _open = ForeignLibrary.main.lookup('open');
final ForeignFunction _lseek = ForeignLibrary.main.lookup('lseek');
-final ForeignFunction _mmap = ForeignLibrary.main.lookup('mmap');
final ForeignFunction _poll = ForeignLibrary.main.lookup('poll');
/// GPIO modes.
@@ -46,6 +44,12 @@ enum Mode {
/// Base GPIO interface supported by all GPIO implementations.
abstract class GPIO {
+ /// The default number of pins for GPIO is 50.
+ static const int defaultPins = 50;
+
+ /// Number of pins exposed by this GPIO.
+ int get pins;
+
/// Set the mode of [pin] to [mode].
void setMode(int pin, Mode mode);
@@ -63,162 +67,19 @@ abstract class GPIO {
bool getPin(int pin);
}
-/// Pull-up/down resistor state.
-enum PullUpDown {
- floating,
- pullDown,
- pullUp,
-}
-
// Internal base class.
-class _GPIOBase {
+abstract class GPIOBase implements GPIO {
// Number of GPIO pins.
- final int _maxPins;
+ final int _pins;
- _GPIOBase(this._maxPins);
+ GPIOBase(this._pins);
- void _checkPinRange(int pin) {
- if (pin < 0 || _maxPins <= pin) {
- throw new RangeError.index(pin, this, 'pin', null, _maxPins);
- }
- }
-}
+ get pins => _pins;
-/// Provide GPIO access on Raspberry Pi using direct memory access.
-///
-/// The following code shows how to turn on GPIO pin 4:
-///
-/// ```
-/// PiMemoryMappedGPIO gpio = new PiMemoryMappedGPIO();
-/// gpio.setMode(4, Mode.output);
-/// gpio.setPin(4, true));
-/// ```
-///
-/// The following code shows how to read GPIO pin 17:
-///
-/// ```
-/// PiMemoryMappedGPIO gpio = new PiMemoryMappedGPIO();
-/// gpio.setMode(17, Mode.input);
-/// print(gpio.getPin(17));
-/// ```
-class PiMemoryMappedGPIO extends _GPIOBase implements GPIO {
- // See datasheet:
- // https://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
-
- // Raspberry Pi model 1 (A/A+/B)
- // BCM2708 / BCM 2835
-
- // Raspberry Pi model 2
- // BCM2709 / BCM 2836
-
- // Peripherals base address.
- static const int _baseAddressModel1 = 0x20000000;
- static const int _baseAddressModel2 = 0x3F000000;
- static const int _baseAddressGPIOOffset = 0x00200000;
-
- // Size of the peripherals area.
- static const int _blockSize = 4096;
-
- // Offsets (in bytes) to various areas.
- static const int _gpioFunctionSelectBase = 0 << 2;
- static const int _gpioOutputSetBase = 7 << 2;
- static const int _gpioOutputClearBase = 10 << 2;
- static const int _gpioPinLevelBase = 13 << 2;
- static const int _gpioPullUpPullDown = 37 << 2;
- static const int _gpioPullUpPullDownClockBase = 38 << 2;
-
- // All alternative functions are mapped to `Mode.other` for now.
- static const _functionToMode =
- [Mode.input, Mode.output,
- Mode.other, Mode.other, Mode.other, Mode.other, Mode.other];
-
- int _fd; // File descriptor for /dev/mem.
- ForeignPointer _addr;
- ForeignMemory _mem;
-
- PiMemoryMappedGPIO(): super(54) {
- // From /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h.
- const int oRDWR = 02; // O_RDWR
- // Found from C code 'printf("%x\n", O_SYNC);'.
- const int oSync = 0x101000; // O_SYNC
-
- // Open /dev/mem to get to the physical memory.
- var devMem = new ForeignMemory.fromStringAsUTF8('/dev/mem');
- _fd = _open.icall$2Retry(devMem, oRDWR | oSync);
- if (_fd < 0) {
- throw new GPIOException("Failed to open '/dev/mem'", Foreign.errno);
+ void checkPinRange(int pin) {
+ if (pin < 0 || _pins <= pin) {
+ throw new RangeError.index(pin, this, 'pin', null, _pins);
}
- devMem.free();
-
- // From /usr/include/x86_64-linux-gnu/bits/mman-linux.h.
- const int protRead = 0x1; // PROT_READ.
- const int protWrite = 0x2; // PROT_WRITE.
- const int mapShared = 0x01; // MAP_SHARED.
-
- _addr = _mmap.pcall$6(0, _blockSize, protRead | protWrite, mapShared,
- _fd, _baseAddressModel2 + _baseAddressGPIOOffset);
- _mem = new ForeignMemory.fromAddress(_addr.address, _blockSize);
- }
-
- void setMode(int pin, Mode mode) {
- _checkPinRange(pin);
- // GPIO function select registers each have 3 bits for 10 pins.
- var fsel = (pin ~/ 10);
- var shift = (pin % 10) * 3;
- var function = mode == Mode.input ? 0 : 1;
- var offset = _gpioFunctionSelectBase + (fsel << 2);
- var value = _mem.getUint32(offset);
- value = (value & ~(0x07 << shift)) | function << shift;
- _mem.setUint32(offset, value);
- }
-
- Mode getMode(int pin) {
- _checkPinRange(pin);
- // GPIO function select registers each have 3 bits for 10 pins.
- var fsel = (pin ~/ 10);
- var shift = (pin % 10) * 3;
- var offset = _gpioFunctionSelectBase + (fsel << 2);
- var function = (_mem.getUint32(offset) >> shift) & 0x07;
- return _functionToMode[function];
- }
-
- void setPin(int pin, bool value) {
- _checkPinRange(pin);
- // GPIO output set and output clear registers each have 1 bits for 32 pins.
- int register = pin ~/ 32;
- int shift = pin % 32;
- if (value) {
- _mem.setUint32(_gpioOutputSetBase + (register << 2), 1 << shift);
- } else {
- _mem.setUint32(_gpioOutputClearBase + (register << 2), 1 << shift);
- }
- }
-
- bool getPin(int pin) {
- _checkPinRange(pin);
- // GPIO pin level registers each have 1 bits for 32 pins.
- int register = pin ~/ 32;
- int shift = pin % 32;
- return
- (_mem.getUint32(_gpioPinLevelBase + (register << 2)) & 1 << shift) != 0;
- }
-
- /// Set the floating/pull-up/pull-down state of [pin].
- ///
- /// Use `0` for floating, `1` for pull down and `2` for pull-up.
- void setPullUpDown(int pin, PullUpDown pullUpDown) {
- _checkPinRange(pin);
- int register = pin ~/ 32;
- int shift = pin % 32;
- // First set the value in the update register.
- _mem.setUint32(_gpioPullUpPullDown, pullUpDown.index);
- sleep(1); // Datasheet says: "Wait for 150 cycles".
- // Then set the clock bit.
- _mem.setUint32(_gpioPullUpPullDownClockBase + (register << 2), 1 << shift);
- sleep(1); // Datasheet says: "Wait for 150 cycles".
- // Clear value and clock bit.
- _mem.setUint32(_gpioPullUpPullDown, 0);
- _mem.setUint32(_gpioPullUpPullDownClockBase + (register << 2), 0);
}
}
@@ -267,7 +128,7 @@ enum Trigger {
/// gpio.setPin(4, value);
/// }
/// ```
-class SysfsGPIO extends _GPIOBase implements GPIO {
+class SysfsGPIO extends GPIOBase {
// For documentation on the GPIO Sysfs Interface for Userspace see
// https://www.kernel.org/doc/Documentation/gpio/sysfs.txt.
static const String _basePath = '/sys/class/gpio/';
@@ -286,7 +147,7 @@ class SysfsGPIO extends _GPIOBase implements GPIO {
List<File> _tracked;
/// Create a GPIO controller using the GPIO Sysfs Interface.
- SysfsGPIO([int maxPins = 54]): super(maxPins) {
+ SysfsGPIO([int pins = GPIO.defaultPins]): super(pins) {
sigurdm 2015/10/05 07:22:18 How come this changed from 54 to 50? Was the other
Søren Gjesse 2015/10/05 07:43:39 The value 50 is a pretty arbitrary default. 54 is
// Byte buffers for string constants.
var data;
data = new Uint8List(1);
@@ -316,8 +177,8 @@ class SysfsGPIO extends _GPIOBase implements GPIO {
// Find the exported pins by just running through all trying to open
// the value file.
- _tracked = new List<File>(_maxPins);
- for (int pin = 0; pin < _maxPins; pin++) {
+ _tracked = new List<File>(pins);
+ for (int pin = 0; pin < pins; pin++) {
_track(pin);
}
}
@@ -343,14 +204,14 @@ class SysfsGPIO extends _GPIOBase implements GPIO {
}
void _checkTracked(int pin) {
- _checkPinRange(pin);
+ checkPinRange(pin);
if (!isTracked(pin)) throw 'Pin $pin is not tracked';
}
/// Returns a list with the pins currently tracked.
List tracked() {
var result = [];
- for (int pin = 0; pin < _maxPins; pin++) {
+ for (int pin = 0; pin < pins; pin++) {
if (_tracked[pin] != null) result.add(pin);
}
return result;
@@ -478,7 +339,7 @@ class SysfsGPIO extends _GPIOBase implements GPIO {
}
void exportPin(int pin) {
- _checkPinRange(pin);
+ checkPinRange(pin);
// If already exported do nothing.
if (isTracked(pin)) return;
_exportUnexport(true, pin);
@@ -486,7 +347,7 @@ class SysfsGPIO extends _GPIOBase implements GPIO {
}
void unexportPin(int pin) {
- _checkPinRange(pin);
+ checkPinRange(pin);
// If not exported do nothing.
if (!isTracked(pin)) return;
_exportUnexport(false, pin);
« no previous file with comments | « no previous file | pkg/gpio/lib/gpio_mock.dart » ('j') | pkg/gpio/lib/gpio_mock.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698