view src/avr_jtag.c @ 2:abf221bf3ce4

AVR JTAG server.
author Thinker K.F. Li <thinker@branda.to>
date Sat, 21 Feb 2009 23:06:50 +0800
parents
children e410832c3280
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "avriotools.h"
#include "cmd_proto.h"
#include "jtag.h"

#define BAUD_RATE 420000

static char client_buf[255 + CP_CMD_OVERHEAD];

static
void ack(int seq) {
    int i;
    int sz;
    
    sz = cmd_proto_cmd_fill(client_buf, seq, CPCMD_ACK, 0);
    
    for(i = 0; i < sz; i++)
	uart_putc(client_buf[i]);
}

static
void nak(int seq, const char *msg) {
    int i;
    int sz;
    
    memcpy(client_buf + CP_CMD_HEAD_SZ, msg, strlen(msg));
    sz = cmd_proto_cmd_fill(client_buf, seq, CPCMD_NAK, 7);
    
    for(i = 0; i < sz; i++)
	uart_putc(client_buf[i]);
}

static
void send_client(const char *buf, int bsz) {
    int i;
    
    for(i = 0; i < bsz; i++)
	uart_putc(buf[i]);
}

#define GET_DATA_BITS(data) ((data)[0] | ((data)[1] << 8))

int main(int argc, char * const argv[]) {
    cp_cmd_t *cmd;
    cmd_proto_t *cp;
    int c, nbits;
    int bsz;
    char buf[16];
    
    jtag_init();
    uart_init(BAUD_RATE);

    cp = cmd_proto_new();
    
    while(1) {
	uart_getc(c);
	cmd = cmd_proto_rcv(cp, c);

	if(cmd == &BAD_CMD) {
	    nak(cmd->seq, "BAD CMD");
	    continue;
	}
	
	if(cmd == &CSUM_ERR_CMD) {
	    nak(cmd->seq, "CSUM ERR");
	    continue;
	}
	
	switch(cmd->code) {
	case CPCMD_PING:
	    memcpy(client_buf + CP_CMD_HEAD_SZ, cmd->data, cmd->data_sz);
	    bsz = cmd_proto_cmd_fill(client_buf, cmd->seq,
				     CPCMD_PONG, cmd->data_sz);
	    send_client(client_buf, bsz);
	    break;
	    
	case CPCMD_SHIFT_TDI:
	    nbits = GET_DATA_BITS(cmd->data);
	    jtag_shift(cmd->data + 2, nbits);
	    ack(cmd->seq);
	    break;
	    
	case CPCMD_SHIFT_TMS:
	    nbits = GET_DATA_BITS(cmd->data);
	    jtag_tms(cmd->data + 2, nbits);
	    ack(cmd->seq);
	    break;
	    
	case CPCMD_SHIFT_TDI_TDO:
	    nbits = GET_DATA_BITS(cmd->data);
	    jtag_shift_inout(cmd->data + 2,
			     client_buf + CP_CMD_HEAD_SZ + 2,
			     nbits);
	    
	    client_buf[CP_CMD_HEAD_SZ] = nbits & 0xff;
	    client_buf[CP_CMD_HEAD_SZ + 1] = nbits >> 8;
	    
	    bsz = cmd_proto_cmd_fill(client_buf, cmd->seq,
				     CPCMD_DATA, (nbits + 23) / 8);
	    send_client(client_buf, bsz);
	    break;
	    
	default:
	    sprintf(buf, "CODE 0x%02x", cmd->code);
	    nak(cmd->seq, buf);
	}
    }
}