Import old unfinished FT232R bit-banging code for sim sniffing

This code never really worked due to large sample clock jitter, lost
USB messages and the lack of CLK sniffing ability
This commit is contained in:
Harald Welte 2010-11-18 22:59:40 +01:00
parent 1a37d4095f
commit 41f028df96
7 changed files with 302 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,9 @@
___________________________________-------
__________---_______----___---------------
____________________________________-----------
____________________________________-------
___________________________________---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
___---------____---____---------___----------------------
___________________________________---------------------------------------------------------------------------------------------------------------------

10
ft232r/Makefile Normal file
View File

@ -0,0 +1,10 @@
LDFLAGS=-lftdi
bitbang: bitbang.o soft_uart.o
$(CC) $(LDFLAGS) -o $@ $^
clean:
rm -f bitbang bitbang.o soft_uart.o
%: %.o
$(CC) $(LDFLAGS) -o $@ $^

120
ft232r/bitbang.c Normal file
View File

@ -0,0 +1,120 @@
/* This program is distributed under the GPL, version 2 */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ftdi.h>
#include "soft_uart.h"
static unsigned char last;
static struct suart_data su;
#define CLK_BIT 0x20
#define RST_BIT 0x08
#define IO_BIT 0x02
static void handle_sample(unsigned char c)
{
uint8_t rst = 0, io = 0, clk = 0;
if (c & RST_BIT)
rst = 1;
if (c & CLK_BIT)
clk = 1;
if (c & IO_BIT)
io = 1;
#if 0
if ((c & 0xf) != last) {
printf("%02x ", c & ~(CLK_BIT|IO_BIT));
}
last = c;
#endif
#if 0
if (c & RST_BIT)
printf("-");
else
printf("_");
#endif
#if 1
if (c & IO_BIT)
printf("-");
else
printf("_");
#endif
//suart_process_sample_bit(&su, clk, rst, io);
}
#define OVERSAMPLING 4
int main(int argc, char **argv)
{
struct ftdi_context ftdic;
int f,i;
unsigned char buf[1<<16];
//unsigned int sample_rate = 12900 * OVERSAMPLING; /* 192kS/s */
unsigned int sample_rate = (1 << 18);
memset(&su, 0, sizeof(su));
if (ftdi_init(&ftdic) < 0)
{
fprintf(stderr, "ftdi_init failed\n");
return EXIT_FAILURE;
}
f = ftdi_usb_open(&ftdic, 0x0403, 0x6001);
if (f < 0 && f != -5)
{
fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(&ftdic));
exit(-1);
}
printf("ftdi open succeeded: %d\n",f);
printf("enabling bitbang mode\n");
//ftdi_disable_bitbang(&ftdic);
//ftdi_set_line_property(&ftdic, 8, 1, EVEN);
ftdi_set_bitmode(&ftdic, 0x0, BITMODE_BITBANG);
ftdi_read_data_set_chunksize(&ftdic, sizeof(buf));
ftdi_set_latency_timer(&ftdic, 255);
//ftdi_set_latency_timer(&ftdic, 1);
//f = ftdi_set_baudrate(&ftdic, 300000);
f = ftdi_set_baudrate(&ftdic, sample_rate/16);
if (f < 0) {
fprintf(stderr, "error setting baudrate\n");
exit(1);
}
su.samplerate = sample_rate;
su.recip_etu = sample_rate / OVERSAMPLING;
su.num_bits = 8;
suart_init(&su);
while (1) {
memset(buf, 0, sizeof(buf));
f = ftdi_read_data(&ftdic, buf, sizeof(buf));
if (f < 0) {
fprintf(stderr,"read failed for 0x%x, error %d (%s)\n",buf[0],f, ftdi_get_error_string(&ftdic));
exit(1);
}
//printf("ftdi returned %u (of %u)\n", f, sizeof(buf));
for (i = 0; i < f; i++) {
handle_sample(buf[i]);
}
fflush(stdout);
//num_samples += f;
}
printf("\n");
printf("disabling bitbang mode\n");
ftdi_disable_bitbang(&ftdic);
ftdi_usb_close(&ftdic);
ftdi_deinit(&ftdic);
}

5
ft232r/samples.txt Normal file
View File

@ -0,0 +1,5 @@
___----___----___----___----_______-------
___----___----___---____---_______-------
____---____---____---_____---_______----------
____---___----___----___----_______--------
___----___----___----____----_______-------

122
ft232r/soft_uart.c Normal file
View File

@ -0,0 +1,122 @@
#include <stdint.h>
#include <stdio.h>
#include <sys/types.h>
#include "soft_uart.h"
static inline uint32_t samples_per_etu(struct suart_data *su)
{
return su->samplerate / su->recip_etu;
}
static const char *state_strings[] = {
[WAIT_RESET] = "WAIT_RESET",
[IN_RESET] = "IN_RESET",
[WAIT_START_FALLEDGE] = "WAIT_START_FALLEDGE",
[WAIT_START_ETU07] = "WAIT_START_ETU07",
[RX_BITS] = "RX_BITS",
[POST_RX_WAIT_HIGH] = "POST_RX_WAIT_HIGH",
};
static void change_state(struct suart_data *su, enum suart_state new_state)
{
printf("State change: %s -> %s\n", state_strings[su->state], state_strings[new_state]);
su->state = new_state;
}
/* According to ISO/IEC 7816-3 Section 6.1.2 */
int suart_process_sample_bit(struct suart_data *suart, uint8_t clk_bit, uint8_t rst_bit, uint8_t sample_bit)
{
uint32_t samp_per_etu = samples_per_etu(suart);
uint8_t next_bit;
if (rst_bit == 0 && suart->state != IN_RESET) {
change_state(suart, IN_RESET);
/* FIXME: reset some other things? */
}
switch (suart->state) {
case WAIT_RESET:
if (rst_bit == 0)
change_state(suart, IN_RESET);
break;
case IN_RESET:
if (rst_bit == 1)
change_state(suart, WAIT_START_FALLEDGE);
break;
case WAIT_START_FALLEDGE:
if (sample_bit == 0) {
suart->sample_after_sbit = 0;
suart->bits_pending = suart->num_bits + 1;
change_state(suart, WAIT_START_ETU07);
}
break;
case WAIT_START_ETU07:
if (suart->sample_after_sbit > (samp_per_etu/2)+1) {
if (sample_bit != 0) {
printf("!!!!!!!!!!!!!!!!!!!!! start bit after 0.7 * ETU no longer low\n");
} else {
change_state(suart, RX_BITS);
suart->rx_char = 0;
}
}
/* else stay in this state until the condition is true */
break;
case RX_BITS:
next_bit = suart->num_bits+1 - suart->bits_pending;
#if 0
printf("\tRX_BITS: IO = %u, next_bit = %u, sample_after_sbit = %u, samp_per_etu = %u, required_after_sbit = %u\n",
sample_bit, next_bit, suart->sample_after_sbit, samp_per_etu,
(samp_per_etu/2) + ((next_bit+1) * samp_per_etu));
#endif
if (suart->sample_after_sbit > (samp_per_etu/2) + ((next_bit+1) * samp_per_etu)) {
/* check if this is the parity bit */
//printf("new_bit = %u\n", sample_bit);
if (next_bit == suart->num_bits) {
/* FIXME calculate parity */
} else {
/* an actual data bit */
/* Section 6.1.4.1 */
if (suart->convention == INVERSE_CONVENTION) {
if (sample_bit == 1)
sample_bit = 0x00;
else
sample_bit = 0x80;
/* shift existing patter one to the right */
suart->rx_char = suart->rx_char >> 1;
/* mask in the additional bit */
suart->rx_char |= sample_bit;
} else {
suart->rx_char |= (sample_bit << next_bit);
}
}
suart->bits_pending--;
}
if (suart->bits_pending == 0) {
/* output the character that we decoded */
printf("Output Byte: %02x\n", suart->rx_char);
change_state(suart, POST_RX_WAIT_HIGH);
}
break;
case POST_RX_WAIT_HIGH:
if (sample_bit == 0x01) {
/* return to initial state */
change_state(suart, WAIT_START_FALLEDGE);
}
break;
}
suart->sample_after_sbit++;
}
void suart_init(struct suart_data *su)
{
su->state = WAIT_RESET;
su->convention = DIRECT_CONVENTION;
printf("Samplerate = %u\n", su->samplerate);
printf("etu = 1 / %u\n", su->recip_etu);
printf("samp_per_etu = %u\n", samples_per_etu(su));
}

35
ft232r/soft_uart.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef _SOFT_UART_H
#define _SOFT_UART_H
enum suart_state {
WAIT_RESET,
IN_RESET,
WAIT_START_FALLEDGE,
WAIT_START_ETU07,
RX_BITS,
POST_RX_WAIT_HIGH,
};
enum suart_convention {
DIRECT_CONVENTION,
INVERSE_CONVENTION,
};
struct suart_data {
uint32_t samplerate; /* samples per second input rate */
uint32_t recip_etu; /* 1/etu */
uint8_t num_bits;
enum suart_state state;
enum suart_convention convention;
uint32_t sample_after_sbit;
uint8_t bits_pending;
uint8_t rx_char;
};
int suart_process_sample_bit(struct suart_data *suart, uint8_t clk_bit, uint8_t rst_bit, uint8_t sample_bit);
void suart_init(struct suart_data *su);
#endif