1.1 --- a/test.c Mon Feb 11 23:01:39 2013 +0000
1.2 +++ b/test.c Wed Feb 13 00:06:17 2013 +0000
1.3 @@ -17,6 +17,13 @@
1.4 #include <stdio.h>
1.5 #include <signal.h>
1.6 #include <stdlib.h>
1.7 +#include <usb.h>
1.8 +
1.9 +/* Found in Python's asdl.h. */
1.10 +
1.11 +#ifndef __cplusplus
1.12 +typedef enum {false, true} bool;
1.13 +#endif
1.14
1.15 /* Pin assignments:
1.16 *
1.17 @@ -45,6 +52,11 @@
1.18 #define MAX_REG_READ 0x00
1.19 #define MAX_REG_WRITE 0x02
1.20
1.21 +#define MAX_REG_RCVFIFO 1
1.22 +#define MAX_REG_SNDFIFO 2
1.23 +#define MAX_REG_SUDFIFO 4
1.24 +#define MAX_REG_RCVBC 6
1.25 +#define MAX_REG_SNDBC 7
1.26 #define MAX_REG_USBIRQ 13
1.27 #define MAX_REG_USBIEN 14
1.28 #define MAX_REG_USBCTL 15
1.29 @@ -54,7 +66,9 @@
1.30 #define MAX_REG_HIRQ 25
1.31 #define MAX_REG_HIEN 26
1.32 #define MAX_REG_MODE 27
1.33 +#define MAX_REG_PERADDR 28
1.34 #define MAX_REG_HCTL 29
1.35 +#define MAX_REG_HXFR 30
1.36 #define MAX_REG_HRSL 31
1.37
1.38 #define MAX_USBIRQ_OSCOKIRQ 1
1.39 @@ -98,9 +112,20 @@
1.40 #define MAX_MODE_HOST_LOWSPEED MAX_MODE_HOST_ENABLED | MAX_MODE_LOWSPEED
1.41
1.42 #define MAX_HCTL_SAMPLEBUS 4
1.43 +#define MAX_HCTL_RCVTOG0 16
1.44 +#define MAX_HCTL_RCVTOG1 32
1.45 +#define MAX_HCTL_SNDTOG0 64
1.46 +#define MAX_HCTL_SNDTOG1 128
1.47 +
1.48 +#define MAX_HXFR_SETUP 16
1.49 +#define MAX_HXFR_OUTNIN 32
1.50 +#define MAX_HXFR_HS 128
1.51
1.52 #define MAX_HRSL_JSTATUS 128
1.53 #define MAX_HRSL_KSTATUS 64
1.54 +#define MAX_HRSL_SNDTOGRD 32
1.55 +#define MAX_HRSL_RCVTOGRD 16
1.56 +#define MAX_HRSL_HRSLT 15
1.57
1.58 #define max_reg(n) ((uint8_t) (n << 3))
1.59 #define max_reg_read(n) (max_reg(n) | MAX_REG_READ)
1.60 @@ -188,6 +213,193 @@
1.61 return status;
1.62 }
1.63
1.64 +/**
1.65 + * Return whether data can be sent.
1.66 + */
1.67 +bool max_can_send()
1.68 +{
1.69 + uint8_t status = max_read(MAX_REG_HIRQ, NULL);
1.70 +
1.71 + return !(status & MAX_HIRQ_SNDBAVIRQ);
1.72 +}
1.73 +
1.74 +/**
1.75 + * Set the sending data toggle.
1.76 + */
1.77 +void max_set_send_toggle(bool toggle)
1.78 +{
1.79 + max_write(MAX_REG_HCTL, toggle ? MAX_HCTL_SNDTOG1 : MAX_HCTL_SNDTOG0);
1.80 +}
1.81 +
1.82 +/**
1.83 + * Return the sending data toggle.
1.84 + */
1.85 +bool max_get_send_toggle()
1.86 +{
1.87 + return (max_read(MAX_REG_HRSL, NULL) & MAX_HRSL_SNDTOGRD) != 0;
1.88 +}
1.89 +
1.90 +/**
1.91 + * Set the receiving data toggle.
1.92 + */
1.93 +void max_set_recv_toggle(bool toggle)
1.94 +{
1.95 + max_write(MAX_REG_HCTL, toggle ? MAX_HCTL_RCVTOG1 : MAX_HCTL_RCVTOG0);
1.96 +}
1.97 +
1.98 +/**
1.99 + * Return the receiving data toggle.
1.100 + */
1.101 +bool max_get_recv_toggle()
1.102 +{
1.103 + return (max_read(MAX_REG_HRSL, NULL) & MAX_HRSL_RCVTOGRD) != 0;
1.104 +}
1.105 +
1.106 +/**
1.107 + * Wait for handshake/timeout after a transfer.
1.108 + */
1.109 +uint8_t max_wait_transfer(uint8_t status)
1.110 +{
1.111 + while (!(status & MAX_HIRQ_HXFRDNIRQ))
1.112 + {
1.113 + status = max_read(MAX_REG_HIRQ, NULL);
1.114 + }
1.115 +
1.116 + return status;
1.117 +}
1.118 +
1.119 +/**
1.120 + * Send HS payload for control transfers.
1.121 + */
1.122 +uint8_t max_send_hs()
1.123 +{
1.124 + uint8_t status = max_write(MAX_REG_HXFR, MAX_HXFR_HS);
1.125 + return max_wait_transfer(status);
1.126 +}
1.127 +
1.128 +/**
1.129 + * Write the given data to the FIFO.
1.130 + */
1.131 +void max_write_fifo(uint8_t endpoint, uint8_t *data, uint8_t len)
1.132 +{
1.133 + uint8_t count;
1.134 +
1.135 + for (count = 0; count < len; count++)
1.136 + {
1.137 + max_write(endpoint ? MAX_REG_SNDFIFO : MAX_REG_SUDFIFO, data[count]);
1.138 + }
1.139 +
1.140 + if (endpoint)
1.141 + max_write(MAX_REG_SNDBC, len);
1.142 +}
1.143 +
1.144 +/**
1.145 + * Read the data from the FIFO.
1.146 + */
1.147 +void max_read_fifo(uint8_t *data, uint8_t *len, uint8_t *datalimit)
1.148 +{
1.149 + uint8_t count, received = max_read(MAX_REG_RCVBC, NULL);
1.150 +
1.151 + *len += received;
1.152 +
1.153 + for (count = 0; (count < received) && (data < datalimit); count++)
1.154 + {
1.155 + *data++ = max_read(MAX_REG_RCVFIFO, NULL);
1.156 + }
1.157 +}
1.158 +
1.159 +/**
1.160 + * Send a request to the given address and endpoint, using the supplied data
1.161 + * payload with the given length, indicating the preserved toggle state of the
1.162 + * endpoint (which will be updated).
1.163 + */
1.164 +uint8_t max_send(uint8_t address, uint8_t endpoint, uint8_t *data, uint8_t len, bool *toggle)
1.165 +{
1.166 + uint8_t status, hrsl = 0;
1.167 +
1.168 + max_write_fifo(endpoint, data, len);
1.169 +
1.170 + max_set_send_toggle(*toggle);
1.171 +
1.172 + /* Set the address. */
1.173 +
1.174 + max_write(MAX_REG_PERADDR, address);
1.175 +
1.176 + /* Initiate the transfer. */
1.177 +
1.178 + do
1.179 + {
1.180 + status = max_write(MAX_REG_HXFR, endpoint | MAX_HXFR_OUTNIN | (endpoint ? 0 : MAX_HXFR_SETUP));
1.181 + status = max_wait_transfer(status);
1.182 +
1.183 + /* Test for usable data. */
1.184 +
1.185 + if (!(status & MAX_HIRQ_SNDBAVIRQ))
1.186 + continue;
1.187 +
1.188 + hrsl = max_read(MAX_REG_HRSL, &status);
1.189 + }
1.190 + while ((hrsl & MAX_HRSL_HRSLT) != 0);
1.191 +
1.192 + *toggle = max_get_send_toggle();
1.193 +
1.194 + return status;
1.195 +}
1.196 +
1.197 +/**
1.198 + * Make a request for data from the given address and endpoint, collecting it in
1.199 + * the supplied buffer with the given length, indicating the preserved toggle
1.200 + * state of the endpoint (which will be updated), and providing optional setup
1.201 + * data (for control transfers). The length will be updated to indicate the
1.202 + * total length of the received data.
1.203 + */
1.204 +uint8_t max_recv(uint8_t address, uint8_t endpoint, uint8_t *data, uint8_t *len, bool *toggle, uint8_t *setup)
1.205 +{
1.206 + uint8_t *datalimit = data + *len;
1.207 + uint8_t status, hrsl = 0;
1.208 +
1.209 + /* Write control transfer information, if appropriate. */
1.210 +
1.211 + if (!endpoint)
1.212 + max_write_fifo(endpoint, setup, 8);
1.213 +
1.214 + max_set_send_toggle(*toggle);
1.215 +
1.216 + /* Set the address. */
1.217 +
1.218 + max_write(MAX_REG_PERADDR, address);
1.219 +
1.220 + /* Initiate the transfer. */
1.221 +
1.222 + do
1.223 + {
1.224 + status = max_write(MAX_REG_HXFR, endpoint);
1.225 + status = max_wait_transfer(status);
1.226 +
1.227 + /* Test for usable data. */
1.228 +
1.229 + if (!(status & MAX_HIRQ_RCVDAVIRQ))
1.230 + continue;
1.231 +
1.232 + hrsl = max_read(MAX_REG_HRSL, &status);
1.233 + }
1.234 + while ((hrsl & MAX_HRSL_HRSLT) != 0);
1.235 +
1.236 + do
1.237 + {
1.238 + max_read_fifo(data, len, datalimit);
1.239 +
1.240 + /* Indicate that all data has been read. */
1.241 +
1.242 + status = max_write(MAX_REG_HIRQ, MAX_HIRQ_RCVDAVIRQ);
1.243 + }
1.244 + while (status & MAX_HIRQ_RCVDAVIRQ);
1.245 +
1.246 + *toggle = max_get_send_toggle();
1.247 +
1.248 + return status;
1.249 +}
1.250 +
1.251 void chipreset()
1.252 {
1.253 printf("Resetting...\n");
1.254 @@ -239,7 +451,11 @@
1.255 while (!samplebusready());
1.256 }
1.257
1.258 -void devicechanged()
1.259 +/**
1.260 + * Handle the connection or disconnection of a device, returning true if the
1.261 + * device is now connected or false otherwise.
1.262 + */
1.263 +bool devicechanged()
1.264 {
1.265 uint8_t hrsl, mode;
1.266
1.267 @@ -273,7 +489,23 @@
1.268 printf("Device is full speed.\n");
1.269 max_write(MAX_REG_MODE, MAX_MODE_HOST_FULLSPEED);
1.270 }
1.271 +
1.272 + return true;
1.273 }
1.274 +
1.275 + return false;
1.276 +}
1.277 +
1.278 +void setup_packet(uint8_t *setup, uint8_t request_type, uint8_t request, uint16_t value, uint16_t index, uint16_t length)
1.279 +{
1.280 + setup[0] = request_type;
1.281 + setup[1] = request;
1.282 + setup[2] = value & 0xff;
1.283 + setup[3] = value >> 8;
1.284 + setup[4] = index & 0xff;
1.285 + setup[5] = index >> 8;
1.286 + setup[6] = length & 0xff;
1.287 + setup[7] = length >> 8;
1.288 }
1.289
1.290 void shutdown(int signum)
1.291 @@ -287,6 +519,8 @@
1.292 {
1.293 uint8_t status = 0, revision = 0;
1.294 uint16_t count;
1.295 + bool in_toggle = 0;
1.296 + uint8_t data[64], len = 64, setup[8];
1.297
1.298 signal(SIGINT, &shutdown);
1.299
1.300 @@ -361,8 +595,12 @@
1.301 {
1.302 status = max_read(MAX_REG_HIRQ, NULL);
1.303
1.304 - if (status & MAX_HIRQ_CONDETIRQ)
1.305 - devicechanged();
1.306 + if ((status & MAX_HIRQ_CONDETIRQ) && devicechanged() && max_can_send())
1.307 + {
1.308 + printf("Sending control request to address 0, endpoint 0...\n");
1.309 + setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE);
1.310 + max_recv(0, 0, data, &len, &in_toggle, setup);
1.311 + }
1.312 if (status & MAX_HIRQ_SUSDNIRQ)
1.313 printf("Suspend done.\n");
1.314 if (status & MAX_HIRQ_BUSEVENTIRQ)