summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-11-11 22:49:28 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-11-11 22:49:28 +0000
commit9c4ddbfafab6fe96480edeb8c5fee1b76e103300 (patch)
treeab2f847b1bdb19f3283c301d9fae711727846965
parentd3d625a0e1027c0f328d2d1f620390ecec1fb3cf (diff)
Add support for using the uBCSP implementation
-rw-r--r--tools/csr_bcsp.c161
1 files changed, 159 insertions, 2 deletions
diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c
index 582d6859..f39a4182 100644
--- a/tools/csr_bcsp.c
+++ b/tools/csr_bcsp.c
@@ -39,9 +39,40 @@ static uint16_t seqnum = 0x0000;
static int fd = -1;
+#ifdef HAVE_UBCSP
+#include "ubcsp.h"
+#else
+#define UBCSP_PACKET_SENT 0x01
+#define UBCSP_PACKET_RECEIVED 0x02
+#define UBCSP_PEER_RESET 0x04
+#define UBCSP_PACKET_ACK 0x08
+
+struct ubcsp_packet
+{
+ uint8_t channel;
+ uint8_t reliable;
+ uint8_t use_crc;
+ uint16_t length;
+ uint8_t *payload;
+};
+
+static inline void ubcsp_initialize(void) {}
+static inline void ubcsp_send_packet(struct ubcsp_packet *send_packet) {}
+static inline void ubcsp_receive_packet(struct ubcsp_packet *receive_packet) {}
+static inline uint8_t ubcsp_poll(uint8_t *activity) { return 20; }
+#endif
+
+static struct ubcsp_packet send_packet;
+static uint8_t send_buffer[512];
+
+static struct ubcsp_packet receive_packet;
+static uint8_t receive_buffer[512];
+
int csr_open_bcsp(char *device)
{
struct termios ti;
+ uint8_t delay, activity = 0x00;
+ int timeout = 0;
if (!device)
device = "/dev/ttyS0";
@@ -93,14 +124,140 @@ int csr_open_bcsp(char *device)
return -1;
}
+ memset(&send_packet, 0, sizeof(send_packet));
+ memset(&receive_packet, 0, sizeof(receive_packet));
+
+ ubcsp_initialize();
+
+ send_packet.length = 512;
+ send_packet.payload = send_buffer;
+
+ receive_packet.length = 512;
+ receive_packet.payload = receive_buffer;
+
+ ubcsp_receive_packet(&receive_packet);
+
+ while (1) {
+ delay = ubcsp_poll(&activity);
+
+ if (activity & UBCSP_PACKET_RECEIVED)
+ break;
+
+ if (delay) {
+ usleep(delay * 100);
+
+ if (timeout++ > 100) {
+ fprintf(stderr, "Initialization timed out\n");
+ return -1;
+ }
+ }
+ }
+
return 0;
}
+void put_uart(uint8_t ch)
+{
+ write(fd, &ch, 1);
+}
+
+uint8_t get_uart(uint8_t *ch)
+{
+ int res = read(fd, ch, 1);
+ return res > 0 ? res : 0;
+}
+
static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length)
{
- errno = EIO;
+ unsigned char cp[254], rp[254];
+ uint8_t cmd[10];
+ uint16_t size;
+ uint8_t delay, activity = 0x00;
+ int timeout = 0, sent = 0;
- return -1;
+ size = (length < 8) ? 9 : ((length + 1) / 2) + 5;
+
+ cmd[0] = command & 0xff;
+ cmd[1] = command >> 8;
+ cmd[2] = size & 0xff;
+ cmd[3] = size >> 8;
+ cmd[4] = seqnum & 0xff;
+ cmd[5] = seqnum >> 8;
+ cmd[6] = varid & 0xff;
+ cmd[7] = varid >> 8;
+ cmd[8] = 0x00;
+ cmd[9] = 0x00;
+
+ memset(cp, 0, sizeof(cp));
+ cp[0] = 0x00;
+ cp[1] = 0xfc;
+ cp[2] = (size * 2) + 1;
+ cp[3] = 0xc2;
+ memcpy(cp + 4, cmd, sizeof(cmd));
+ memcpy(cp + 14, value, length);
+
+ receive_packet.length = 512;
+ ubcsp_receive_packet(&receive_packet);
+
+ send_packet.channel = 5;
+ send_packet.reliable = 1;
+ send_packet.length = (size * 2) + 4;
+ memcpy(send_packet.payload, cp, (size * 2) + 4);
+
+ ubcsp_send_packet(&send_packet);
+
+ while (1) {
+ delay = ubcsp_poll(&activity);
+
+ if (activity & UBCSP_PACKET_RECEIVED) {
+ if (sent && receive_packet.channel == 5 &&
+ receive_packet.payload[0] == 0xff) {
+ memcpy(rp, receive_packet.payload,
+ receive_packet.length);
+ break;
+ }
+
+ receive_packet.length = 512;
+ ubcsp_receive_packet(&receive_packet);
+ timeout = 0;
+ }
+
+ if (activity & UBCSP_PACKET_SENT) {
+ switch (varid) {
+ case CSR_VARID_COLD_RESET:
+ case CSR_VARID_WARM_RESET:
+ case CSR_VARID_COLD_HALT:
+ case CSR_VARID_WARM_HALT:
+ return 0;
+ }
+
+ sent = 1;
+ timeout = 0;
+ }
+
+ if (delay) {
+ usleep(delay * 100);
+
+ if (timeout++ > 100) {
+ fprintf(stderr, "Operation timed out\n");
+ return -1;
+ }
+ }
+ }
+
+ if (rp[0] != 0xff || rp[2] != 0xc2) {
+ errno = EIO;
+ return -1;
+ }
+
+ if ((rp[11] + (rp[12] << 8)) != 0) {
+ errno = ENXIO;
+ return -1;
+ }
+
+ memcpy(value, rp + 13, length);
+
+ return 0;
}
int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length)