/// <summary> /// Construct an SPI device attached to a particular module /// </summary> /// <param name="spiModule">The module this device is attached to</param> /// <param name="chipSelect">The chip select pin used by this device</param> /// <param name="chipSelectMode">The ChipSelectMode to use with this device</param> /// <param name="speedMhz">The speed to operate this device at</param> /// <param name="mode">The SpiMode of this device</param> public SpiDevice(Spi spiModule, SpiChipSelectPin chipSelect, ChipSelectMode chipSelectMode = ChipSelectMode.SpiActiveLow, double speedMhz = 6, SpiMode mode = SpiMode.Mode00) { ChipSelectMode = chipSelectMode; ChipSelect = chipSelect; _spi = spiModule; Frequency = speedMhz; Mode = mode; _spi.Enabled = true; ChipSelect.MakeDigitalPushPullOutAsync(); // Set the initial chip select state if (chipSelectMode == ChipSelectMode.PulseLowAtBeginning || chipSelectMode == ChipSelectMode.PulseLowAtEnd || chipSelectMode == ChipSelectMode.SpiActiveLow) { ChipSelect.DigitalValue = true; } else { ChipSelect.DigitalValue = false; } }
/// <summary> /// Construct an LED shift register attached directly to a board SPI module /// </summary> /// <param name="SpiModule">The board's SPI module</param> /// <param name="LatchPin">The pin to use for latches</param> /// <param name="OutputEnablePin">The PWM pin to use, allowing controllable global brightness.</param> /// <param name="ChannelCount">The number of channels this LED shift register has</param> /// <param name="speedMhz">The speed, in MHz, to use when communicating</param> public LedShiftRegister(Spi SpiModule, SpiChipSelectPin LatchPin, Pwm OutputEnablePin, LedChannelCount ChannelCount = LedChannelCount.SixteenChannel, double speedMhz = 6) : base(SpiModule, LatchPin, (int)ChannelCount / 8, speedMhz) { oePwm = OutputEnablePin; Start(ChannelCount); }
public SuperNesController(Spi spi, SpiChipSelectPin ps) : base(spi, ps) { X = new Button(new DigitalInPeripheralPin(this)); Y = new Button(new DigitalInPeripheralPin(this)); L = new Button(new DigitalInPeripheralPin(this)); R = new Button(new DigitalInPeripheralPin(this)); }
/// <summary> /// Set up a ChainableShiftRegisterOutput connected to an SPI port. /// </summary> /// <param name="spiModule">the SPI module to use</param> /// <param name="latchPin">The latch pin to use</param> /// <param name="numBytes">The number of bytes to write to this device</param> /// <param name="mode">The SPI mode to use for all shift registers in this chain</param> /// <param name="csMode">The ChipSelectMode to use for all shift registers in this chain</param> /// <param name="speedMhz">The speed to use for all shift registers in this chain</param> public ChainableShiftRegisterOutput(Spi spiModule, SpiChipSelectPin latchPin, int numBytes = 1, double speedMhz = 6, SpiMode mode = SpiMode.Mode00, ChipSelectMode csMode = ChipSelectMode.PulseHighAtEnd) { spiDevice = new SpiDevice(spiModule, latchPin, csMode, speedMhz, mode); this.numBytes = numBytes; CurrentValue = new byte[numBytes]; lastValues = new byte[numBytes]; }
public NesController(Spi spi, SpiChipSelectPin ps) { dev = new SpiDevice(spi, ps, ChipSelectMode.PulseHighAtBeginning); A = new Button(new DigitalInPeripheralPin(this)); B = new Button(new DigitalInPeripheralPin(this)); Start = new Button(new DigitalInPeripheralPin(this)); Select = new Button(new DigitalInPeripheralPin(this)); }
/// <summary> /// Construct a FLIR Lepton /// </summary> /// <param name="spi">The Spi module to use</param> /// <param name="cs">The chip-select pin</param> public FlirLepton(Spi spi, SpiChipSelectPin cs) { this.dev = new SpiDevice(spi, cs, ChipSelectMode.SpiActiveLow, 6, SpiMode.Mode11); this.cs = cs; blackFrame = new ushort[height, width]; for (var i = 0; i < height; i++) { for (var j = 0; j < width; j++) { blackFrame[i, j] = 0xffff; } } }
public Nrf24l01(Spi spi, SpiChipSelectPin csPin, DigitalOut cePin, DigitalIn irqPin) { dev = new SpiDevice(spi, csPin); this.irqPin = irqPin; this.cePin = cePin; Task.Run(irqPin.MakeDigitalInAsync).Wait(); Task.Run(cePin.MakeDigitalPushPullOutAsync).Wait(); cePin.DigitalValue = false; irqPin.DigitalValueChanged += IrqPin_DigitalValueChanged; Task.Run(() => dev.SendReceiveAsync(new byte[] { 0x50, 0x73 })).Wait(); // enable feature register Task.Run(() => WriteRegister((byte)Registers.Feature, 0b00000111)).Wait(); Task.Run(() => WriteRegister((byte)Registers.DynamicPayloadLength, 0b00111111)).Wait(); Task.Run(writeConfig).Wait(); for (int i = 0; i < 6; i++) { pipes[i] = new Pipe(i, this); } // set default addresses pipes[0].address = 0xE7E7E7E7E7; pipes[1].address = 0xC2C2C2C2C2; pipes[2].address = 0xC2C2C2C2C3; pipes[3].address = 0xC2C2C2C2C4; pipes[4].address = 0xC2C2C2C2C5; pipes[5].address = 0xC2C2C2C2C6; // set default enable state pipes[0].enablePipe = true; pipes[1].enablePipe = true; Task.Run(() => Task.Delay(5)).Wait(); Task.Run(FlushRx).Wait(); Task.Run(FlushTx).Wait(); powerUp = true; Task.Run(writeConfig).Wait(); Task.Run(() => Task.Delay(5)).Wait(); // manually call the ISR just in case there's something pending IrqPin_DigitalValueChanged(this, new DigitalInValueChangedEventArgs(cePin.DigitalValue)); }
/// <summary> /// Construct a new instance of a Max7219 device /// </summary> /// <param name="SpiModule">A reference to the Treehopper SPI module</param> /// <param name="LoadPin">The pin attached tot he LOAD input</param> /// <param name="Address">The index of the Max7219 device attached to this bus</param> /// <param name="SpeedMHz">The SPI speed to use. The maximum is 10 MHz.</param> public Max7219(Spi SpiModule, SpiChipSelectPin LoadPin, int Address = 0, double SpeedMHz = 6) : base(64, true, false) { if (SpeedMHz > 10) { throw new ArgumentOutOfRangeException("SpeedMhz", "The MAX7219 supports a maximum clock rate of 10 MHz."); } dev = new SpiDevice(SpiModule, LoadPin, speedMhz: SpeedMHz, chipSelectMode: ChipSelectMode.PulseHighAtEnd); address = Address; sendTest(false); ScanLimit = 7; sendDecodeMode(0); Clear().Wait(); Shutdown = false; SetGlobalBrightness(1); }
public Pcd8544(Spi spi, SpiChipSelectPin csPin, DigitalOut dc, DigitalOut rst, byte biasValue = 0x04) : base(84, 48) { this.spi = new SpiDevice(spi, csPin, ChipSelectMode.SpiActiveLow, 6); this.dc = dc; this.rst = rst; this.dc.MakeDigitalPushPullOutAsync(); this.rst.MakeDigitalPushPullOutAsync(); this.rst.DigitalValue = true; this.rst.DigitalValue = false; this.rst.DigitalValue = true; sendCommand(Command.EnterExtendedCommandMode).Wait(); sendCommand(Command.SetVop, 0x30).Wait(); sendCommand(Command.SetTempCoefficient, 0x00).Wait(); sendCommand(Command.SetBias, biasValue).Wait(); sendCommand(Command.ExitExtendedCommandMode).Wait(); sendCommand(Command.DisplayOn).Wait(); }
public Mcp425x(Spi spi, SpiChipSelectPin cs) : base(spi, cs) { scale = 256; }
/// <summary> /// Construct a DM632 16-channel, 16-bit PWM LED controller attached directly to an SPI port /// </summary> /// <param name="SpiModule">The SPI module to use</param> /// <param name="LatchPin">The latch pin to use</param> /// <param name="speedMhz">The speed, in MHz, to use</param> public Dm632(Spi SpiModule, SpiChipSelectPin LatchPin, double speedMhz = 6) : base(SpiModule, LatchPin, 32, speedMhz) { start(); }
public Mcp423x(Spi spi, SpiChipSelectPin cs) : base(spi, cs) { }
/// <summary> /// Construct a new 74HC595-type shift register that is directly connected to a Treehopper's SPI port /// </summary> public Hc595(Spi spiModule, SpiChipSelectPin latchPin, double speedMhz = 6) : base(spiModule, latchPin, 8, SpiMode.Mode00, ChipSelectMode.PulseHighAtEnd, speedMhz) { }
/// <summary> /// Send/receive data /// </summary> /// <param name="dataToWrite"> /// a byte array of the data to send. The length of the transaction is determined by the length of this array. /// </param> /// <param name="chipSelect">The chip select pin, if any, to use during this transaction.</param> /// <param name="chipSelectMode">The chip select mode to use during this transaction (if a CS pin is selected)</param> /// <param name="speedMhz">The speed to perform this transaction at.</param> /// <param name="burstMode"The burst mode (if any) to use.</param> /// <param name="spiMode">The SPI mode to use during this transaction.</param> /// <returns>An awaitable byte array with the received data.</returns> public async Task <byte[]> SendReceiveAsync(byte[] dataToWrite, SpiChipSelectPin chipSelect = null, ChipSelectMode chipSelectMode = ChipSelectMode.SpiActiveLow, double speedMhz = 6, SpiBurstMode burstMode = SpiBurstMode.NoBurst, SpiMode spiMode = SpiMode.Mode00) { var transactionLength = dataToWrite.Length; var returnedData = new byte[transactionLength]; if (Enabled != true) { Utility.Error("SPI module must be enabled before starting transaction", true); } if (chipSelect != null && chipSelect.SpiModule != this) { Utility.Error("Chip select pin must belong to this SPI module", true); } if (speedMhz > 0.8 && speedMhz < 6) { Debug.WriteLine( "NOTICE: automatically rounding up SPI speed to 6 MHz, due to a possible silicon bug. This bug affects SPI speeds between 0.8 and 6 MHz, so if you need a speed lower than 6 MHz, please set to 0.8 MHz or lower."); speedMhz = 6; } using (await _device.ComsLock.LockAsync().ConfigureAwait(false)) { var spi0Ckr = (int)Math.Round(24.0 / speedMhz - 1); if (spi0Ckr > 255.0) { spi0Ckr = 255; Debug.WriteLine( "NOTICE: Requested SPI frequency of {0} MHz is below the minimum frequency, and will be clipped to 0.09375 MHz (93.75 kHz).", speedMhz); } else if (spi0Ckr < 0) { spi0Ckr = 0; Debug.WriteLine( "NOTICE: Requested SPI frequency of {0} MHz is above the maximum frequency, and will be clipped to 24 MHz.", speedMhz); } var actualFrequency = 48.0 / (2.0 * (spi0Ckr + 1.0)); if (Math.Abs(actualFrequency - speedMhz) > 1) { Debug.WriteLine( "NOTICE: SPI module actual frequency of {0} MHz is more than 1 MHz away from the requested frequency of {1} MHz", actualFrequency, speedMhz); } if (dataToWrite.Length > 255) { throw new Exception("Maximum packet length is 255 bytes"); } var header = new byte[7]; header[0] = (byte)DeviceCommands.SpiTransaction; header[1] = (byte)(chipSelect?.PinNumber ?? 255); header[2] = (byte)chipSelectMode; header[3] = (byte)spi0Ckr; header[4] = (byte)spiMode; header[5] = (byte)burstMode; header[6] = (byte)transactionLength; // just send the header if (burstMode == SpiBurstMode.BurstRx) { await _device.SendPeripheralConfigPacketAsync(header).ConfigureAwait(false); } else { var dataToSend = new byte[transactionLength + header.Length]; Array.Copy(header, dataToSend, header.Length); Array.Copy(dataToWrite, 0, dataToSend, header.Length, transactionLength); var bytesRemaining = dataToSend.Length; var offset = 0; while (bytesRemaining > 0) { var transferLength = bytesRemaining > 64 ? 64 : bytesRemaining; var tmp = dataToSend.Skip(offset).Take(transferLength); await _device.SendPeripheralConfigPacketAsync(tmp.ToArray()).ConfigureAwait(false); offset += transferLength; bytesRemaining -= transferLength; } } // no need to wait if we're not reading anything if (burstMode != SpiBurstMode.BurstTx) { var bytesRemaining = transactionLength; var srcIndex = 0; while (bytesRemaining > 0) { var numBytesToTransfer = bytesRemaining > 64 ? 64 : bytesRemaining; var receivedData = await _device.ReceiveCommsResponsePacketAsync((uint)numBytesToTransfer) .ConfigureAwait(false); Array.Copy(receivedData, 0, returnedData, srcIndex, receivedData.Length); // just in case we don't get what we're expecting srcIndex += numBytesToTransfer; bytesRemaining -= numBytesToTransfer; } } } return(returnedData); }
public Mcp413x(Spi spi, SpiChipSelectPin cs) { this.dev = new SpiDevice(spi, cs); scale = 128; }
public SpiFlash(Spi dev, SpiChipSelectPin cs) { this.dev = new SpiDevice(dev, cs, ChipSelectMode.SpiActiveLow, 6); }
/// <summary> /// Construct a shift register attached to an SPI port /// </summary> /// <param name="spiModule">The SPI module this shift register is attached to</param> /// <param name="latchPin">The latch pin to use</param> /// <param name="numPins">The number of pins on the shift register</param> /// <param name="mode">THe SPI mode to use with this shift register (and subsequent ones on this chain)</param> /// <param name="csMode">The chip select mode to use with this shift register (and subsequent ones on this chain)</param> /// <param name="speedMhz">The speed to operate this shift register (and subsequent ones on this chain) with</param> public ShiftOut(Spi spiModule, SpiChipSelectPin latchPin, int numPins = 8, SpiMode mode = SpiMode.Mode00, ChipSelectMode csMode = ChipSelectMode.PulseHighAtEnd, double speedMhz = 1) : base(spiModule, latchPin, numPins / 8, speedMhz, mode, csMode) { setup(numPins); }