Skip to content

Instantly share code, notes, and snippets.

@theterg
Last active December 29, 2018 12:29
Show Gist options
  • Select an option

  • Save theterg/5106107 to your computer and use it in GitHub Desktop.

Select an option

Save theterg/5106107 to your computer and use it in GitHub Desktop.
Reverse-engineered pyusb code to read from a renesas RL78G13 promotion board. It uses some random MCU as a debug/programmer tool and a USB->serial device. Windows drivers only. All of the ctrl_transfers were sniffed using wireshark inbetween a windows VM.
import usb.core
import usb.util
import sys
from commands import getstatusoutput
import json
# find our device
dev = usb.core.find(idVendor=0x045b, idProduct=0x0212)
# was it found?
if dev is None:
raise ValueError('Device not found')
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(dev,interface_number)
intf = usb.util.find_descriptor(
cfg, bInterfaceNumber = interface_number,
bAlternateSetting = alternate_setting
)
ep = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN
)
assert ep is not None
# open serial port and set parameters (
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x03\x01')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x01\x03')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x00\x80\x25\x00\x00\x01')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x04\x00\x00')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x01\x03')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x01\x03')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x00\x80\x25\x00\x00\x01')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x04\x00\x00')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x02\x11\x13')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x04\x00\x00')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x00\x80\x25\x00\x00\x01')
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x04\x00\x00')
def changeVolume(volume):
code,output = getstatusoutput('pactl set-sink-volume 0 -- '+str(volume)+'%')
sys.stdout.write(str(volume)+'% \r')
sys.stdout.flush()
if code != 0:
print "Error changing volume: "+output
def buttonPress(button):
code = 0
output = ''
if button == 1:
code,output = getstatusoutput('xdotool key XF86AudioNext')
sys.stdout.write('next \r')
sys.stdout.flush()
elif button == 2:
code,output = getstatusoutput('xdotool key XF86AudioPlay')
sys.stdout.write('play/pause\r')
sys.stdout.flush()
elif button == 3:
code,output = getstatusoutput('xdotool key XF86AudioPrev')
sys.stdout.write('prev \r')
sys.stdout.flush()
if code != 0:
print "Error pressing key: "+output
def parseLine(line):
jdata = json.loads(line)
if 'volume' in jdata:
changeVolume(jdata['volume'])
elif 'buttonDown' in jdata:
buttonPress(jdata['buttonDown'])
print "Reading volume data from remote:"
reading = True
line = ''
while(reading):
try:
newchar = chr(dev.read(ep.bEndpointAddress, 1, intf, 5000)[0])
line += newchar
if newchar == '\n' and line[-2] == '\r':
parseLine(line.rstrip())
#print line.rstrip()
#changeVolume(line.split(',')[0])
line = ''
except KeyboardInterrupt:
reading = False
#let device know we're closing the port
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x03\x00')
print "Port Closed."
except usb.core.USBError as e:
#on a USB timeout (err 110), continue, otherwise, close
if e.errno != 110:
print e
reading = False
#let device know we're closing the port
dev.ctrl_transfer(0x40, 11, 0x0000, 0, '\x03\x00')
print "USB error, Port Closed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment