//private void Transfer(int b) //{ // var gs = new GpioSequence((this._DigitalWriteRead as Nusbio).GetGpioMask()); // gs.ShiftOut(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b); // gs.Send(this._DigitalWriteRead as Nusbio); //} //public void Transfer(int b0, int b1, int b2, int b3) // { // var gs = new GpioSequence((this._DigitalWriteRead as Nusbio).GetGpioMask()); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b0, gs, send: false); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b1, gs, send: false); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b2, gs, send: false); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b3, gs, send: true); // } private void Transfer(params int[] buffer) { var s = this._nusbio.GetTransferBufferSize(); var gs = new GpioSequence((this._nusbio as Nusbio).GetGpioMask(), s); var i = 0; while (i < buffer.Length) { if (gs.EmptySpace >= GpioSequence.BIT_PER_BYTE) { // Add one byte to the gpio sequence gs.ShiftOut(this._nusbio as Nusbio, this._dataPin, this._clockPin, buffer[i], dataAndClockSameCycleOptimized: CombineSPIDataAndClockOnSameCycle); i += 1; } else { gs.Send(this._nusbio as Nusbio, OptimizeDataLine); var lastMaskValue = gs[gs.Count - 1]; //gs = new GpioSequence((this._DigitalWriteRead as Nusbio).GetGpioMask()); gs = new GpioSequence(lastMaskValue, this._nusbio.GetTransferBufferSize()); } } if (gs.Count > 0) { gs.Send(this._nusbio as Nusbio, OptimizeDataLine); } }
public static EEPROM_BUFFER ReadPageOptimized_SendReadData (GpioSequence spiSeq, int startByteToSkip, int byteToRead, SPIEngine spi) { var nusbio = spi.Nusbio; var eb = new EEPROM_BUFFER(); if (spiSeq.Send(nusbio)) { var inBuffer = spiSeq.GetInputBuffer(nusbio).ToList(); if (startByteToSkip == 0) { inBuffer.RemoveAt(0); // Extra byte from somewhere } if (startByteToSkip > 0) { var offSetToSkip = SPIEngine.BYTES_PER_BIT * 8 * startByteToSkip; // Skip the first 3 bytes, bitbanging the command and 16 bit address inBuffer = inBuffer.GetRange(offSetToSkip, inBuffer.Count - offSetToSkip); } var buffer = __spi_buf_r(byteToRead, inBuffer, spi); for (var i = 0; i < startByteToSkip; i++) // Remove the last startByteToSkip because they were not yet sent { buffer.RemoveAt(buffer.Count - 1); } eb.Buffer = buffer.ToArray(); eb.Succeeded = true; } return(eb); }
public static GpioSequence ShiftOutHardWare(Nusbio nusbio, int dataPin, int clockPin, int val, GpioSequence gs = null, bool send = true, BitOrder bitOrder = BitOrder.MSBFIRST) { if (gs == null) { gs = new GpioSequence(nusbio.GetGpioMask()); } for (var i = 0; i < 8; i++) { int a = 0; if (bitOrder == BitOrder.LSBFIRST) { a = (val & (1 << i)); } else { a = (val & (1 << (7 - i))); } gs.ClockBit(nusbio[clockPin], nusbio[dataPin], a > 0); } if (send) { nusbio.SetGpioMask(gs.ToArray()); } return(gs); }
public void SetGpioMask(int v) { this._gs = new GpioSequence(this._nusbio.GetGpioMask(), this._nusbio.GetTransferBufferSize()); //this._nusbio.GPIOS[_latchPin].DigitalWrite(PinState.Low); if (this.MaxGpio == 16) { // 16 bit - 2 Shift Register ShiftOutFast(_nusbio, _dataPin, _clockPin, (byte)(v >> 8)); ShiftOutFast(_nusbio, _dataPin, _clockPin, (byte)(v & 0xFF)); } else { // 8 bit - 1 Shift Register ShiftOutFast(_nusbio, _dataPin, _clockPin, (byte)(v & 0xFF)); } _gs.Send(_nusbio); _nusbio.GPIOS[_latchPin].DigitalWrite(PinState.Low); _nusbio.GPIOS[_latchPin].DigitalWrite(PinState.High); _nusbio.GPIOS[_latchPin].DigitalWrite(PinState.Low); //if (this.MaxGpio == 16) //{ // _nusbio.GPIOS[_latchPin].DigitalWrite(PinState.Low); // _nusbio.GPIOS[_latchPin].DigitalWrite(PinState.High); //} //if (this.MaxGpio == 24) //{ // // todo //} }
public static GpioSequence ShiftOutHardWare(Nusbio nusbio, int dataPin , int clockPin, int val, GpioSequence gs = null, bool send = true, SB bitOrder = SB.MSBFIRST) { if(gs == null) gs = new GpioSequence(nusbio.GetGpioMask()); for (var i = 0; i < 8; i++) { int a = 0; if (bitOrder == SB.LSBFIRST) a = (val & (1 << i)); else a = (val & (1 << (7 - i))); gs.ClockBit(nusbio[clockPin], nusbio[dataPin], a > 0); } if(send) nusbio.SetGpioMask(gs.ToArray()); return gs; }
void PulseEnable() { if (OptimizeForNusbio()) { // Use Nusbio hardware acceleration to send the pulse var gs = new GpioSequence(this.Nusbio.GetGpioMask()); // Already low by default -- gs.DigitalWrite(this.Nusbio[_enable_pin], PinState.Low); gs.DigitalWrite(this.Nusbio[_enable_pin], PinState.High); gs.DigitalWrite(this.Nusbio[_enable_pin], PinState.Low); this.Nusbio.SetGpioMask(gs.ToArray()); } else { // Use regular bit banging which is compatible with a gpio extender added to Nusbio // but this is slower, because there is not hardware acceleration // Already low by default -- DigitalWrite(_enable_pin, PinState.Low); DigitalWrite(_enable_pin, PinState.High); DigitalWrite(_enable_pin, PinState.Low); } }
/// <summary> /// Read pages using an optimized way to transfer page /// Transfer around 20Kb/s. /// /// About optimizing transfer with Nusbio /// /// There are 2 optimizations /// 1) - We send 64 0 from the master to the slave to force the slave to send the data /// Since we know it all 0 the data line need to be set only once. We therefore save 1 cycle out of 3. /// The cycle saved are used to request more data in the limited 2024 cycles buffer that we hace in one /// USB Transaction /// </summary> /// <param name="addr"></param> /// <param name="len"></param> /// <returns></returns> public EEPROM_BUFFER ReadPageOptimized(int addr, int len = -1) { if (len == -1) { len = this.PAGE_SIZE; } var eb = new EEPROM_BUFFER(); //int byteSent = 0; var nusbio = this._spi.Nusbio; var spi = this._spi; var spiBufferCmdAddr = this.GetEepromApiReadBuffer(addr); var spiBufferDummyData = this.GetEepromApiDataBuffer(len); var buffer = new List <byte>(); buffer.AddRange(spiBufferCmdAddr); // Command + 16 bit Address buffer.AddRange(spiBufferDummyData); // Dummy data to be sent which will force the EEPROM to send the right data back var startByteToSkip = spiBufferCmdAddr.Length; var finalBuffer = new List <byte>(); this._spi.Select(); // Set select now so it is part of the bit banging sequence try { var byteBitBanged = 0; var spiSeq = new GpioSequence(nusbio.GetGpioMask(), nusbio.GetTransferBufferSize()); // Convert the 3 Command Bytes + the 64 0 Bytes into a bit banging buffer // The 64 bytes part is optimized since all the value are 0 we just need to set // the data line once for (var bx = 0; bx < buffer.Count; bx++) { for (byte bit = (1 << 7); bit > 0; bit >>= 1) // MSB - Most significant bit first { spiSeq.ClockBit(nusbio[spi.ClockGpio], nusbio[spi.MosiGpio], WinUtil.BitUtil.IsSet(buffer[bx], bit), compactData: (bx >= spiBufferCmdAddr.Length) // For simplicity do not compact the first 3 commands byte, so we know exactly where the data start after the first 3 bytes ); } byteBitBanged++; if (spiSeq.IsSpaceAvailable(8 * 2)) // If we only have left space to compute 1 byte or less { var peb = ReadPageOptimized_SendReadData(spiSeq, startByteToSkip, byteBitBanged, this._spi); if (peb.Succeeded) { finalBuffer.AddRange(peb.Buffer); spiSeq = new GpioSequence(nusbio.GetGpioMask(), nusbio.GetTransferBufferSize()); startByteToSkip = 0; // We skipped it, let's forget about it byteBitBanged = 0; } else { return(eb); // failed } } } var peb2 = ReadPageOptimized_SendReadData(spiSeq, startByteToSkip, byteBitBanged, this._spi); if (peb2.Succeeded) { finalBuffer.AddRange(peb2.Buffer); eb.Buffer = finalBuffer.ToArray(); eb.Succeeded = true; } else { return(eb); // failed } } finally { this._spi.Unselect(); } return(eb); }
//private void Transfer(int b) //{ // var gs = new GpioSequence((this._DigitalWriteRead as Nusbio).GetGpioMask()); // gs.ShiftOut(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b); // gs.Send(this._DigitalWriteRead as Nusbio); //} //public void Transfer(int b0, int b1, int b2, int b3) // { // var gs = new GpioSequence((this._DigitalWriteRead as Nusbio).GetGpioMask()); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b0, gs, send: false); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b1, gs, send: false); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b2, gs, send: false); // gs = Shift.ShiftOutHardWare(this._DigitalWriteRead as Nusbio, this._dataPin, this._clockPin, b3, gs, send: true); // } private void Transfer(params int[] buffer) { var s = this._nusbio.GetTransferBufferSize(); var gs = new GpioSequence((this._nusbio as Nusbio).GetGpioMask(), s); var i = 0; while (i < buffer.Length) { if (gs.EmptySpace >= GpioSequence.BIT_PER_BYTE) { // Add one byte to the gpio sequence gs.ShiftOut(this._nusbio as Nusbio, this._dataPin, this._clockPin, buffer[i]); i += 1; } else { gs.Send(this._nusbio as Nusbio); var lastMaskValue = gs[gs.Count - 1]; //gs = new GpioSequence((this._DigitalWriteRead as Nusbio).GetGpioMask()); gs = new GpioSequence(lastMaskValue, this._nusbio.GetTransferBufferSize()); } } if (gs.Count > 0) gs.Send(this._nusbio as Nusbio); }