Te cuelgo mi ultima actualizacion Picuino, ya con un poco mas de codigo de AVR, segun el PDF "
AVR Assembler User Guide"
Aunque le falta un poco de trabajo, ya note unas cosas que podria mejorar todavia, pero te hago las preguntas asi ya directamente hago todo de una sola ves
BUFF_SIZE EQU 64 ; En bytes, y Multiplo de 8 debe ser
NUM_ROUND EQU 32 ; Cantidad de Rondas
ADDRESS_BUFFER_HIGH EQU 0x00 ; Direccion de base del buffer de datos, Solo si se usa direccion absoluta
ADDRESS_BUFFER_LOW EQU 0x00 ;
ADDRESS_KEY_HIGH EQU 0x00 ; Direccion de base de llaves,
ADDRESS_KEY_LOW EQU 0x00 ; Unica restriccion: 0x00 <= ZL <= 0xC0
XTEA_DELTA[3] EQU 0x9E ; MSB
XTEA_DELTA[2] EQU 0x37 ; Si XTEA < (0x100000000 / NUM_ROUND) no se produce Overflow, para caso de 32
XTEA_DELTA[1] EQU 0x79 ; es XTEA < 0x8000000 o que es lo mismo que XTEA <= 0x7FFFFFF
XTEA_DELTA[0] EQU 0xB9
SUM[3] EQU 0xC6 ; MSB, Precalculado con XTEA_DELTA * NUM_ROUND
SUM[2] EQU 0xEF ; Hecho asi para ahorrar espacio en instrucciones
SUM[1] EQU 0x37
SUM[0] EQU 0x20
.def Loop_Buff = r4
.def Round = r5
.def sum[0] = r6
.def sum[1] = r7
.def sum[2] = r8
.def sum[3] = r9
.def V0[0] = r10
.def V0[1] = r11
.def V0[2] = r12
.def V0[3] = r13
.def V1[0] = r14
.def V1[1] = r15
.def V1[2] = r16
.def V1[3] = r17
.def Vtemp0[0] = r18
.def Vtemp0[1] = r19
.def Vtemp0[2] = r20
.def Vtemp0[3] = r21
.def Vtemp1[0] = r22
.def Vtemp1[1] = r23
.def Vtemp1[2] = r24
.def Vtemp1[3] = r25
.def XL = r26
.def XH = r27
.def YL = r28
.def YH = r29
.def ZL = r30
.def ZH = r31
; Declaracion de espacio reservado en RAM para el Buffer, Aunque esto deberia haberse realizado antes con la UART
.DSEG
Buffer: .BYTE BUFF_SIZE
.CSEG
; ******************************************************************************
; XTAE_Init - Llamar antes de Iniciar la conversion, setea los punteros para el algortimo
;
; Entradas:
; ADDRES_KEY_* - CONST - Puntero a base de las llaves
;
; Salidas:
; -
;
; Pre-Requisitos:
; Haber creado una variable Buffer, y haberla llenado de datos.
;
; *****************************************************************************
XTEA_Init:
LDI YL,ADDRESS_BUFFER_LOW ; Y: Puntero de lectura/escritura, Y permite direccionamiento por offset
LDI YH,ADDRESS_BUFFER_HIGH
LDI ZH,ADDRESS_KEY_HIHG ; Z: Puntero a base de llave
LDI ZL,ADDRESS_KEY_LOW
;o, Aca hay que elegir si va a ser aboluta la direccion (arriba) o que lo maneje el linker (abajo)
LDI YL,low(Buffer) ; Y: Puntero de lectura/escritura, Y permite direccionamiento por offset
LDI YH,high(Buffer)
LDI ZH,ADDRESS_KEY_HIHG ; Z: Puntero a base de llave
LDI ZL,ADDRESS_KEY_LOW
RET
; ******************************************************************************
; Decodificacion XTEA, desencripta con XTEA un bloque de BUFF_SIZE bytes
;
; Entradas:
; Y - Puntero a base del Buffer en la SRAM
;
; Salidas:
; Y -> Reescribe el buffer de BUFF_SIZE de entrada
;
; Pre-Requisitos:
; Valor Inicial SUM pre-calculado
;
; *****************************************************************************
XTEA_Dec:
LDI Loop_Buff,(BUFF_SIZE/8) ;Recargamos el contador para saber cuando termino de recorrer el Buffer
LDI sum[3],SUM[3] ;Recargamos el valor de suma ya pre-calculada.
LDI sum[2],SUM[2]
LDI sum[1],SUM[1]
LDI sum[0],SUM[0]
XTEA_Dec_Aux:
LDD V0[0],Y+0 ; Cargo valores de V0
LDD V0[1],Y+1
LDD V0[2],Y+2
LDD V0[3],Y+3
LDD V1[0],Y+4 ; Cargo valores de V1
LDD V1[1],Y+5
LDD V1[2],Y+6
LDD V1[3],Y+7
RCALL Decodificacion ; Decodificacion
ST Y+,V0[0] ; Guardo los valores ya tratados
ST Y+,V0[1]
ST Y+,V0[2]
ST Y+,V0[3]
ST Y+,V1[0]
ST Y+,V1[1]
ST Y+,V1[2]
ST Y+,V1[3] ; Me deja Y ya preparado para los proximos 8 bytes
DEC Loop_Buff
BRNE XTEA_Dec_Aux
RET
; ******************************************************************************
; Subrutina de XTEA_Dec, While en C, Realiza las NUM_ROUND sobre 8 bytes
;
; Entradas:
; V0[4] - 4 bytes del primer valor
; v1[4] - 4 bytes del segundo valor
; NUM_ROUND - CONST - Indica la cantidad de veces que se produce el arlgoritmo
;
; Salidas:
; Y -> Reescribe 8 bytes del Buffer de entrada
;
; Pre-Requisitos:
; -
;
; *****************************************************************************
Decodificacion:
LDI Count,(NUM_ROUND*2)
Loop_while_aux:
RCALL Termino
SUB sum[0],XTEA_DELTA[0] ; sum -= XTEA_DELTA;
SBC sum[1],XTEA_DELTA[1]
SBC sum[2],XTEA_DELTA[2]
SBC sum[3],XTEA_DELTA[3]
MOVW Vtemp0[0],V1[0] ;Cambio de lugar v0 y v1
MOVW Vtemp0[2],V1[2]
MOVW V1[0],V0[0]
MOVW V1[2],V0[2]
MOVW V0[0],Vtemp0[0]
MOVW V0[2],Vtemp0[2]
RCALL Termino
MOVW Vtemp0[0],V1[0] ;Cambio de lugar v0 y v1 , para la proxima ronda, o para cuando hay que depositarlo
MOVW Vtemp0[2],V1[2]
MOVW V1[0],V0[0]
MOVW V1[2],V0[2]
MOVW V0[0],Vtemp0[0]
MOVW V0[2],Vtemp0[2]
DEC Count
BRNE Loop_while_aux
RET
; ******************************************************************************
; Subrutina de Decodificacion, procede a realizar lo siguiente:
;
; v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]) Para Count Par
; v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[sum & 3]) Para Count Impar
;
; Entradas:
; V[4] - 4 bytes
; Z - Puntero a base de las llaves en la SRAM
; Count - Indicador de que ronda va
;
; Salidas:
; v[4] - 4 bytes
;
; Pre-Requisitos:
; -
;
; *****************************************************************************
Termino:
LDI ZL,ADDRESS_KEY_LOW ; Recargo valor de Z con el valor original, para el proximo termino, lo hago aca para ahorrar espacio, ademas al comienzo para que se mas facil verlo para cambiarlo
MOVW Vtemp0[0],V0[0] ; Vtemp0 para (v0<<4) y Vtemp1 para (V0 >> 5)
MOVW Vtemp0[2],V0[2]
MOVW Vtemp1[0],V0[0]
MOVW Vtemp1[2],V0[2]
LDI R0,4
RotateLeftv0: ; (v0 << 4)
LSL Vtemp0[0]
ROL Vtemp0[1]
ROL Vtemp0[2]
ROL Vtemp0[3] ; Por ser de 32 bits se deberian perder los bits que salgan de aca
DEC R0
BRNE RotateLeftv0
LDI R0,5
RotateRightv0: ; (V0 >> 5 )
LSR Vtemp1[3]
ROR Vtemp1[2]
ROR Vtemp1[1]
ROR Vtemp1[0]
DEC R0
BRNE RotateRightv0
EOR Vtemp0[0],Vtemp1[0] ; (v0 << 4) ^ (v0 >> 5)
EOR Vtemp0[1],Vtemp1[1]
EOR Vtemp0[2],Vtemp1[2]
EOR Vtemp0[3],Vtemp1[3]
ADD Vtemp0[0],V0[0] ; ((v0 << 4) ^ (v0 >> 5)) + v0
ADC Vtemp0[1],V0[1] ; Vtemp0 = ((v0 << 4) ^ (v0 >> 5)) + v0
ADC Vtemp0[2],V0[2]
ADC Vtemp0[3],V0[3]
SBRS Count,0
RJMP Primer_t ; Si es Par indica que es el primero. Si es impar es el segundo
MOV R0,sum[0] ; sum & 3
LSL R0
LSL R0
RJMP Save_Sum
Primer_t:
MOV R0,sum[1] ; sum>>11 & 3
LSR R0
Save_Sum:
ANDI R0,0x0C ; 0000 aa00
ADD ZL,R0 ; Le sumo el valor de R0 o lo que es igual a 4 * index
LD Vtemp1[0],Z+ ; key[sum&3] o key[(key>>11) & 3]
LD Vtemp1[1],Z+
LD Vtemp1[2],Z+
LD Vtemp1[3],Z+
ADD Vtemp1[0],sum[0] ; sum + key[(sum>>11) & 3]
ADC Vtemp1[1],sum[1] ; Aux = sum + key[(sum>>11) & 3]
ADC Vtemp1[2],sum[2]
ADC Vtemp1[3],sum[3]
EOR Vtemp0[0],Vtemp1[0] ; (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3])
EOR Vtemp0[1],Vtemp1[1] ; Vtemp[0]
EOR Vtemp0[2],Vtemp1[2]
EOR Vtemp0[3],Vtemp1[3]
SUB V1[0],Vtemp0[0] ; v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3])
SBC V1[1],Vtemp0[1]
SBC V1[2],Vtemp0[2]
SBC V1[3],Vtemp0[3] ; si ocurrio overflow, lo lamento
RET
Tengo una serie de preguntas mas por hacerte. Tanto a vos como a planeta que tiene mas experiencia.
1-
XTEA_DELTA si se puede seleccionar un valor tal que XTEA_DELTA <= 0x7FFFFFF
Ahi no se produciria un overflow, tendria que ver si es que realmente implica algo el que no exista ese ultimo byte, ya que si lo pensas en una resta a la sumo te queda el carry a restarle a la parte "superior", asi que se podria decir que no afectaria
Vos decidiras si es que deseas cambiarlo o no
2-
La llave donde va a ir? Memoria de programa, o RAM con unas "constantes" tal cual ves los EQU en el codigo?
Si es Memoria de programa debo cambiar algunas instrucciones (creo que achicando en 2 instrucciones), y tenes que pensar que van a ir 16 bytes mas en la FLASH
Si es la RAM, se debe agregar muchas mas instrucciones para inicializar esos datos en la RAM y poder tomarlos desde alli, no quitaria nada y agregaria unas 18 instrucciones
Velocidad vs Espacio
3-
Que tipo de direccionamiento queres? Podes elegir que el linker te "reserve" el espacio en la RAM y obtener la direccion con high(variable) y low(variable) o.. podes hacerlo con un direccionamiento absoluto a traves de los EQU
Si te fijas en XTEA_Init, hay 2 ejemplos, tengo que arreglarlo a eso para que quede 1 solo, y tambien lo de las llaves, Por eso cree un XTEA_Init, segun sea el caso que elijas de estas preguntas, desapareceria esa funcion o no.
Definir el buffer lo deberias hacer con la UART (me refiero a lo de "reservar" el espacio de la RAM ), y directamente desde aca pedis la direccion de inicio para comenzar.
4-
Tenes pensado poner los valores de las llaves en algun valor de direccion en particular? se puede usar el .ORG para eso, y .DW para almacenar los valores en la FLASH , fijate que hay una restriccion asi como esta realizado el codigo sobre los valroes de direccion de las llaves, si lo queres para que este en cualquier posicion, entonces deberia agregar unas 2 instrucciones mas. Lo hice asi por el espacio :/
5-
Debo salvar algun registro a la pila por algun valor que estes utilizando ?
Por que no se me ocurre alguno, tal ves el de Z, o Y, que son los punteros, pero no creo que los necesites ya que una ves que pasas la decodificacion, fue por que recibiste todo.
6-
Vas a crear solamente 1 Buffer de 64 bytes o mas?, Si tenes pensado crear 4 buffer solo cambia el valor de BUFFER_SIZE a 4*64 , Solo prestar atencion que debe ser multiplo de 8
7-
Como estan guardados los datos? Ya que de tomarlo de otra punta terminaria mal, esto para acomodar cuando los cargo/grabo a la RAM.
Ejemplo, los pimeros 8 bytes 0x12345678 0x12345678
Guardados asi:
0x12 0x34 0x56 0x78 0x12 0x34 0x56 0x78
o asi:
0x78 0x56 0x34 0x12 0x78 0x56 0x34 0x12
Esto va a depender de tu UART y cmo los envies
8-
Tenes idea si se permiten los corchetes en los nombres? Yo lo hize asi por que era mas facil para mi darme cuenta
Resuelta estas dudas creo que termino el codigo, Aunque sin probarlo :/
Y ya reviso tu codigo haber si me das una mejor idea o si es lo mismo realizado en ASM