2
|
1 #include <stdio.h>
|
|
2 #include <stdlib.h>
|
|
3 #include <string.h>
|
3
|
4 #include <util/delay.h>
|
2
|
5 #include "avriotools.h"
|
|
6 #include "cmd_proto.h"
|
|
7 #include "jtag.h"
|
|
8
|
|
9 #define BAUD_RATE 420000
|
|
10
|
3
|
11 static char client_buf[256 + CP_CMD_OVERHEAD];
|
2
|
12
|
|
13 static
|
|
14 void ack(int seq) {
|
|
15 int i;
|
|
16 int sz;
|
|
17
|
|
18 sz = cmd_proto_cmd_fill(client_buf, seq, CPCMD_ACK, 0);
|
|
19
|
|
20 for(i = 0; i < sz; i++)
|
|
21 uart_putc(client_buf[i]);
|
|
22 }
|
|
23
|
|
24 static
|
|
25 void nak(int seq, const char *msg) {
|
|
26 int i;
|
|
27 int sz;
|
|
28
|
|
29 memcpy(client_buf + CP_CMD_HEAD_SZ, msg, strlen(msg));
|
|
30 sz = cmd_proto_cmd_fill(client_buf, seq, CPCMD_NAK, 7);
|
|
31
|
|
32 for(i = 0; i < sz; i++)
|
|
33 uart_putc(client_buf[i]);
|
|
34 }
|
|
35
|
|
36 static
|
|
37 void send_client(const char *buf, int bsz) {
|
|
38 int i;
|
|
39
|
|
40 for(i = 0; i < bsz; i++)
|
|
41 uart_putc(buf[i]);
|
|
42 }
|
|
43
|
3
|
44 void flash_init(void) {
|
|
45 pin_mode(&PORTB, PINB4, PM_OUTPUT);
|
|
46 pin_mode(&PORTB, PINB5, PM_OUTPUT);
|
|
47 pin_lo(PORTB, PINB4);
|
|
48 pin_lo(PORTB, PINB5);
|
|
49 }
|
|
50
|
|
51 void flash_led(void) {
|
|
52 pin_hi(PORTB, PINB4);
|
|
53 _delay_ms(50);
|
|
54 pin_lo(PORTB, PINB4);
|
|
55 }
|
|
56
|
2
|
57 #define GET_DATA_BITS(data) ((data)[0] | ((data)[1] << 8))
|
|
58
|
|
59 int main(int argc, char * const argv[]) {
|
|
60 cp_cmd_t *cmd;
|
|
61 cmd_proto_t *cp;
|
|
62 int c, nbits;
|
|
63 int bsz;
|
3
|
64 static char buf[16];
|
2
|
65
|
3
|
66 flash_init();
|
|
67 flash_led();
|
|
68
|
2
|
69 uart_init(BAUD_RATE);
|
3
|
70 jtag_init();
|
2
|
71 cp = cmd_proto_new();
|
3
|
72
|
2
|
73 while(1) {
|
|
74 uart_getc(c);
|
|
75 cmd = cmd_proto_rcv(cp, c);
|
3
|
76 if(cmd == NULL)
|
|
77 continue;
|
2
|
78
|
|
79 if(cmd == &BAD_CMD) {
|
|
80 nak(cmd->seq, "BAD CMD");
|
|
81 continue;
|
|
82 }
|
|
83
|
|
84 if(cmd == &CSUM_ERR_CMD) {
|
|
85 nak(cmd->seq, "CSUM ERR");
|
|
86 continue;
|
|
87 }
|
3
|
88
|
2
|
89 switch(cmd->code) {
|
|
90 case CPCMD_PING:
|
|
91 memcpy(client_buf + CP_CMD_HEAD_SZ, cmd->data, cmd->data_sz);
|
|
92 bsz = cmd_proto_cmd_fill(client_buf, cmd->seq,
|
|
93 CPCMD_PONG, cmd->data_sz);
|
|
94 send_client(client_buf, bsz);
|
|
95 break;
|
|
96
|
|
97 case CPCMD_SHIFT_TDI:
|
|
98 nbits = GET_DATA_BITS(cmd->data);
|
|
99 jtag_shift(cmd->data + 2, nbits);
|
|
100 ack(cmd->seq);
|
|
101 break;
|
|
102
|
|
103 case CPCMD_SHIFT_TMS:
|
|
104 nbits = GET_DATA_BITS(cmd->data);
|
|
105 jtag_tms(cmd->data + 2, nbits);
|
|
106 ack(cmd->seq);
|
|
107 break;
|
|
108
|
|
109 case CPCMD_SHIFT_TDI_TDO:
|
|
110 nbits = GET_DATA_BITS(cmd->data);
|
|
111 jtag_shift_inout(cmd->data + 2,
|
|
112 client_buf + CP_CMD_HEAD_SZ + 2,
|
|
113 nbits);
|
|
114
|
|
115 client_buf[CP_CMD_HEAD_SZ] = nbits & 0xff;
|
|
116 client_buf[CP_CMD_HEAD_SZ + 1] = nbits >> 8;
|
|
117
|
|
118 bsz = cmd_proto_cmd_fill(client_buf, cmd->seq,
|
|
119 CPCMD_DATA, (nbits + 23) / 8);
|
|
120 send_client(client_buf, bsz);
|
|
121 break;
|
|
122
|
7
|
123 case CPCMD_TRST:
|
|
124 jtag_trst();
|
|
125 bsz = cmd_proto_cmd_fill(client_buf, cmd->seq,
|
|
126 CPCMD_ACK, 0);
|
|
127 send_client(client_buf, bsz);
|
|
128 break;
|
|
129
|
2
|
130 default:
|
|
131 sprintf(buf, "CODE 0x%02x", cmd->code);
|
|
132 nak(cmd->seq, buf);
|
|
133 }
|
|
134 }
|
|
135 }
|