Estoy trabajando con Infineon del XMC4500 Relajarse Kit y estoy tratando de extraer el firmware a través de un único pin GPIO.
Mi muy ingenua idea es volcar de a un bit por vez a través del pin GPIO y de alguna manera "oler" los datos con un analizador lógico.
Pseudocódigo:
while(word by word memory copy hasn't finished)
...
register = value;
temp_value = value AND 0x1;
pin = temp_value;
value = value >> 1;
...
Estoy en el camino correcto? ¿Alguien tiene una mejor/mejor idea de cómo archivar esto?
### EDIT ###
En realidad un requisito de mi (shell)código sería el que debe ser muy pequeño. He encontrado este ingenioso truco sobre cómo dump del firmware mediante el parpadeo de los LEDs.
Sin embargo, yo estoy luchando para recibir valores correctos con Saleae Analizador lógico.
Básicamente lo que estoy haciendo es:
- Configurar el pin GPIO las direcciones de salida
- Parpadeo LED1 (pin 1.1) con un reloj SPI (serial clock)
- Parpadeo LED2 (pin 1.0) con los bits de datos (SPI MOSI)
- Oler los pines con un analizador lógico
Aquí está mi código C:
#include "XMC4500.h"
#define DEL 1260
void init()
{
// P1.0 output, push pull
PORT1->IOCR0 = 0x80UL << 0;
// P1.1 output, push pull
PORT1->IOCR0 |= 0x80UL << 8;
}
void delay(int i) {
while(--i) {
asm("nop\n");
asm("nop\n");
}
}
// Sets a pin to high
// P1.0 = SPI MOSI
// P1.1 = SPI CLOCK
void output_high(int i) {
// P1.0 high
if(i == 0) {
PORT1->OUT |= 0x1UL;
}
// P1.1 high
if(i == 1) {
PORT1->OUT |= 0x2UL;
}
}
// Sets a pin to low
// P1.0 = SPI MOSI
// P1.1 = SPI CLOCK
void output_low(int i) {
// P1.0 low
if(i == 0) {
PORT1->OUT &= (~0x1UL);
}
// P1.1 low
if(i == 1) {
PORT1->OUT &= (~0x2UL);
}
}
// SPI bit banging
void spi_send_byte(unsigned char data)
{
int i;
// Send bits 7..0
for (i = 0; i < 8; i++)
{
// Sets P1.1 to low (serial clock)
output_low(1);
// Consider leftmost bit
// Set line high if bit is 1, low if bit is 0
if (data & 0x80)
// Sets P1.0 to high (MOSI)
output_high(0);
else
// Sets P1.0 to low (MOSI)
output_low(0);
delay(DEL);
// Sets P1.1 to high (Serial Clock)
output_high(1);
// Shift byte left so next bit will be leftmost
data <<= 1;
}
}
int main() {
init();
while(1) {
spi_send_byte('t');
spi_send_byte('e');
spi_send_byte('s');
spi_send_byte('t');
}
return 0;
}
### La 2ª EDICIÓN de ###
Finalmente ordenados. El Dumping de memoria flash está trabajando muy bien con el siguiente código:
#include "XMC4500.h"
// SPI bit banging
void spi_send_word(uint32_t data)
{
int i;
// LSB first, 32 bits per transfer
for (i = 0; i < 32; i++)
{
// set pin 1.1 to low (SPI clock)
PORT1->OUT &= (~0x2UL);
// set line high if bit is 1, low if bit is 0
if (data & 0x1) {
// set pin 1.0 to high (SPI MOSI)
PORT1->OUT |= 0x1UL;
}
else {
// set pin 1.0 to low (SPI MOSI)
PORT1->OUT &= (~0x1UL);
}
// set pin 1.1 to high (SPI clock)
PORT1->OUT |= 0x2UL;
data >>= 1;
}
}
int main() {
// start dumping at memory address 0x08000000
unsigned int *p;
p = (uint32_t *)(0x08000000u);
// configure pin 1.0 and pin 1.1 as output (push-pull)
PORT1->IOCR0 = 0x8080UL;
while(1) {
spi_send_word(*p);
p++;
}
}