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 <time.h> 19 #include <unistd.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_GPINPOL 24 55 #define MAX_REG_HIRQ 25 56 #define MAX_REG_HIEN 26 57 #define MAX_REG_MODE 27 58 #define MAX_REG_HCTL 29 59 #define MAX_REG_HRSL 31 60 61 #define MAX_USBIRQ_OSCOKIRQ 1 62 #define MAX_USBIRQ_NOVBUSIRQ 32 63 #define MAX_USBIRQ_VBUSIRQ 64 64 65 #define MAX_USBCTL_PWRDOWN 16 66 #define MAX_USBCTL_CHIPRES 32 67 68 #define MAX_CPUCTL_IE 1 69 70 #define MAX_PINCTL_POSINT_LOW 0 71 #define MAX_PINCTL_POSINT_HIGH 4 72 #define MAX_PINCTL_INTLEVEL_EDGE 0 73 #define MAX_PINCTL_INTLEVEL_LEVEL 8 74 #define MAX_PINCTL_FDUPSPI_HALF 0 75 #define MAX_PINCTL_FDUPSPI_FULL 16 76 77 #define MAX_HIRQ_BUSEVENTIRQ 1 78 #define MAX_HIRQ_RWUIRQ 2 79 #define MAX_HIRQ_RCVDAVIRQ 4 80 #define MAX_HIRQ_SNDBAVIRQ 8 81 #define MAX_HIRQ_SUSDNIRQ 16 82 #define MAX_HIRQ_CONDETIRQ 32 83 #define MAX_HIRQ_FRAMEIRQ 64 84 #define MAX_HIRQ_HXFRDNIRQ 128 85 86 #define MAX_HIEN_CONDETIE 32 87 88 #define MAX_MODE_PERIPHERAL 0 89 #define MAX_MODE_HOST 1 90 #define MAX_MODE_LOWSPEED 2 91 #define MAX_MODE_SOFKAENAB 8 92 #define MAX_MODE_SEPIRQ_OFF 0 93 #define MAX_MODE_SEPIRQ_ON 16 94 #define MAX_MODE_DMPULLDN 64 95 #define MAX_MODE_DPPULLDN 128 96 97 #define MAX_HCTL_SAMPLEBUS 4 98 99 #define MAX_HRSL_JSTATUS 128 100 #define MAX_HRSL_KSTATUS 64 101 102 #define max_reg(n) ((uint8_t) (n << 3)) 103 #define max_reg_read(n) (max_reg(n) | MAX_REG_READ) 104 #define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE) 105 106 #define nanosleep(a, b) if (0) 107 #define usleep(a) if (0) 108 109 struct timespec tCSS = {0, 20}, 110 tL = {0, 30}, 111 tCSW = {0, 200}, 112 tCL = {0, 17}, 113 tCH = {0, 17}, 114 tDS = {0, 5}, 115 tDH = {0, 10}, 116 tDO = {0, 15}, 117 tDI = {0, 15}, 118 tON = {0, 4}, 119 tRESET = {0, 200}, 120 tTEST = {0, 100}; 121 122 void spi_begin() 123 { 124 CLR(MAX_SS); 125 nanosleep(&tL, NULL); /* tCSS is the minimum, but tL is more conservative */ 126 } 127 128 void spi_end() 129 { 130 SET(MAX_SS); 131 nanosleep(&tCSW, NULL); 132 } 133 134 /** 135 * Send the given value via MOSI while receiving a value via MISO. 136 * This requires full-duplex SPI and will produce a status value for the first 137 * value sent (the command). 138 */ 139 uint8_t spi_sendrecv(uint8_t v) 140 { 141 uint8_t result = 0; 142 uint8_t mask; 143 144 for (mask = 0x80; mask; mask >>= 1) 145 { 146 if (v & mask) 147 { 148 #ifdef DEBUG 149 printf("1"); 150 #endif 151 SET(MAX_MOSI); 152 } 153 else 154 { 155 #ifdef DEBUG 156 printf("0"); 157 #endif 158 CLR(MAX_MOSI); 159 } 160 161 /* Wait for stable output signal. */ 162 163 nanosleep(&tDS, NULL); 164 165 SET(MAX_SCLK); 166 167 if (PIN(MAX_MISO)) 168 result |= mask; 169 170 nanosleep(&tCH, NULL); 171 CLR(MAX_SCLK); 172 nanosleep(&tCL, NULL); 173 } 174 175 #ifdef DEBUG 176 printf("\n"); 177 #endif 178 return result; 179 } 180 181 uint8_t max_read(uint8_t reg, uint8_t *status) 182 { 183 uint8_t result = 0, tmpstatus = 0; 184 185 tmpstatus = 0; 186 187 spi_begin(); 188 tmpstatus = spi_sendrecv(max_reg_read(reg)); 189 result = spi_sendrecv(0); 190 spi_end(); 191 192 if (status != NULL) 193 *status = tmpstatus; 194 195 return result; 196 } 197 198 uint8_t max_write(uint8_t reg, uint8_t value) 199 { 200 uint8_t status = 0; 201 202 spi_begin(); 203 status = spi_sendrecv(max_reg_write(reg)); 204 spi_sendrecv(value); 205 spi_end(); 206 207 return status; 208 } 209 210 void chipreset() 211 { 212 printf("Resetting...\n"); 213 max_write(MAX_REG_USBCTL, MAX_USBCTL_CHIPRES); 214 215 printf("Clearing the reset...\n"); 216 max_write(MAX_REG_USBCTL, 0); 217 } 218 219 uint8_t check() 220 { 221 uint8_t oscillator; 222 223 oscillator = max_read(MAX_REG_USBIRQ, NULL); 224 225 return (oscillator & ~(MAX_USBIRQ_NOVBUSIRQ | MAX_USBIRQ_VBUSIRQ)) == MAX_USBIRQ_OSCOKIRQ; 226 } 227 228 uint8_t wait() 229 { 230 uint16_t timeout = 1024; 231 232 /* Wait for the oscillator before performing USB activity. */ 233 234 printf("Waiting...\n"); 235 236 while ((timeout > 0) && (!check())) 237 { 238 usleep(3000); /* 3ms */ 239 timeout--; 240 } 241 242 printf("Iterations remaining: %d\n", timeout); 243 244 return timeout; 245 } 246 247 int main(int argc, char *argv[]) 248 { 249 uint8_t status = 0, revision = 0, result = 0; 250 uint16_t count; 251 252 if (ubb_open(0) < 0) { 253 perror("ubb_open"); 254 return 1; 255 } 256 257 ubb_power(1); 258 printf("Power on.\n"); 259 260 OUT(MAX_SS); 261 OUT(MAX_MOSI); 262 OUT(MAX_SCLK); 263 OUT(MAX_RESET); 264 IN(MAX_INT); 265 IN(MAX_MISO); 266 267 /* Initialise SPI. */ 268 /* Set SS# to 1. */ 269 270 SET(MAX_SS); 271 CLR(MAX_MOSI); 272 CLR(MAX_SCLK); 273 SET(MAX_RESET); 274 275 /* Initialise the MAX3421E. */ 276 277 /* Set full-duplex, interrupt signalling. */ 278 279 printf("Setting pin control...\n"); 280 max_write(MAX_REG_PINCTL, MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL); 281 282 chipreset(); 283 printf("Ready? %d\n", wait()); 284 285 /* Read from the REVISION register. */ 286 287 printf("Reading...\n"); 288 revision = max_read(MAX_REG_REVISION, &status); 289 printf("Status = %x\n", status); 290 printf("Revision = %x\n", revision); 291 292 /* Check various registers. */ 293 294 for (count = 0; count < 256; count++) 295 { 296 max_write(MAX_REG_GPINPOL, count); 297 result = max_read(MAX_REG_GPINPOL, NULL); 298 if (count != result) 299 { 300 printf("Count: %d\n", count); 301 printf("Retrieved: %d\n", result); 302 printf("Status = %x\n", status); 303 } 304 } 305 306 printf("Closing...\n"); 307 ubb_close(0); 308 309 return 0; 310 }