Hi, I am trying to use GHI Pulse Count Module with Windows 10 IoT. Unfortunately, I am not able to configure the module. Can you give me a hint please? I am begginer. My code looks like this:
static class LS7366
{
/*******************************************************************
// LS7366 REGISTERS
//------------------------------------------------------------------
// MDR0 : MoDe Register 0 (8 bit read/write)
// Upon power up, MDR0 is set to zero
// B1 B0: count mode 1
// 00 = non quadrature mode (A = clock, B = direction)
// 01 = x1 quadrature mode (one count per quad. cycle)
// 10 = x2 quadrature mode (two counts per quad. cycle)
// 11 = x4 quadrature mode (four counts per quad. cycle)
// B3 B2: count mode 2
// 00 = free running count mode
// 01 = single-cycle count mode (disabled on carry or
// borrow, resumed on reset)
// 10 = range limit count mode (up and down between DTR
// and zero, freezes at limit and resumes on
// direction change
// 11 = modulo-n count, where n = DTR in both directions
// B5 B4: index function
// 00 =
// 01 =
// 10 =
// 11 =
// B6: 0 = asynchronous index
// 1 = synchronous index (overriden in non-quad. mode)
// B7: 0 = filter clock division factor = 1
// 1 = filter clock division factor = 2
//------------------------------------------------------------------
// MDR1 : MoDe Register 1 (8 bit read/write) as appendix to MDR0
// Upon power up, MDR0 is set to zero
// B1 B0: count mode 1
// 00 = 4-byte counter mode
// 01 = 3-byte counter mode
// 10 = 2-byte counter mode
// 11 = 1-byte counter mode
// B2: 0 = enable counting
// 1 = disable counting
// B3: not used
// B4: 0 = NOP
// 1 = FLAG on IDX (B4 of STR) \
// B5: 0 = NOP |
// 1 = FLAG on CMP (B5 of STR) | NOTE: applicable on
// B6: 0 = NOP > both LFLAG and DFLAG
// 1 = FLAG on BW (B6 of STR) |
// B7: 0 = NOP |
// 1 = FLAG on CY (B7 of STR) /
//------------------------------------------------------------------
// DTR : DaTa Register input (8, 16, 24 or 32 bits)
// Can be written directly from MOSI
//------------------------------------------------------------------
// CNTR : CouNTer Register (8, 16, 24 or 32 bits)
// This register counts the up/down pulses from the quad.
// clock applied at the A and B inputs or alternatively
// from the A input in non-quad. mode
//------------------------------------------------------------------
// OTR : OuTput Register (8, 16, 24 or 32 bits)
// Shadow register from CNTR to read the counter value
// during counting. Can be read directly from MOSI while
// the counter still counts
//------------------------------------------------------------------
// STR : STatus Register (8 bit read)
// B0: S = signbit (0 neg, 1 pos)
// B1: U/D = up/down indicator (0 down, 1 up)
// B2: PLS = power loss indicator latch; set upon powerup
// B3: CEN = count enable status (0 disabled, 1 enabled)
// B4: IDX = index latch
// B5: CMP = compare (CNTR = DTR) latch
// B6: BW = borrow (CNTR underlow) latch
// B7: CY = carry (CNTR overflow) latch
//------------------------------------------------------------------
// IR : Instruction Register (8 bit write)
// B2 B1 B0 : XXX (don't care)
// B5 B4 B3 : 000 = select none
// 001 = select MDR0
// 010 = select MDR1
// 011 = select DTR
// 100 = select CNTR
// 101 = select OTR
// 110 = select STR
// 111 = select none
// B7 B6 : 00 = CLR register
// 01 = RD register
// 10 = WR register
// 11 = LOAD register
/*******************************************************************
// Number of Bytes | OP Code | Register | Operation
//-----------------+---------+----------+---------------------------
// | | MDR0 | Clear MDR0 to zero
// | | MDR1 | Clear MDR1 to zero
// 1 | CLR | DTR | None
// | | CNTR | Clear CNTR to zero
// | | OTR | None
// | | STR | Clear STR to zero
//-----------------+---------+----------+---------------------------
// | | MDR0 | Output MDR0 on MISO
// | | MDR1 | Output MDR1 on MISO
// 2 to 5 | RD | DTR | None
// | | CNTR | Transfer CNTR to OTR,
// | | | then output OTR on MISO
// | | OTR | Output OTR on MISO
// | | STR | Output STR on MISO
//-----------------+---------+----------+---------------------------
// | | MDR0 | Write at MOSI into MDR0
// | | MDR1 | Write at MOSI into MDR1
// 2 to 5 | WR | DTR | Write at MOSI into DTR
// | | CNTR | None
// | | OTR | None
// | | STR | None
//-----------------+---------+----------+---------------------------
// | | MDR0 | None
// | | MDR1 | None
// 1 | LOAD | DTR | None
// | | CNTR | Transfer DTR to CNTR
// | | OTR | Transfer CNTR to OTR
*******************************************************************/
#region Registers, commands and modes
// LS7366 Commands
public enum Commands : byte
{
LS7366_CLEAR = 0x00, // clear register
LS7366_READ = 0x40, // read register
LS7366_WRITE = 0x80, // write register
LS7366_LOAD = 0xC0, // load register
}
// LS7366 Registers
public enum Registers : byte
{
LS7366_MDR0 = 0x08, // select MDR0
LS7366_MDR1 = 0x10, // select MDR1
LS7366_DTR = 0x18, // select DTR
LS7366_CNTR = 0x20, // select CNTR
LS7366_OTR = 0x28, // select OTR
LS7366_STR = 0x30, // select STR
}
// LS7366 MDR0 Counter modes
public enum MDR0Mode : byte
{
LS7366_MDR0_QUAD0 = 0x00, // none quadrature mode
LS7366_MDR0_QUAD1 = 0x01, // quadrature x1 mode
LS7366_MDR0_QUAD2 = 0x02, // quadrature x2 mode
LS7366_MDR0_QUAD4 = 0x03, // quadrature x4 mode
LS7366_MDR0_FREER = 0x00, // free run mode
LS7366_MDR0_SICYC = 0x04, // single cycle count mode
LS7366_MDR0_RANGE = 0x08, // range limit count mode (0-DTR-0)
// counting freezes at limits but
// resumes on direction reverse
LS7366_MDR0_MODTR = 0x0C, // modulo-n count (n=DTR both dirs)
LS7366_MDR0_DIDX = 0x00, // disable index
LS7366_MDR0_LDCNT = 0x10, // config IDX as load DTR to CNTR
LS7366_MDR0_RECNT = 0x20, // config IDX as reset CNTR (=0)
LS7366_MDR0_LDOTR = 0x30, // config IDX as load CNTR to OTR
LS7366_MDR0_ASIDX = 0x00, // asynchronous index
LS7366_MDR0_SYINX = 0x40, // synchronous IDX (if !NQUAD)
LS7366_MDR0_FFAC1 = 0x00, // filter clock division factor=1
LS7366_MDR0_FFAC2 = 0x80, // filter clock division factor=2
LS7366_MDR0_NOFLA = 0x00, // no flags
}
// LS7366 MDR1 counter modes
public enum MDR1Mode : byte
{
LS7366_MDR1_4BYTE = 0x00, // 4 byte counter mode
LS7366_MDR1_3BYTE = 0x01, // 3 byte counter mode
LS7366_MDR1_2BYTE = 0x02, // 2 byte counter mode
LS7366_MDR1_1BYTE = 0x03, // 1 byte counter mode
LS7366_MDR1_ENCNT = 0x00, // enable counting
LS7366_MDR1_DICNT = 0x04, // disable counting
LS7366_MDR1_FLIDX = 0x20, // FLAG on IDX (index)
LS7366_MDR1_FLCMP = 0x40, // FLAG on CMP (compare)
LS7366_MDR1_FLCY = 0x80, // FLAG on CY (carry)
}
#endregion Registers, commands and modes
}
//Pulse Counter (GHI)
private async void InitPulseCounter()
{
const string SPI_CONTROLLER_NAME = "SPI0";
const Int32 SPI_CHIP_SELECT_LINE = 0;
var settings = new SpiConnectionSettings(SPI_CHIP_SELECT_LINE);
settings.ClockFrequency = 4000000;
settings.Mode = SpiMode.Mode3;
string spis = SpiDevice.GetDeviceSelector(SPI_CONTROLLER_NAME);
var dis = await DeviceInformation.FindAllAsync(spis);
this.spiPulseCounter = await SpiDevice.FromIdAsync(dis[0].Id, settings);
if (spiPulseCounter == null)
{
System.Diagnostics.Debug.WriteLine(
"SPI Controller is currently in use by " +
"another application. Please ensure that no other applications are using SPI.");
}
#region Clear registers
// Clear MDR0 register
this.spiPulseCounter.Write(new byte[] { (byte)LS7366.Commands.LS7366_CLEAR | (byte)LS7366.Registers.LS7366_MDR0 });
// Clear MDR1 register
this.spiPulseCounter.Write(new byte[] { (byte)LS7366.Commands.LS7366_CLEAR | (byte)LS7366.Registers.LS7366_MDR1 });
// Clear STR register
this.spiPulseCounter.Write(new byte[] { (byte)LS7366.Commands.LS7366_CLEAR | (byte)LS7366.Registers.LS7366_STR });
// Clear CNTR
this.spiPulseCounter.Write(new byte[] { (byte)LS7366.Commands.LS7366_CLEAR | (byte)LS7366.Registers.LS7366_CNTR });
// Clear ORT (write CNTR into OTR)
this.spiPulseCounter.Write(new byte[] { (byte)LS7366.Commands.LS7366_LOAD | (byte)LS7366.Registers.LS7366_OTR });
#endregion
#region Configure MDR0 and MDR1 registers
// Configure MDR0 register
this.spiPulseCounter.Write(new byte[2] { (byte)LS7366.Commands.LS7366_WRITE // write command
| (byte)LS7366.Registers.LS7366_MDR0, // to MDR0
(byte)LS7366.MDR0Mode.LS7366_MDR0_QUAD0 // none quadrature mode
| (byte)LS7366.MDR0Mode.LS7366_MDR0_MODTR // modulo-n counting
| (byte)LS7366.MDR0Mode.LS7366_MDR0_DIDX }); // disable index
// Configure MDR1 register
this.spiPulseCounter.Write(new byte[2] { (byte)LS7366.Commands.LS7366_WRITE // write command
| (byte)LS7366.Registers.LS7366_MDR1, // to MDR1
(byte)LS7366.MDR1Mode.LS7366_MDR1_4BYTE // 4 byte counter mode
| (byte)LS7366.MDR1Mode.LS7366_MDR1_ENCNT // enable counting
/* | (byte)LS7366.MDR1Mode.LS7366_MDR1_FLCMP */ }); // FLAG on CMP (compare)
#endregion
#region Read registers to test
// Read/write buffers
byte[] LS7366_2B_rd = new byte[2]; // read two bytes
byte[] LS7366_4B_rd = new byte[4]; // read four bytes
// Read MDR0 register
this.spiPulseCounter.TransferFullDuplex(new byte[2] { (byte)LS7366.Commands.LS7366_READ // read
| (byte)LS7366.Registers.LS7366_MDR0, 0 }, LS7366_2B_rd); // MDR0
System.Diagnostics.Debug.WriteLine($" B0={LS7366_2B_rd[0]}, B1={LS7366_2B_rd[1]}");
// Read MDR1 register
this.spiPulseCounter.TransferFullDuplex(new byte[2] { (byte)LS7366.Commands.LS7366_READ // read
| (byte)LS7366.Registers.LS7366_MDR1, 0 }, LS7366_2B_rd); // MDR1
System.Diagnostics.Debug.WriteLine($" B0={LS7366_2B_rd[0]}, B1={LS7366_2B_rd[1]}");
// Read STR register
this.spiPulseCounter.TransferFullDuplex(new byte[2] { (byte)LS7366.Commands.LS7366_READ // read
| (byte)LS7366.Registers.LS7366_STR, 0 }, LS7366_2B_rd); // MDR1
System.Diagnostics.Debug.WriteLine($" B0={LS7366_2B_rd[0]}, B1={LS7366_2B_rd[1]}");
#endregion
}
Thank you!