1.1 --- a/spi.c Sun Mar 24 01:01:32 2013 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,310 +0,0 @@
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 -#include <unistd.h>
1.23 -
1.24 -/* Pin assignments:
1.25 - *
1.26 - * Sniffer UBB Shield
1.27 - * ------- ---- ------
1.28 - * DAT2 DAT2 9 (INT)
1.29 - * CD DAT3 10 (SS)
1.30 - * CMD CMD 7 (RESET)
1.31 - * VCC VDD VIN
1.32 - * CLK CLK 13 (SCLK)
1.33 - * GND GND GND
1.34 - * DAT0 DAT0 11 (MOSI)
1.35 - * DAT1 DAT1 12 (MISO)
1.36 - * 8 (GPX) (not assigned)
1.37 - */
1.38 -
1.39 -#define MAX_RESET UBB_CMD
1.40 -#define MAX_SCLK UBB_CLK
1.41 -#define MAX_MOSI UBB_DAT0
1.42 -#define MAX_MISO UBB_DAT1
1.43 -#define MAX_INT UBB_DAT2
1.44 -#define MAX_SS UBB_DAT3
1.45 -
1.46 -/* MAX3421E definitions. */
1.47 -
1.48 -#define MAX_REG_READ 0x00
1.49 -#define MAX_REG_WRITE 0x02
1.50 -
1.51 -#define MAX_REG_USBIRQ 13
1.52 -#define MAX_REG_USBIEN 14
1.53 -#define MAX_REG_USBCTL 15
1.54 -#define MAX_REG_CPUCTL 16
1.55 -#define MAX_REG_PINCTL 17
1.56 -#define MAX_REG_REVISION 18
1.57 -#define MAX_REG_GPINPOL 24
1.58 -#define MAX_REG_HIRQ 25
1.59 -#define MAX_REG_HIEN 26
1.60 -#define MAX_REG_MODE 27
1.61 -#define MAX_REG_HCTL 29
1.62 -#define MAX_REG_HRSL 31
1.63 -
1.64 -#define MAX_USBIRQ_OSCOKIRQ 1
1.65 -#define MAX_USBIRQ_NOVBUSIRQ 32
1.66 -#define MAX_USBIRQ_VBUSIRQ 64
1.67 -
1.68 -#define MAX_USBCTL_PWRDOWN 16
1.69 -#define MAX_USBCTL_CHIPRES 32
1.70 -
1.71 -#define MAX_CPUCTL_IE 1
1.72 -
1.73 -#define MAX_PINCTL_POSINT_LOW 0
1.74 -#define MAX_PINCTL_POSINT_HIGH 4
1.75 -#define MAX_PINCTL_INTLEVEL_EDGE 0
1.76 -#define MAX_PINCTL_INTLEVEL_LEVEL 8
1.77 -#define MAX_PINCTL_FDUPSPI_HALF 0
1.78 -#define MAX_PINCTL_FDUPSPI_FULL 16
1.79 -
1.80 -#define MAX_HIRQ_BUSEVENTIRQ 1
1.81 -#define MAX_HIRQ_RWUIRQ 2
1.82 -#define MAX_HIRQ_RCVDAVIRQ 4
1.83 -#define MAX_HIRQ_SNDBAVIRQ 8
1.84 -#define MAX_HIRQ_SUSDNIRQ 16
1.85 -#define MAX_HIRQ_CONDETIRQ 32
1.86 -#define MAX_HIRQ_FRAMEIRQ 64
1.87 -#define MAX_HIRQ_HXFRDNIRQ 128
1.88 -
1.89 -#define MAX_HIEN_CONDETIE 32
1.90 -
1.91 -#define MAX_MODE_PERIPHERAL 0
1.92 -#define MAX_MODE_HOST 1
1.93 -#define MAX_MODE_LOWSPEED 2
1.94 -#define MAX_MODE_SOFKAENAB 8
1.95 -#define MAX_MODE_SEPIRQ_OFF 0
1.96 -#define MAX_MODE_SEPIRQ_ON 16
1.97 -#define MAX_MODE_DMPULLDN 64
1.98 -#define MAX_MODE_DPPULLDN 128
1.99 -
1.100 -#define MAX_HCTL_SAMPLEBUS 4
1.101 -
1.102 -#define MAX_HRSL_JSTATUS 128
1.103 -#define MAX_HRSL_KSTATUS 64
1.104 -
1.105 -#define max_reg(n) ((uint8_t) (n << 3))
1.106 -#define max_reg_read(n) (max_reg(n) | MAX_REG_READ)
1.107 -#define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE)
1.108 -
1.109 -#define nanosleep(a, b) if (0)
1.110 -#define usleep(a) if (0)
1.111 -
1.112 -struct timespec tCSS = {0, 20},
1.113 - tL = {0, 30},
1.114 - tCSW = {0, 200},
1.115 - tCL = {0, 17},
1.116 - tCH = {0, 17},
1.117 - tDS = {0, 5},
1.118 - tDH = {0, 10},
1.119 - tDO = {0, 15},
1.120 - tDI = {0, 15},
1.121 - tON = {0, 4},
1.122 - tRESET = {0, 200},
1.123 - tTEST = {0, 100};
1.124 -
1.125 -void spi_begin()
1.126 -{
1.127 - CLR(MAX_SS);
1.128 - nanosleep(&tL, NULL); /* tCSS is the minimum, but tL is more conservative */
1.129 -}
1.130 -
1.131 -void spi_end()
1.132 -{
1.133 - SET(MAX_SS);
1.134 - nanosleep(&tCSW, NULL);
1.135 -}
1.136 -
1.137 -/**
1.138 - * Send the given value via MOSI while receiving a value via MISO.
1.139 - * This requires full-duplex SPI and will produce a status value for the first
1.140 - * value sent (the command).
1.141 - */
1.142 -uint8_t spi_sendrecv(uint8_t v)
1.143 -{
1.144 - uint8_t result = 0;
1.145 - uint8_t mask;
1.146 -
1.147 - for (mask = 0x80; mask; mask >>= 1)
1.148 - {
1.149 - if (v & mask)
1.150 - {
1.151 - #ifdef DEBUG
1.152 - printf("1");
1.153 - #endif
1.154 - SET(MAX_MOSI);
1.155 - }
1.156 - else
1.157 - {
1.158 - #ifdef DEBUG
1.159 - printf("0");
1.160 - #endif
1.161 - CLR(MAX_MOSI);
1.162 - }
1.163 -
1.164 - /* Wait for stable output signal. */
1.165 -
1.166 - nanosleep(&tDS, NULL);
1.167 -
1.168 - SET(MAX_SCLK);
1.169 -
1.170 - if (PIN(MAX_MISO))
1.171 - result |= mask;
1.172 -
1.173 - nanosleep(&tCH, NULL);
1.174 - CLR(MAX_SCLK);
1.175 - nanosleep(&tCL, NULL);
1.176 - }
1.177 -
1.178 - #ifdef DEBUG
1.179 - printf("\n");
1.180 - #endif
1.181 - return result;
1.182 -}
1.183 -
1.184 -uint8_t max_read(uint8_t reg, uint8_t *status)
1.185 -{
1.186 - uint8_t result = 0, tmpstatus = 0;
1.187 -
1.188 - tmpstatus = 0;
1.189 -
1.190 - spi_begin();
1.191 - tmpstatus = spi_sendrecv(max_reg_read(reg));
1.192 - result = spi_sendrecv(0);
1.193 - spi_end();
1.194 -
1.195 - if (status != NULL)
1.196 - *status = tmpstatus;
1.197 -
1.198 - return result;
1.199 -}
1.200 -
1.201 -uint8_t max_write(uint8_t reg, uint8_t value)
1.202 -{
1.203 - uint8_t status = 0;
1.204 -
1.205 - spi_begin();
1.206 - status = spi_sendrecv(max_reg_write(reg));
1.207 - spi_sendrecv(value);
1.208 - spi_end();
1.209 -
1.210 - return status;
1.211 -}
1.212 -
1.213 -void chipreset()
1.214 -{
1.215 - printf("Resetting...\n");
1.216 - max_write(MAX_REG_USBCTL, MAX_USBCTL_CHIPRES);
1.217 -
1.218 - printf("Clearing the reset...\n");
1.219 - max_write(MAX_REG_USBCTL, 0);
1.220 -}
1.221 -
1.222 -uint8_t check()
1.223 -{
1.224 - uint8_t oscillator;
1.225 -
1.226 - oscillator = max_read(MAX_REG_USBIRQ, NULL);
1.227 -
1.228 - return (oscillator & ~(MAX_USBIRQ_NOVBUSIRQ | MAX_USBIRQ_VBUSIRQ)) == MAX_USBIRQ_OSCOKIRQ;
1.229 -}
1.230 -
1.231 -uint8_t wait()
1.232 -{
1.233 - uint16_t timeout = 1024;
1.234 -
1.235 - /* Wait for the oscillator before performing USB activity. */
1.236 -
1.237 - printf("Waiting...\n");
1.238 -
1.239 - while ((timeout > 0) && (!check()))
1.240 - {
1.241 - usleep(3000); /* 3ms */
1.242 - timeout--;
1.243 - }
1.244 -
1.245 - printf("Iterations remaining: %d\n", timeout);
1.246 -
1.247 - return timeout;
1.248 -}
1.249 -
1.250 -int main(int argc, char *argv[])
1.251 -{
1.252 - uint8_t status = 0, revision = 0, result = 0;
1.253 - uint16_t count;
1.254 -
1.255 - if (ubb_open(0) < 0) {
1.256 - perror("ubb_open");
1.257 - return 1;
1.258 - }
1.259 -
1.260 - ubb_power(1);
1.261 - printf("Power on.\n");
1.262 -
1.263 - OUT(MAX_SS);
1.264 - OUT(MAX_MOSI);
1.265 - OUT(MAX_SCLK);
1.266 - OUT(MAX_RESET);
1.267 - IN(MAX_INT);
1.268 - IN(MAX_MISO);
1.269 -
1.270 - /* Initialise SPI. */
1.271 - /* Set SS# to 1. */
1.272 -
1.273 - SET(MAX_SS);
1.274 - CLR(MAX_MOSI);
1.275 - CLR(MAX_SCLK);
1.276 - SET(MAX_RESET);
1.277 -
1.278 - /* Initialise the MAX3421E. */
1.279 -
1.280 - /* Set full-duplex, interrupt signalling. */
1.281 -
1.282 - printf("Setting pin control...\n");
1.283 - max_write(MAX_REG_PINCTL, MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL);
1.284 -
1.285 - chipreset();
1.286 - printf("Ready? %d\n", wait());
1.287 -
1.288 - /* Read from the REVISION register. */
1.289 -
1.290 - printf("Reading...\n");
1.291 - revision = max_read(MAX_REG_REVISION, &status);
1.292 - printf("Status = %x\n", status);
1.293 - printf("Revision = %x\n", revision);
1.294 -
1.295 - /* Check various registers. */
1.296 -
1.297 - for (count = 0; count < 256; count++)
1.298 - {
1.299 - max_write(MAX_REG_GPINPOL, count);
1.300 - result = max_read(MAX_REG_GPINPOL, NULL);
1.301 - if (count != result)
1.302 - {
1.303 - printf("Count: %d\n", count);
1.304 - printf("Retrieved: %d\n", result);
1.305 - printf("Status = %x\n", status);
1.306 - }
1.307 - }
1.308 -
1.309 - printf("Closing...\n");
1.310 - ubb_close(0);
1.311 -
1.312 - return 0;
1.313 -}