1 /* 2 * Ben NanoNote and Arduino USB Host shield communication. 3 * 4 * Copyright 2013 Paul Boddie 5 * 6 * SPI functions derived from those in lib/atben.c by Werner Almesberger: 7 * 8 * Copyright 2010-2011 Werner Almesberger 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 */ 15 16 #include <ubb/ubb.h> 17 #include <stdio.h> 18 #include <signal.h> 19 #include <stdlib.h> 20 21 /* Pin assignments: 22 * 23 * Sniffer UBB Shield 24 * ------- ---- ------ 25 * DAT2 DAT2 9 (INT) 26 * CD DAT3 10 (SS) 27 * CMD CMD 7 (RESET) 28 * VCC VDD VIN 29 * CLK CLK 13 (SCLK) 30 * GND GND GND 31 * DAT0 DAT0 11 (MOSI) 32 * DAT1 DAT1 12 (MISO) 33 * 8 (GPX) (not assigned) 34 */ 35 36 #define MAX_RESET UBB_CMD 37 #define MAX_SCLK UBB_CLK 38 #define MAX_MOSI UBB_DAT0 39 #define MAX_MISO UBB_DAT1 40 #define MAX_INT UBB_DAT2 41 #define MAX_SS UBB_DAT3 42 43 /* MAX3421E definitions. */ 44 45 #define MAX_REG_READ 0x00 46 #define MAX_REG_WRITE 0x02 47 48 #define MAX_REG_USBIRQ 13 49 #define MAX_REG_USBIEN 14 50 #define MAX_REG_USBCTL 15 51 #define MAX_REG_CPUCTL 16 52 #define MAX_REG_PINCTL 17 53 #define MAX_REG_REVISION 18 54 #define MAX_REG_HIRQ 25 55 #define MAX_REG_HIEN 26 56 #define MAX_REG_MODE 27 57 #define MAX_REG_HCTL 29 58 #define MAX_REG_HRSL 31 59 60 #define MAX_USBIRQ_OSCOKIRQ 1 61 #define MAX_USBIRQ_NOVBUSIRQ 32 62 #define MAX_USBIRQ_VBUSIRQ 64 63 64 #define MAX_USBCTL_PWRDOWN 16 65 #define MAX_USBCTL_CHIPRES 32 66 67 #define MAX_CPUCTL_IE 1 68 69 #define MAX_PINCTL_POSINT_LOW 0 70 #define MAX_PINCTL_POSINT_HIGH 4 71 #define MAX_PINCTL_INTLEVEL_EDGE 0 72 #define MAX_PINCTL_INTLEVEL_LEVEL 8 73 #define MAX_PINCTL_FDUPSPI_HALF 0 74 #define MAX_PINCTL_FDUPSPI_FULL 16 75 76 #define MAX_HIRQ_BUSEVENTIRQ 1 77 #define MAX_HIRQ_RWUIRQ 2 78 #define MAX_HIRQ_RCVDAVIRQ 4 79 #define MAX_HIRQ_SNDBAVIRQ 8 80 #define MAX_HIRQ_SUSDNIRQ 16 81 #define MAX_HIRQ_CONDETIRQ 32 82 #define MAX_HIRQ_FRAMEIRQ 64 83 #define MAX_HIRQ_HXFRDNIRQ 128 84 85 #define MAX_HIEN_CONDETIE 32 86 87 #define MAX_MODE_PERIPHERAL 0 88 #define MAX_MODE_HOST 1 89 #define MAX_MODE_LOWSPEED 2 90 #define MAX_MODE_SOFKAENAB 8 91 #define MAX_MODE_SEPIRQ_OFF 0 92 #define MAX_MODE_SEPIRQ_ON 16 93 #define MAX_MODE_DMPULLDN 64 94 #define MAX_MODE_DPPULLDN 128 95 96 #define MAX_MODE_HOST_ENABLED MAX_MODE_HOST | MAX_MODE_SEPIRQ_OFF | MAX_MODE_DMPULLDN | MAX_MODE_DPPULLDN 97 #define MAX_MODE_HOST_FULLSPEED MAX_MODE_HOST_ENABLED 98 #define MAX_MODE_HOST_LOWSPEED MAX_MODE_HOST_ENABLED | MAX_MODE_LOWSPEED 99 100 #define MAX_HCTL_SAMPLEBUS 4 101 102 #define MAX_HRSL_JSTATUS 128 103 #define MAX_HRSL_KSTATUS 64 104 105 #define max_reg(n) ((uint8_t) (n << 3)) 106 #define max_reg_read(n) (max_reg(n) | MAX_REG_READ) 107 #define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE) 108 109 void spi_begin() 110 { 111 CLR(MAX_SS); 112 } 113 114 void spi_end() 115 { 116 SET(MAX_SS); 117 } 118 119 /** 120 * Send the given value via MOSI while receiving a value via MISO. 121 * This requires full-duplex SPI and will produce a status value for the first 122 * value sent (the command). 123 */ 124 uint8_t spi_sendrecv(uint8_t v) 125 { 126 uint8_t result = 0; 127 uint8_t mask; 128 129 for (mask = 0x80; mask; mask >>= 1) 130 { 131 if (v & mask) 132 { 133 #ifdef DEBUG 134 printf("1"); 135 #endif 136 SET(MAX_MOSI); 137 } 138 else 139 { 140 #ifdef DEBUG 141 printf("0"); 142 #endif 143 CLR(MAX_MOSI); 144 } 145 146 /* Wait for stable output signal. */ 147 148 SET(MAX_SCLK); 149 150 if (PIN(MAX_MISO)) 151 result |= mask; 152 153 CLR(MAX_SCLK); 154 } 155 156 #ifdef DEBUG 157 printf("\n"); 158 #endif 159 return result; 160 } 161 162 uint8_t max_read(uint8_t reg, uint8_t *status) 163 { 164 uint8_t result = 0, tmpstatus = 0; 165 166 tmpstatus = 0; 167 168 spi_begin(); 169 tmpstatus = spi_sendrecv(max_reg_read(reg)); 170 result = spi_sendrecv(0); 171 spi_end(); 172 173 if (status != NULL) 174 *status = tmpstatus; 175 176 return result; 177 } 178 179 uint8_t max_write(uint8_t reg, uint8_t value) 180 { 181 uint8_t status = 0; 182 183 spi_begin(); 184 status = spi_sendrecv(max_reg_write(reg)); 185 spi_sendrecv(value); 186 spi_end(); 187 188 return status; 189 } 190 191 void chipreset() 192 { 193 printf("Resetting...\n"); 194 max_write(MAX_REG_USBCTL, MAX_USBCTL_CHIPRES); 195 196 printf("Clearing the reset...\n"); 197 max_write(MAX_REG_USBCTL, 0); 198 } 199 200 uint8_t check() 201 { 202 uint8_t oscillator; 203 204 oscillator = max_read(MAX_REG_USBIRQ, NULL); 205 206 return (oscillator & ~(MAX_USBIRQ_NOVBUSIRQ | MAX_USBIRQ_VBUSIRQ)) == MAX_USBIRQ_OSCOKIRQ; 207 } 208 209 uint8_t wait() 210 { 211 uint16_t timeout = 1024; 212 213 /* Wait for the oscillator before performing USB activity. */ 214 215 printf("Waiting...\n"); 216 217 while ((timeout > 0) && (!check())) 218 { 219 timeout--; 220 } 221 222 printf("Iterations remaining: %d\n", timeout); 223 224 return timeout; 225 } 226 227 uint8_t samplebusready() 228 { 229 uint8_t result; 230 231 result = max_read(MAX_REG_HCTL, NULL); 232 233 return !(result & MAX_HCTL_SAMPLEBUS); 234 } 235 236 void samplebus() 237 { 238 max_write(MAX_REG_HCTL, MAX_HCTL_SAMPLEBUS); 239 while (!samplebusready()); 240 } 241 242 void devicechanged() 243 { 244 uint8_t hrsl, mode; 245 246 hrsl = max_read(MAX_REG_HRSL, NULL); 247 mode = max_read(MAX_REG_MODE, NULL); 248 249 if ((hrsl & MAX_HRSL_JSTATUS) && (hrsl & MAX_HRSL_KSTATUS)) 250 { 251 printf("Bad device status.\n"); 252 } 253 else if (!(hrsl & MAX_HRSL_JSTATUS) && !(hrsl & MAX_HRSL_KSTATUS)) 254 { 255 printf("Device disconnected.\n"); 256 } 257 else 258 { 259 printf("Device connected.\n"); 260 261 /* Low speed device when J and lowspeed have the same level. 262 Since J and K should have opposing levels, K can be tested when 263 lowspeed is low. */ 264 265 if (((hrsl & MAX_HRSL_JSTATUS) && (mode & MAX_MODE_LOWSPEED)) || 266 ((hrsl & MAX_HRSL_KSTATUS) && !(mode & MAX_MODE_LOWSPEED))) 267 { 268 printf("Device is low speed.\n"); 269 max_write(MAX_REG_MODE, MAX_MODE_HOST_LOWSPEED); 270 } 271 else 272 { 273 printf("Device is full speed.\n"); 274 max_write(MAX_REG_MODE, MAX_MODE_HOST_FULLSPEED); 275 } 276 } 277 } 278 279 void shutdown(int signum) 280 { 281 printf("Closing...\n"); 282 ubb_close(0); 283 exit(1); 284 } 285 286 int main(int argc, char *argv[]) 287 { 288 uint8_t status = 0, revision = 0; 289 uint16_t count; 290 291 signal(SIGINT, &shutdown); 292 293 if (ubb_open(0) < 0) { 294 perror("ubb_open"); 295 return 1; 296 } 297 298 ubb_power(1); 299 printf("Power on.\n"); 300 301 OUT(MAX_SS); 302 OUT(MAX_MOSI); 303 OUT(MAX_SCLK); 304 OUT(MAX_RESET); 305 IN(MAX_INT); 306 IN(MAX_MISO); 307 308 /* Initialise SPI. */ 309 /* Set SS# to 1. */ 310 311 SET(MAX_SS); 312 CLR(MAX_MOSI); 313 CLR(MAX_SCLK); 314 SET(MAX_RESET); 315 316 /* Initialise the MAX3421E. */ 317 318 /* Set full-duplex, interrupt signalling. */ 319 320 printf("Setting pin control...\n"); 321 max_write(MAX_REG_PINCTL, MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL); 322 323 chipreset(); 324 printf("Ready? %d\n", wait()); 325 326 /* Check various registers. */ 327 328 printf("Mode: %x\n", max_read(MAX_REG_MODE, &status)); 329 printf("IRQ: %x\n", max_read(MAX_REG_HIRQ, &status)); 330 331 /* Set host mode. */ 332 333 printf("Setting mode...\n"); 334 status = max_write(MAX_REG_MODE, MAX_MODE_HOST_ENABLED); 335 336 printf("Setting INT signalling...\n"); 337 status = max_write(MAX_REG_CPUCTL, MAX_CPUCTL_IE); 338 339 printf("Setting connection signalling...\n"); 340 status = max_write(MAX_REG_HIEN, MAX_HIEN_CONDETIE); 341 342 /* Check various registers. */ 343 344 printf("Mode: %x\n", max_read(MAX_REG_MODE, &status)); 345 printf("IRQ: %x\n", max_read(MAX_REG_HIRQ, &status)); 346 printf("IE: %x\n", max_read(MAX_REG_HIEN, &status)); 347 printf("CPU: %x\n", max_read(MAX_REG_CPUCTL, &status)); 348 printf("Pin: %x\n", max_read(MAX_REG_PINCTL, &status)); 349 printf("USBIRQ: %x\n", max_read(MAX_REG_USBIRQ, &status)); 350 printf("USBIE: %x\n", max_read(MAX_REG_USBIEN, &status)); 351 352 /* Read from the REVISION register. */ 353 354 printf("Reading...\n"); 355 revision = max_read(MAX_REG_REVISION, &status); 356 printf("Revision = %x\n", revision); 357 358 for (count = 0; count <= 65535; count++) 359 { 360 if (!PIN(MAX_INT)) 361 { 362 status = max_read(MAX_REG_HIRQ, NULL); 363 364 if (status & MAX_HIRQ_CONDETIRQ) 365 devicechanged(); 366 if (status & MAX_HIRQ_SUSDNIRQ) 367 printf("Suspend done.\n"); 368 if (status & MAX_HIRQ_BUSEVENTIRQ) 369 printf("Bus event.\n"); 370 if (status & MAX_HIRQ_RCVDAVIRQ) 371 printf("Data received.\n"); 372 373 max_write(MAX_REG_HIRQ, status); 374 } 375 } 376 377 printf("Closing...\n"); 378 ubb_close(0); 379 380 return 0; 381 }