Read gpio with raw_usb_bus_access?
mabaquero opened this issue · 2 comments
mabaquero commented
spectrometer and system information
- model: HR4000CG-UV-NIR
- operating system: Windows 10 64bit
current problem
Dear experts,
I want to read one of the digital GPIO pins in my spectrometer, but unfortunately the gpio feature does not seem to be available for my device.
From what I can tell, the only feature that is available is "raw_usb_bus_access".
Does anyone know how to use this feature to configure GPIO pin 0 as an input, and then read it?
If so, could you please share with me a couple of lines of code that I can use as a reference?
Thanks!
anpjam459 commented
Hello @mabaquero
Here are my method use to access FPGA and configure GPIO:
import struct
import seabreeze
seabreeze.use('cseabreeze')
from seabreeze.spectrometers import list_devices, Spectrometer
# FPGA commnd bytes
FPGA_WRITE = 0x6A
FPGA_READ = 0x6B
# FPGA address for GPIO
MUX_TYPE = 0x48 # GPIO Mux Register (0 = pin is GPIO pin, 1 = pin is alternate function)
DIR_TYPE = 0x50 # GPIO Output Enable (1 = pin is output, 0=pin is input)
VAL_TYPE = 0x54 # GPIO Data Register (For Ouput = Write value of signal, For Input = Read current GPIO state)
def write_fpga_register(spec: Spectrometer, address: int, val: int):
b0 = FPGA_WRITE
b1 = address.to_bytes(1, byteorder='little')[0]
b2, b3 = val.to_bytes(2, byteorder='little')
request = struct.pack("BBBB", b0, b1, b2, b3)
spec.f.raw_usb_bus_access.raw_usb_write(data=request, endpoint='primary_out')
def read_fpga_register(spec: Spectrometer, address: int):
b0 = FPGA_READ
b1 = address.to_bytes(1, byteorder='little')[0]
request = struct.pack("BB", b0, b1)
spec.f.raw_usb_bus_access.raw_usb_write(data=request, endpoint='primary_out')
response = spec.f.raw_usb_bus_access.raw_usb_read(endpoint='primary_in', buffer_length=3)
return (response[2] << 8) + response[1]
def fpga_major_version(spec: Spectrometer):
data = read_fpga_register(spec, 0x04)
major = (data >> 12) & 0x0f
minor = (data >> 4) & 0xff
path = (data >> 0) & 0x0f
return major
def get_gpio_bit(spec: Spectrometer, type: bytes, pin: int):
data = read_fpga_register(spec, type)
return (data & (1 << pin))
def set_gpio_bit(spec: Spectrometer,type: bytes, pin: int, val: int):
data = read_fpga_register(spec, type)
mask = (1 << pin)
data &= ~mask
if val == 1:
data |= mask
write_fpga_register(spec, type, data)
# Define variables
GPIO_PIN = 0
spec = Spectrometer.from_first_available()
set_gpio_bit(spec, MUX_TYPE, GPIO_PIN, 0) # GPIO pin
set_gpio_bit(spec, DIR_TYPE, GPIO_PIN, 1) # Output signal
set_gpio_bit(spec, VAL_TYPE, GPIO_PIN, 1) # Signal goes HIGH at GPIO pin
#Check signal value of GPIO pin
pin0_status = get_gpio_bit(spec, VAL_TYPE, GPIO_PIN)
print(pin0_status )
spec.close()
Result: Spectrometer pulse HIGH digital signal to GPIO PIN 0
Cheer!!!
mabaquero commented
Thank you very much @anpjam459 ! I will give it a try :)