added comments
[goodfet] / client / goodfet.cc2500
1 #!/usr/bin/env python
2
3 #GoodFET Chipcon CC2500 SPI Client
4 #by Jean-Michel Picod <jean-michel.picod at cassidan.com>
5
6 import sys
7
8 from GoodFETCC2500 import GoodFETCC2500
9
10 if len(sys.argv) == 1:
11     print "Usage: %s verb [objects]\n" % sys.argv[0]
12     print "%s info" % sys.argv[0]
13 #    print "%s test" % sys.argv[0]
14     print "%s regs" % sys.argv[0]
15     print "%s pyregs" % sys.argv[0]
16     print ""
17     print "%s tunelelo\n\tTunes to Lelo vibrator configuration." % sys.argv[0]
18     print "%s snifflelo\n\tSniffs Lelo vibrator packets" % sys.argv[0]
19     print "%s setlelo [0-128]\n\tSet Lelo vibrator strength to a given value" % sys.argv[0]
20     print ""
21     sys.exit()
22
23 #Initialize FET and set baud rate
24 client = GoodFETCC2500()
25 client.serInit()
26 client.setup()
27
28 def printconfig(client):
29     print "Encoding     %s (with%s Manchester)" % (client.RF_get_modulation(), "out" if client.peek_by_name("MDMCFG2") & 0x8 else "")
30     print "Base Freq    %.3f MHz" % (client.RF_get_frequency() / 10**6)
31     print "IF Freq      %.3f kHz" % (client.RF_get_IF_freq() / 1000)
32     print "Channel      %d" % client.RF_get_channel()
33     print "Chan spacing %.3f kHz" % (client.RF_get_chan_spacing() / 1000)
34     print "Eff Freq     %.3f MHz" % (((client.RF_get_channel() * client.RF_get_chan_spacing()) + client.RF_get_frequency()) / 10**6)
35     print "Bandwith     %i kHz" % client.RF_getbandwith()
36     print "Rate         %d kbps" % round(client.RF_get_datarate() / 1000)
37     l = client.RF_get_pkt_len()
38     if l > 0:
39         print "PacketLen    %i bytes (fixed)" % l
40     elif l < 0:
41         print "PacketLen    %i bytes (variable)" % -l
42     elif l == None:
43         print "PacketLen    Infinite"
44     print "Preamble     %d bytes" % client.RF_get_preamble_len()
45     print "Sync         0x%04x" % client.RF_get_syncword()
46     print "CRC          %s" % ("Enabled" if client.peek_by_name("PKTCTRL0") & 0x4 else "Disabled")
47     print "Whitening    %s" % ("Enabled" if client.peek_by_name("PKTCTRL0") & 0x40 else "Disabled")
48     print "Address      %d" % client.RF_get_addr()
49
50 if sys.argv[1] == "info":
51     printconfig(client)
52
53 if sys.argv[1] == "regs":
54     regs = client.regs()
55     for k,v in regs:
56         print "%-8s = 0x%02x" % (k, v)
57
58 if sys.argv[1] == "pyregs":
59     regs = client.regs()
60     for k,v in regs:
61         print "client.poke_by_name('%s', 0x%02x)" % (k, v)
62
63 def leloremote_setup(client):
64     """Based on scanlime blog post: scanlime.org/2012/11/hacking-my-vagina/"""
65     client.CC_strobe_RES()
66     client.poke(0x0B, [0x0A, 0x00]) # FSCTRL
67     client.poke(0x0D, [0x5D, 0x13, 0xB1]) # FREQ
68     client.poke(0x10, [0x2D, 0x3B, 0x73, 0x22, 0xF8]) # MDMCFG
69     client.poke(0x0A, 0x01) # CHANNR
70     client.poke(0x15, 0x00) # DEVIATN
71     client.poke(0x21, [0xB6, 0x10]) # FREND
72     client.poke(0x18, 0x18) # MCSM0
73     client.poke(0x19, 0x1D) # FOCCFG
74     client.poke(0x1A, 0x1C) # BSCFG
75     client.poke(0x1B, [0xC7, 0x00, 0xB0]) # AGCTRL
76     client.poke(0x23, [0xEA, 0x0A, 0x00, 0x11]) # FSCAL3
77     client.poke(0x29, 0x59) # FSTEST
78     client.poke(0x2C, [0x88, 0x31, 0x0B]) # TEST
79     client.poke(0x00, 0x29) # IOCFG2
80     client.poke(0x02, 0x06) # IOCFG0
81     client.poke(0x07, [0x0A, 0x04]) # PKTCTRL
82     client.poke(0x09, 0x01) # ADDR
83     client.poke(0x06, 0x09) # PKTLEN
84     client.poke(0x7E, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]) # PATABLE
85     client.CC_strobe_FRX()
86     client.CC_strobe_FTX()
87     client.CC_strobe_IDLE()
88
89 if sys.argv[1] == "tunelelo":
90     leloremote_setup(client)
91
92 if sys.argv[1] == "snifflelo":
93     leloremote_setup(client)
94     ## Always receive
95     client.RF_set_rxoff_mode("IDLE")
96     client.CC_strobe_FRX() ## Flush FIFO
97     print "Entering receive mode..."
98     while True:
99         data = client.RF_rxpacket(bytes=9)
100         if data is None or data == "":
101             continue
102         if isinstance(data, str):
103             data = [ord(x) for x in data]
104         if data[0:2] == [ 0x01, 0x00, 0xA5 ] and data[5:9] == [ 0x00, 0x00, 0x00, 0x05 ]:
105             print "Motor1: %d (0x%02x)" % (data[2], data[2])
106             print "Motor2: %d (0x%02x)" % (data[3], data[3])
107         else:
108             print "Invalid Lelo packet: %s" % " ".join(["%02X" % x for x in data])
109
110 if sys.argv[1] == "setlelo":
111     if len(sys.argv) > 2:
112         strength = min(128, max(0, int(sys.argv[2])))
113         print "Setting Lelo vibrator strengh to %d out of 128" % strength
114         client.RF_txpacket([0x01, 0x00, 0xA5, strength, strength, 0x00, 0x00, 0x00, 0x05])
115     else:
116         print "ERROR: missing motor strength"
117