Project

General

Profile

Download (3.28 KB) Statistics
| Branch: | Tag: | Revision:
1

    
2
#include <stdint.h>
3
#include <stdio.h>
4
#include <sys/types.h>
5

    
6
#include "soft_uart.h"
7

    
8
static inline uint32_t samples_per_etu(struct suart_data *su)
9
{
10
	return su->samplerate / su->recip_etu;
11
}
12

    
13
static const char *state_strings[] = {
14
	[WAIT_RESET]		= "WAIT_RESET",
15
	[IN_RESET]		= "IN_RESET",
16
	[WAIT_START_FALLEDGE]	= "WAIT_START_FALLEDGE",
17
	[WAIT_START_ETU07]	= "WAIT_START_ETU07",
18
	[RX_BITS]		= "RX_BITS",
19
	[POST_RX_WAIT_HIGH]	= "POST_RX_WAIT_HIGH",
20
};
21

    
22
static void change_state(struct suart_data *su, enum suart_state new_state)
23
{
24
	printf("State change: %s -> %s\n", state_strings[su->state], state_strings[new_state]);
25
	su->state = new_state;
26
}
27

    
28
/* According to ISO/IEC 7816-3 Section 6.1.2 */
29
int suart_process_sample_bit(struct suart_data *suart, uint8_t clk_bit, uint8_t rst_bit, uint8_t sample_bit)
30
{
31
	uint32_t samp_per_etu = samples_per_etu(suart);
32
	uint8_t next_bit;
33

    
34
	if (rst_bit == 0 && suart->state != IN_RESET) {
35
		change_state(suart, IN_RESET);
36
		/* FIXME: reset some other things? */
37
	}
38

    
39
	switch (suart->state) {
40
	case WAIT_RESET:
41
		if (rst_bit == 0)
42
			change_state(suart, IN_RESET);
43
		break;
44
	case IN_RESET:
45
		if (rst_bit == 1)
46
			change_state(suart, WAIT_START_FALLEDGE);
47
		break;
48
	case WAIT_START_FALLEDGE:
49
		if (sample_bit == 0) {
50
			suart->sample_after_sbit = 0;
51
			suart->bits_pending = suart->num_bits + 1;
52
			change_state(suart, WAIT_START_ETU07);
53
		}
54
		break;
55
	case WAIT_START_ETU07:
56
		if (suart->sample_after_sbit > (samp_per_etu/2)+1) {
57
			if (sample_bit != 0) {
58
				printf("!!!!!!!!!!!!!!!!!!!!! start bit after 0.7 * ETU no longer low\n");
59
			} else {
60
				change_state(suart, RX_BITS);
61
				suart->rx_char = 0;
62
			}
63
		}
64
		/* else stay in this state until the condition is true */
65
		break;
66
	case RX_BITS:
67
		next_bit = suart->num_bits+1 - suart->bits_pending;
68
#if 0
69
		printf("\tRX_BITS: IO = %u, next_bit = %u, sample_after_sbit = %u, samp_per_etu = %u, required_after_sbit = %u\n",
70
			sample_bit, next_bit, suart->sample_after_sbit, samp_per_etu,
71
			(samp_per_etu/2) + ((next_bit+1) * samp_per_etu));
72
#endif
73
		if (suart->sample_after_sbit > (samp_per_etu/2) + ((next_bit+1) * samp_per_etu)) {
74
			/* check if this is the parity bit */
75
			//printf("new_bit = %u\n", sample_bit);
76
			if (next_bit == suart->num_bits) {
77
				/* FIXME calculate parity */
78
			} else {
79
				/* an actual data bit */
80
				/* Section 6.1.4.1 */
81
				if (suart->convention == INVERSE_CONVENTION) {
82
					if (sample_bit == 1)
83
						sample_bit = 0x00;
84
					else
85
						sample_bit = 0x80;	
86
					/* shift existing patter one to the right */
87
					suart->rx_char = suart->rx_char >> 1;
88
					/* mask in the additional bit */
89
					suart->rx_char |= sample_bit;
90
				} else {
91
					suart->rx_char |= (sample_bit << next_bit);
92
				}
93
			}
94
			suart->bits_pending--;
95
		}
96

    
97
		if (suart->bits_pending == 0) {
98

    
99
			/* output the character that we decoded */
100
			printf("Output Byte: %02x\n", suart->rx_char);
101

    
102
			change_state(suart, POST_RX_WAIT_HIGH);
103
		}
104
		break;
105
	case POST_RX_WAIT_HIGH:
106
		if (sample_bit == 0x01) {
107
			/* return to initial state */
108
			change_state(suart, WAIT_START_FALLEDGE);
109
		}
110
		break;
111
	}
112
	suart->sample_after_sbit++;
113
}
114

    
115
void suart_init(struct suart_data *su)
116
{
117
	su->state = WAIT_RESET;
118
	su->convention = DIRECT_CONVENTION;
119
	printf("Samplerate = %u\n", su->samplerate);
120
	printf("etu = 1 / %u\n", su->recip_etu);
121
	printf("samp_per_etu = %u\n", samples_per_etu(su));
122
}
(6-6/7)
Add picture from clipboard (Maximum size: 48.8 MB)