I am working with an Infineon XMC4500 Relax Kit and I am trying to extract the firmware through a single GPIO pin.
My most naive idea is to flush one bit at a time through the GPIO pin and somehow “sniff” the data using a logic analyzer.
pseudo code:
while(word by word memory copy hasn't finished)
...
register = value;
temp_value = value AND 0x1;
pin = temp_value;
value = value >> 1;
...
Am I on the right track? Does anyone have a better / better idea how to do this?
### EDIT ###
Actually, the requirement of my (shell) code would be that it should be really tiny. I found this great trick on how to reset firmware by flashing LEDs.
However, I am struggling to get the correct values using the Analyzer Analyzer.
Basically what I do:
- Configure GPIO output directions for output
- 1 ( 1.1) ( SPI)
- Blink LED2 ( 1.0) (SPI MOSI)
- Sniff pins
C:
#include "XMC4500.h"
#define DEL 1260
void init()
{
PORT1->IOCR0 = 0x80UL << 0;
PORT1->IOCR0 |= 0x80UL << 8;
}
void delay(int i) {
while(--i) {
asm("nop\n");
asm("nop\n");
}
}
void output_high(int i) {
if(i == 0) {
PORT1->OUT |= 0x1UL;
}
if(i == 1) {
PORT1->OUT |= 0x2UL;
}
}
void output_low(int i) {
if(i == 0) {
PORT1->OUT &= (~0x1UL);
}
if(i == 1) {
PORT1->OUT &= (~0x2UL);
}
}
void spi_send_byte(unsigned char data)
{
int i;
for (i = 0; i < 8; i++)
{
output_low(1);
if (data & 0x80)
output_high(0);
else
output_low(0);
delay(DEL);
output_high(1);
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;
}
### 2nd EDIT ###
- :
#include "XMC4500.h"
void spi_send_word(uint32_t data)
{
int i;
for (i = 0; i < 32; i++)
{
PORT1->OUT &= (~0x2UL);
if (data & 0x1) {
PORT1->OUT |= 0x1UL;
}
else {
PORT1->OUT &= (~0x1UL);
}
PORT1->OUT |= 0x2UL;
data >>= 1;
}
}
int main() {
unsigned int *p;
p = (uint32_t *)(0x08000000u);
PORT1->IOCR0 = 0x8080UL;
while(1) {
spi_send_word(*p);
p++;
}
}