Initial commit
[csrprogrammer:csrremote.git] / usbprogrammer.cpp
1 #include "usbprogrammer.h"
2
3 #define convertEndianess(A) (uint16_t)((((uint16_t)(A) & 0xff00) >> 8) | \
4                              (((uint16_t)(A) & 0x00ff) << 8))
5
6 #define arr unsigned char[]
7
8 #define __packed __attribute__((__packed__))
9
10 struct RWPacket{
11     uint16_t cmd;
12     uint8_t  padding;
13     uint16_t addr;
14     uint16_t size;
15     uint16_t data[505];
16 } __packed;
17
18 UsbProgrammer::UsbProgrammer()
19 {
20     progInit = usb.USBInit(CSRVENDOR,CSRDEVICE);
21     SetMode(true);
22     SetTransferSpeed(20);
23     ClearCmdBits();
24 }
25
26 bool UsbProgrammer::IsConnected(void)
27 {
28     return progInit;
29 }
30
31 bool UsbProgrammer::ReadBlock(uint16_t addr, int size, uint16_t buffer[])
32 {
33     RWPacket packet;
34     packet.cmd = 0x100;
35     packet.padding = 0;
36
37     int readed = 0;
38     unsigned short address = addr;
39
40     do {
41
42         int psize = 0x1F8;
43         if(psize+readed > size)
44             psize = size - readed;
45
46         packet.addr = convertEndianess(address);
47         packet.size = convertEndianess(psize);
48
49         if(!usb.WriteData((unsigned char*)&packet,7)) return false;
50
51         uint16_t tmp[3+psize];
52         if(!usb.ReadData((unsigned char*)tmp,6+psize*2)) return false;
53
54         for(int i=readed; i<readed+psize; i++)
55             buffer[i] = convertEndianess(tmp[3+i-readed]);
56
57         address += psize;
58         readed += psize;
59
60     } while (readed < size);
61
62
63     return true;
64 }
65
66 bool UsbProgrammer::WriteBlock(uint16_t addr, int size, uint16_t buffer[])
67 {
68     RWPacket packet;
69     packet.cmd = 0x200;
70     packet.padding = 0;
71
72     int writed = 0;
73     unsigned short address = addr;
74
75     do {
76
77         int psize = 0x1F8;
78         if(psize+writed > size)
79             psize = size - writed;
80
81         packet.addr = convertEndianess(address);
82         packet.size = convertEndianess(psize);
83
84         for(int i=writed; i<writed+psize; i++)
85             packet.data[i-writed] = convertEndianess(buffer[i]);
86
87         if(!usb.WriteData((unsigned char*)&packet,7+psize*2)) return false;
88
89         address += psize;
90         writed += psize;
91
92     } while (writed < size);
93
94
95     return true;
96 }
97
98 bool UsbProgrammer::SetTransferSpeed(uint16_t speedkhz)
99 {
100     uint16_t speed = (1000000 / speedkhz - 434) / 126;
101
102     uint8_t low = speed;
103     uint8_t high = speed >> 8;
104     unsigned char cmd[] = {0,3,0,high,low};
105     return usb.WriteData(cmd,5);
106 }
107
108 bool UsbProgrammer::IsXAPStopped(void)
109 {
110     uint16_t data[2];
111     unsigned char cmd[] = {0,4,0};
112     usb.WriteData(cmd,3);
113     usb.ReadData((unsigned char*)data,4);
114     return data[1];
115 }
116
117 bool UsbProgrammer::SetMode(bool spi)
118 {
119     uint8_t data = spi ? 0 : 0xff;
120     unsigned char cmd[] = {0,9,0,0,data};
121     return usb.WriteData(cmd,5);
122 }
123
124 bool UsbProgrammer::ClearCmdBits()
125 {
126     unsigned char cmd[] = {0,15,0,0,0,0,0};
127     return usb.WriteData(cmd,7);
128 }