1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Makefile Fri Feb 08 22:50:08 2013 +0000
1.3 @@ -0,0 +1,37 @@
1.4 +# Makefile - Build the UBB library
1.5 +#
1.6 +# Copyright 2013 Paul Boddie
1.7 +#
1.8 +# This program is free software; you can redistribute it and/or modify
1.9 +# it under the terms of the GNU General Public License as published by
1.10 +# the Free Software Foundation; either version 2 of the License, or
1.11 +# (at your option) any later version.
1.12 +
1.13 +LIBUBB = ../ben-blinkenlights/libubb
1.14 +SYSLIBS = ../openwrt-xburst/staging_dir/target-mipsel_eglibc-2.15/usr/lib
1.15 +
1.16 +ARCH = mipsel-openwrt-linux
1.17 +CC = $(ARCH)-gcc
1.18 +
1.19 +CFLAGS = -g -Wall -fPIC -march=mips32 -I$(LIBUBB)/include
1.20 +LDFLAGS = -lubb -L$(LIBUBB) #-static #-L$(SYSLIBS)
1.21 +
1.22 +TARGET = test
1.23 +SRC = test.c
1.24 +OBJ = $(SRC:.c=.o)
1.25 +
1.26 +.PHONY: all clean distclean
1.27 +
1.28 +all: $(TARGET)
1.29 +
1.30 +clean:
1.31 + rm -f $(OBJ) $(TARGET)
1.32 +
1.33 +distclean: clean
1.34 + echo "Nothing else to clean."
1.35 +
1.36 +$(TARGET): $(OBJ)
1.37 + $(CC) $(LDFLAGS) $< -o $@
1.38 +
1.39 +.c.o:
1.40 + $(CC) -c $(CFLAGS) $< -o $@
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/shift.c Fri Feb 08 22:50:08 2013 +0000
2.3 @@ -0,0 +1,124 @@
2.4 +#include <ubb/ubb.h>
2.5 +#include <stdio.h>
2.6 +#include <time.h>
2.7 +
2.8 +/* Pin assignments:
2.9 + *
2.10 + * M74HC595B1R
2.11 + *
2.12 + * QB |----| VCC UBB_VDD
2.13 + * QC | | QA
2.14 + * QD | | SI UBB_DAT2
2.15 + * QE | | G UBB_DAT0
2.16 + * QF | | RCK UBB_DAT1
2.17 + * QG | | SCK UBB_CLK
2.18 + * QH | | SCLR UBB_CMD
2.19 + * UBB_GND GND |----| QH' UBB_DAT3
2.20 + */
2.21 +
2.22 +#define SHIFT_SI UBB_DAT2
2.23 +#define SHIFT_QH UBB_DAT3
2.24 +#define SHIFT_SCLR UBB_CMD
2.25 +#define SHIFT_SCK UBB_CLK
2.26 +#define SHIFT_G UBB_DAT0
2.27 +#define SHIFT_RCK UBB_DAT1
2.28 +
2.29 +struct timespec tSCKs = {0, 15},
2.30 + tWH = {0, 15},
2.31 + tWL = {0, 15};
2.32 +
2.33 +void shift_in(uint8_t v)
2.34 +{
2.35 + uint8_t mask;
2.36 +
2.37 + for (mask = 0x80; mask; mask >>= 1)
2.38 + {
2.39 + if (v & mask)
2.40 + {
2.41 + printf("1");
2.42 + SET(SHIFT_SI);
2.43 + }
2.44 + else
2.45 + {
2.46 + printf("0");
2.47 + CLR(SHIFT_SI);
2.48 + }
2.49 +
2.50 + nanosleep(&tSCKs, NULL);
2.51 + SET(SHIFT_SCK);
2.52 + nanosleep(&tWH, NULL);
2.53 + CLR(SHIFT_SCK);
2.54 + }
2.55 +
2.56 + printf("\n");
2.57 +}
2.58 +
2.59 +uint8_t shift_out()
2.60 +{
2.61 + uint8_t mask, result = 0;
2.62 +
2.63 + for (mask = 0x80; mask; mask >>= 1)
2.64 + {
2.65 + if (PIN(SHIFT_QH))
2.66 + {
2.67 + result |= mask;
2.68 + printf("1");
2.69 + }
2.70 + else
2.71 + printf("0");
2.72 +
2.73 + nanosleep(&tSCKs, NULL);
2.74 + SET(SHIFT_SCK);
2.75 + nanosleep(&tWH, NULL);
2.76 + CLR(SHIFT_SCK);
2.77 + }
2.78 +
2.79 + printf("\n");
2.80 + return result;
2.81 +}
2.82 +
2.83 +int main(int argc, char *argv[])
2.84 +{
2.85 + uint8_t result = 0;
2.86 +
2.87 + if (ubb_open(0) < 0) {
2.88 + perror("ubb_open");
2.89 + return 1;
2.90 + }
2.91 +
2.92 + ubb_power(1);
2.93 + printf("Power on.\n");
2.94 +
2.95 + OUT(SHIFT_SI);
2.96 + OUT(SHIFT_RCK);
2.97 + OUT(SHIFT_SCLR);
2.98 + OUT(SHIFT_SCK);
2.99 + OUT(SHIFT_G);
2.100 + IN(SHIFT_QH);
2.101 +
2.102 + CLR(SHIFT_SCK);
2.103 + CLR(SHIFT_RCK);
2.104 +
2.105 + /* Clear the register. */
2.106 +
2.107 + CLR(SHIFT_SCLR);
2.108 + SET(SHIFT_SCK);
2.109 + nanosleep(&tWL, NULL);
2.110 + CLR(SHIFT_SCK);
2.111 + SET(SHIFT_SCLR);
2.112 +
2.113 + /* Shift in a value. */
2.114 +
2.115 + shift_in(0xa6);
2.116 +
2.117 + /* Shift out the value. */
2.118 +
2.119 + result = shift_out();
2.120 +
2.121 + printf("Result: %x\n", result);
2.122 +
2.123 + printf("Closing...\n");
2.124 + ubb_close(0);
2.125 +
2.126 + return 0;
2.127 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/test.c Fri Feb 08 22:50:08 2013 +0000
3.3 @@ -0,0 +1,286 @@
3.4 +/*
3.5 + * Ben NanoNote and Arduino USB Host shield communication.
3.6 + *
3.7 + * Copyright 2013 Paul Boddie
3.8 + *
3.9 + * SPI functions derived from those in lib/atben.c by Werner Almesberger:
3.10 + *
3.11 + * Copyright 2010-2011 Werner Almesberger
3.12 + *
3.13 + * This program is free software; you can redistribute it and/or modify
3.14 + * it under the terms of the GNU General Public License as published by
3.15 + * the Free Software Foundation; either version 2 of the License, or
3.16 + * (at your option) any later version.
3.17 + */
3.18 +
3.19 +#include <ubb/ubb.h>
3.20 +#include <stdio.h>
3.21 +#include <time.h>
3.22 +
3.23 +/* Pin assignments:
3.24 + *
3.25 + * Sniffer UBB Shield
3.26 + * ------- ---- ------
3.27 + * DAT2 DAT2 9 (INT)
3.28 + * CD DAT3 10 (SS)
3.29 + * CMD CMD 7 (RESET)
3.30 + * VCC VDD VIN
3.31 + * CLK CLK 13 (SCLK)
3.32 + * GND GND GND
3.33 + * DAT0 DAT0 11 (MOSI)
3.34 + * DAT1 DAT1 12 (MISO)
3.35 + * 8 (GPX) (not assigned)
3.36 + */
3.37 +
3.38 +#define MAX_RESET UBB_CMD
3.39 +#define MAX_SCLK UBB_CLK
3.40 +#define MAX_MOSI UBB_DAT0
3.41 +#define MAX_MISO UBB_DAT1
3.42 +#define MAX_INT UBB_DAT2
3.43 +#define MAX_SS UBB_DAT3
3.44 +
3.45 +/* MAX3421E definitions. */
3.46 +
3.47 +#define MAX_REG_READ 0x00
3.48 +#define MAX_REG_WRITE 0x02
3.49 +
3.50 +#define MAX_REG_USBCTL 15
3.51 +#define MAX_REG_PINCTL 17
3.52 +#define MAX_REG_REVISION 18
3.53 +#define MAX_REG_MODE 27
3.54 +#define MAX_REG_HRSL 31
3.55 +
3.56 +#define MAX_USBCTL_PWRDOWN 16
3.57 +#define MAX_USBCTL_CHIPRES 32
3.58 +
3.59 +#define MAX_PINCTL_POSINT_LOW 0
3.60 +#define MAX_PINCTL_POSINT_HIGH 4
3.61 +#define MAX_PINCTL_INTLEVEL_EDGE 0
3.62 +#define MAX_PINCTL_INTLEVEL_LEVEL 8
3.63 +#define MAX_PINCTL_FDUPSPI_HALF 0
3.64 +#define MAX_PINCTL_FDUPSPI_FULL 16
3.65 +
3.66 +#define MAX_MODE_PERIPHERAL 0
3.67 +#define MAX_MODE_HOST 1
3.68 +#define MAX_MODE_SEPIRQ_OFF 0
3.69 +#define MAX_MODE_SEPIRQ_ON 16
3.70 +#define MAX_MODE_DMPULLDN 64
3.71 +#define MAX_MODE_DPPULLDN 128
3.72 +
3.73 +#define max_reg(n) ((uint8_t) (n << 3))
3.74 +#define max_reg_read(n) (max_reg(n) | MAX_REG_READ)
3.75 +#define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE)
3.76 +
3.77 +struct timespec tCSS = {0, 20},
3.78 + tL = {0, 30},
3.79 + tCSW = {0, 200},
3.80 + tCL = {0, 17},
3.81 + tCH = {0, 17},
3.82 + tDS = {0, 5},
3.83 + tDH = {0, 10},
3.84 + tDO = {0, 15},
3.85 + tDI = {0, 15},
3.86 + tON = {0, 4},
3.87 + tRESET = {0, 200},
3.88 + tTEST = {0, 100};
3.89 +
3.90 +void spi_begin()
3.91 +{
3.92 + CLR(MAX_SS);
3.93 + nanosleep(&tL, NULL); /* tCSS is the minimum, but tL is more conservative */
3.94 +}
3.95 +
3.96 +void spi_end()
3.97 +{
3.98 + SET(MAX_SS);
3.99 + nanosleep(&tCSW, NULL);
3.100 +}
3.101 +
3.102 +/**
3.103 + * Send the given value via MOSI while receiving a value via MISO.
3.104 + * This requires full-duplex SPI and will produce a status value for the first
3.105 + * value sent (the command).
3.106 + */
3.107 +uint8_t spi_sendrecv(uint8_t v)
3.108 +{
3.109 + uint8_t result = 0;
3.110 + uint8_t mask;
3.111 +
3.112 + for (mask = 0x80; mask; mask >>= 1)
3.113 + {
3.114 + if (v & mask)
3.115 + {
3.116 + printf("1");
3.117 + SET(MAX_MOSI);
3.118 + }
3.119 + else
3.120 + {
3.121 + printf("0");
3.122 + CLR(MAX_MOSI);
3.123 + }
3.124 +
3.125 + /* Wait for stable output signal. */
3.126 +
3.127 + nanosleep(&tDS, NULL);
3.128 +
3.129 + SET(MAX_SCLK);
3.130 +
3.131 + if (PIN(MAX_MISO))
3.132 + result |= mask;
3.133 +
3.134 + nanosleep(&tCH, NULL);
3.135 + CLR(MAX_SCLK);
3.136 + nanosleep(&tCL, NULL);
3.137 + }
3.138 +
3.139 + printf("\n");
3.140 + return result;
3.141 +}
3.142 +
3.143 +void spi_send(uint8_t v)
3.144 +{
3.145 + uint8_t mask;
3.146 +
3.147 + OUT(MAX_MOSI);
3.148 +
3.149 + for (mask = 0x80; mask; mask >>= 1)
3.150 + {
3.151 + if (v & mask)
3.152 + {
3.153 + printf("1");
3.154 + SET(MAX_MOSI);
3.155 + }
3.156 + else
3.157 + {
3.158 + printf("0");
3.159 + CLR(MAX_MOSI);
3.160 + }
3.161 +
3.162 + nanosleep(&tDS, NULL);
3.163 +
3.164 + SET(MAX_SCLK);
3.165 + nanosleep(&tCH, NULL);
3.166 + CLR(MAX_SCLK);
3.167 + nanosleep(&tDO, NULL);
3.168 + }
3.169 +
3.170 + printf("\n");
3.171 +}
3.172 +
3.173 +uint8_t spi_recv()
3.174 +{
3.175 + uint8_t mask, result = 0;
3.176 +
3.177 + IN(MAX_MOSI);
3.178 +
3.179 + for (mask = 0x80; mask; mask >>= 1)
3.180 + {
3.181 + nanosleep(&tON, NULL);
3.182 +
3.183 + SET(MAX_SCLK);
3.184 +
3.185 + if (PIN(MAX_MOSI))
3.186 + {
3.187 + printf("1");
3.188 + result |= mask;
3.189 + }
3.190 + else
3.191 + printf("0");
3.192 +
3.193 + nanosleep(&tCH, NULL);
3.194 + CLR(MAX_SCLK);
3.195 + nanosleep(&tDO, NULL);
3.196 + }
3.197 +
3.198 + printf("\n");
3.199 + return result;
3.200 +}
3.201 +
3.202 +int main(int argc, char *argv[])
3.203 +{
3.204 + uint8_t status = 0, revision = 0, hrsl = 0;
3.205 +
3.206 + if (ubb_open(0) < 0) {
3.207 + perror("ubb_open");
3.208 + return 1;
3.209 + }
3.210 +
3.211 + ubb_power(1);
3.212 + printf("Power on.\n");
3.213 +
3.214 + OUT(MAX_SS);
3.215 + OUT(MAX_MOSI);
3.216 + OUT(MAX_SCLK);
3.217 + OUT(MAX_RESET);
3.218 + IN(MAX_INT);
3.219 + IN(MAX_MISO);
3.220 +
3.221 + /* Initialise SPI. */
3.222 + /* Set SS to 1 (or SS~ to 0). */
3.223 +
3.224 + SET(MAX_SS);
3.225 + CLR(MAX_MOSI);
3.226 + CLR(MAX_SCLK);
3.227 + CLR(MAX_RESET);
3.228 +
3.229 + /* Initialise the MAX3421E. */
3.230 +
3.231 + /* Set full-duplex, interrupt signalling. */
3.232 +
3.233 + printf("Setting pin control...\n");
3.234 + spi_begin();
3.235 + spi_sendrecv(max_reg_write(MAX_REG_PINCTL));
3.236 + spi_sendrecv(MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL);
3.237 + spi_end();
3.238 + printf("INT set to %d\n", PIN(MAX_INT));
3.239 +
3.240 + SET(MAX_RESET);
3.241 + nanosleep(&tRESET, NULL);
3.242 + CLR(MAX_RESET);
3.243 +
3.244 + printf("Resetting...\n");
3.245 + spi_begin();
3.246 + spi_sendrecv(max_reg_write(MAX_REG_USBCTL));
3.247 + spi_sendrecv(MAX_USBCTL_CHIPRES);
3.248 + spi_end();
3.249 +
3.250 + printf("Clearing the reset...\n");
3.251 + spi_begin();
3.252 + spi_sendrecv(max_reg_write(MAX_REG_USBCTL));
3.253 + spi_sendrecv(0);
3.254 + spi_end();
3.255 +
3.256 + /* Set host mode. */
3.257 +
3.258 + printf("Setting mode...\n");
3.259 + spi_begin();
3.260 + spi_sendrecv(max_reg_write(MAX_REG_MODE));
3.261 + spi_sendrecv(MAX_MODE_HOST | MAX_MODE_SEPIRQ_OFF | MAX_MODE_DMPULLDN | MAX_MODE_DPPULLDN);
3.262 + spi_end();
3.263 + printf("INT set to %d\n", PIN(MAX_INT));
3.264 +
3.265 + /* Read from the REVISION register. */
3.266 +
3.267 + printf("Reading...\n");
3.268 + spi_begin();
3.269 + status = spi_sendrecv(max_reg_read(MAX_REG_REVISION));
3.270 + revision = spi_sendrecv(0);
3.271 + spi_end();
3.272 + printf("Status = %x\n", status);
3.273 + printf("Revision = %x\n", revision);
3.274 + printf("INT set to %d\n", PIN(MAX_INT));
3.275 +
3.276 + printf("HRSL...\n");
3.277 + spi_begin();
3.278 + status = spi_sendrecv(max_reg_read(MAX_REG_HRSL));
3.279 + hrsl = spi_sendrecv(0);
3.280 + spi_end();
3.281 + printf("Status = %x\n", status);
3.282 + printf("HRSL = %x\n", hrsl);
3.283 + printf("INT set to %d\n", PIN(MAX_INT));
3.284 +
3.285 + printf("Closing...\n");
3.286 + ubb_close(0);
3.287 +
3.288 + return 0;
3.289 +}