Subversion Repositories freemyipod

Rev

Rev 342 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 342 Rev 343
Line 70... Line 70...
70
    """
70
    """
71
        Class for all embios functions.
71
        Class for all embios functions.
72
    """
72
    """
73
    def __init__(self):
73
    def __init__(self):
74
        self.lib = Lib()
74
        self.lib = Lib()
-
 
75
        
-
 
76
        self.getversioninfo()
75
        self.getpacketsizeinfo()
77
        self.getpacketsizeinfo()
-
 
78
        self.getusermemrange()
76
    
79
    
77
    @staticmethod
80
    @staticmethod
78
    def _alignsplit(addr, size, blksize, align):
81
    def _alignsplit(addr, size, blksize, align):
79
        if size <= blksize: return (size, 0, 0)
82
        if size <= blksize: return (size, 0, 0)
80
        end = addr + size
83
        end = addr + size
Line 129... Line 132...
129
    def getpacketsizeinfo(self):
132
    def getpacketsizeinfo(self):
130
        """ This returns the emBIOS max packet size information.
133
        """ This returns the emBIOS max packet size information.
131
            It also sets the properties of the device object accordingly.
134
            It also sets the properties of the device object accordingly.
132
        """
135
        """
133
        resp = self.lib.monitorcommand(struct.pack("IIII", 1, 1, 0, 0), "HHII", ("coutmax", "cinmax", "doutmax", "dinmax"))
136
        resp = self.lib.monitorcommand(struct.pack("IIII", 1, 1, 0, 0), "HHII", ("coutmax", "cinmax", "doutmax", "dinmax"))
134
        self.lib.dev.packetsizelimit['cout'] = resp.coutmax
137
        self.lib.dev.packetsizelimit.cout = resp.coutmax
135
        self.lib.dev.packetsizelimit['cin'] = resp.cinmax
138
        self.lib.dev.packetsizelimit.cin = resp.cinmax
136
        self.lib.dev.packetsizelimit['din'] = resp.dinmax
139
        self.lib.dev.packetsizelimit.din = resp.dinmax
137
        self.lib.dev.packetsizelimit['dout'] = resp.doutmax
140
        self.lib.dev.packetsizelimit.dout = resp.doutmax
138
        return resp
141
        return resp
139
    
142
    
140
    def getusermemrange(self):
143
    def getusermemrange(self):
141
        """ This returns the memory range the user has access to. """
144
        """ This returns the memory range the user has access to. """
142
        resp = self.lib.monitorcommand(struct.pack("IIII", 1, 2, 0, 0), "III", ("lower", "upper", None))
145
        resp = self.lib.monitorcommand(struct.pack("IIII", 1, 2, 0, 0), "III", ("lower", "upper", None))
Line 161... Line 164...
161
    def read(self, addr, size):
164
    def read(self, addr, size):
162
        """ Reads the memory from location 'addr' with size 'size'
165
        """ Reads the memory from location 'addr' with size 'size'
163
            from the device. This cares about too long packages
166
            from the device. This cares about too long packages
164
            and decides whether to use DMA or not.
167
            and decides whether to use DMA or not.
165
        """
168
        """
166
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
169
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
167
        din_maxsize = self.lib.dev.packetsizelimit["din"]
170
        din_maxsize = self.lib.dev.packetsizelimit.din
168
        data = ""
171
        data = ""
169
        (headsize, bodysize, tailsize) = self._alignsplit(addr, size, cin_maxsize, 16)
172
        (headsize, bodysize, tailsize) = self._alignsplit(addr, size, cin_maxsize, 16)
170
        if headsize != 0:
173
        if headsize != 0:
171
            data += self._readmem(addr, headsize)
174
            data += self._readmem(addr, headsize)
172
            addr += headsize
175
            addr += headsize
Line 186... Line 189...
186
    def write(self, addr, data):
189
    def write(self, addr, data):
187
        """ Writes the data in 'data' to the location 'addr'
190
        """ Writes the data in 'data' to the location 'addr'
188
            in the memory of the device. This cares about too long packages
191
            in the memory of the device. This cares about too long packages
189
            and decides whether to use DMA or not.
192
            and decides whether to use DMA or not.
190
        """
193
        """
191
        cout_maxsize = self.lib.dev.packetsizelimit["cout"] - self.lib.headersize
194
        cout_maxsize = self.lib.dev.packetsizelimit.cout - self.lib.headersize
192
        dout_maxsize = self.lib.dev.packetsizelimit["dout"]
195
        dout_maxsize = self.lib.dev.packetsizelimit.dout
193
        (headsize, bodysize, tailsize) = self._alignsplit(addr, len(data), cout_maxsize, 16)
196
        (headsize, bodysize, tailsize) = self._alignsplit(addr, len(data), cout_maxsize, 16)
194
        offset = 0
197
        offset = 0
195
        if headsize != 0:
198
        if headsize != 0:
196
            self._writemem(addr, data[offset:offset+headsize])
199
            self._writemem(addr, data[offset:offset+headsize])
197
            offset += headsize
200
            offset += headsize
Line 212... Line 215...
212
    
215
    
213
    def readstring(self, addr, maxlength = 256):
216
    def readstring(self, addr, maxlength = 256):
214
        """ Reads a zero terminated string from memory 
217
        """ Reads a zero terminated string from memory 
215
            Reads only a maximum of 'maxlength' chars.
218
            Reads only a maximum of 'maxlength' chars.
216
        """
219
        """
217
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
220
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
218
        string = ""
221
        string = ""
219
        while (len(string) < maxlength or maxlength < 0):
222
        while (len(string) < maxlength or maxlength < 0):
220
            data = self._readmem(addr, min(maxlength - len(string), cin_maxsize))
223
            data = self._readmem(addr, min(maxlength - len(string), cin_maxsize))
221
            length = data.find("\0")
224
            length = data.find("\0")
222
            if length >= 0:
225
            if length >= 0:
Line 244... Line 247...
244
            size = 0
247
            size = 0
245
        return self.lib.monitorcommand(struct.pack("IBBBBII%ds" % size, 9, index, slaveaddr, startaddr, size, 0, 0, data), "III", (None, None, None))
248
        return self.lib.monitorcommand(struct.pack("IBBBBII%ds" % size, 9, index, slaveaddr, startaddr, size, 0, 0, data), "III", (None, None, None))
246
    
249
    
247
    def usbcread(self):
250
    def usbcread(self):
248
        """ Reads one packet with the maximal cin size """
251
        """ Reads one packet with the maximal cin size """
249
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
252
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
250
        resp = self.lib.monitorcommand(struct.pack("IIII", 10, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("validsize", "buffersize", "queuesize", "data"))
253
        resp = self.lib.monitorcommand(struct.pack("IIII", 10, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("validsize", "buffersize", "queuesize", "data"))
251
        resp.data = resp.data[:resp.validsize]
254
        resp.data = resp.data[:resp.validsize]
252
        resp.maxsize = cin_maxsize
255
        resp.maxsize = cin_maxsize
253
        return resp
256
        return resp
254
    
257
    
255
    def usbcwrite(self, data):
258
    def usbcwrite(self, data):
256
        """ Writes data to the USB console """
259
        """ Writes data to the USB console """
257
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
260
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
258
        size = len(data)
261
        size = len(data)
259
        while len(data) > 0:
262
        while len(data) > 0:
260
            writesize = min(cin_maxsize, len(data))
263
            writesize = min(cin_maxsize, len(data))
261
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 11, writesize, 0, 0, data[:writesize]), "III", ("validsize", "buffersize", "freesize"))
264
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 11, writesize, 0, 0, data[:writesize]), "III", ("validsize", "buffersize", "freesize"))
262
            data = data[resp.validsize:]
265
            data = data[resp.validsize:]
Line 264... Line 267...
264
    
267
    
265
    def cread(self, bitmask=0x1):
268
    def cread(self, bitmask=0x1):
266
        """ Reads one packet with the maximal cin size from the device consoles
269
        """ Reads one packet with the maximal cin size from the device consoles
267
            identified with the specified bitmask
270
            identified with the specified bitmask
268
        """
271
        """
269
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
272
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
270
        resp = self.lib.monitorcommand(struct.pack("IIII", 13, bitmask, cin_maxsize, 0), "III%ds" % cin_maxsize, ("size", None, None))
273
        resp = self.lib.monitorcommand(struct.pack("IIII", 13, bitmask, cin_maxsize, 0), "III%ds" % cin_maxsize, ("size", None, None))
271
        resp.data = resp.data[size:]
274
        resp.data = resp.data[size:]
272
        resp.maxsize = cin_maxsize
275
        resp.maxsize = cin_maxsize
273
        return resp
276
        return resp
274
 
277
 
275
    def cwrite(self, data, bitmask=0x1):
278
    def cwrite(self, data, bitmask=0x1):
276
        """ Writes data to the device consoles 
279
        """ Writes data to the device consoles 
277
            identified with the specified bitmask.
280
            identified with the specified bitmask.
278
        """
281
        """
279
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
282
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
280
        size = len(data)
283
        size = len(data)
281
        while len(data) > 0:
284
        while len(data) > 0:
282
            writesize = min(cin_maxsize, len(data))
285
            writesize = min(cin_maxsize, len(data))
283
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 12, bitmask, writesize, 0, data[:writesize]), "III", (None, None, None))
286
            resp = self.lib.monitorcommand(struct.pack("IIII%ds" % writesize, 12, bitmask, writesize, 0, data[:writesize]), "III", (None, None, None))
284
            data = data[writesize:]
287
            data = data[writesize:]
Line 288... Line 291...
288
        """ Flushes the consoles specified with 'bitmask' """
291
        """ Flushes the consoles specified with 'bitmask' """
289
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
292
        return self.lib.monitorcommand(struct.pack("IIII", 14, bitmask, 0, 0), "III", (None, None, None))
290
    
293
    
291
    def getprocinfo(self):
294
    def getprocinfo(self):
292
        """ Gets current state of the scheduler """
295
        """ Gets current state of the scheduler """
293
        cin_maxsize = self.lib.dev.packetsizelimit["cin"] - self.lib.headersize
296
        cin_maxsize = self.lib.dev.packetsizelimit.cin - self.lib.headersize
294
        # Get the size
297
        # Get the size
295
        schedulerstate = self.lockscheduler()
298
        schedulerstate = self.lockscheduler()
296
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
299
        resp = self.lib.monitorcommand(struct.pack("IIII", 15, 0, 0, 0), "III", ("structver", "tablesize", None))
297
        tablesize = resp.tablesize
300
        tablesize = resp.tablesize
298
        size = tablesize
301
        size = tablesize
Line 541... Line 544...
541
        self.connect()
544
        self.connect()
542
        self.findEndpoints()
545
        self.findEndpoints()
543
        
546
        
544
        
547
        
545
        # Device properties
548
        # Device properties
546
        self.packetsizelimit = {}
549
        self.packetsizelimit = Bunch()
547
        self.packetsizelimit['cout'] = None
550
        self.packetsizelimit.cout = None
548
        self.packetsizelimit['cin'] = None
551
        self.packetsizelimit.cin = None
549
        self.packetsizelimit['dout'] = None
552
        self.packetsizelimit.dout = None
550
        self.packetsizelimit['din'] = None
553
        self.packetsizelimit.din = None
551
        
554
        
-
 
555
        self.version = Bunch()
552
        self.version.revision = None
556
        self.version.revision = None
553
        self.version.majorv = None
557
        self.version.majorv = None
554
        self.version.minorv = None
558
        self.version.minorv = None
555
        self.version.patchv = None
559
        self.version.patchv = None
556
        self.swtypeid = None
560
        self.swtypeid = None
557
        self.hwtypeid = None
561
        self.hwtypeid = None
558
        
562
        
-
 
563
        self.usermem = Bunch()
559
        self.usermem.lower = None
564
        self.usermem.lower = None
560
        self.usermem.upper = None
565
        self.usermem.upper = None
561
    
566
    
562
    def __del__(self):
567
    def __del__(self):
563
        self.disconnect()
568
        self.disconnect()
564
    
569
    
565
    def findEndpoints(self):
570
    def findEndpoints(self):
566
        epcounter = 0
571
        epcounter = 0
567
        self.endpoint = {}
572
        self.endpoint = Bunch()
568
        for cfg in self.dev:
573
        for cfg in self.dev:
569
            for intf in cfg:
574
            for intf in cfg:
570
                for ep in intf:
575
                for ep in intf:
571
                    if epcounter == 0:
576
                    if epcounter == 0:
572
                        self.endpoint['cout'] = ep.bEndpointAddress
577
                        self.endpoint.cout = ep.bEndpointAddress
573
                    elif epcounter == 1:
578
                    elif epcounter == 1:
574
                        self.endpoint['cin'] = ep.bEndpointAddress
579
                        self.endpoint.cin = ep.bEndpointAddress
575
                    elif epcounter == 2:
580
                    elif epcounter == 2:
576
                        self.endpoint['dout'] = ep.bEndpointAddress
581
                        self.endpoint.dout = ep.bEndpointAddress
577
                    elif epcounter == 3:
582
                    elif epcounter == 3:
578
                        self.endpoint['din'] = ep.bEndpointAddress
583
                        self.endpoint.din = ep.bEndpointAddress
579
                    epcounter += 1
584
                    epcounter += 1
580
        if epcounter <= 3:
585
        if epcounter <= 3:
581
            raise DeviceError("Not all endpoints found in the descriptor. Only "+str(epcounter)+" found, we need 4")
586
            raise DeviceError("Not all endpoints found in the descriptor. Only "+str(epcounter)+" found, we need 4")
582
    
587
    
583
    def connect(self):
588
    def connect(self):
Line 600... Line 605...
600
        if len(read) != size:
605
        if len(read) != size:
601
            raise ReceiveError("Requested size and read size don't match!")
606
            raise ReceiveError("Requested size and read size don't match!")
602
        return read
607
        return read
603
    
608
    
604
    def cout(self, data):
609
    def cout(self, data):
605
        if self.packetsizelimit['cout'] and len(data) > self.packetsizelimit['cout']:
610
        if self.packetsizelimit.cout and len(data) > self.packetsizelimit.cout:
606
            raise SendError("Packet too big")
611
            raise SendError("Packet too big")
607
        return self.send(self.endpoint['cout'], data)
612
        return self.send(self.endpoint.cout, data)
608
    
613
    
609
    def cin(self, size):
614
    def cin(self, size):
610
        if self.packetsizelimit['cin'] and size > self.packetsizelimit['cin']:
615
        if self.packetsizelimit.cin and size > self.packetsizelimit.cin:
611
            raise ReceiveError("Packet too big")
616
            raise ReceiveError("Packet too big")
612
        return self.receive(self.endpoint['cin'], size)
617
        return self.receive(self.endpoint.cin, size)
613
    
618
    
614
    def dout(self, data):
619
    def dout(self, data):
615
        if self.packetsizelimit['dout'] and len(data) > self.packetsizelimit['dout']:
620
        if self.packetsizelimit.dout and len(data) > self.packetsizelimit.dout:
616
            raise SendError("Packet too big")
621
            raise SendError("Packet too big")
617
        return self.send(self.endpoint['dout'], data)
622
        return self.send(self.endpoint.dout, data)
618
    
623
    
619
    def din(self, size):
624
    def din(self, size):
620
        if self.packetsizelimit['din'] and size > self.packetsizelimit['din']:
625
        if self.packetsizelimit.din and size > self.packetsizelimit.din:
621
            raise ReceiveError("Packet too big")
626
            raise ReceiveError("Packet too big")
622
        return self.receive(self.endpoint['din'], size)
627
        return self.receive(self.endpoint.din, size)
623
 
628
 
624
 
629
 
625
if __name__ == "__main__":
630
if __name__ == "__main__":
626
    # Some tests
631
    # Some tests
627
    import sys
632
    import sys