LPC SPI driver prototype

First contact
On LPC side (init):

  LPC_SSP0->DR = (uint8_t)'R';
  LPC_SSP0->DR = (uint8_t)'V';
  LPC_SSP0->DR = (uint8_t)REFORM_MOTHERBOARD_REV;

On host side:

>>> ssp=spi.SPI("/dev/spidev1.0", 1, 1000000)
>>> ssp.transfer(b'RV0')
b'RV\r'
>>> ssp.transfer(b'1234')
b' \n\x02\x17'
>>> ssp.transfer(b'5678')
b'456\x00'
>>> ssp.transfer(b'abcd')
b' \x0c\x04\x16'
>>> ssp.transfer(b'efgh')
b' \x0c\x04\x16'

On LPC side (uart debug):

IRQ: MIS: 02; RIS: 0A; SR: 10; BUF[0303]: 52 56 30
IRQ: MIS: 04; RIS: 0C; SR: 10; BUF[0404]: 31 32 33 34
IRQ: MIS: 04; RIS: 0C; SR: 10; BUF[0404]: 35 36 37 38
IRQ: MIS: 04; RIS: 0C; SR: 10; BUF[0404]: 61 62 63 64
IRQ: MIS: 04; RIS: 0C; SR: 10; BUF[0404]: 65 66 67 68

so far so good.

3 Likes

More practical example:

>>> from  periphery import spi
>>> ssp=spi.SPI("/dev/spidev1.0", 1, 1000000)
>>> ssp.transfer(b'01234567')
b'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> ssp.transfer(b'01234567')
b'\r\x05m\x01\x00\x00d\xff'
>>> ret=_
>>> print("MB Rev: %d"%ret[0])
MB Rev: 13
>>> print("LPC State: %s"%("Charging","Overvolted","Cooldown","Undervolted","Missing","Full","Suspend")[ret[1]])
LPC State: Full
>>> print("Voltage: %d"%(ret[2]<<8 | ret[3]))
Voltage: 27905
>>> print("Current: %d"%(ret[4]<<8 | ret[5]))
Current: 0
>>> print("Percents: %d"%ret[6])
Percents: 100
>>> print("Controls:\n 5V0: %r\n 3V3: %r\n USB: %r\n AUX: %r\n 1V2: %r\n PE1: %r\n SER: %r\n NTC: %r"%(bool(ret[7]&1), bool(ret[7]&2), bool(ret[7]&4), bool(ret[7]&8), bool(ret[7]&16), bool(ret[7]&32), bool(ret[7]&64), bool(ret[7]&128)))
Controls:
 5V0: True
 3V3: True
 USB: True
 AUX: True
 1V2: True
 PE1: True
 SER: True
 NTC: True

Now at toher console disable UART debug

[root@mnr ~]# sleep 1;echo xUAR0 > /dev/hidraw0

and continue with python:

>>> ret=ssp.transfer(b'01234567')
>>> ret
b'\r\x05l\xfe\x00\x00d\xff'
>>> ret=ssp.transfer(b'01234567')
>>> ret
b'\r\x05lx\x00\x00d\xbf'
>>> print("MB Rev: %d"%ret[0])
MB Rev: 13
>>> print("LPC State: %s"%("Charging","Overvolted","Cooldown","Undervolted","Missing","Full","Suspend")[ret[1]])
LPC State: Full
>>> print("Voltage: %d"%(ret[2]<<8 | ret[3]))
Voltage: 27768
>>> print("Current: %d"%(ret[4]<<8 | ret[5]))
Current: 0
>>> print("Percents: %d"%ret[6])
Percents: 100
>>> print("Controls:\n 5V0: %r\n 3V3: %r\n USB: %r\n AUX: %r\n 1V2: %r\n PE1: %r\n SER: %r\n NTC: %r"%(bool(ret[7]&1), bool(ret[7]&2), bool(ret[7]&4), bool(ret[7]&8), bool(ret[7]&16), bool(ret[7]&32), bool(ret[7]&64), bool(ret[7]&128)))
Controls:
 5V0: True
 3V3: True
 USB: True
 AUX: True
 1V2: True
 PE1: True
 SER: False
 NTC: True
>>>

so yea, kind of works, need to polish data sync

5 Likes

Kinda supercool. Would be nice to incorporate it with waybar battery module!

Amazing! Keep us posted!

Yes absolutely. Although checking battery levels through the LPC is a pretty cool aspect of the laptop to me.

1 Like