1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/test.c Fri Feb 08 22:50:08 2013 +0000
1.3 @@ -0,0 +1,286 @@
1.4 +/*
1.5 + * Ben NanoNote and Arduino USB Host shield communication.
1.6 + *
1.7 + * Copyright 2013 Paul Boddie
1.8 + *
1.9 + * SPI functions derived from those in lib/atben.c by Werner Almesberger:
1.10 + *
1.11 + * Copyright 2010-2011 Werner Almesberger
1.12 + *
1.13 + * This program is free software; you can redistribute it and/or modify
1.14 + * it under the terms of the GNU General Public License as published by
1.15 + * the Free Software Foundation; either version 2 of the License, or
1.16 + * (at your option) any later version.
1.17 + */
1.18 +
1.19 +#include <ubb/ubb.h>
1.20 +#include <stdio.h>
1.21 +#include <time.h>
1.22 +
1.23 +/* Pin assignments:
1.24 + *
1.25 + * Sniffer UBB Shield
1.26 + * ------- ---- ------
1.27 + * DAT2 DAT2 9 (INT)
1.28 + * CD DAT3 10 (SS)
1.29 + * CMD CMD 7 (RESET)
1.30 + * VCC VDD VIN
1.31 + * CLK CLK 13 (SCLK)
1.32 + * GND GND GND
1.33 + * DAT0 DAT0 11 (MOSI)
1.34 + * DAT1 DAT1 12 (MISO)
1.35 + * 8 (GPX) (not assigned)
1.36 + */
1.37 +
1.38 +#define MAX_RESET UBB_CMD
1.39 +#define MAX_SCLK UBB_CLK
1.40 +#define MAX_MOSI UBB_DAT0
1.41 +#define MAX_MISO UBB_DAT1
1.42 +#define MAX_INT UBB_DAT2
1.43 +#define MAX_SS UBB_DAT3
1.44 +
1.45 +/* MAX3421E definitions. */
1.46 +
1.47 +#define MAX_REG_READ 0x00
1.48 +#define MAX_REG_WRITE 0x02
1.49 +
1.50 +#define MAX_REG_USBCTL 15
1.51 +#define MAX_REG_PINCTL 17
1.52 +#define MAX_REG_REVISION 18
1.53 +#define MAX_REG_MODE 27
1.54 +#define MAX_REG_HRSL 31
1.55 +
1.56 +#define MAX_USBCTL_PWRDOWN 16
1.57 +#define MAX_USBCTL_CHIPRES 32
1.58 +
1.59 +#define MAX_PINCTL_POSINT_LOW 0
1.60 +#define MAX_PINCTL_POSINT_HIGH 4
1.61 +#define MAX_PINCTL_INTLEVEL_EDGE 0
1.62 +#define MAX_PINCTL_INTLEVEL_LEVEL 8
1.63 +#define MAX_PINCTL_FDUPSPI_HALF 0
1.64 +#define MAX_PINCTL_FDUPSPI_FULL 16
1.65 +
1.66 +#define MAX_MODE_PERIPHERAL 0
1.67 +#define MAX_MODE_HOST 1
1.68 +#define MAX_MODE_SEPIRQ_OFF 0
1.69 +#define MAX_MODE_SEPIRQ_ON 16
1.70 +#define MAX_MODE_DMPULLDN 64
1.71 +#define MAX_MODE_DPPULLDN 128
1.72 +
1.73 +#define max_reg(n) ((uint8_t) (n << 3))
1.74 +#define max_reg_read(n) (max_reg(n) | MAX_REG_READ)
1.75 +#define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE)
1.76 +
1.77 +struct timespec tCSS = {0, 20},
1.78 + tL = {0, 30},
1.79 + tCSW = {0, 200},
1.80 + tCL = {0, 17},
1.81 + tCH = {0, 17},
1.82 + tDS = {0, 5},
1.83 + tDH = {0, 10},
1.84 + tDO = {0, 15},
1.85 + tDI = {0, 15},
1.86 + tON = {0, 4},
1.87 + tRESET = {0, 200},
1.88 + tTEST = {0, 100};
1.89 +
1.90 +void spi_begin()
1.91 +{
1.92 + CLR(MAX_SS);
1.93 + nanosleep(&tL, NULL); /* tCSS is the minimum, but tL is more conservative */
1.94 +}
1.95 +
1.96 +void spi_end()
1.97 +{
1.98 + SET(MAX_SS);
1.99 + nanosleep(&tCSW, NULL);
1.100 +}
1.101 +
1.102 +/**
1.103 + * Send the given value via MOSI while receiving a value via MISO.
1.104 + * This requires full-duplex SPI and will produce a status value for the first
1.105 + * value sent (the command).
1.106 + */
1.107 +uint8_t spi_sendrecv(uint8_t v)
1.108 +{
1.109 + uint8_t result = 0;
1.110 + uint8_t mask;
1.111 +
1.112 + for (mask = 0x80; mask; mask >>= 1)
1.113 + {
1.114 + if (v & mask)
1.115 + {
1.116 + printf("1");
1.117 + SET(MAX_MOSI);
1.118 + }
1.119 + else
1.120 + {
1.121 + printf("0");
1.122 + CLR(MAX_MOSI);
1.123 + }
1.124 +
1.125 + /* Wait for stable output signal. */
1.126 +
1.127 + nanosleep(&tDS, NULL);
1.128 +
1.129 + SET(MAX_SCLK);
1.130 +
1.131 + if (PIN(MAX_MISO))
1.132 + result |= mask;
1.133 +
1.134 + nanosleep(&tCH, NULL);
1.135 + CLR(MAX_SCLK);
1.136 + nanosleep(&tCL, NULL);
1.137 + }
1.138 +
1.139 + printf("\n");
1.140 + return result;
1.141 +}
1.142 +
1.143 +void spi_send(uint8_t v)
1.144 +{
1.145 + uint8_t mask;
1.146 +
1.147 + OUT(MAX_MOSI);
1.148 +
1.149 + for (mask = 0x80; mask; mask >>= 1)
1.150 + {
1.151 + if (v & mask)
1.152 + {
1.153 + printf("1");
1.154 + SET(MAX_MOSI);
1.155 + }
1.156 + else
1.157 + {
1.158 + printf("0");
1.159 + CLR(MAX_MOSI);
1.160 + }
1.161 +
1.162 + nanosleep(&tDS, NULL);
1.163 +
1.164 + SET(MAX_SCLK);
1.165 + nanosleep(&tCH, NULL);
1.166 + CLR(MAX_SCLK);
1.167 + nanosleep(&tDO, NULL);
1.168 + }
1.169 +
1.170 + printf("\n");
1.171 +}
1.172 +
1.173 +uint8_t spi_recv()
1.174 +{
1.175 + uint8_t mask, result = 0;
1.176 +
1.177 + IN(MAX_MOSI);
1.178 +
1.179 + for (mask = 0x80; mask; mask >>= 1)
1.180 + {
1.181 + nanosleep(&tON, NULL);
1.182 +
1.183 + SET(MAX_SCLK);
1.184 +
1.185 + if (PIN(MAX_MOSI))
1.186 + {
1.187 + printf("1");
1.188 + result |= mask;
1.189 + }
1.190 + else
1.191 + printf("0");
1.192 +
1.193 + nanosleep(&tCH, NULL);
1.194 + CLR(MAX_SCLK);
1.195 + nanosleep(&tDO, NULL);
1.196 + }
1.197 +
1.198 + printf("\n");
1.199 + return result;
1.200 +}
1.201 +
1.202 +int main(int argc, char *argv[])
1.203 +{
1.204 + uint8_t status = 0, revision = 0, hrsl = 0;
1.205 +
1.206 + if (ubb_open(0) < 0) {
1.207 + perror("ubb_open");
1.208 + return 1;
1.209 + }
1.210 +
1.211 + ubb_power(1);
1.212 + printf("Power on.\n");
1.213 +
1.214 + OUT(MAX_SS);
1.215 + OUT(MAX_MOSI);
1.216 + OUT(MAX_SCLK);
1.217 + OUT(MAX_RESET);
1.218 + IN(MAX_INT);
1.219 + IN(MAX_MISO);
1.220 +
1.221 + /* Initialise SPI. */
1.222 + /* Set SS to 1 (or SS~ to 0). */
1.223 +
1.224 + SET(MAX_SS);
1.225 + CLR(MAX_MOSI);
1.226 + CLR(MAX_SCLK);
1.227 + CLR(MAX_RESET);
1.228 +
1.229 + /* Initialise the MAX3421E. */
1.230 +
1.231 + /* Set full-duplex, interrupt signalling. */
1.232 +
1.233 + printf("Setting pin control...\n");
1.234 + spi_begin();
1.235 + spi_sendrecv(max_reg_write(MAX_REG_PINCTL));
1.236 + spi_sendrecv(MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL);
1.237 + spi_end();
1.238 + printf("INT set to %d\n", PIN(MAX_INT));
1.239 +
1.240 + SET(MAX_RESET);
1.241 + nanosleep(&tRESET, NULL);
1.242 + CLR(MAX_RESET);
1.243 +
1.244 + printf("Resetting...\n");
1.245 + spi_begin();
1.246 + spi_sendrecv(max_reg_write(MAX_REG_USBCTL));
1.247 + spi_sendrecv(MAX_USBCTL_CHIPRES);
1.248 + spi_end();
1.249 +
1.250 + printf("Clearing the reset...\n");
1.251 + spi_begin();
1.252 + spi_sendrecv(max_reg_write(MAX_REG_USBCTL));
1.253 + spi_sendrecv(0);
1.254 + spi_end();
1.255 +
1.256 + /* Set host mode. */
1.257 +
1.258 + printf("Setting mode...\n");
1.259 + spi_begin();
1.260 + spi_sendrecv(max_reg_write(MAX_REG_MODE));
1.261 + spi_sendrecv(MAX_MODE_HOST | MAX_MODE_SEPIRQ_OFF | MAX_MODE_DMPULLDN | MAX_MODE_DPPULLDN);
1.262 + spi_end();
1.263 + printf("INT set to %d\n", PIN(MAX_INT));
1.264 +
1.265 + /* Read from the REVISION register. */
1.266 +
1.267 + printf("Reading...\n");
1.268 + spi_begin();
1.269 + status = spi_sendrecv(max_reg_read(MAX_REG_REVISION));
1.270 + revision = spi_sendrecv(0);
1.271 + spi_end();
1.272 + printf("Status = %x\n", status);
1.273 + printf("Revision = %x\n", revision);
1.274 + printf("INT set to %d\n", PIN(MAX_INT));
1.275 +
1.276 + printf("HRSL...\n");
1.277 + spi_begin();
1.278 + status = spi_sendrecv(max_reg_read(MAX_REG_HRSL));
1.279 + hrsl = spi_sendrecv(0);
1.280 + spi_end();
1.281 + printf("Status = %x\n", status);
1.282 + printf("HRSL = %x\n", hrsl);
1.283 + printf("INT set to %d\n", PIN(MAX_INT));
1.284 +
1.285 + printf("Closing...\n");
1.286 + ubb_close(0);
1.287 +
1.288 + return 0;
1.289 +}