[chronojump] Added pydownloader (adapted to Chronopic) to record firmware easy
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Added pydownloader (adapted to Chronopic) to record firmware easy
- Date: Wed, 2 Jun 2010 11:43:44 +0000 (UTC)
commit 5b1ead44e7d7e8f192371b9d71db2a17cbcbc664
Author: Xavier de Blas <xaviblas master gnome org>
Date: Wed Jun 2 19:42:53 2010 +0800
Added pydownloader (adapted to Chronopic) to record firmware easy
.../chronopic_firmware_10ms_unvalidated.hex | 28 +
.../chronopic_firmware_50ms.hex | 28 +
chronopic-firmware/pydownloader-chronopic/ledp.hex | 8 +
.../pydownloader-chronopic/libIris/IntelHex.py | 536 ++++++++++++++++++++
.../pydownloader-chronopic/libIris/IntelHex.pyc | Bin 0 -> 11367 bytes
.../libIris/Pic16_Bootloader.py | 446 ++++++++++++++++
.../libIris/Pic16_Bootloader.pyc | Bin 0 -> 8504 bytes
.../libIris/Pic16_Bootloader.py~ | 446 ++++++++++++++++
.../libIris/Pic16_Firmware.py | 70 +++
.../libIris/Pic16_Firmware.pyc | Bin 0 -> 5167 bytes
.../pydownloader-chronopic/libIris/__init__.py | 51 ++
.../pydownloader-chronopic/libIris/__init__.pyc | Bin 0 -> 1132 bytes
.../pydownloader-chronopic/libIris/__init__.py~ | 51 ++
.../pydownloader-chronopic/pydownloader-wx.py | 443 ++++++++++++++++
14 files changed, 2107 insertions(+), 0 deletions(-)
---
diff --git a/chronopic-firmware/pydownloader-chronopic/chronopic_firmware_10ms_unvalidated.hex b/chronopic-firmware/pydownloader-chronopic/chronopic_firmware_10ms_unvalidated.hex
new file mode 100644
index 0000000..f830719
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/chronopic_firmware_10ms_unvalidated.hex
@@ -0,0 +1,28 @@
+:02000000662870
+:08000800A000030EA1000B197A
+:100010001A280B181F280C1813280428210E8300F7
+:10002000A00E200E09000C10FF30220203190E282A
+:10003000A20A0E280B11D9308100A3030E28AA08AA
+:1000400003192628A2018F018E01AA012208A4000B
+:100050000F08A5000E08A600A2018F018E01013035
+:10006000A3000130A900D930810006080B108B11C4
+:100070000E2883161930990024309800831290308E
+:10008000980008008C1E42281A0808000C1E4628FA
+:1000900099000800FF30AB00FF30AC006400AC0BEF
+:1000A0004F28AB0B4C280800061A00340134270DEA
+:1000B000023A8600080006080B108B1508008B1109
+:1000C00045304620270846208B150800831611303E
+:1000D00086000730810039200B118312D93081004E
+:1000E000831231309000A2018F018E0183160C140F
+:1000F00083124A205B20A2010130A3000030A90036
+:100100000130AA005420A70057208B160B178B171D
+:1001100064008C1E91284220AD0045302D02031949
+:100120005F200030290203199E280130290203199B
+:100130009F28023029020319BD2888288828A3088F
+:10014000031D882806080B105420A8002808270241
+:100150000319AF282808A7000230A900882826081C
+:100160008E0703188F0A25088F070318A20A240890
+:10017000A2070030A9005B208828583046202708B5
+:100180004620240846202508462026084620003020
+:08019000A90057205B2088281C
+:00000001FF
diff --git a/chronopic-firmware/pydownloader-chronopic/chronopic_firmware_50ms.hex b/chronopic-firmware/pydownloader-chronopic/chronopic_firmware_50ms.hex
new file mode 100644
index 0000000..4fce9bb
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/chronopic_firmware_50ms.hex
@@ -0,0 +1,28 @@
+:02000000662870
+:08000800A000030EA1000B197A
+:100010001A280B181F280C1813280428210E8300F7
+:10002000A00E200E09000C10FF30220203190E282A
+:10003000A20A0E280B11D9308100A3030E28AA08AA
+:1000400003192628A2018F018E01AA012208A4000B
+:100050000F08A5000E08A600A2018F018E01053031
+:10006000A3000130A900D930810006080B108B11C4
+:100070000E2883161930990024309800831290308E
+:10008000980008008C1E42281A0808000C1E4628FA
+:1000900099000800FF30AB00FF30AC006400AC0BEF
+:1000A0004F28AB0B4C280800061A00340134270DEA
+:1000B000023A8600080006080B108B1508008B1109
+:1000C00045304620270846208B150800831611303E
+:1000D00086000730810039200B118312D93081004E
+:1000E000831231309000A2018F018E0183160C140F
+:1000F00083124A205B20A2010530A3000030A90032
+:100100000130AA005420A70057208B160B178B171D
+:1001100064008C1E91284220AD0045302D02031949
+:100120005F200030290203199E280130290203199B
+:100130009F28023029020319BD2888288828A3088F
+:10014000031D882806080B105420A8002808270241
+:100150000319AF282808A7000230A900882826081C
+:100160008E0703188F0A25088F070318A20A240890
+:10017000A2070030A9005B208828583046202708B5
+:100180004620240846202508462026084620003020
+:08019000A90057205B2088281C
+:00000001FF
diff --git a/chronopic-firmware/pydownloader-chronopic/ledp.hex b/chronopic-firmware/pydownloader-chronopic/ledp.hex
new file mode 100644
index 0000000..98f09d1
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/ledp.hex
@@ -0,0 +1,8 @@
+:0400000000000428D0
+:080008008A110A120728FD30DD
+:10001000831603138600023083128606FF30FF002A
+:10002000FF3014200B28080083120313A3007F085D
+:10003000A2002208230403192228FF30A207031C70
+:06004000A30319280800CB
+:02400E00FF3F72
+:00000001FF
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/IntelHex.py b/chronopic-firmware/pydownloader-chronopic/libIris/IntelHex.py
new file mode 100644
index 0000000..6a8111f
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/libIris/IntelHex.py
@@ -0,0 +1,536 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+
+# Description: File downloader library for SkyPIC
+# Copyright (C) 2007 by Rafael Treviño Menéndez
+# Author: Rafael Treviño Menéndez <skasi 7 gmail com>
+# Juan Gonzalez Gomez <juan iearobotics com>
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+
+
+#------------------------------------------------------------------------------
+"""
+ Libreria para el analisis de ficheros .hex que esten en formato Hex de
+ Intel. Se incluyen ademas funciones para realizar conversiones entre
+ diferentes formas de representacion de los programas en codigo maquina
+
+ FORMATOS DE DATOS. En esta libreria se usan tres tipos de formatos
+ para representar la informacion que hay en un fichero .HEX
+
+ -FORMATO 1: Memoria (mem). Se asocia cada direccion con su palabra.
+ Es una lista de tuplas (direccion,palabra). La palabra se representa
+ a su vez mediante una otra tupla con su byte alto y su byte bajo
+ El formato lo podemos expresar asi:
+ mem = [tupla1, tupla2....] = [(dir1, pal1), (dir2,pal2), ...] =
+ = [ (dir1, (dato1h,dato1l)), (dir2,(dato2h,dato2l)), ... ]
+ Este es el formato mas generico
+
+ -FORMATO 2: Lista de bloques. Los contenidos que estan en posiciones de
+ memoria consecutivas se agrupan en bloques. La representacion es una
+ lista de bloques:
+ programa = [bloque1, bloque2.....] Cada uno de estos bloques es a su
+ vez una lista de PALABRAS (no bytes). La primera palabra es la direccion
+ de comienzo del bloque
+ bloque1 = [direccion, palabra1, palabra2,.....]
+
+ -FORMATO 3: Lista de bloques de 16 palabras. Es el mismo que el formato 2
+ pero ahora los bloques son como maximo de 16 palabras
+
+ USO DE LOS FORMATOS
+
+ -FORMATO 1: Es el mas generico. Contiene tuplas con las direcciones y
+ las palabras almacenadas.
+ -FORMATO 2: Bloques contiguos de palabras. Su principal utilidad es para
+ almacenar programas que se grabaran en el PIC. Los bloques
+ pueden ser de cualquier tamano
+ -FORMATO 3: Bloques contiguos de como maximo 16 palabras. Es igual que el
+ formato 2 pero con la limitacion de tamano de bloques. Su
+ principal utilidad es para la carga de programas con el
+ Bootloader. Por cada bloque de 16 palabras se envia un
+ checksum para comprobar que el envio es correcto
+
+"""
+#------------------------------------------------------------------------------
+
+
+class ReaderError (Exception):
+#----------------------------------------------------------------------------
+ """
+ Excepciones producidas en el modulo IntelHex
+ """
+#----------------------------------------------------------------------------
+ pass
+
+
+
+
+class HexReader:
+#----------------------------------------------------------------------------
+ """
+ Clase principal para la lectura de ficheros .HEX y realizar conversiones
+ """
+#----------------------------------------------------------------------------
+
+
+ def __init__ (self, file):
+ #----------------------------------------------------------------------------
+ """
+ Inicializacion de la clase. Se le pasa el fichero que se quiere parsear
+ Bien se puede pasar el descriptor o el nombre del fichero
+ """
+ #----------------------------------------------------------------------------
+
+ #-- Comprobar si lo que se pasa es una cadena con el nombre del
+ #-- fichero. En ese caso se abre el fichero para obtener su descriptor
+ if isinstance (file, str):
+
+ #-- Abrir el fichero o devolver una excepcion si hay error
+ try:
+ fd = open (file)
+ except IOError,msg:
+ raise ReaderError, msg
+
+ #-- Indicar que se especifico el fichero por su nombre
+ fileName=True;
+
+ else:
+ fd = file; #-- El argumento se toma directamente como un descriptor
+ fileName=False;
+
+ #-- Realizar el parseo y obtener el contenido en formato 2
+ self.__memory = readHex(fd)
+
+ #-- En el caso de que se haya especificado el fichero mediante un
+ #-- nombre se cierra el fichero. En caso contrario se deja abierto
+ if fileName:
+ fd.close()
+
+
+ def memory (self):
+ #-------------------------------------------------------------
+ """
+ Devolver el fichero .HEX en formato 1, como una memoria
+ """
+ #-------------------------------------------------------------
+ return self.__memory
+
+
+ def dataBlocks(self):
+ #----------------------------------------------------------------------
+ """
+ Devolver el fichero .HEX como una lista de bloques en formato 2
+ """
+ #----------------------------------------------------------------------
+ return memToBlocks(self.__memory)
+
+
+
+ def dataBlocks16(self):
+ #----------------------------------------------------------------------
+ """
+ Devolver el fichero .Hex como una lista de bloques en formato 3
+ """
+ #----------------------------------------------------------------------
+ return memToBlocks16(self.__memory)
+
+
+
+ def size(self):
+ #-------------------------------------------------------------------------
+ """
+ Devolver el tamano en palabras. No se distingue entre codigo y datos
+ """
+ #-------------------------------------------------------------------------
+ return len(self.__memory)
+
+
+ def blocks(self):
+ #------------------------------------------------------------------
+ """
+ Devolver el numero de bloques
+ """
+ #------------------------------------------------------------------
+ blocks = memToBlocks(self.__memory)
+ return len(blocks)
+
+
+ def blocks16(self):
+ #------------------------------------------------------------------
+ """
+ Devolver el numero de bloques con tamano maximo de 16 palabras
+ """
+ #------------------------------------------------------------------
+ blocks = memToBlocks16(self.__memory)
+ return len(blocks)
+
+
+
+ def outputPython(self,name="prog"):
+ #-------------------------------------------------------------------
+ """
+ Devuelve una cadena de Salida en formato python con el codigo
+ maquina del fichero .hex
+ """
+ #-------------------------------------------------------------------
+
+ #-- Convertir a bloques y luego a cadena python
+ blocks = memToBlocks(self.__memory)
+ return blocksToStrPython(blocks,name)
+
+
+ def outputPython16(self,name="prog"):
+ #-------------------------------------------------------------------
+ """
+ Devuelve una cadena de Salida en formato python con el codigo
+ maquina del fichero .hex
+ La lista esta formada por bloques con tamano menor o igual a 16
+ """
+ #-------------------------------------------------------------------
+
+ #-- Convertir a bloques y luego a cadena python
+ blocks = memToBlocks16(self.__memory)
+ return blocksToStrPython(blocks,name)
+
+
+ def outputTable(self):
+ #------------------------------------------------------------
+ """
+ Salida como una tabla Direccion - Contenido
+ """
+ #------------------------------------------------------------
+ return memToStrTable(self.__memory)
+
+
+ def outputBlocks(self):
+ #----------------------------------------------------------
+ """
+ Salida como bloques en formato 2. Direccion - Bloque
+ """
+ #----------------------------------------------------------
+ blocks = memToBlocks(self.__memory)
+ return blocksToStr(blocks)
+
+
+ def outputBlocks16(self):
+ #----------------------------------------------------------
+ """
+ Salida como bloques en formato 3. Direccion - Bloque
+ """
+ #----------------------------------------------------------
+ blocks = memToBlocks16(self.__memory)
+ return blocksToStr(blocks)
+
+
+
+
+#------------------------------------------------------------------------------
+# FUNCIONES ESTATICAS QUE SE PUEDEN INVOCAR DIRECTAMENTE
+#------------------------------------------------------------------------------
+
+
+
+def readHex (fd):
+#--------------------------------------------------------------
+ """
+ Funciona para analizar ficheros .HEX.
+ ENTRADAS: Descriptor del fichero
+ DEVUELVE: Una lista en el FORMATO 1 (memoria)
+ """
+#--------------------------------------------------------------
+
+ #-- Leer las lineas del fichero .hex
+ lines = fd.readlines ()
+ fd.close ()
+
+ # Inicializar la lista de salida
+ mem = []
+
+ #-- Recorrer todas las lineas del fichero
+ for line in lines:
+
+ #-- FORMAT .HEX
+ #-- CAMPO 1. (1 byte) Comienzo de linea. Caracter ':'
+ if line [0] != ':':
+ raise ReaderError, 'Error en formato HEX: Comienzo de linea incorrecto'
+
+ #-- CAMPO 2. (2 bytes) Numero de bytes de los datos
+ count = int (line [1:3], 16)
+
+ #-- CAMPO 3. (2 bytes) Direccion de comienzo de los datos
+ addr = int (line [3:7], 16) / 2
+
+ #-- CAMPO 4. (1 byte). Tipo de comando (registro)
+ rectype = int (line [7:9], 16)
+
+ #-- El registro de tipo 1 indica que es el final del fichero
+ #-- Si es asi se termina y se devuelve el contenido leido
+ if rectype == 1:
+ return mem
+
+ #-- Si es un registro mayor a 1 se ignora
+ #-- Los registro de tipo 4 no tengo muy claro para que son
+ #-- Creo que indican cual es la direccion de comienzo del
+ #-- programa
+ #-- Los registros normales son los de tipo 0 (datos)
+ if rectype > 1:
+ continue
+
+ #-- Inicializar Checksum
+ chk = count + (addr * 2 & 0xFF) + (addr >> 7) + rectype
+
+ #-- CAMPO 5: Datos. Una cadena de "count" bytes. Se deben interpretar
+ #-- como palabras. El primer byte es el bajo y el segundo el alto
+ for loop in xrange (0, count / 2):
+ #-- Crear la tupla con el (byte alto, byte bajo)
+ data = (int (line [11 + 4 * loop: 13 + 4 * loop], 16),
+ int (line [9 + 4 * loop: 11 + 4 * loop], 16))
+
+ #-- Actualizar checksum
+ chk += data [0] + data [1]
+
+ #-- En el pic las palabras son de 14 bits por lo que el byte alto
+ #-- NUNCA puede ser mayor de 0x3F
+ if data [0] > 0x3F:
+ raise ReaderError, 'Error en formato HEX: Palabra incorrecta'
+
+ #-- Anadir la tupla con la direccion y los datos
+ mem.append ((addr, data))
+
+ #-- Incrementar la direccion
+ addr += 1
+
+ #-- CAMPO 6: Checksum del fichero
+ checksum = int (line [9 + count * 2: 11 + count * 2], 16)
+ chk = (0x100 - chk & 0xFF) & 0xFF
+
+ #-- Comprobación del checksum. Ver si el checksum del fichero es igual
+ #-- al calculado.
+ if chk != checksum:
+ raise ReaderError, 'Error en formato HEX: Fallo en checksum'
+
+ raise ReaderError, 'Error en formato HEX: Final erroneo'
+
+
+
+def memToBlocks(mem):
+#----------------------------------------------------------------------
+ """
+ Conversion del FORMATO 1 (memoria) al FORMATO 2: lista de bloques
+ contiguos
+ ENTRADA: Lista en formato 1 (memoria)
+ DEVUELVE: Lista en FORMATO 2
+ """
+#----------------------------------------------------------------------
+
+ #-- obtener una copia local de la memoria para no borrar la original
+ data = [] + mem
+
+ #-- Obtener la primera tupla
+ address, (d0, d1) = data [0]
+ del data [0]
+ a = address
+
+ #-- Inicializar programa. Un programa es una lista de bloques contiguos
+ #-- de palabras
+ program = []
+
+ #-- Comenzar el primer bloque. Situar el primer elemento
+ block = [a, (d0 * 0x100 + d1)]
+
+ #-- Repetir para cada palabra del fichero .hex
+ while len (data):
+
+ #-- Obtener la siguiente palabra y su direccion
+ address, (d0, d1) = data [0]
+ del data [0]
+
+ #-- Si la palabra esta a continuacion de la anterior
+ if address== a + 1:
+ #-- Anadir palabra al bloque
+ block.append (d0 * 0x100 + d1)
+ a = address
+ else:
+ #-- La palabra NO es contigua
+ #-- Hay dos casos:
+ #-- 1) Que este en el mismo subbloque de 8. En ese caso se considera
+ #-- que forman parte del mismo bloque. Los "gaps" se rellenan con ceros
+ #-- 2) Que esten en diferentes subbloques. Eso significa que
+ #-- pertenecen a bloques separados.
+ if address/8 == (a+1)/8: #-- Caso 1. Mismo subbloque
+ block.extend ((address - (a + 1)) * [0])
+ block.append (d0 * 0x100 + d1)
+ a = address
+ else: #-- Caso 2: Distinto Bloque
+ #-- Anadir el bloque actual al programa
+ #-- Pero SOLO si es un bloque de codigo. Es decir, si su direccion
+ #-- de inicio esta por debajo de 0x2000. A partir de esa direccion
+ #-- lo que se tiene es la configuracion
+ program.append (block)
+
+ #-- Crear el bloque nuevo. Meter el primer elemento
+ a = address
+ block = [a, (d0 * 0x100 + d1)]
+
+ #-- Falta por añadir al programa el ultimo bloque leido
+ program.append (block)
+
+ return program
+
+
+
+def blocksToBlocks16(prog1):
+#--------------------------------------------------------------------------
+ """
+ CONVERSION DEL FORMATO 2 al FORMATO 3: Lista de bloques de
+ datos de tamano maximo de 16 palabras
+ ENTRADA: Lista en formato 2
+ DEVUELVE: Lista de bloques en FORMATO 3
+ """
+#---------------------------------------------------------------------------
+ #-- Programa de salida: lista de bloques de tamano 16 palabras
+ prog2 = []
+
+ #---- Recorrer todos los bloques y trocearlos en bloques de 16 palabras
+ for block in prog1:
+
+ #-- Si el bloque tiene un tamano menor o igual a 16 no hace
+ #-- falta trocearlo
+ if len(block)<=16:
+ prog2.append(block)
+ else:
+ #-- Bloque tiene tamano mayor a 16. Hay que trocear.
+
+ #-- Guardar la direccion de inicio
+ addr = block[0]
+ del block[0]
+
+ #-- Calcular el numero de subbloques de 16 palabras que hay
+ nblock = len(block)/16;
+
+ #-- Obtener los subbloques completos
+ for i in range(nblock):
+ nuevo_bloque = [addr] + block[0:16]
+
+ #-- Anadir subbloque
+ prog2.append(nuevo_bloque)
+ addr+=16;
+ del block[0:16]
+
+
+ #--- El ultimo bloque esta formados por los "restos"
+ if (len(block)!=0):
+ nuevo_bloque = [addr] + block
+ prog2.append(nuevo_bloque)
+
+ return prog2
+
+
+
+def memToBlocks16(mem):
+#--------------------------------------------------------------------------
+ """
+ CONVERSION DEL FORMATO 1 (memoria) al FORMATO 3: Lista de bloques de
+ datos de tamano maximo de 16 palabras
+ ENTRADA: Lista en formato 2
+ DEVUELVE: Lista de bloques en FORMATO 3
+ """
+#---------------------------------------------------------------------------
+
+ #-- Primero agrupar en bloques contiguos
+ prog1 = memToBlocks(mem)
+
+ #-- "trocear" en bloques de 16
+ return blocksToBlocks16(prog1)
+
+
+
+
+#------------------------------------------------------------------------------#
+# FUNCIONES DE CONVERSION A CADENAS DE CARACTERES #
+#------------------------------------------------------------------------------#
+
+
+def blocksToStrPython(program,name="prog"):
+#-------------------------------------------------------------------
+ """
+ Convertir a una cadena en formato de lista de Python
+ Se crea una cadena con syntaxis python con el codigo maquina
+ El parametro name es el nombre del programa en el codigo python
+ ENTRADAS:
+ -blocks: LIsta de bloques en FORMATO 2 o 3
+ -name: Cadena a asignar como nombre a la lista de salida
+ DEVUELVE: Una cadena con la lista, en formato PYTHON
+ """
+#-------------------------------------------------------------------
+
+ #-- Comienzo de la cadena
+ prog_str = "%s=[" % (name)
+
+ #-- Recorrer todos los bloques y pasarlos a un string
+ for block in program:
+ cad=["0x%04X" % (palabra) for palabra in block]
+ prog_str = prog_str + "[" + ", ".join(cad) + "],"
+
+ #-- Final de la cadena
+ prog_str+="]"
+
+ #-- Devolver la cadena
+ return prog_str
+
+ #-- Esta es la version compacta. Hace lo mismo que todo lo anterior
+ #-- return '%s = [%s]' % (name, ', '.join (['[%s]' % (', '.join (["0x%04X" %
+ # palabra for palabra in block])) for block in self.__program]))
+
+
+
+def memToStrTable(mem):
+#--------------------------------------------------------------------------
+ """
+ Convertir una memoria (formato 1) en una cadena en forma de tabla.
+ Cada una de las filas contiene la direccion y su contenido
+ ENTRADAS: mem: Memoria en FORMATO 1
+ """
+#--------------------------------------------------------------------------
+
+ #-- Volcar la memoria
+ tabla= "Dir: Contenido\n"
+ tabla+= "---- ---------\n"
+ for addres,palabra in mem:
+ tabla+= "%04X: %04X\n" % (addres, palabra[0]*0x100 + palabra[1])
+ return tabla
+
+
+
+def blocksToStr(data):
+#----------------------------------------------------------------
+ """
+ Convertir a una lista en formato 2 o 3 en una cadena
+ ENTRADAS: data: datos en FORMATO 2 o 3
+ """
+#----------------------------------------------------------------
+ salida=""
+ for block in data:
+ salida+= "Direccion: %04X\n" % (block[0])
+ cad=["%04X" % (palabra) for palabra in block[1:]]
+ salida= salida + " ".join(cad)
+ salida+="\n\n"
+ return salida
+
+ #-- Esta es la version compacta (sustituye al resto)
+ #-- return ''.join (['Direccion: %04X\n%s\n\n' % (block [0], ' '.join
+ #(["%04X" % (palabra) for palabra in block[1:]])) for block in self.__program])
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/IntelHex.pyc b/chronopic-firmware/pydownloader-chronopic/libIris/IntelHex.pyc
new file mode 100644
index 0000000..e534bf2
Binary files /dev/null and b/chronopic-firmware/pydownloader-chronopic/libIris/IntelHex.pyc differ
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.py b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.py
new file mode 100644
index 0000000..49e7687
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.py
@@ -0,0 +1,446 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+
+# Description: File downloader library for SkyPIC
+# Copyright (C) 2007 by Rafael Treviño Menéndez
+# Author: Rafael Treviño Menéndez <skasi 7 gmail com>
+# Juan Gonzalez <juan iearobotics com>
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+"""
+ Modulo Cliente para comunicarse con el PIC_BOOTLOADER y descargar
+ ficheros .hex en la tarejta Skypic
+
+ Ademas se incorporan metodos para que el usuario pueda acceder
+ a los diferentes servicios del Bootloader por si quiere implementarse
+ su propio programa de descarga o quiere hacer modificaciones a bajo
+ nivel en el bootloader
+"""
+
+import serial
+import time
+import IntelHex
+import sys
+
+
+#############
+# CONSTANTS #
+#############
+
+#--------------------------------------
+#- Configuracion del puerto serie
+#--------------------------------------
+#-- Timeout por defecto para el acceso al puerto serie
+SERIAL_TIMEOUT = 0.2
+
+#--- Velocidad de transmision para la comunicacion con el PIC Bootloader
+BAUDIOS = 19200
+
+#------------------------------------------------------------------
+#- IDENTIFICACION DE LOS COMANDOS DEL PROTOCOLO DEL BOOTLOADER
+#------------------------------------------------------------------
+CMD_WRITE = '\xE3' #-- Escritura de un bloque
+CMD_DATA_OK = '\xE7' #-- Datos enviados correctamente
+CMD_OK = '\xE4' #-- Operacion ejecutada
+CMD_IDENT = '\xEA' #-- Comando de identificacion del bootloader
+CMD_IDACK = '\xEB' #-- Bootloader identificado
+CMD_SEND_DONE= '\xED' #-- Comando de ejecucion
+
+#------------------------------------------------------------------------
+#-- Constantes usadas con el metodo download para indicar
+#-- lo que va ocurriendo con la descarga
+#------------------------------------------------------------------------
+WRITING_START=1 #-- Comienzo de la escritura
+WRITING_INC=2 #-- Escritura de una palabra
+WRITING_END=3 #-- Fin de la escritura
+
+IDENT_START=4 #-- Comienzo de la identificacion del bootloader
+IDENT_NACK=5 #-- No se ha recibido respuesta
+
+#-- Timeout por defecto, en segundos, que se espera a detectar el
+#-- Bootloader
+DEFAULT_TIMEOUT = 10
+
+
+#----------------------------------------
+#- Clase para la gestion de los errores
+#----------------------------------------
+class IrisError (Exception):
+ """
+ Excepciones producidas en el modulo Pic16_Bootloader
+ """
+ pass
+
+
+def default_logCallback(msg):
+ """
+ Funcion de "log" por defecto.
+ Simplemente se imprimen los mensajes
+ """
+ sys.stdout.write(msg)
+ sys.stdout.flush()
+
+
+#-----------------------------------------------------------------------------
+def default_stateCallback(op,inc,total):
+ """
+ Funcion de estado por defecto
+ Se imprime informacion en la consola
+ La funcion debe devolver TRUE si todo esta OK y se quiere continuar
+ con el proceso. FALSE en caso contrario. La descarga se aborta
+ Los parametros recibidos son:
+ -op: Tipo de operacion. Indica la fase de la descarga que se ha iniciado
+ -inc:
+ -En el estado IDENT_NACK indica el numero reitentos hasta el momento
+ -En el estado WRITING_INC indica el numero de bloques enviados
+ -total:
+ -En el estado IDENT_NACK indica el tiempo total transcurrido desde
+ el comienzo de la identificacion (en segundos)
+ -En el estado WRITING_INC indica el numero total de bloques del
+ del programa a transmitir
+
+ El usuario puede crear su propia funcion de estado para actualizar el
+ interfaz de su aplicacion como quiera. Esta funcion es un ejemplo para
+ una interfaz de consola
+ """
+
+
+ #--------------------------------------------------
+ #- Comienzo de la identificacion del Bootloader
+ #--------------------------------------------------
+ if op==IDENT_START:
+ print "Esperando Bootloader"
+ return True
+
+ #-------------------------------------------------------------------------
+ #-- Timeout en la identificacion.
+ #-- Cuando el tiempo transcurrido supera el timeout en la identificacion
+ #-- se aborta devolviendose False
+ #-------------------------------------------------------------------------
+ elif op==IDENT_NACK:
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ if total<=DEFAULT_TIMEOUT:
+ return True
+ else :
+ return False
+
+ #-----------------------------------------------------------------------
+ #-- Comienzo de la descarga
+ #-- Se imprime una barra de status en ASCII formada por '.' y se lleva
+ #-- el cursor a la izquierda (imprimiendo el caracter '\b'
+ #----------------------------------------------------------------------
+ elif op==WRITING_START:
+ sys.stdout.write("\nDescargando:\n")
+ cad="".join(["." for i in range(total)])
+ back="".join(["\b" for i in range(total)])
+
+ #-- Imprimir la "barra de estado" con '.'. Un '.' por cada bloque
+ sys.stdout.write(cad)
+
+ #-- Llevar el cursos a la izquierda
+ sys.stdout.write(back)
+ sys.stdout.flush()
+
+ return True
+
+ #----------------------------------------------------------------------
+ #-- Se ha grabado un bloque. Se actualiza la "barra de estado ascii"
+ #----------------------------------------------------------------------
+ elif op==WRITING_INC:
+ sys.stdout.write("*")
+ sys.stdout.flush()
+ return True
+
+ #----------------------------------------
+ #- Fin de la descarga
+ #----------------------------------------
+ elif op==WRITING_END:
+ print " OK"
+ return True
+
+
+#----------------------------------------------------------------------------
+#-- CLASE PRINCIPAL
+#----------------------------------------------------------------------------
+class Iris:
+ """
+ Clase prinipal del modulo Pic16_Bootloader. Se utiliza para comunicarse
+ con el Bootloader y descargar programas en la Skypic
+ """
+
+ #---------------------
+ #- Destructor
+ #---------------------
+ def __del__(self):
+
+ #-- Cerrar el pueto serie
+ if self.__serial:
+ #print "Debug: cerrando puerto serie: %s" % (self.__serial.portstr)
+ self.__serial.close()
+
+
+ def __init__ (self, serialName, logCallback = default_logCallback):
+ #-------------------------------------------------------------------------
+ """
+ Constructor
+ ENTRADAS:
+ serialName: Dispositivo serie
+ logCallback: Funcion de retrollamada para el "log"
+ """
+ #--------------------------------------------------------------------------
+
+ self.__serial = None
+ self.__log = logCallback
+
+ #-- Abrir puerto serie
+ try:
+ self.__serial = serial.Serial(serialName, BAUDIOS)
+ except serial.SerialException:
+ raise IrisError,'Error al abrir puerto serie %s.' % serialName
+
+ if self.__log:
+ self.__log ('Serial port %s opened.\n' % self.__serial.portstr)
+
+ #-- Configurar timeout
+ #-- He detectado que en Linux al configurar el timeout se modifica
+ #-- el estado del DTR. No en todos los casos (depende del driver
+ #-- del conversor USB-serie usado). El problema siempre esta en que
+ #-- los valores del DTR no estan estandarizados y cada driver los
+ #-- maneja a su propia manera.
+ #-- La solucion que se esta utilizando es la de configurar el
+ #-- timeout al principio
+ self.__serial.timeout = SERIAL_TIMEOUT
+
+ #-- Vaciar los buffers del puerto serie
+ self.__serial.flushInput()
+ self.__serial.flushOutput()
+
+
+ def close(self):
+ #-----------------------------
+ """
+ Cerrar el puerto serie
+ """
+ #-----------------------------
+ if self.__serial!=None:
+ self.__serial.close()
+
+
+
+ def sendDone (self):
+ #--------------------------------------------------------------------
+ """
+ Enviar comando SENDDONE para que arranque el programa cargado
+ """
+ #--------------------------------------------------------------------
+
+ #-- Enviar el comando
+ self.__serial.write (CMD_SEND_DONE)
+
+ #-- Esperar la respuesta
+ ch = self.__serial.read (1)
+ if ch != CMD_OK:
+ raise IrisError, "Error en Done"
+
+ if self.__log:
+ self.__log ('Ejecutando programa\n')
+
+
+ def skypicReset (self):
+ #----------------------------------------------------------------
+ """
+ Hacer reset de la Skypic. Solo funcionara si el jumper JP4
+ esta colocado en la posicion DTR
+ """
+ #----------------------------------------------------------------
+
+ #-- Desactivar la senal DTR durante 0.5 segundos
+ self.__serial.setDTR (0)
+
+ #-- Esto es para depurar
+ #if self.__log:
+ # self.__log("%s: DTR OFF\n" % self.__serial.portstr)
+ time.sleep (0.5)
+
+ #-- Volver a activarla. Reset hecho
+ self.__serial.setDTR (1)
+
+ #-- Esto es para depurar
+ #if self.__log:
+ # self.__log("%s: DTR ON\n" % self.__serial.portstr)
+
+ if self.__log:
+ self.__log ('Reset Skypic\n')
+
+
+
+ def identBootloader (self, timeoutCallback=default_stateCallback):
+ #-----------------------------------------------------------------------
+ """
+ Identificar el Bootloader
+ Devuelve:
+ -TRUE si se ha detectado
+ -FALSE si ha transcurrido el timeout y no se ha detectado
+ Esto puede ocurrir bien porque no haya comunicacion con el bootloader
+ o bien porque no se haya pulsado el boton de reset de la skypic
+ ENTRADAS:
+ -timeoutCallback : Funcion de estado. Se invoca al comienzo de la
+ identificacion y si no se ha podio encontrar el Bootloader
+ """
+ #-----------------------------------------------------------------------
+
+ #-- Inicializacion de la funcion de callback
+ if timeoutCallback:
+ timeoutCallback(IDENT_START,0,0)
+
+ # Timeout or bad reply
+ nack=0;
+ while True:
+
+ #-- Enviar comando de identificacion
+ self.__serial.write (CMD_IDENT)
+
+ #-- Esperar la respuesta
+ id = self.__serial.read (1)
+
+ #-- Condicion de deteccion del bootloader
+ if len (id) == 1 and id == CMD_IDACK:
+ if self.__log:
+ self.__log ('Bootloader OK\n')
+ return True
+
+ nack+=1
+ #-- Invocar la funcion de callback
+ if timeoutCallback:
+ ret = timeoutCallback(IDENT_NACK,nack,float(nack)*SERIAL_TIMEOUT)
+ if ret==False:
+ #-- Bootloder NO detectado
+ if self.__log:
+ self.__log ('TIMEOUT\n')
+
+ raise IrisError,'Bootloader No detectado'
+
+
+ def writeData(self,block):
+ #--------------------------------------------------
+ """
+ Escribir un bloque a traves del booloader
+ El primer elemento del bloque es la direccion
+ """
+ #--------------------------------------------------
+
+ #-- Obtener la direccion de comienzo del bloque
+ addr=block[0]
+
+ #-- Obtener el bloque en bytes
+ #-- Se almacena en data. Primero el byte alto y luego el bajo
+ data=[]
+ for i in block[1:]:
+ data.append(i>>8 & 0xFF) #-- Andir byte alto
+ data.append(i&0xFF) #-- Anadir byte bajo
+
+ #-- Calcular el Checksum
+ chk = sum(data) & 0xFF
+
+ #-- Tamano del bloque en bytes
+ tam = len (data)
+
+ #------------------------------------
+ #-- Comenzar la escritura del bloque
+ #------------------------------------
+ #-- Enviar comando
+ self.__serial.write (CMD_WRITE)
+
+ #-- Enviar direccion de comienzo del bloque
+ self.__serial.write ('%c%c' % (chr (addr >> 8 & 0xFF),
+ chr (addr & 0xFF)))
+
+ #-- Enviar tamano
+ self.__serial.write (chr (tam))
+
+ #-- Enviar checksum
+ self.__serial.write (chr (chk))
+
+ #-- Enviar los datos
+ for d in data:
+ self.__serial.write (chr(d))
+
+ #-----------------------------
+ #-- Comprobar las respuestas
+ #-----------------------------
+
+ # --- Datos correctos?
+ ch = self.__serial.read (1)
+ if ch != CMD_DATA_OK:
+ raise IrisError, 'Data error.'
+
+ # --- Escritura ok?
+ ch = self.__serial.read (1)
+ if ch != CMD_OK:
+ raise IrisError, 'Write error.'
+
+
+ def download (self, program, stateCallback=default_stateCallback):
+ #---------------------------------------------------------------------------
+ """
+ Descargar un programa a traves del bootloader
+ Para cada fase de la descarga se invoca la funcion de retrollamda
+ stateCallback
+ """
+ #---------------------------------------------------------------------------
+
+ #-- Hacer un reset
+ self.skypicReset()
+
+ #-- Identificar el bootloader
+ #-- Se invoca a la funcion de estado
+ self.identBootloader(timeoutCallback=stateCallback)
+
+ #-- Obtener Tamano del programa en bloques
+ tam = len(program)
+
+ #-- Invocar la funcion de estado para indicar el comienzo
+ #-- de la descarga
+ if stateCallback:
+ ok=stateCallback(WRITING_START, 0, tam);
+ if not ok:
+ raise IrisError, "Abortado"
+
+ #-- Escribir los bloques
+ count=1;
+ for block in program:
+ self.writeData(block)
+
+ #-- Invocar funcion de estado para indicar que se ha descargado
+ #-- un bloque
+ if stateCallback:
+ ok=stateCallback(WRITING_INC,count,tam);
+ if not ok:
+ raise IrisError, "Abortado"
+
+ #-- Incrementar contador de numero de bloques descargados
+ count=count + 1
+
+ #-- Invocar la funcion de estado para indicar que se ha terminado
+ #-- la descarga, siempre que no haya sido abortada
+ if stateCallback:
+ ok=stateCallback(WRITING_END,0,tam);
+ if not ok:
+ raise IrisError, "Abortado"
+
+ #-- Ejecutar el programa
+ self.sendDone ()
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.pyc b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.pyc
new file mode 100644
index 0000000..36cf0cf
Binary files /dev/null and b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.pyc differ
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.py~ b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.py~
new file mode 100644
index 0000000..a7205cd
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Bootloader.py~
@@ -0,0 +1,446 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+
+# Description: File downloader library for SkyPIC
+# Copyright (C) 2007 by Rafael Treviño Menéndez
+# Author: Rafael Treviño Menéndez <skasi 7 gmail com>
+# Juan Gonzalez <juan iearobotics com>
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+"""
+ Modulo Cliente para comunicarse con el PIC_BOOTLOADER y descargar
+ ficheros .hex en la tarejta Skypic
+
+ Ademas se incorporan metodos para que el usuario pueda acceder
+ a los diferentes servicios del Bootloader por si quiere implementarse
+ su propio programa de descarga o quiere hacer modificaciones a bajo
+ nivel en el bootloader
+"""
+
+import serial
+import time
+import IntelHex
+import sys
+
+
+#############
+# CONSTANTS #
+#############
+
+#--------------------------------------
+#- Configuracion del puerto serie
+#--------------------------------------
+#-- Timeout por defecto para el acceso al puerto serie
+SERIAL_TIMEOUT = 0.2
+
+#--- Velocidad de transmision para la comunicacion con el PIC Bootloader
+BAUDIOS = 38400
+
+#------------------------------------------------------------------
+#- IDENTIFICACION DE LOS COMANDOS DEL PROTOCOLO DEL BOOTLOADER
+#------------------------------------------------------------------
+CMD_WRITE = '\xE3' #-- Escritura de un bloque
+CMD_DATA_OK = '\xE7' #-- Datos enviados correctamente
+CMD_OK = '\xE4' #-- Operacion ejecutada
+CMD_IDENT = '\xEA' #-- Comando de identificacion del bootloader
+CMD_IDACK = '\xEB' #-- Bootloader identificado
+CMD_SEND_DONE= '\xED' #-- Comando de ejecucion
+
+#------------------------------------------------------------------------
+#-- Constantes usadas con el metodo download para indicar
+#-- lo que va ocurriendo con la descarga
+#------------------------------------------------------------------------
+WRITING_START=1 #-- Comienzo de la escritura
+WRITING_INC=2 #-- Escritura de una palabra
+WRITING_END=3 #-- Fin de la escritura
+
+IDENT_START=4 #-- Comienzo de la identificacion del bootloader
+IDENT_NACK=5 #-- No se ha recibido respuesta
+
+#-- Timeout por defecto, en segundos, que se espera a detectar el
+#-- Bootloader
+DEFAULT_TIMEOUT = 10
+
+
+#----------------------------------------
+#- Clase para la gestion de los errores
+#----------------------------------------
+class IrisError (Exception):
+ """
+ Excepciones producidas en el modulo Pic16_Bootloader
+ """
+ pass
+
+
+def default_logCallback(msg):
+ """
+ Funcion de "log" por defecto.
+ Simplemente se imprimen los mensajes
+ """
+ sys.stdout.write(msg)
+ sys.stdout.flush()
+
+
+#-----------------------------------------------------------------------------
+def default_stateCallback(op,inc,total):
+ """
+ Funcion de estado por defecto
+ Se imprime informacion en la consola
+ La funcion debe devolver TRUE si todo esta OK y se quiere continuar
+ con el proceso. FALSE en caso contrario. La descarga se aborta
+ Los parametros recibidos son:
+ -op: Tipo de operacion. Indica la fase de la descarga que se ha iniciado
+ -inc:
+ -En el estado IDENT_NACK indica el numero reitentos hasta el momento
+ -En el estado WRITING_INC indica el numero de bloques enviados
+ -total:
+ -En el estado IDENT_NACK indica el tiempo total transcurrido desde
+ el comienzo de la identificacion (en segundos)
+ -En el estado WRITING_INC indica el numero total de bloques del
+ del programa a transmitir
+
+ El usuario puede crear su propia funcion de estado para actualizar el
+ interfaz de su aplicacion como quiera. Esta funcion es un ejemplo para
+ una interfaz de consola
+ """
+
+
+ #--------------------------------------------------
+ #- Comienzo de la identificacion del Bootloader
+ #--------------------------------------------------
+ if op==IDENT_START:
+ print "Esperando Bootloader"
+ return True
+
+ #-------------------------------------------------------------------------
+ #-- Timeout en la identificacion.
+ #-- Cuando el tiempo transcurrido supera el timeout en la identificacion
+ #-- se aborta devolviendose False
+ #-------------------------------------------------------------------------
+ elif op==IDENT_NACK:
+ sys.stdout.write('.')
+ sys.stdout.flush()
+ if total<=DEFAULT_TIMEOUT:
+ return True
+ else :
+ return False
+
+ #-----------------------------------------------------------------------
+ #-- Comienzo de la descarga
+ #-- Se imprime una barra de status en ASCII formada por '.' y se lleva
+ #-- el cursor a la izquierda (imprimiendo el caracter '\b'
+ #----------------------------------------------------------------------
+ elif op==WRITING_START:
+ sys.stdout.write("\nDescargando:\n")
+ cad="".join(["." for i in range(total)])
+ back="".join(["\b" for i in range(total)])
+
+ #-- Imprimir la "barra de estado" con '.'. Un '.' por cada bloque
+ sys.stdout.write(cad)
+
+ #-- Llevar el cursos a la izquierda
+ sys.stdout.write(back)
+ sys.stdout.flush()
+
+ return True
+
+ #----------------------------------------------------------------------
+ #-- Se ha grabado un bloque. Se actualiza la "barra de estado ascii"
+ #----------------------------------------------------------------------
+ elif op==WRITING_INC:
+ sys.stdout.write("*")
+ sys.stdout.flush()
+ return True
+
+ #----------------------------------------
+ #- Fin de la descarga
+ #----------------------------------------
+ elif op==WRITING_END:
+ print " OK"
+ return True
+
+
+#----------------------------------------------------------------------------
+#-- CLASE PRINCIPAL
+#----------------------------------------------------------------------------
+class Iris:
+ """
+ Clase prinipal del modulo Pic16_Bootloader. Se utiliza para comunicarse
+ con el Bootloader y descargar programas en la Skypic
+ """
+
+ #---------------------
+ #- Destructor
+ #---------------------
+ def __del__(self):
+
+ #-- Cerrar el pueto serie
+ if self.__serial:
+ #print "Debug: cerrando puerto serie: %s" % (self.__serial.portstr)
+ self.__serial.close()
+
+
+ def __init__ (self, serialName, logCallback = default_logCallback):
+ #-------------------------------------------------------------------------
+ """
+ Constructor
+ ENTRADAS:
+ serialName: Dispositivo serie
+ logCallback: Funcion de retrollamada para el "log"
+ """
+ #--------------------------------------------------------------------------
+
+ self.__serial = None
+ self.__log = logCallback
+
+ #-- Abrir puerto serie
+ try:
+ self.__serial = serial.Serial(serialName, BAUDIOS)
+ except serial.SerialException:
+ raise IrisError,'Error al abrir puerto serie %s.' % serialName
+
+ if self.__log:
+ self.__log ('Serial port %s opened.\n' % self.__serial.portstr)
+
+ #-- Configurar timeout
+ #-- He detectado que en Linux al configurar el timeout se modifica
+ #-- el estado del DTR. No en todos los casos (depende del driver
+ #-- del conversor USB-serie usado). El problema siempre esta en que
+ #-- los valores del DTR no estan estandarizados y cada driver los
+ #-- maneja a su propia manera.
+ #-- La solucion que se esta utilizando es la de configurar el
+ #-- timeout al principio
+ self.__serial.timeout = SERIAL_TIMEOUT
+
+ #-- Vaciar los buffers del puerto serie
+ self.__serial.flushInput()
+ self.__serial.flushOutput()
+
+
+ def close(self):
+ #-----------------------------
+ """
+ Cerrar el puerto serie
+ """
+ #-----------------------------
+ if self.__serial!=None:
+ self.__serial.close()
+
+
+
+ def sendDone (self):
+ #--------------------------------------------------------------------
+ """
+ Enviar comando SENDDONE para que arranque el programa cargado
+ """
+ #--------------------------------------------------------------------
+
+ #-- Enviar el comando
+ self.__serial.write (CMD_SEND_DONE)
+
+ #-- Esperar la respuesta
+ ch = self.__serial.read (1)
+ if ch != CMD_OK:
+ raise IrisError, "Error en Done"
+
+ if self.__log:
+ self.__log ('Ejecutando programa\n')
+
+
+ def skypicReset (self):
+ #----------------------------------------------------------------
+ """
+ Hacer reset de la Skypic. Solo funcionara si el jumper JP4
+ esta colocado en la posicion DTR
+ """
+ #----------------------------------------------------------------
+
+ #-- Desactivar la senal DTR durante 0.5 segundos
+ self.__serial.setDTR (0)
+
+ #-- Esto es para depurar
+ #if self.__log:
+ # self.__log("%s: DTR OFF\n" % self.__serial.portstr)
+ time.sleep (0.5)
+
+ #-- Volver a activarla. Reset hecho
+ self.__serial.setDTR (1)
+
+ #-- Esto es para depurar
+ #if self.__log:
+ # self.__log("%s: DTR ON\n" % self.__serial.portstr)
+
+ if self.__log:
+ self.__log ('Reset Skypic\n')
+
+
+
+ def identBootloader (self, timeoutCallback=default_stateCallback):
+ #-----------------------------------------------------------------------
+ """
+ Identificar el Bootloader
+ Devuelve:
+ -TRUE si se ha detectado
+ -FALSE si ha transcurrido el timeout y no se ha detectado
+ Esto puede ocurrir bien porque no haya comunicacion con el bootloader
+ o bien porque no se haya pulsado el boton de reset de la skypic
+ ENTRADAS:
+ -timeoutCallback : Funcion de estado. Se invoca al comienzo de la
+ identificacion y si no se ha podio encontrar el Bootloader
+ """
+ #-----------------------------------------------------------------------
+
+ #-- Inicializacion de la funcion de callback
+ if timeoutCallback:
+ timeoutCallback(IDENT_START,0,0)
+
+ # Timeout or bad reply
+ nack=0;
+ while True:
+
+ #-- Enviar comando de identificacion
+ self.__serial.write (CMD_IDENT)
+
+ #-- Esperar la respuesta
+ id = self.__serial.read (1)
+
+ #-- Condicion de deteccion del bootloader
+ if len (id) == 1 and id == CMD_IDACK:
+ if self.__log:
+ self.__log ('Bootloader OK\n')
+ return True
+
+ nack+=1
+ #-- Invocar la funcion de callback
+ if timeoutCallback:
+ ret = timeoutCallback(IDENT_NACK,nack,float(nack)*SERIAL_TIMEOUT)
+ if ret==False:
+ #-- Bootloder NO detectado
+ if self.__log:
+ self.__log ('TIMEOUT\n')
+
+ raise IrisError,'Bootloader No detectado'
+
+
+ def writeData(self,block):
+ #--------------------------------------------------
+ """
+ Escribir un bloque a traves del booloader
+ El primer elemento del bloque es la direccion
+ """
+ #--------------------------------------------------
+
+ #-- Obtener la direccion de comienzo del bloque
+ addr=block[0]
+
+ #-- Obtener el bloque en bytes
+ #-- Se almacena en data. Primero el byte alto y luego el bajo
+ data=[]
+ for i in block[1:]:
+ data.append(i>>8 & 0xFF) #-- Andir byte alto
+ data.append(i&0xFF) #-- Anadir byte bajo
+
+ #-- Calcular el Checksum
+ chk = sum(data) & 0xFF
+
+ #-- Tamano del bloque en bytes
+ tam = len (data)
+
+ #------------------------------------
+ #-- Comenzar la escritura del bloque
+ #------------------------------------
+ #-- Enviar comando
+ self.__serial.write (CMD_WRITE)
+
+ #-- Enviar direccion de comienzo del bloque
+ self.__serial.write ('%c%c' % (chr (addr >> 8 & 0xFF),
+ chr (addr & 0xFF)))
+
+ #-- Enviar tamano
+ self.__serial.write (chr (tam))
+
+ #-- Enviar checksum
+ self.__serial.write (chr (chk))
+
+ #-- Enviar los datos
+ for d in data:
+ self.__serial.write (chr(d))
+
+ #-----------------------------
+ #-- Comprobar las respuestas
+ #-----------------------------
+
+ # --- Datos correctos?
+ ch = self.__serial.read (1)
+ if ch != CMD_DATA_OK:
+ raise IrisError, 'Data error.'
+
+ # --- Escritura ok?
+ ch = self.__serial.read (1)
+ if ch != CMD_OK:
+ raise IrisError, 'Write error.'
+
+
+ def download (self, program, stateCallback=default_stateCallback):
+ #---------------------------------------------------------------------------
+ """
+ Descargar un programa a traves del bootloader
+ Para cada fase de la descarga se invoca la funcion de retrollamda
+ stateCallback
+ """
+ #---------------------------------------------------------------------------
+
+ #-- Hacer un reset
+ self.skypicReset()
+
+ #-- Identificar el bootloader
+ #-- Se invoca a la funcion de estado
+ self.identBootloader(timeoutCallback=stateCallback)
+
+ #-- Obtener Tamano del programa en bloques
+ tam = len(program)
+
+ #-- Invocar la funcion de estado para indicar el comienzo
+ #-- de la descarga
+ if stateCallback:
+ ok=stateCallback(WRITING_START, 0, tam);
+ if not ok:
+ raise IrisError, "Abortado"
+
+ #-- Escribir los bloques
+ count=1;
+ for block in program:
+ self.writeData(block)
+
+ #-- Invocar funcion de estado para indicar que se ha descargado
+ #-- un bloque
+ if stateCallback:
+ ok=stateCallback(WRITING_INC,count,tam);
+ if not ok:
+ raise IrisError, "Abortado"
+
+ #-- Incrementar contador de numero de bloques descargados
+ count=count + 1
+
+ #-- Invocar la funcion de estado para indicar que se ha terminado
+ #-- la descarga, siempre que no haya sido abortada
+ if stateCallback:
+ ok=stateCallback(WRITING_END,0,tam);
+ if not ok:
+ raise IrisError, "Abortado"
+
+ #-- Ejecutar el programa
+ self.sendDone ()
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Firmware.py b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Firmware.py
new file mode 100644
index 0000000..5762006
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Firmware.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+
+# Description: File downloader library for SkyPIC
+# Copyright (C) 2007 by Rafael Treviño Menéndez
+# Author: Rafael Treviño Menéndez <skasi 7 gmail com>
+# Juan Gonzalez <juan iearobotics com>
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+#----------------------------------------------------------------------------
+"""
+ Libreria que contiene FIRMWARE para la Skypic
+ El firmware ha sido obtenido a partir de los ficheros .hex utilizando
+ la herramienta hex2python, de la siguiente manera:
+
+ $ ./hex2python.py fichero.hex f3 nombre_lista
+
+ Por ejemplo, el clasico programa del led parpdeante se ha obtenido asi:
+
+ ./hex2python.py ledp1.hex f3 ledp1
+"""
+#----------------------------------------------------------------------------
+
+
+#---------------------------------------------------------------------------
+#- LEDON. Encender el led de la Skypic
+#---------------------------------------------------------------------------
+ledon=[[0x0000, 0x0000, 0x118A, 0x120A, 0x280C, 0x0000, 0x1683, 0x1303, 0x1086, 0x1283, 0x1486, 0x280A, 0x0008, 0x118A, 0x120A, 0x2805],]
+
+#----------------------------------------------------------------------
+#- LEDP1. Programa del ledp, que hace parpadear el led de la skypic
+#----------------------------------------------------------------------
+ledp1=[[0x0000, 0x0000, 0x118A, 0x120A, 0x2821, 0x0000, 0x30FD, 0x1683, 0x1303, 0x0086, 0x3002, 0x1283, 0x0686, 0x30FF, 0x00FF, 0x30FF, 0x2012],[0x0010, 0x2809, 0x0008, 0x1283, 0x1303, 0x00A3, 0x087F, 0x00A2, 0x0822, 0x0423, 0x1903, 0x2820, 0x30FF, 0x07A2, 0x1C03, 0x03A3, 0x2817],[0x0020, 0x0008, 0x118A, 0x120A, 0x2805],]
+
+#----------------------------------------------------------------------
+#- LEDP2. Programa del ledp, que hace parpadear el led de la skypic.
+#- Se diferencia del ledp1 en que el parpadeo es mas rapido
+#----------------------------------------------------------------------
+ledp2=[[0x0000, 0x0000, 0x118A, 0x120A, 0x2821, 0x0000, 0x30FD, 0x1683, 0x1303, 0x0086, 0x3002, 0x1283, 0x0686, 0x3000, 0x00FF, 0x3080, 0x2012],[0x0010, 0x2809, 0x0008, 0x1283, 0x1303, 0x00A3, 0x087F, 0x00A2, 0x0822, 0x0423, 0x1903, 0x2820, 0x30FF, 0x07A2, 0x1C03, 0x03A3, 0x2817],[0x0020, 0x0008, 0x118A, 0x120A, 0x2805],]
+
+#----------------------------------------------------------------------------
+#- FIRMWARE DEL PROYECTO STARGATE
+#----------------------------------------------------------------------------
+
+#--- Servidor de Eco. V1. Velocidad 9600 Baudios
+echo=[[0x0000, 0x0183, 0x3000, 0x008A, 0x2804, 0x1683, 0x3081, 0x0099, 0x3024, 0x0098, 0x1283, 0x3090, 0x0098, 0x1683, 0x0186, 0x1283, 0x30FF],[0x0010, 0x0086, 0x2015, 0x2019, 0x0086, 0x2811, 0x1E8C, 0x2815, 0x081A, 0x0008, 0x1E0C, 0x2819, 0x0099, 0x0008],]
+
+#--- Servidor GENERICO. V1. Velocidad 9600 baudios
+generic=[[0x0000, 0x0183, 0x3000, 0x008A, 0x2804, 0x1683, 0x3081, 0x0099, 0x3024, 0x0098, 0x1283, 0x3090, 0x0098, 0x1683, 0x1086, 0x1283, 0x3002],[0x0010, 0x0086, 0x2048, 0x00A0, 0x3050, 0x0220, 0x1903, 0x2824, 0x3049, 0x0220, 0x1903, 0x2827, 0x304C, 0x0220, 0x1903, 0x2830, 0x3053],[0x0020, 0x0220, 0x1903, 0x2838, 0x2811, 0x304F, 0x204C, 0x2811, 0x3049, 0x204C, 0x3020, 0x204C, 0x3030, 0x204C, 0x3010, 0x204C, 0x2811],[0x0030, 0x203E, 0x0800, 0x00A3, 0x304C, 0x204C, 0x0823, 0x204C, 0x2811, 0x203E, 0x2048, 0x0080, 0x3053, 0x204C, 0x2811, 0x2048, 0x0084],[0x0040, 0x2048, 0x00A1, 0x1821, 0x2846, 0x1383, 0x2847, 0x1783, 0x0008, 0x1E8C, 0x2848, 0x081A, 0x0008, 0x1E0C, 0x284C, 0x0099, 0x0008],]
+
+#--- Servidor SERVOS8. V1. Velocidad 9600 baudios
+servos8=[[0x0000, 0x0000, 0x118A, 0x120A, 0x2907, 0x00F2, 0x0E03, 0x0183, 0x1283, 0x1303, 0x00F1, 0x080A, 0x00F0, 0x018A, 0x110B, 0x3000, 0x1283],[0x0010, 0x1303, 0x042B, 0x1D03, 0x2820, 0x0829, 0x052A, 0x1283, 0x1303, 0x0086, 0x30EA, 0x0081, 0x3001, 0x1283, 0x1303, 0x00AB, 0x2862],[0x0020, 0x082B, 0x3A01, 0x1D03, 0x2839, 0x0828, 0x3E20, 0x00AF, 0x3000, 0x1803, 0x3E01, 0x00B0, 0x082F, 0x0084, 0x1383, 0x1830, 0x1783],[0x0030, 0x0800, 0x1283, 0x1303, 0x0081, 0x3002, 0x1283, 0x1303, 0x00AB, 0x2862, 0x082B, 0x3A02, 0x1D03, 0x2861, 0x1283, 0x1303, 0x0186],[0x0040, 0x1283, 0x1303, 0x0828, 0x3E20, 0x00AF, 0x3000, 0x1803, 0x3E01, 0x00B0, 0x082F, 0x0084, 0x1383, 0x1830, 0x1783, 0x0800, 0x3C52],[0x0050, 0x1283, 0x1303, 0x0081, 0x1283, 0x1303, 0x01AB, 0x1003, 0x0DA9, 0x0AA8, 0x3000, 0x0429, 0x1D03, 0x2862, 0x3001, 0x00A9, 0x01A8],[0x0060, 0x2862, 0x01AB, 0x1283, 0x1303, 0x0870, 0x008A, 0x0183, 0x0E71, 0x0083, 0x0EF2, 0x0E72, 0x0009, 0x1683, 0x1303, 0x0186, 0x3002],[0x0070, 0x1283, 0x00
86, 0x1283, 0x1303, 0x01B4, 0x3008, 0x0234, 0x1803, 0x2889, 0x0834, 0x3E20, 0x00B5, 0x3000, 0x1803, 0x3E01, 0x00B6],[0x0080, 0x0835, 0x0084, 0x1383, 0x1836, 0x1783, 0x30B0, 0x0080, 0x0AB4, 0x2875, 0x01AA, 0x01A8, 0x01AB, 0x3001, 0x00A9, 0x20FD, 0x20DF],[0x0090, 0x20F7, 0x1283, 0x1303, 0x00B4, 0x3A45, 0x1903, 0x28AA, 0x0834, 0x3A49, 0x1903, 0x28A6, 0x0834, 0x3A50, 0x1903, 0x28A4, 0x0834],[0x00A0, 0x3A57, 0x1903, 0x28A8, 0x2890, 0x20DC, 0x2890, 0x20D3, 0x2890, 0x20B2, 0x2890, 0x20AD, 0x2890, 0x0008, 0x20F7, 0x1283, 0x1303],[0x00B0, 0x00AA, 0x0008, 0x20F7, 0x1283, 0x1303, 0x00AC, 0x20F7, 0x1283, 0x1303, 0x00B1, 0x3099, 0x0231, 0x1C03, 0x28C0, 0x3099, 0x00B1],[0x00C0, 0x032C, 0x00B2, 0x3E20, 0x00B2, 0x3000, 0x1803, 0x3E01, 0x00B3, 0x0831, 0x3CFF, 0x00B1, 0x0832, 0x0084, 0x1383, 0x1833, 0x1783],[0x00D0, 0x0831, 0x0080, 0x0008, 0x3049, 0x20E9, 0x3030, 0x20E9, 0x3030, 0x20E9, 0x3011, 0x20E9, 0x0008, 0x304F, 0x20E9, 0x0008, 0x3005],[0x00E0, 0x1683, 0x1303, 0x0081, 0x110B, 0x168B, 0x
178B, 0x1283, 0x0181, 0x0008, 0x1283, 0x1303, 0x00AE, 0x1283, 0x1303, 0x1E0C, 0x28EC],[0x00F0, 0x1283, 0x1303, 0x082E, 0x1283, 0x1303, 0x0099, 0x0008, 0x1283, 0x1303, 0x1E8C, 0x28F7, 0x081A, 0x0008, 0x3081, 0x1683, 0x1303],[0x0100, 0x0099, 0x3024, 0x0098, 0x3090, 0x1283, 0x0098, 0x0008, 0x118A, 0x120A, 0x286C],]
+
+
+#--- Servidor PICP. V2. Velocidad 9600 baudios
+picp=[[0x0000, 0x0000, 0x118A, 0x120A, 0x2997, 0x0000, 0x218D, 0x3067, 0x1683, 0x0086, 0x1283, 0x0186, 0x2174, 0x2187, 0x1283, 0x1303, 0x00B5],[0x0010, 0x3A41, 0x1903, 0x2842, 0x0835, 0x3A42, 0x1903, 0x2840, 0x0835, 0x3A43, 0x1903, 0x2846, 0x0835, 0x3A44, 0x1903, 0x283E, 0x0835],[0x0020, 0x3A49, 0x1903, 0x283A, 0x0835, 0x3A4A, 0x1903, 0x284A, 0x0835, 0x3A50, 0x1903, 0x2838, 0x0835, 0x3A52, 0x1903, 0x2844, 0x0835],[0x0030, 0x3A54, 0x1903, 0x283C, 0x0835, 0x3A57, 0x1903, 0x2848, 0x280C, 0x20E2, 0x280C, 0x20D9, 0x280C, 0x20CD, 0x280C, 0x20BA, 0x280C],[0x0040, 0x20B5, 0x280C, 0x20B0, 0x280C, 0x20A2, 0x280C, 0x2099, 0x280C, 0x2084, 0x280C, 0x204D, 0x280C, 0x0008, 0x2187, 0x1283, 0x1303],[0x0050, 0x00B2, 0x2187, 0x1283, 0x1303, 0x00B3, 0x3000, 0x0433, 0x1903, 0x285C, 0x3001, 0x00B4, 0x285D, 0x01B4, 0x3000, 0x0434, 0x1903],[0x0060, 0x286F, 0x30FF, 0x00B4, 0x3006, 0x2110, 0x1283, 0x1303, 0x0BB4, 0x2863, 0x3006, 0x2110, 0x1283, 0x1303, 0x03B3, 0x2855, 0x3000],[0x0070, 0x0432, 0x1903,
0x2876, 0x3001, 0x00B3, 0x2877, 0x01B3, 0x3000, 0x0433, 0x1903, 0x2881, 0x3006, 0x2110, 0x1283, 0x1303, 0x03B2],[0x0080, 0x286F, 0x304A, 0x2179, 0x0008, 0x2187, 0x1283, 0x1303, 0x00B0, 0x2187, 0x1283, 0x1303, 0x00B1, 0x3002, 0x2110, 0x1283, 0x1303],[0x0090, 0x0830, 0x00FF, 0x0831, 0x20FA, 0x3008, 0x2110, 0x3057, 0x2179, 0x0008, 0x3000, 0x2110, 0x3000, 0x00FF, 0x3000, 0x20FA, 0x3043],[0x00A0, 0x2179, 0x0008, 0x3004, 0x2110, 0x20E5, 0x3052, 0x2179, 0x1283, 0x1303, 0x0820, 0x2179, 0x1283, 0x1303, 0x0821, 0x2179, 0x0008],[0x00B0, 0x3006, 0x2110, 0x3041, 0x2179, 0x0008, 0x3008, 0x2110, 0x3042, 0x2179, 0x0008, 0x2187, 0x1283, 0x1303, 0x00AE, 0x2187, 0x1283],[0x00C0, 0x1303, 0x00AF, 0x3002, 0x2110, 0x1283, 0x1303, 0x082E, 0x00FF, 0x082F, 0x20FA, 0x3044, 0x2179, 0x0008, 0x3010, 0x1283, 0x1303],[0x00D0, 0x0086, 0x3002, 0x2161, 0x1283, 0x1303, 0x0186, 0x3054, 0x2179, 0x0008, 0x3049, 0x2179, 0x3040, 0x2179, 0x3030, 0x2179, 0x3012],[0x00E0, 0x2179, 0x0008, 0x304F, 0x2179, 0x0008, 0x168
3, 0x1303, 0x1786, 0x3001, 0x2127, 0x3008, 0x2127, 0x00A0, 0x3007, 0x2127, 0x00A1],[0x00F0, 0x1003, 0x0C21, 0x00AD, 0x303F, 0x052D, 0x00A1, 0x1683, 0x1303, 0x0186, 0x0008, 0x1283, 0x1303, 0x00AB, 0x087F, 0x00AC, 0x3001],[0x0100, 0x00FF, 0x3000, 0x2144, 0x3008, 0x00FF, 0x1283, 0x1303, 0x082C, 0x2144, 0x3007, 0x00FF, 0x1283, 0x1303, 0x082B, 0x2144, 0x0008],[0x0110, 0x1283, 0x1303, 0x00AA, 0x30F0, 0x1283, 0x1303, 0x0586, 0x3006, 0x00FF, 0x1283, 0x1303, 0x082A, 0x2144, 0x1283, 0x1303, 0x1786],[0x0120, 0x30FF, 0x0085, 0x0185, 0x30FF, 0x0085, 0x0185, 0x0008, 0x1283, 0x1303, 0x00A7, 0x01A8, 0x01A9, 0x0827, 0x0229, 0x1803, 0x2942],[0x0130, 0x1003, 0x0CA8, 0x1283, 0x1303, 0x1586, 0x30F0, 0x0586, 0x1B86, 0x293D, 0x1283, 0x1303, 0x13A8, 0x2940, 0x1283, 0x1303, 0x17A8],[0x0140, 0x0AA9, 0x292C, 0x0828, 0x0008, 0x1283, 0x1303, 0x00A4, 0x087F, 0x00A5, 0x01A6, 0x0825, 0x0226, 0x1803, 0x2960, 0x1824, 0x2954],[0x0150, 0x1283, 0x1303, 0x1386, 0x2957, 0x1283, 0x1303, 0x1786, 0x1586, 0x30F0, 0x0
586, 0x1003, 0x1283, 0x1303, 0x0CA4, 0x0AA6, 0x294A],[0x0160, 0x0008, 0x1283, 0x1303, 0x00A3, 0x3000, 0x0423, 0x1903, 0x2973, 0x303D, 0x1283, 0x1303, 0x0081, 0x110B, 0x1D0B, 0x296D, 0x1283],[0x0170, 0x1303, 0x03A3, 0x2964, 0x0008, 0x3087, 0x1683, 0x1303, 0x0081, 0x0008, 0x1283, 0x1303, 0x00A2, 0x1283, 0x1303, 0x1E0C, 0x297C],[0x0180, 0x1283, 0x1303, 0x0822, 0x1283, 0x1303, 0x0099, 0x0008, 0x1283, 0x1303, 0x1E8C, 0x2987, 0x081A, 0x0008, 0x3081, 0x1683, 0x1303],[0x0190, 0x0099, 0x3024, 0x0098, 0x3090, 0x1283, 0x0098, 0x0008, 0x118A, 0x120A, 0x2805],]
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Firmware.pyc b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Firmware.pyc
new file mode 100644
index 0000000..97bbf14
Binary files /dev/null and b/chronopic-firmware/pydownloader-chronopic/libIris/Pic16_Firmware.pyc differ
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/__init__.py b/chronopic-firmware/pydownloader-chronopic/libIris/__init__.py
new file mode 100644
index 0000000..589feb1
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/libIris/__init__.py
@@ -0,0 +1,51 @@
+#! /usr/bin/python
+# -*- coding: iso-8859-15 -*-
+
+#-- Paqute LibIris
+
+
+# Description: File downloader library for SkyPIC
+# Copyright (C) 2007 by Rafael Treviño Menéndez
+# Author: Rafael Treviño Menéndez <skasi 7 gmail com>
+# Juan Gonzalez <juan iearobotics com>
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+"""
+ Paquete LibIris: Descarga de programas en la tarjeta skypic
+
+Este paquete esta formado por tres modulos:
+
+ * IntelHex : Lectura de ficheros en formato .hex de Intel
+ * Pic16_Bootloader: Descarga de ficheros a traves del bootloader
+ * Pic16_Firmware : Programas para el PIC16F876A. Incluye los servidores
+ del proyecto stargate y programas de prubas, como el
+ ledp
+
+Incluye ademas las siguientes utilidades:
+
+ * hex-view : Visualizacion de ficheros .hex
+ * hex2python: Convertir un fichero .hex a un script en python que contiene
+ el codigo maquina en una lista
+ * skypic-test: Prueba de descargas en la skypic. Se graba el programama del
+ ledp. Permite comprobar si la skypic esta funcionando
+ correctamente
+
+
+"""
+
+#-- Version de la libIris
+VERSION = 1.2
+print "Chronopic version!"
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/__init__.pyc b/chronopic-firmware/pydownloader-chronopic/libIris/__init__.pyc
new file mode 100644
index 0000000..0732741
Binary files /dev/null and b/chronopic-firmware/pydownloader-chronopic/libIris/__init__.pyc differ
diff --git a/chronopic-firmware/pydownloader-chronopic/libIris/__init__.py~ b/chronopic-firmware/pydownloader-chronopic/libIris/__init__.py~
new file mode 100644
index 0000000..aad0dc3
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/libIris/__init__.py~
@@ -0,0 +1,51 @@
+#! /usr/bin/python
+# -*- coding: iso-8859-15 -*-
+
+#-- Paqute LibIris
+
+
+# Description: File downloader library for SkyPIC
+# Copyright (C) 2007 by Rafael Treviño Menéndez
+# Author: Rafael Treviño Menéndez <skasi 7 gmail com>
+# Juan Gonzalez <juan iearobotics com>
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+"""
+ Paquete LibIris: Descarga de programas en la tarjeta skypic
+
+Este paquete esta formado por tres modulos:
+
+ * IntelHex : Lectura de ficheros en formato .hex de Intel
+ * Pic16_Bootloader: Descarga de ficheros a traves del bootloader
+ * Pic16_Firmware : Programas para el PIC16F876A. Incluye los servidores
+ del proyecto stargate y programas de prubas, como el
+ ledp
+
+Incluye ademas las siguientes utilidades:
+
+ * hex-view : Visualizacion de ficheros .hex
+ * hex2python: Convertir un fichero .hex a un script en python que contiene
+ el codigo maquina en una lista
+ * skypic-test: Prueba de descargas en la skypic. Se graba el programama del
+ ledp. Permite comprobar si la skypic esta funcionando
+ correctamente
+
+
+"""
+
+#-- Version de la libIris
+VERSION = 1.2
+print "hola!"
diff --git a/chronopic-firmware/pydownloader-chronopic/pydownloader-wx.py b/chronopic-firmware/pydownloader-chronopic/pydownloader-wx.py
new file mode 100755
index 0000000..043607c
--- /dev/null
+++ b/chronopic-firmware/pydownloader-chronopic/pydownloader-wx.py
@@ -0,0 +1,443 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Description: Example of use of libIris
+# Copyright (C) 2007 by Rafael Treviño Menéndez
+# Author: Rafael Treviño Menéndez <skasi 7 gmail com>
+# Juan Gonzalez <juan iearobotics com>
+# Xavier de Blas <xaviblas gmail com> (2010 adapted to Chronopic)
+
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+import wx
+import sys
+import os
+sys.path = ['..'] + sys.path
+
+
+#---------------------------
+#-- Modulos de LibIris
+#---------------------------
+
+import libIris.Pic16_Bootloader
+import libIris.IntelHex
+import libIris.Pic16_Firmware
+
+#-- Timeout para la deteccion del bootloader (en segundos)
+#-- Si el programa previamente grabado utiliza el puerto serie
+#-- (por ejemplo el servidor de eco esta cargado) este tiempo ya
+#-- no es en segundos.
+
+#-- con este timeout esta unos 25 segundos esperando cuando el servidor
+#-- de eco esta cargado (400 si no se usa el puerto serie)
+TIMEOUT = 800
+
+#----------------------------------------------
+#- Clase para realizar el Drag and Drop
+#----------------------------------------------
+class myDragDrog(wx.FileDropTarget):
+
+ #-- En el constructor se le pasa el frame principal
+ #-- Se usa para invocar el metodo download
+ def __init__(self,obj):
+ wx.FileDropTarget.__init__(self)
+ self.frame = obj
+
+ #-- Se invoca cada vez que se recibe la lista de ficheros arrastrados
+ #-- Solo se descarga el primer fichero de la lista recibida
+ def OnDropFiles(self,x,y, filenames):
+
+ #-- Obtener el nombre del fichero (el primero de la lista)
+ file = filenames[0]
+
+ #-- Meter el fichero en el entry "fichero .hex"
+ self.frame.text_ctrl_2.SetValue(file)
+
+ #-- Activar la grabacion....
+ self.frame.update()
+ self.frame.download()
+
+ return True
+
+#-------------------------------------------------------------------
+#-- CLASE PRINCIPAL
+#-------------------------------------------------------------------
+class MyFrame(wx.Frame):
+ def __init__(self, app, *args, **kwds):
+
+
+ #----------------------------------------------------------------
+ #--- Esta parte del codigo se ha generado automaticamente con la
+ #-- herramienta wxglade. NO modificar.
+ #---------------------------------------------------------------
+ # begin wxGlade: MyFrame.__init__
+ kwds["style"] = wx.DEFAULT_FRAME_STYLE
+ wx.Frame.__init__(self, *args, **kwds)
+ self.panel_1 = wx.Panel(self, -1)
+ self.sizer_4_copy_staticbox = wx.StaticBox(self.panel_1, -1, "Port / Puerto")
+ self.sizer_2_staticbox = wx.StaticBox(self.panel_1, -1, "Process / Proceso")
+ self.sizer_4_staticbox = wx.StaticBox(self.panel_1, -1, "Firmware Chronopic")
+ self.frame_1_statusbar = self.CreateStatusBar(1, 0)
+ self.text_ctrl_2 = wx.TextCtrl(self.panel_1, -1, "")
+ self.button_2 = wx.Button(self.panel_1, -1, "Search / Buscar", style=wx.BU_EXACTFIT)
+ self.button_7 = wx.Button(self.panel_1, -1, "Record / Grabar", style=wx.BU_EXACTFIT)
+ self.combo_box_1 = wx.ComboBox(self.panel_1, -1, choices=[], style=wx.CB_DROPDOWN)
+ self.gauge_1 = wx.Gauge(self.panel_1, -1, 100)
+ self.button_6 = wx.Button(self.panel_1, -1, "Cancel / Cancelar")
+
+ self.__set_properties()
+ self.__do_layout()
+
+ self.Bind(wx.EVT_BUTTON, self.boton_abrir, self.button_2)
+ self.Bind(wx.EVT_BUTTON, self.boton_grabar, self.button_7)
+ self.Bind(wx.EVT_BUTTON, self.boton_cancelar, self.button_6)
+ # end wxGlade
+ #--------------------------------------------
+ # Fin del codigo generado automaticamente
+ #--------------------------------------------
+
+
+ #-- Guardar la aplicacion
+ self.app=app;
+
+ #-- Para configurar para el drag-and-drop
+ test = myDragDrog(self)
+ self.SetDropTarget(test)
+ self.text_ctrl_2.SetDropTarget(myDragDrog(self))
+ self.combo_box_1.SetDropTarget(myDragDrog(self))
+
+ #-- Establecer la habilitacion de los widgets
+ #-- Todos menos el boton de cancelar estan activos inicialmente
+ self.button_6.Disable()
+
+ #----------------------------------------------------------------
+ #--- Esta parte del codigo se ha generado automaticamente con la
+ #-- herramienta wxglade. NO modificar.
+ #---------------------------------------------------------------
+
+ def __set_properties(self):
+ # begin wxGlade: MyFrame.__set_properties
+ self.SetTitle("PyDownloader")
+ self.frame_1_statusbar.SetStatusWidths([-1])
+ # statusbar fields
+ frame_1_statusbar_fields = ["Change / Cambiar Chronopic firmware"]
+ for i in range(len(frame_1_statusbar_fields)):
+ self.frame_1_statusbar.SetStatusText(frame_1_statusbar_fields[i], i)
+ self.text_ctrl_2.SetMinSize((250, 27))
+ self.combo_box_1.SetMinSize((250,30))
+ # end wxGlade
+
+ def __do_layout(self):
+ # begin wxGlade: MyFrame.__do_layout
+ sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
+ sizer_3 = wx.BoxSizer(wx.VERTICAL)
+ sizer_2 = wx.StaticBoxSizer(self.sizer_2_staticbox, wx.VERTICAL)
+ sizer_4_copy = wx.StaticBoxSizer(self.sizer_4_copy_staticbox, wx.HORIZONTAL)
+ sizer_4 = wx.StaticBoxSizer(self.sizer_4_staticbox, wx.HORIZONTAL)
+ sizer_4.Add(self.text_ctrl_2, 0, wx.TOP|wx.BOTTOM|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
+ sizer_4.Add(self.button_2, 0, wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
+ sizer_3.Add(sizer_4, 0, wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)
+ sizer_4_copy.Add(self.combo_box_1, 0, wx.TOP|wx.BOTTOM|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5)
+ sizer_4_copy.Add(self.button_7, 0, wx.ALIGN_CENTER_VERTICAL, 0)
+ sizer_3.Add(sizer_4_copy, 0, wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5)
+ sizer_2.Add(self.gauge_1, 0, wx.LEFT|wx.RIGHT|wx.TOP|wx.EXPAND|wx.ADJUST_MINSIZE, 4)
+ sizer_2.Add((20, 10), 0, wx.ADJUST_MINSIZE, 0)
+ sizer_2.Add(self.button_6, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+ sizer_3.Add(sizer_2, 1, wx.ALL|wx.EXPAND, 5)
+ self.panel_1.SetAutoLayout(True)
+ self.panel_1.SetSizer(sizer_3)
+ sizer_3.Fit(self.panel_1)
+ sizer_3.SetSizeHints(self.panel_1)
+ sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
+ self.SetAutoLayout(True)
+ self.SetSizer(sizer_1)
+ sizer_1.Fit(self)
+ sizer_1.SetSizeHints(self)
+ self.Layout()
+ # end wxGlade
+ #--------------------------------------------
+ # Fin del codigo generado automaticamente
+ #--------------------------------------------
+
+
+ #------------------------------------------------------------------
+ #-- Funcion de retrollamada del boton de exploracion de ficheros
+ #------------------------------------------------------------------
+ def boton_abrir(self, event): # wxGlade: MyFrame.<event_handler>
+
+ #-- Abrir un dialogo de busqueda de ficheros
+ filechooser = wx.FileDialog(self,wildcard = "*.hex;*.HEX")
+
+ #-- Esperar a que el usuario seleccione el fichero
+ opcion = filechooser.ShowModal()
+
+ #-- Segun la opcion...
+ if opcion == wx.ID_OK:
+
+ #-- Se ha pulsado ok. Obtener el nombre del fichero
+ fichero = filechooser.GetPath()
+
+ #-- Meter el fichero en el entry "fichero .hex"
+ self.text_ctrl_2.SetValue(fichero)
+
+ else: #-- No se ha seleccionado ninguno
+ print "Cancel..."
+
+
+ #-----------------------------------------------------------------
+ #-- Funciones de retrollamada de los diferentes botones
+ #-----------------------------------------------------------------
+ def boton_grabar(self, event): # wxGlade: MyFrame.<event_handler>
+ self.download()
+
+
+ def boton_cancelar(self, event): # wxGlade: MyFrame.<event_handler>
+ self.cancelar = True
+
+
+ def boton_eco(self, event): # wxGlade: MyFrame.<event_handler>
+ self.download_program(libIris.Pic16_Firmware.echo)
+
+
+
+ #-------------------------------------
+ #-- Actualizar el interfaz
+ #-------------------------------------
+ def update(self):
+ while (self.app.Pending()):
+ self.app.Dispatch();
+
+ #------------------------------------------------------------
+ #-- Activar todos los botones relacionados con la descarga
+ #-- El boton de cancel se desactiva
+ #------------------------------------------------------------
+ def botones_modo_descarga(self):
+ #-- Cancelar: Deshabilitado
+ self.button_6.Disable()
+ #-- Resto: Habilitados
+ self.button_7.Enable()
+
+ #-----------------------------------------------------------------------
+ #-- Desactivar todos los botones de descarga. El de cancelar se activa
+ #-----------------------------------------------------------------------
+ def botones_modo_cancelar(self):
+ #-- Cancelar Activado, resto desactivados
+ self.button_6.Enable()
+ self.button_7.Disable()
+
+ #---------------------------------------------------------
+ #-- Metodo para descargar un fichero .hex en la skypic
+ #-- Se lee el nombre del fichero de la interfaz grafica
+ #---------------------------------------------------------
+ def download(self):
+
+ #----------------------------------------
+ #-- Abrir y parsear el fichero .hex
+ #----------------------------------------
+ #-- Obtener el nombre
+ file = str(self.text_ctrl_2.GetLineText(0))
+
+ #-- Si no hay ningun fichero especificado: Error
+ if file=="":
+ self.frame_1_statusbar.SetStatusText("Fichero .hex no especificado", 0)
+ return
+
+ #-- Realizar el parseo
+ try:
+ hr = libIris.IntelHex.HexReader (file)
+ except libIris.IntelHex.ReaderError,msg:
+ #-- Convertir el mensaje a una cadena
+ msg = "%s" % msg
+ self.frame_1_statusbar.SetStatusText(msg, 0)
+ return
+
+ #----------------------------------
+ #-- Realizar la descarga!!
+ #----------------------------------
+
+ #-- Obtener el programa en el formato correcto
+ program = hr.dataBlocks16()
+
+ self.download_program(program)
+
+ #------------------------------------------------------------------------
+ #-- Funcion de retrollamada de libIris. Segun el estado de la descarga
+ #-- Se hace una cosa u otra
+ #------------------------------------------------------------------------
+ def state(self,op,inc,total):
+ #-----------------------------
+ #-- Comienzo de descarga
+ #-----------------------------
+ if op==libIris.Pic16_Bootloader.WRITING_START:
+
+ #-- Barra de progreso a cero
+ self.gauge_1.SetValue(0)
+
+ #-- Actualizar barra de status
+ self.frame_1_statusbar.SetStatusText("Recording / Grabando", 0)
+ self.update()
+
+ return True
+
+
+ #------------------------------
+ #-- Incremento en la descarga
+ #------------------------------
+ elif op==libIris.Pic16_Bootloader.WRITING_INC:
+ self.gauge_1.SetValue(100*inc/total)
+ self.update()
+
+ #-- Comprobar si se ha apretado boton de Cancelar
+ if self.cancelar:
+ return False
+
+ return True
+
+ #-------------------------------
+ #-- Fin de la descarga
+ #-------------------------------
+ elif op==libIris.Pic16_Bootloader.WRITING_END:
+ self.gauge_1.SetValue(100)
+ self.frame_1_statusbar.SetStatusText("Complete / Completado", 0)
+ self.update()
+ return True
+
+ #---------------------------------------------------
+ #-- Comienzo de la identificacion del bootloader
+ #---------------------------------------------------
+ elif op==libIris.Pic16_Bootloader.IDENT_START:
+ #-- Hay que esperar a que detecte el Bootloader
+ self.frame_1_statusbar.SetStatusText("Press Reset on Chronopic / Pulse Reset en el Chronopic", 0)
+ self.update()
+ return True
+
+
+ #-----------------------------------------------------------------
+ #-- Respuesta no recibida del bootloader tras un mini-timeout
+ #-----------------------------------------------------------------
+ elif op==libIris.Pic16_Bootloader.IDENT_NACK:
+
+ #-- Mientras que el tiempo total acumulado sea menor que el
+ #-- TIMEOUT indicado, continuar esperando
+ self.update()
+
+ #-- Si apretado boton de cancelar abortar...
+ if self.cancelar:
+ return False
+
+ if total<=TIMEOUT:
+ return True
+ else :
+ return False
+
+
+ #----------------------------------------
+ #- Descargar un programa
+ #----------------------------------------
+ def download_program(self,prog):
+
+ #-- Poner la barra de progreso a 0
+ self.gauge_1.SetValue(0)
+ self.update()
+
+ #-- Desactivar flag de cancelacion
+ self.cancelar=False
+
+ #-- Si ya se habia abierto un puerto serie, cerrarlo
+ #-- Esto ha sido necesario ponerlo para que funcione
+ #-- bien en WINDOWS
+ if self.app.iris!=None:
+ self.app.iris.close()
+
+ #------------------------------------
+ #-- Abrir puerto serie
+ #------------------------------------
+ #-- Primero obtener el nombre del dispositivo serie
+ serialName=self.combo_box_1.GetValue()
+
+ try:
+ self.app.iris = libIris.Pic16_Bootloader.Iris(serialName,
+ logCallback=None)
+ except libIris.Pic16_Bootloader.IrisError,msg:
+
+ #-- Si hay error indicarlo en la barra de estado y abortar
+ msg = "%s" % msg
+ self.frame_1_statusbar.SetStatusText(msg, 0)
+ return
+
+ #-- Actualizar la sensibilidad de los botones
+ self.botones_modo_cancelar()
+ self.update()
+
+ try:
+ self.app.iris.download(prog,stateCallback=self.state)
+ except libIris.Pic16_Bootloader.IrisError,msg:
+ msg= "%s" % msg
+ self.frame_1_statusbar.SetStatusText(msg, 0)
+
+ #-- Poner botones en su estado inicial:
+ self.botones_modo_descarga()
+ return
+
+ #-- Poner botones en su estado inicial:
+ self.botones_modo_descarga()
+
+# end of class MyFrame
+
+
+#---------------------------------------------------------
+#-- Funcion para obtener la lista de puerto serie
+#-- Esto depende de la plataforma en la que se ejecute
+#---------------------------------------------------------
+def getSerialPorts():
+
+ #-- Windows
+ if os.name == 'nt':
+
+ #-- Se usan los nueve primeros puertos serie
+ return ["COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9"]
+
+ #-- Linux
+ elif os.name == 'posix':
+ return ["/dev/ttyUSB0","/dev/ttyUSB1"]
+
+ else:
+ return []
+
+
+class MyApp(wx.App):
+
+ def OnInit(self):
+ self.iris=None
+ frame = MyFrame(self,None, -1, "")
+ frame.Show(True)
+ self.SetTopWindow(frame)
+
+ #-- Anadir los nombres de los puertos serie al combobox
+ serialports = getSerialPorts()
+ for disp in serialports:
+ frame.combo_box_1.Append(disp)
+
+ return True
+
+
+def main():
+ app = MyApp(0)
+ app.MainLoop()
+
+
+if __name__ == "__main__":
+ main()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]