ben-arduino-usb

Changeset

37:e70891fd5413
2013-03-24 Paul Boddie raw files shortlog changelog graph Moved various experiments into the examples directory. default tip
examples/shift.c (file) examples/spi.c (file) shift.c spi.c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/examples/shift.c	Sun Mar 24 19:54:16 2013 +0000
     1.3 @@ -0,0 +1,124 @@
     1.4 +#include <ubb/ubb.h>
     1.5 +#include <stdio.h>
     1.6 +#include <time.h>
     1.7 +
     1.8 +/* Pin assignments:
     1.9 + *
    1.10 + *           M74HC595B1R
    1.11 + *
    1.12 + *           QB |----| VCC   UBB_VDD
    1.13 + *           QC |    | QA
    1.14 + *           QD |    | SI    UBB_DAT2
    1.15 + *           QE |    | G     UBB_DAT0
    1.16 + *           QF |    | RCK   UBB_DAT1
    1.17 + *           QG |    | SCK   UBB_CLK
    1.18 + *           QH |    | SCLR  UBB_CMD
    1.19 + * UBB_GND  GND |----| QH'   UBB_DAT3
    1.20 + */
    1.21 +
    1.22 +#define SHIFT_SI    UBB_DAT2
    1.23 +#define SHIFT_QH    UBB_DAT3
    1.24 +#define SHIFT_SCLR  UBB_CMD
    1.25 +#define SHIFT_SCK   UBB_CLK
    1.26 +#define SHIFT_G     UBB_DAT0
    1.27 +#define SHIFT_RCK   UBB_DAT1
    1.28 +
    1.29 +struct timespec tSCKs   = {0, 15},
    1.30 +                tWH     = {0, 15},
    1.31 +                tWL     = {0, 15};
    1.32 +
    1.33 +void shift_in(uint8_t v)
    1.34 +{
    1.35 +    uint8_t mask;
    1.36 +
    1.37 +    for (mask = 0x80; mask; mask >>= 1)
    1.38 +    {
    1.39 +        if (v & mask)
    1.40 +        {
    1.41 +            printf("1");
    1.42 +            SET(SHIFT_SI);
    1.43 +        }
    1.44 +        else
    1.45 +        {
    1.46 +            printf("0");
    1.47 +            CLR(SHIFT_SI);
    1.48 +        }
    1.49 +
    1.50 +        nanosleep(&tSCKs, NULL);
    1.51 +        SET(SHIFT_SCK);
    1.52 +        nanosleep(&tWH, NULL);
    1.53 +        CLR(SHIFT_SCK);
    1.54 +    }
    1.55 +
    1.56 +    printf("\n");
    1.57 +}
    1.58 +
    1.59 +uint8_t shift_out()
    1.60 +{
    1.61 +    uint8_t mask, result = 0;
    1.62 +
    1.63 +    for (mask = 0x80; mask; mask >>= 1)
    1.64 +    {
    1.65 +        if (PIN(SHIFT_QH))
    1.66 +        {
    1.67 +            result |= mask;
    1.68 +            printf("1");
    1.69 +        }
    1.70 +        else
    1.71 +            printf("0");
    1.72 +
    1.73 +        nanosleep(&tSCKs, NULL);
    1.74 +        SET(SHIFT_SCK);
    1.75 +        nanosleep(&tWH, NULL);
    1.76 +        CLR(SHIFT_SCK);
    1.77 +    }
    1.78 +
    1.79 +    printf("\n");
    1.80 +    return result;
    1.81 +}
    1.82 +
    1.83 +int main(int argc, char *argv[])
    1.84 +{
    1.85 +    uint8_t result = 0;
    1.86 +
    1.87 +    if (ubb_open(0) < 0) {
    1.88 +        perror("ubb_open");
    1.89 +        return 1;
    1.90 +    }
    1.91 +
    1.92 +    ubb_power(1);
    1.93 +    printf("Power on.\n");
    1.94 +
    1.95 +    OUT(SHIFT_SI);
    1.96 +    OUT(SHIFT_RCK);
    1.97 +    OUT(SHIFT_SCLR);
    1.98 +    OUT(SHIFT_SCK);
    1.99 +    OUT(SHIFT_G);
   1.100 +    IN(SHIFT_QH);
   1.101 +
   1.102 +    CLR(SHIFT_SCK);
   1.103 +    CLR(SHIFT_RCK);
   1.104 +
   1.105 +    /* Clear the register. */
   1.106 +
   1.107 +    CLR(SHIFT_SCLR);
   1.108 +    SET(SHIFT_SCK);
   1.109 +    nanosleep(&tWL, NULL);
   1.110 +    CLR(SHIFT_SCK);
   1.111 +    SET(SHIFT_SCLR);
   1.112 +
   1.113 +    /* Shift in a value. */
   1.114 +
   1.115 +    shift_in(0xa6);
   1.116 +
   1.117 +    /* Shift out the value. */
   1.118 +
   1.119 +    result = shift_out();
   1.120 +
   1.121 +    printf("Result: %x\n", result);
   1.122 +
   1.123 +    printf("Closing...\n");
   1.124 +    ubb_close(0);
   1.125 +
   1.126 +    return 0;
   1.127 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/examples/spi.c	Sun Mar 24 19:54:16 2013 +0000
     2.3 @@ -0,0 +1,310 @@
     2.4 +/*
     2.5 + * Ben NanoNote and Arduino USB Host shield communication.
     2.6 + *
     2.7 + * Copyright 2013 Paul Boddie
     2.8 + *
     2.9 + * SPI functions derived from those in lib/atben.c by Werner Almesberger:
    2.10 + *
    2.11 + * Copyright 2010-2011 Werner Almesberger
    2.12 + *
    2.13 + * This program is free software; you can redistribute it and/or modify
    2.14 + * it under the terms of the GNU General Public License as published by
    2.15 + * the Free Software Foundation; either version 2 of the License, or
    2.16 + * (at your option) any later version.
    2.17 + */
    2.18 +
    2.19 +#include <ubb/ubb.h>
    2.20 +#include <stdio.h>
    2.21 +#include <time.h>
    2.22 +#include <unistd.h>
    2.23 +
    2.24 +/* Pin assignments:
    2.25 + *
    2.26 + * Sniffer  UBB   Shield
    2.27 + * -------  ----  ------
    2.28 + * DAT2     DAT2       9 (INT)
    2.29 + * CD       DAT3      10 (SS)
    2.30 + * CMD      CMD        7 (RESET)
    2.31 + * VCC      VDD      VIN
    2.32 + * CLK      CLK       13 (SCLK)
    2.33 + * GND      GND      GND
    2.34 + * DAT0     DAT0      11 (MOSI)
    2.35 + * DAT1     DAT1      12 (MISO)
    2.36 + *                     8 (GPX) (not assigned)
    2.37 + */
    2.38 +
    2.39 +#define MAX_RESET UBB_CMD
    2.40 +#define MAX_SCLK  UBB_CLK
    2.41 +#define MAX_MOSI  UBB_DAT0
    2.42 +#define MAX_MISO  UBB_DAT1
    2.43 +#define MAX_INT   UBB_DAT2
    2.44 +#define MAX_SS    UBB_DAT3
    2.45 +
    2.46 +/* MAX3421E definitions. */
    2.47 +
    2.48 +#define MAX_REG_READ                0x00
    2.49 +#define MAX_REG_WRITE               0x02
    2.50 +
    2.51 +#define MAX_REG_USBIRQ              13
    2.52 +#define MAX_REG_USBIEN              14
    2.53 +#define MAX_REG_USBCTL              15
    2.54 +#define MAX_REG_CPUCTL              16
    2.55 +#define MAX_REG_PINCTL              17
    2.56 +#define MAX_REG_REVISION            18
    2.57 +#define MAX_REG_GPINPOL             24
    2.58 +#define MAX_REG_HIRQ                25
    2.59 +#define MAX_REG_HIEN                26
    2.60 +#define MAX_REG_MODE                27
    2.61 +#define MAX_REG_HCTL                29
    2.62 +#define MAX_REG_HRSL                31
    2.63 +
    2.64 +#define MAX_USBIRQ_OSCOKIRQ         1
    2.65 +#define MAX_USBIRQ_NOVBUSIRQ        32
    2.66 +#define MAX_USBIRQ_VBUSIRQ          64
    2.67 +
    2.68 +#define MAX_USBCTL_PWRDOWN          16
    2.69 +#define MAX_USBCTL_CHIPRES          32
    2.70 +
    2.71 +#define MAX_CPUCTL_IE               1
    2.72 +
    2.73 +#define MAX_PINCTL_POSINT_LOW       0
    2.74 +#define MAX_PINCTL_POSINT_HIGH      4
    2.75 +#define MAX_PINCTL_INTLEVEL_EDGE    0
    2.76 +#define MAX_PINCTL_INTLEVEL_LEVEL   8
    2.77 +#define MAX_PINCTL_FDUPSPI_HALF     0
    2.78 +#define MAX_PINCTL_FDUPSPI_FULL     16
    2.79 +
    2.80 +#define MAX_HIRQ_BUSEVENTIRQ        1
    2.81 +#define MAX_HIRQ_RWUIRQ             2
    2.82 +#define MAX_HIRQ_RCVDAVIRQ          4
    2.83 +#define MAX_HIRQ_SNDBAVIRQ          8
    2.84 +#define MAX_HIRQ_SUSDNIRQ           16
    2.85 +#define MAX_HIRQ_CONDETIRQ          32
    2.86 +#define MAX_HIRQ_FRAMEIRQ           64
    2.87 +#define MAX_HIRQ_HXFRDNIRQ          128
    2.88 +
    2.89 +#define MAX_HIEN_CONDETIE           32
    2.90 +
    2.91 +#define MAX_MODE_PERIPHERAL         0
    2.92 +#define MAX_MODE_HOST               1
    2.93 +#define MAX_MODE_LOWSPEED           2
    2.94 +#define MAX_MODE_SOFKAENAB          8
    2.95 +#define MAX_MODE_SEPIRQ_OFF         0
    2.96 +#define MAX_MODE_SEPIRQ_ON          16
    2.97 +#define MAX_MODE_DMPULLDN           64
    2.98 +#define MAX_MODE_DPPULLDN           128
    2.99 +
   2.100 +#define MAX_HCTL_SAMPLEBUS          4
   2.101 +
   2.102 +#define MAX_HRSL_JSTATUS            128
   2.103 +#define MAX_HRSL_KSTATUS            64
   2.104 +
   2.105 +#define max_reg(n) ((uint8_t) (n << 3))
   2.106 +#define max_reg_read(n) (max_reg(n) | MAX_REG_READ)
   2.107 +#define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE)
   2.108 +
   2.109 +#define nanosleep(a, b) if (0)
   2.110 +#define usleep(a) if (0)
   2.111 +
   2.112 +struct timespec tCSS   = {0, 20},
   2.113 +                tL     = {0, 30},
   2.114 +                tCSW   = {0, 200},
   2.115 +                tCL    = {0, 17},
   2.116 +                tCH    = {0, 17},
   2.117 +                tDS    = {0, 5},
   2.118 +                tDH    = {0, 10},
   2.119 +                tDO    = {0, 15},
   2.120 +                tDI    = {0, 15},
   2.121 +                tON    = {0, 4},
   2.122 +                tRESET = {0, 200},
   2.123 +                tTEST  = {0, 100};
   2.124 +
   2.125 +void spi_begin()
   2.126 +{
   2.127 +    CLR(MAX_SS);
   2.128 +    nanosleep(&tL, NULL); /* tCSS is the minimum, but tL is more conservative */
   2.129 +}
   2.130 +
   2.131 +void spi_end()
   2.132 +{
   2.133 +    SET(MAX_SS);
   2.134 +    nanosleep(&tCSW, NULL);
   2.135 +}
   2.136 +
   2.137 +/**
   2.138 + * Send the given value via MOSI while receiving a value via MISO.
   2.139 + * This requires full-duplex SPI and will produce a status value for the first
   2.140 + * value sent (the command).
   2.141 + */
   2.142 +uint8_t spi_sendrecv(uint8_t v)
   2.143 +{
   2.144 +    uint8_t result = 0;
   2.145 +    uint8_t mask;
   2.146 +
   2.147 +    for (mask = 0x80; mask; mask >>= 1)
   2.148 +    {
   2.149 +        if (v & mask)
   2.150 +        {
   2.151 +            #ifdef DEBUG
   2.152 +            printf("1");
   2.153 +            #endif
   2.154 +            SET(MAX_MOSI);
   2.155 +        }
   2.156 +        else
   2.157 +        {
   2.158 +            #ifdef DEBUG
   2.159 +            printf("0");
   2.160 +            #endif
   2.161 +            CLR(MAX_MOSI);
   2.162 +        }
   2.163 +
   2.164 +        /* Wait for stable output signal. */
   2.165 +
   2.166 +        nanosleep(&tDS, NULL);
   2.167 +
   2.168 +        SET(MAX_SCLK);
   2.169 +
   2.170 +        if (PIN(MAX_MISO))
   2.171 +            result |= mask;
   2.172 +
   2.173 +        nanosleep(&tCH, NULL);
   2.174 +        CLR(MAX_SCLK);
   2.175 +        nanosleep(&tCL, NULL);
   2.176 +    }
   2.177 +
   2.178 +    #ifdef DEBUG
   2.179 +    printf("\n");
   2.180 +    #endif
   2.181 +    return result;
   2.182 +}
   2.183 +
   2.184 +uint8_t max_read(uint8_t reg, uint8_t *status)
   2.185 +{
   2.186 +    uint8_t result = 0, tmpstatus = 0;
   2.187 +
   2.188 +    tmpstatus = 0;
   2.189 +
   2.190 +    spi_begin();
   2.191 +    tmpstatus = spi_sendrecv(max_reg_read(reg));
   2.192 +    result = spi_sendrecv(0);
   2.193 +    spi_end();
   2.194 +
   2.195 +    if (status != NULL)
   2.196 +        *status = tmpstatus;
   2.197 +
   2.198 +    return result;
   2.199 +}
   2.200 +
   2.201 +uint8_t max_write(uint8_t reg, uint8_t value)
   2.202 +{
   2.203 +    uint8_t status = 0;
   2.204 +
   2.205 +    spi_begin();
   2.206 +    status = spi_sendrecv(max_reg_write(reg));
   2.207 +    spi_sendrecv(value);
   2.208 +    spi_end();
   2.209 +
   2.210 +    return status;
   2.211 +}
   2.212 +
   2.213 +void chipreset()
   2.214 +{
   2.215 +    printf("Resetting...\n");
   2.216 +    max_write(MAX_REG_USBCTL, MAX_USBCTL_CHIPRES);
   2.217 +
   2.218 +    printf("Clearing the reset...\n");
   2.219 +    max_write(MAX_REG_USBCTL, 0);
   2.220 +}
   2.221 +
   2.222 +uint8_t check()
   2.223 +{
   2.224 +    uint8_t oscillator;
   2.225 +
   2.226 +    oscillator = max_read(MAX_REG_USBIRQ, NULL);
   2.227 +
   2.228 +    return (oscillator & ~(MAX_USBIRQ_NOVBUSIRQ | MAX_USBIRQ_VBUSIRQ)) == MAX_USBIRQ_OSCOKIRQ;
   2.229 +}
   2.230 +
   2.231 +uint8_t wait()
   2.232 +{
   2.233 +    uint16_t timeout = 1024;
   2.234 +
   2.235 +    /* Wait for the oscillator before performing USB activity. */
   2.236 +
   2.237 +    printf("Waiting...\n");
   2.238 +
   2.239 +    while ((timeout > 0) && (!check()))
   2.240 +    {
   2.241 +        usleep(3000); /* 3ms */
   2.242 +        timeout--;
   2.243 +    }
   2.244 +
   2.245 +    printf("Iterations remaining: %d\n", timeout);
   2.246 +
   2.247 +    return timeout;
   2.248 +}
   2.249 +
   2.250 +int main(int argc, char *argv[])
   2.251 +{
   2.252 +    uint8_t status = 0, revision = 0, result = 0;
   2.253 +    uint16_t count;
   2.254 +
   2.255 +    if (ubb_open(0) < 0) {
   2.256 +        perror("ubb_open");
   2.257 +        return 1;
   2.258 +    }
   2.259 +
   2.260 +    ubb_power(1);
   2.261 +    printf("Power on.\n");
   2.262 +
   2.263 +    OUT(MAX_SS);
   2.264 +    OUT(MAX_MOSI);
   2.265 +    OUT(MAX_SCLK);
   2.266 +    OUT(MAX_RESET);
   2.267 +    IN(MAX_INT);
   2.268 +    IN(MAX_MISO);
   2.269 +
   2.270 +    /* Initialise SPI. */
   2.271 +    /* Set SS# to 1. */
   2.272 +
   2.273 +    SET(MAX_SS);
   2.274 +    CLR(MAX_MOSI);
   2.275 +    CLR(MAX_SCLK);
   2.276 +    SET(MAX_RESET);
   2.277 +
   2.278 +    /* Initialise the MAX3421E. */
   2.279 +
   2.280 +    /* Set full-duplex, interrupt signalling. */
   2.281 +
   2.282 +    printf("Setting pin control...\n");
   2.283 +    max_write(MAX_REG_PINCTL, MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL);
   2.284 +
   2.285 +    chipreset();
   2.286 +    printf("Ready? %d\n", wait());
   2.287 +
   2.288 +    /* Read from the REVISION register. */
   2.289 +
   2.290 +    printf("Reading...\n");
   2.291 +    revision = max_read(MAX_REG_REVISION, &status);
   2.292 +    printf("Status = %x\n", status);
   2.293 +    printf("Revision = %x\n", revision);
   2.294 +
   2.295 +    /* Check various registers. */
   2.296 +
   2.297 +    for (count = 0; count < 256; count++)
   2.298 +    {
   2.299 +        max_write(MAX_REG_GPINPOL, count);
   2.300 +        result = max_read(MAX_REG_GPINPOL, NULL);
   2.301 +        if (count != result)
   2.302 +        {
   2.303 +            printf("Count: %d\n", count);
   2.304 +            printf("Retrieved: %d\n", result);
   2.305 +            printf("Status = %x\n", status);
   2.306 +        }
   2.307 +    }
   2.308 +
   2.309 +    printf("Closing...\n");
   2.310 +    ubb_close(0);
   2.311 +
   2.312 +    return 0;
   2.313 +}
     3.1 --- a/shift.c	Sun Mar 24 01:01:32 2013 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,124 +0,0 @@
     3.4 -#include <ubb/ubb.h>
     3.5 -#include <stdio.h>
     3.6 -#include <time.h>
     3.7 -
     3.8 -/* Pin assignments:
     3.9 - *
    3.10 - *           M74HC595B1R
    3.11 - *
    3.12 - *           QB |----| VCC   UBB_VDD
    3.13 - *           QC |    | QA
    3.14 - *           QD |    | SI    UBB_DAT2
    3.15 - *           QE |    | G     UBB_DAT0
    3.16 - *           QF |    | RCK   UBB_DAT1
    3.17 - *           QG |    | SCK   UBB_CLK
    3.18 - *           QH |    | SCLR  UBB_CMD
    3.19 - * UBB_GND  GND |----| QH'   UBB_DAT3
    3.20 - */
    3.21 -
    3.22 -#define SHIFT_SI    UBB_DAT2
    3.23 -#define SHIFT_QH    UBB_DAT3
    3.24 -#define SHIFT_SCLR  UBB_CMD
    3.25 -#define SHIFT_SCK   UBB_CLK
    3.26 -#define SHIFT_G     UBB_DAT0
    3.27 -#define SHIFT_RCK   UBB_DAT1
    3.28 -
    3.29 -struct timespec tSCKs   = {0, 15},
    3.30 -                tWH     = {0, 15},
    3.31 -                tWL     = {0, 15};
    3.32 -
    3.33 -void shift_in(uint8_t v)
    3.34 -{
    3.35 -    uint8_t mask;
    3.36 -
    3.37 -    for (mask = 0x80; mask; mask >>= 1)
    3.38 -    {
    3.39 -        if (v & mask)
    3.40 -        {
    3.41 -            printf("1");
    3.42 -            SET(SHIFT_SI);
    3.43 -        }
    3.44 -        else
    3.45 -        {
    3.46 -            printf("0");
    3.47 -            CLR(SHIFT_SI);
    3.48 -        }
    3.49 -
    3.50 -        nanosleep(&tSCKs, NULL);
    3.51 -        SET(SHIFT_SCK);
    3.52 -        nanosleep(&tWH, NULL);
    3.53 -        CLR(SHIFT_SCK);
    3.54 -    }
    3.55 -
    3.56 -    printf("\n");
    3.57 -}
    3.58 -
    3.59 -uint8_t shift_out()
    3.60 -{
    3.61 -    uint8_t mask, result = 0;
    3.62 -
    3.63 -    for (mask = 0x80; mask; mask >>= 1)
    3.64 -    {
    3.65 -        if (PIN(SHIFT_QH))
    3.66 -        {
    3.67 -            result |= mask;
    3.68 -            printf("1");
    3.69 -        }
    3.70 -        else
    3.71 -            printf("0");
    3.72 -
    3.73 -        nanosleep(&tSCKs, NULL);
    3.74 -        SET(SHIFT_SCK);
    3.75 -        nanosleep(&tWH, NULL);
    3.76 -        CLR(SHIFT_SCK);
    3.77 -    }
    3.78 -
    3.79 -    printf("\n");
    3.80 -    return result;
    3.81 -}
    3.82 -
    3.83 -int main(int argc, char *argv[])
    3.84 -{
    3.85 -    uint8_t result = 0;
    3.86 -
    3.87 -    if (ubb_open(0) < 0) {
    3.88 -        perror("ubb_open");
    3.89 -        return 1;
    3.90 -    }
    3.91 -
    3.92 -    ubb_power(1);
    3.93 -    printf("Power on.\n");
    3.94 -
    3.95 -    OUT(SHIFT_SI);
    3.96 -    OUT(SHIFT_RCK);
    3.97 -    OUT(SHIFT_SCLR);
    3.98 -    OUT(SHIFT_SCK);
    3.99 -    OUT(SHIFT_G);
   3.100 -    IN(SHIFT_QH);
   3.101 -
   3.102 -    CLR(SHIFT_SCK);
   3.103 -    CLR(SHIFT_RCK);
   3.104 -
   3.105 -    /* Clear the register. */
   3.106 -
   3.107 -    CLR(SHIFT_SCLR);
   3.108 -    SET(SHIFT_SCK);
   3.109 -    nanosleep(&tWL, NULL);
   3.110 -    CLR(SHIFT_SCK);
   3.111 -    SET(SHIFT_SCLR);
   3.112 -
   3.113 -    /* Shift in a value. */
   3.114 -
   3.115 -    shift_in(0xa6);
   3.116 -
   3.117 -    /* Shift out the value. */
   3.118 -
   3.119 -    result = shift_out();
   3.120 -
   3.121 -    printf("Result: %x\n", result);
   3.122 -
   3.123 -    printf("Closing...\n");
   3.124 -    ubb_close(0);
   3.125 -
   3.126 -    return 0;
   3.127 -}
     4.1 --- a/spi.c	Sun Mar 24 01:01:32 2013 +0000
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,310 +0,0 @@
     4.4 -/*
     4.5 - * Ben NanoNote and Arduino USB Host shield communication.
     4.6 - *
     4.7 - * Copyright 2013 Paul Boddie
     4.8 - *
     4.9 - * SPI functions derived from those in lib/atben.c by Werner Almesberger:
    4.10 - *
    4.11 - * Copyright 2010-2011 Werner Almesberger
    4.12 - *
    4.13 - * This program is free software; you can redistribute it and/or modify
    4.14 - * it under the terms of the GNU General Public License as published by
    4.15 - * the Free Software Foundation; either version 2 of the License, or
    4.16 - * (at your option) any later version.
    4.17 - */
    4.18 -
    4.19 -#include <ubb/ubb.h>
    4.20 -#include <stdio.h>
    4.21 -#include <time.h>
    4.22 -#include <unistd.h>
    4.23 -
    4.24 -/* Pin assignments:
    4.25 - *
    4.26 - * Sniffer  UBB   Shield
    4.27 - * -------  ----  ------
    4.28 - * DAT2     DAT2       9 (INT)
    4.29 - * CD       DAT3      10 (SS)
    4.30 - * CMD      CMD        7 (RESET)
    4.31 - * VCC      VDD      VIN
    4.32 - * CLK      CLK       13 (SCLK)
    4.33 - * GND      GND      GND
    4.34 - * DAT0     DAT0      11 (MOSI)
    4.35 - * DAT1     DAT1      12 (MISO)
    4.36 - *                     8 (GPX) (not assigned)
    4.37 - */
    4.38 -
    4.39 -#define MAX_RESET UBB_CMD
    4.40 -#define MAX_SCLK  UBB_CLK
    4.41 -#define MAX_MOSI  UBB_DAT0
    4.42 -#define MAX_MISO  UBB_DAT1
    4.43 -#define MAX_INT   UBB_DAT2
    4.44 -#define MAX_SS    UBB_DAT3
    4.45 -
    4.46 -/* MAX3421E definitions. */
    4.47 -
    4.48 -#define MAX_REG_READ                0x00
    4.49 -#define MAX_REG_WRITE               0x02
    4.50 -
    4.51 -#define MAX_REG_USBIRQ              13
    4.52 -#define MAX_REG_USBIEN              14
    4.53 -#define MAX_REG_USBCTL              15
    4.54 -#define MAX_REG_CPUCTL              16
    4.55 -#define MAX_REG_PINCTL              17
    4.56 -#define MAX_REG_REVISION            18
    4.57 -#define MAX_REG_GPINPOL             24
    4.58 -#define MAX_REG_HIRQ                25
    4.59 -#define MAX_REG_HIEN                26
    4.60 -#define MAX_REG_MODE                27
    4.61 -#define MAX_REG_HCTL                29
    4.62 -#define MAX_REG_HRSL                31
    4.63 -
    4.64 -#define MAX_USBIRQ_OSCOKIRQ         1
    4.65 -#define MAX_USBIRQ_NOVBUSIRQ        32
    4.66 -#define MAX_USBIRQ_VBUSIRQ          64
    4.67 -
    4.68 -#define MAX_USBCTL_PWRDOWN          16
    4.69 -#define MAX_USBCTL_CHIPRES          32
    4.70 -
    4.71 -#define MAX_CPUCTL_IE               1
    4.72 -
    4.73 -#define MAX_PINCTL_POSINT_LOW       0
    4.74 -#define MAX_PINCTL_POSINT_HIGH      4
    4.75 -#define MAX_PINCTL_INTLEVEL_EDGE    0
    4.76 -#define MAX_PINCTL_INTLEVEL_LEVEL   8
    4.77 -#define MAX_PINCTL_FDUPSPI_HALF     0
    4.78 -#define MAX_PINCTL_FDUPSPI_FULL     16
    4.79 -
    4.80 -#define MAX_HIRQ_BUSEVENTIRQ        1
    4.81 -#define MAX_HIRQ_RWUIRQ             2
    4.82 -#define MAX_HIRQ_RCVDAVIRQ          4
    4.83 -#define MAX_HIRQ_SNDBAVIRQ          8
    4.84 -#define MAX_HIRQ_SUSDNIRQ           16
    4.85 -#define MAX_HIRQ_CONDETIRQ          32
    4.86 -#define MAX_HIRQ_FRAMEIRQ           64
    4.87 -#define MAX_HIRQ_HXFRDNIRQ          128
    4.88 -
    4.89 -#define MAX_HIEN_CONDETIE           32
    4.90 -
    4.91 -#define MAX_MODE_PERIPHERAL         0
    4.92 -#define MAX_MODE_HOST               1
    4.93 -#define MAX_MODE_LOWSPEED           2
    4.94 -#define MAX_MODE_SOFKAENAB          8
    4.95 -#define MAX_MODE_SEPIRQ_OFF         0
    4.96 -#define MAX_MODE_SEPIRQ_ON          16
    4.97 -#define MAX_MODE_DMPULLDN           64
    4.98 -#define MAX_MODE_DPPULLDN           128
    4.99 -
   4.100 -#define MAX_HCTL_SAMPLEBUS          4
   4.101 -
   4.102 -#define MAX_HRSL_JSTATUS            128
   4.103 -#define MAX_HRSL_KSTATUS            64
   4.104 -
   4.105 -#define max_reg(n) ((uint8_t) (n << 3))
   4.106 -#define max_reg_read(n) (max_reg(n) | MAX_REG_READ)
   4.107 -#define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE)
   4.108 -
   4.109 -#define nanosleep(a, b) if (0)
   4.110 -#define usleep(a) if (0)
   4.111 -
   4.112 -struct timespec tCSS   = {0, 20},
   4.113 -                tL     = {0, 30},
   4.114 -                tCSW   = {0, 200},
   4.115 -                tCL    = {0, 17},
   4.116 -                tCH    = {0, 17},
   4.117 -                tDS    = {0, 5},
   4.118 -                tDH    = {0, 10},
   4.119 -                tDO    = {0, 15},
   4.120 -                tDI    = {0, 15},
   4.121 -                tON    = {0, 4},
   4.122 -                tRESET = {0, 200},
   4.123 -                tTEST  = {0, 100};
   4.124 -
   4.125 -void spi_begin()
   4.126 -{
   4.127 -    CLR(MAX_SS);
   4.128 -    nanosleep(&tL, NULL); /* tCSS is the minimum, but tL is more conservative */
   4.129 -}
   4.130 -
   4.131 -void spi_end()
   4.132 -{
   4.133 -    SET(MAX_SS);
   4.134 -    nanosleep(&tCSW, NULL);
   4.135 -}
   4.136 -
   4.137 -/**
   4.138 - * Send the given value via MOSI while receiving a value via MISO.
   4.139 - * This requires full-duplex SPI and will produce a status value for the first
   4.140 - * value sent (the command).
   4.141 - */
   4.142 -uint8_t spi_sendrecv(uint8_t v)
   4.143 -{
   4.144 -    uint8_t result = 0;
   4.145 -    uint8_t mask;
   4.146 -
   4.147 -    for (mask = 0x80; mask; mask >>= 1)
   4.148 -    {
   4.149 -        if (v & mask)
   4.150 -        {
   4.151 -            #ifdef DEBUG
   4.152 -            printf("1");
   4.153 -            #endif
   4.154 -            SET(MAX_MOSI);
   4.155 -        }
   4.156 -        else
   4.157 -        {
   4.158 -            #ifdef DEBUG
   4.159 -            printf("0");
   4.160 -            #endif
   4.161 -            CLR(MAX_MOSI);
   4.162 -        }
   4.163 -
   4.164 -        /* Wait for stable output signal. */
   4.165 -
   4.166 -        nanosleep(&tDS, NULL);
   4.167 -
   4.168 -        SET(MAX_SCLK);
   4.169 -
   4.170 -        if (PIN(MAX_MISO))
   4.171 -            result |= mask;
   4.172 -
   4.173 -        nanosleep(&tCH, NULL);
   4.174 -        CLR(MAX_SCLK);
   4.175 -        nanosleep(&tCL, NULL);
   4.176 -    }
   4.177 -
   4.178 -    #ifdef DEBUG
   4.179 -    printf("\n");
   4.180 -    #endif
   4.181 -    return result;
   4.182 -}
   4.183 -
   4.184 -uint8_t max_read(uint8_t reg, uint8_t *status)
   4.185 -{
   4.186 -    uint8_t result = 0, tmpstatus = 0;
   4.187 -
   4.188 -    tmpstatus = 0;
   4.189 -
   4.190 -    spi_begin();
   4.191 -    tmpstatus = spi_sendrecv(max_reg_read(reg));
   4.192 -    result = spi_sendrecv(0);
   4.193 -    spi_end();
   4.194 -
   4.195 -    if (status != NULL)
   4.196 -        *status = tmpstatus;
   4.197 -
   4.198 -    return result;
   4.199 -}
   4.200 -
   4.201 -uint8_t max_write(uint8_t reg, uint8_t value)
   4.202 -{
   4.203 -    uint8_t status = 0;
   4.204 -
   4.205 -    spi_begin();
   4.206 -    status = spi_sendrecv(max_reg_write(reg));
   4.207 -    spi_sendrecv(value);
   4.208 -    spi_end();
   4.209 -
   4.210 -    return status;
   4.211 -}
   4.212 -
   4.213 -void chipreset()
   4.214 -{
   4.215 -    printf("Resetting...\n");
   4.216 -    max_write(MAX_REG_USBCTL, MAX_USBCTL_CHIPRES);
   4.217 -
   4.218 -    printf("Clearing the reset...\n");
   4.219 -    max_write(MAX_REG_USBCTL, 0);
   4.220 -}
   4.221 -
   4.222 -uint8_t check()
   4.223 -{
   4.224 -    uint8_t oscillator;
   4.225 -
   4.226 -    oscillator = max_read(MAX_REG_USBIRQ, NULL);
   4.227 -
   4.228 -    return (oscillator & ~(MAX_USBIRQ_NOVBUSIRQ | MAX_USBIRQ_VBUSIRQ)) == MAX_USBIRQ_OSCOKIRQ;
   4.229 -}
   4.230 -
   4.231 -uint8_t wait()
   4.232 -{
   4.233 -    uint16_t timeout = 1024;
   4.234 -
   4.235 -    /* Wait for the oscillator before performing USB activity. */
   4.236 -
   4.237 -    printf("Waiting...\n");
   4.238 -
   4.239 -    while ((timeout > 0) && (!check()))
   4.240 -    {
   4.241 -        usleep(3000); /* 3ms */
   4.242 -        timeout--;
   4.243 -    }
   4.244 -
   4.245 -    printf("Iterations remaining: %d\n", timeout);
   4.246 -
   4.247 -    return timeout;
   4.248 -}
   4.249 -
   4.250 -int main(int argc, char *argv[])
   4.251 -{
   4.252 -    uint8_t status = 0, revision = 0, result = 0;
   4.253 -    uint16_t count;
   4.254 -
   4.255 -    if (ubb_open(0) < 0) {
   4.256 -        perror("ubb_open");
   4.257 -        return 1;
   4.258 -    }
   4.259 -
   4.260 -    ubb_power(1);
   4.261 -    printf("Power on.\n");
   4.262 -
   4.263 -    OUT(MAX_SS);
   4.264 -    OUT(MAX_MOSI);
   4.265 -    OUT(MAX_SCLK);
   4.266 -    OUT(MAX_RESET);
   4.267 -    IN(MAX_INT);
   4.268 -    IN(MAX_MISO);
   4.269 -
   4.270 -    /* Initialise SPI. */
   4.271 -    /* Set SS# to 1. */
   4.272 -
   4.273 -    SET(MAX_SS);
   4.274 -    CLR(MAX_MOSI);
   4.275 -    CLR(MAX_SCLK);
   4.276 -    SET(MAX_RESET);
   4.277 -
   4.278 -    /* Initialise the MAX3421E. */
   4.279 -
   4.280 -    /* Set full-duplex, interrupt signalling. */
   4.281 -
   4.282 -    printf("Setting pin control...\n");
   4.283 -    max_write(MAX_REG_PINCTL, MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL);
   4.284 -
   4.285 -    chipreset();
   4.286 -    printf("Ready? %d\n", wait());
   4.287 -
   4.288 -    /* Read from the REVISION register. */
   4.289 -
   4.290 -    printf("Reading...\n");
   4.291 -    revision = max_read(MAX_REG_REVISION, &status);
   4.292 -    printf("Status = %x\n", status);
   4.293 -    printf("Revision = %x\n", revision);
   4.294 -
   4.295 -    /* Check various registers. */
   4.296 -
   4.297 -    for (count = 0; count < 256; count++)
   4.298 -    {
   4.299 -        max_write(MAX_REG_GPINPOL, count);
   4.300 -        result = max_read(MAX_REG_GPINPOL, NULL);
   4.301 -        if (count != result)
   4.302 -        {
   4.303 -            printf("Count: %d\n", count);
   4.304 -            printf("Retrieved: %d\n", result);
   4.305 -            printf("Status = %x\n", status);
   4.306 -        }
   4.307 -    }
   4.308 -
   4.309 -    printf("Closing...\n");
   4.310 -    ubb_close(0);
   4.311 -
   4.312 -    return 0;
   4.313 -}