1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-10-01 15:12:34 +03:00

Merged uSD driver into unified tool build, completed conversion of tools.

- atusd/tools/lib/atusd.c: moved to tools/lib/
- atusd/tools/lib/atusd.h: removed, we can now use tools/include/atspi.h
- tools/lib/atusd.c: added copyright header
- tools/lib/atusd.c: updated for driver API
- tools/lib/Makefile: added atusd.o
- tools/Makefile.common: moved common elements from all other makefiles in
  tools/*/ here
- tools/Makefile.common: added target-specific compiler and flags
- tools/atspi-id/Makefile, tools/atspi-reset/Makefile,
  tools/atspi-rssi/Makefile, tools/atspi-trim/Makefile,
  tools/atspi-txrx/Makefile, tools/lib/Makefile: used Makefile.common
- tools/lib/Makefile: differentiate USB and uSD build
- tools/atspi-id/atspi-id.c, tools/atspi-reset/atspi-reset.c,
  tools/atspi-rssi/atspi-rssi.c, tools/atspi-trim/atspi-trim.c,
  tools/atspi-txr/atspi-txr.c: updated for driver-agnostic API
- tools/atspi-id/atspi-id.c, tools/atspi-reset/atspi-reset.c,
  tools/atspi-rssi/atspi-rssi.c, tools/atspi-trim/atspi-trim.c,
  tools/atspi-txr/atspi-txr.c: corrected AF86RF230 typo in title
- tools/include/atspi.h, tools/lib/atspi.c, tools/lib/driver.c,
  tools/lib/atusb.c: brought back support for atspi_error and
  atspi_clear_error
- tools/atspi-id/atspi-id.c (atspi_get_protocol): renamed to get_protocol,
  to make it clear that it's not from libatspi
- tools/atspi-id/atspi-id.c (atspi_get_build): renamed to get_build, to
  make it clear that it's not from libatspi
- tools/include/atspi.h, tools/lib/atspi.c (atspi_usb_handle): new function
  to obtain a driver's USB device handle (or NULL if the driver doesn't use
  USB)
This commit is contained in:
Werner Almesberger 2010-09-05 20:32:58 -03:00
parent e2b2df2e31
commit f20d685f8e
18 changed files with 289 additions and 200 deletions

View File

@ -1,17 +0,0 @@
#ifndef ATUSD_H
#define ATUSD_H
#include <stdint.h>
struct atusd_dsc;
struct atusd_dsc *atusd_open(void);
void atusd_close(struct atusd_dsc *dsc);
void atusd_cycle(struct atusd_dsc *dsc);
void atusd_reset(struct atusd_dsc *dsc);
void atusd_reg_write(struct atusd_dsc *dsc, uint8_t reg, uint8_t v);
uint8_t atusd_reg_read(struct atusd_dsc *dsc, uint8_t reg);
#endif /* ATUSD_H */

31
tools/Makefile.common Normal file
View File

@ -0,0 +1,31 @@
#
# tools/Makefile.common - Common items in ATSPI tool makefiles
#
# Written 2010 by Werner Almesberger
# Copyright 2010 Werner Almesberger
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
ifeq ($(TARGET),)
TARGET = host
endif
F32XBASE = ../../../f32xbase
ifneq ($(MAIN),)
include $(F32XBASE)/lib/Makefile.common
endif
CC_host = gcc
CC_ben = mipsel-openwrt-linux-gcc
LDLIBS_host = -lusb
LDLIBS_ben =
MACROS_host = -DHAVE_USB
MACROS_ben = -DHAVE_USD
CFLAGS += -I../../atrf/fw/include -I../include $(MACROS_$(TARGET))
LDLIBS = $(LDLIBS_$(TARGET)) -L../lib -latspi

View File

@ -11,11 +11,6 @@
#
F32XBASE = ../../../f32xbase
MAIN = atspi-id
include $(F32XBASE)/lib/Makefile.common
CFLAGS += -I../../atrf/fw/include -I../include
LDLIBS += -L../lib -latspi
include ../Makefile.common

View File

@ -1,5 +1,5 @@
/*
* atspi-id/atspi-id.c - Identify a ben-wpan AF86RF230 board
* atspi-id/atspi-id.c - Identify a ben-wpan AT86RF230 board
*
* Written 2010 by Werner Almesberger
* Copyright 2010 Werner Almesberger
@ -37,7 +37,7 @@ static int get_id(usb_dev_handle *dev, void *data, int size)
}
static int atspi_get_protocol(usb_dev_handle *dev,
static int get_protocol(usb_dev_handle *dev,
uint8_t *major, uint8_t *minor, uint8_t *target)
{
uint8_t ids[3];
@ -55,7 +55,7 @@ static int atspi_get_protocol(usb_dev_handle *dev,
}
static int atspi_get_build(usb_dev_handle *dev, char *buf, size_t size)
static int get_build(usb_dev_handle *dev, char *buf, size_t size)
{
int res;
@ -67,31 +67,41 @@ static int atspi_get_build(usb_dev_handle *dev, char *buf, size_t size)
}
static void show_info(usb_dev_handle *dev)
static void show_usb_info(usb_dev_handle *dev)
{
const struct usb_device *device = usb_device(dev);
uint8_t major, minor, target;
char buf[BUF_SIZE+1]; /* +1 for terminating \0 */
int len;
uint8_t part, version, man_id_0, man_id_1;
printf("%04x:%04x ",
device->descriptor.idVendor, device->descriptor.idProduct);
if (atspi_get_protocol(dev, &major, &minor, &target) < 0)
if (get_protocol(dev, &major, &minor, &target) < 0)
exit(1);
printf("protocol %u.%u hw %u\n", major, minor, target);
len = atspi_get_build(dev, buf, sizeof(buf)-1);
len = get_build(dev, buf, sizeof(buf)-1);
if (len < 0)
exit(1);
buf[len] = 0;
printf("%10s%s\n", "", buf);
}
part = atspi_reg_read(dev, REG_PART_NUM);
version = atspi_reg_read(dev, REG_VERSION_NUM);
man_id_0 = atspi_reg_read(dev, REG_MAN_ID_0);
man_id_1 = atspi_reg_read(dev, REG_MAN_ID_1);
static void show_info(struct atspi_dsc *dsc)
{
usb_dev_handle *dev;
uint8_t part, version, man_id_0, man_id_1;
dev = atspi_usb_handle(dsc);
if (dev)
show_usb_info(dev);
part = atspi_reg_read(dsc, REG_PART_NUM);
version = atspi_reg_read(dsc, REG_VERSION_NUM);
man_id_0 = atspi_reg_read(dsc, REG_MAN_ID_0);
man_id_1 = atspi_reg_read(dsc, REG_MAN_ID_1);
printf("%10spart 0x%02x version %u manufacturer xxxx%02x%02x\n", "",
part, version, man_id_1, man_id_0);
}
@ -106,15 +116,15 @@ static void usage(const char *name)
int main(int argc, const char **argv)
{
usb_dev_handle *dev;
struct atspi_dsc *dsc;
if (argc != 1)
usage(*argv);
dev = atspi_open();
if (!dev)
dsc = atspi_open();
if (!dsc)
return 1;
show_info(dev);
show_info(dsc);
return 0;
}

View File

@ -11,11 +11,6 @@
#
F32XBASE = ../../../f32xbase
MAIN = atspi-reset
include $(F32XBASE)/lib/Makefile.common
CFLAGS += -I../../atrf/fw/include -I../include
LDLIBS += -L../lib -latspi
include ../Makefile.common

View File

@ -1,5 +1,5 @@
/*
* atspi-rssi/atspi-rssi.c - ben-wpan AF86RF230 spectrum scan
* atspi-rssi/atspi-rssi.c - ben-wpan AT86RF230 spectrum scan
*
* Written 2010 by Werner Almesberger
* Copyright 2010 Werner Almesberger
@ -14,7 +14,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <usb.h>
#include "atspi.h"
@ -32,7 +31,7 @@ static void usage(const char *name)
int main(int argc, const char **argv)
{
usb_dev_handle *dev;
struct atspi_dsc *dsc;
int txrx = 1;
switch (argc) {
@ -49,14 +48,14 @@ int main(int argc, const char **argv)
usage(*argv);
}
dev = atspi_open();
if (!dev)
dsc = atspi_open();
if (!dsc)
return 1;
if (txrx)
atspi_reset_rf(dev);
atspi_reset_rf(dsc);
else
atspi_reset(dev);
atspi_reset(dsc);
return 0;
}

View File

@ -11,11 +11,6 @@
#
F32XBASE = ../../../f32xbase
MAIN = atspi-rssi
include $(F32XBASE)/lib/Makefile.common
CFLAGS += -I../../atrf/fw/include -I../include
LDLIBS += -L../lib -latspi
include ../Makefile.common

View File

@ -1,5 +1,5 @@
/*
* atspi-rssi/atspi-rssi.c - ben-wpan AF86RF230 spectrum scan
* atspi-rssi/atspi-rssi.c - ben-wpan AT86RF230 spectrum scan
*
* Written 2010 by Werner Almesberger
* Copyright 2010 Werner Almesberger
@ -13,7 +13,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <usb.h>
#include <sys/time.h>
#include "at86rf230.h"
@ -24,19 +23,19 @@
static struct timeval t0;
static void sweep(usb_dev_handle *dev)
static void sweep(struct atspi_dsc *dsc)
{
int chan, rssi;
struct timeval t;
for (chan = 11; chan <= 26; chan++) {
atspi_reg_write(dev, REG_PHY_CC_CCA, chan);
atspi_reg_write(dsc, REG_PHY_CC_CCA, chan);
/*
* No need to explicitly wait for the PPL lock - going USB-SPI
* is pretty slow, leaving the transceiver plenty of time.
*/
gettimeofday(&t, NULL);
rssi = atspi_reg_read(dev, REG_PHY_RSSI) & RSSI_MASK;
rssi = atspi_reg_read(dsc, REG_PHY_RSSI) & RSSI_MASK;
t.tv_sec -= t0.tv_sec;
t.tv_usec -= t0.tv_usec;
printf("%d %f %d\n",
@ -57,7 +56,7 @@ static void usage(const char *name)
int main(int argc, const char **argv)
{
usb_dev_handle *dev;
struct atspi_dsc *dsc;
unsigned long sweeps, i;
char *end;
@ -67,22 +66,22 @@ int main(int argc, const char **argv)
if (*end)
usage(*argv);
dev = atspi_open();
if (!dev)
dsc = atspi_open();
if (!dsc)
return 1;
atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF);
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
/*
* No need to explicitly wait for things to stabilize - going USB-SPI
* is pretty slow, leaving the transceiver more than enough time.
*/
atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_RX_ON);
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
gettimeofday(&t0, NULL);
for (i = 0; i != sweeps; i++)
sweep(dev);
sweep(dsc);
atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF);
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
return 0;
}

View File

@ -11,11 +11,6 @@
#
F32XBASE = ../../../f32xbase
MAIN = atspi-trim
include $(F32XBASE)/lib/Makefile.common
CFLAGS += -I../../atrf/fw/include -I../include
LDLIBS += -L../lib -latspi
include ../Makefile.common

View File

@ -1,5 +1,5 @@
/*
* atspi-trim/atspi-trim.c - AF86RF230 oscillator trim utility
* atspi-trim/atspi-trim.c - AT86RF230 oscillator trim utility
*
* Written 2010 by Werner Almesberger
* Copyright 2010 Werner Almesberger
@ -13,7 +13,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <usb.h>
#include <sys/time.h>
#include "at86rf230.h"
@ -30,7 +29,7 @@ static void usage(const char *name)
int main(int argc, const char **argv)
{
usb_dev_handle *dev;
struct atspi_dsc *dsc;
int trim = -1;
char *end;
@ -46,15 +45,15 @@ int main(int argc, const char **argv)
usage(*argv);
}
dev = atspi_open();
if (!dev)
dsc = atspi_open();
if (!dsc)
return 1;
if (trim == -1) {
trim = atspi_reg_read(dev, REG_XOSC_CTRL) & XTAL_TRIM_MASK;
trim = atspi_reg_read(dsc, REG_XOSC_CTRL) & XTAL_TRIM_MASK;
printf("%d (%d.%d pF)\n", trim, trim*3/10, trim*3 % 10);
} else {
atspi_reg_write(dev, REG_XOSC_CTRL,
atspi_reg_write(dsc, REG_XOSC_CTRL,
(XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim);
}

View File

@ -11,11 +11,6 @@
#
F32XBASE = ../../../f32xbase
MAIN = atspi-txrx
include $(F32XBASE)/lib/Makefile.common
CFLAGS += -I../../atrf/fw/include -I../include
LDLIBS += -L../lib -latspi
include ../Makefile.common

View File

@ -1,5 +1,5 @@
/*
* atspi-txrx/atspi-txrx.c - ben-wpan AF86RF230 TX/RX
* atspi-txrx/atspi-txrx.c - ben-wpan AT86RF230 TX/RX
*
* Written 2010 by Werner Almesberger
* Copyright 2010 Werner Almesberger
@ -13,8 +13,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <usb.h>
#include "at86rf230.h"
#include "atspi/ep0.h"
@ -45,56 +45,56 @@ static double tx_pwr[] = {
};
static usb_dev_handle *init_txrx(int trim)
static struct atspi_dsc *init_txrx(int trim)
{
usb_dev_handle *dev;
struct atspi_dsc *dsc;
dev = atspi_open();
if (!dev)
dsc = atspi_open();
if (!dsc)
exit(1);
atspi_reset_rf(dev);
atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF);
atspi_reg_write(dev, REG_XOSC_CTRL,
atspi_reset_rf(dsc);
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
atspi_reg_write(dsc, REG_XOSC_CTRL,
(XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim);
atspi_reg_write(dev, REG_TRX_CTRL_0, 0); /* disable CLKM */
atspi_reg_write(dsc, REG_TRX_CTRL_0, 0); /* disable CLKM */
return dev;
return dsc;
}
static void set_channel(usb_dev_handle *dev, int channel)
static void set_channel(struct atspi_dsc *dsc, int channel)
{
atspi_reg_write(dev, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
atspi_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
}
static void set_power(usb_dev_handle *dev, double power)
static void set_power(struct atspi_dsc *dsc, double power)
{
int n;
for (n = 0; n != sizeof(tx_pwr)/sizeof(*tx_pwr)-1; n++)
if (tx_pwr[n] <= power)
break;
atspi_reg_write(dev, REG_PHY_TX_PWR, TX_AUTO_CRC_ON | n);
atspi_reg_write(dsc, REG_PHY_TX_PWR, TX_AUTO_CRC_ON | n);
}
static void receive(usb_dev_handle *dev)
static void receive(struct atspi_dsc *dsc)
{
uint8_t irq;
uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */
int n, ok, i;
uint8_t lq;
atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_RX_ON);
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
(void) atspi_reg_read(dev, REG_IRQ_STATUS);
(void) atspi_reg_read(dsc, REG_IRQ_STATUS);
fprintf(stderr, "Ready.\n");
while (1) {
irq = atspi_reg_read(dev, REG_IRQ_STATUS);
if (atspi_error())
irq = atspi_reg_read(dsc, REG_IRQ_STATUS);
if (atspi_error(dsc))
exit(1);
if (!irq)
continue;
@ -116,14 +116,14 @@ static void receive(usb_dev_handle *dev)
break;
}
n = atspi_buf_read(dev, buf, sizeof(buf));
n = atspi_buf_read(dsc, buf, sizeof(buf));
if (n < 0)
exit(1);
if (n < 3) {
fprintf(stderr, "%d bytes received\n", n);
exit(1);
}
ok = !!(atspi_reg_read(dev, REG_PHY_RSSI) & RX_CRC_VALID);
ok = !!(atspi_reg_read(dsc, REG_PHY_RSSI) & RX_CRC_VALID);
lq = buf[n-1];
fprintf(stderr, "%d bytes payload, CRC %s, LQI %u\n",
n-3, ok ? "OK" : "BAD", lq);
@ -133,20 +133,20 @@ static void receive(usb_dev_handle *dev)
}
static void transmit(usb_dev_handle *dev, const char *msg)
static void transmit(struct atspi_dsc *dsc, const char *msg)
{
uint8_t buf[MAX_PSDU];
atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_PLL_ON);
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
/*
* We need to copy the message to append the CRC placeholders.
*/
strcpy((void *) buf, msg);
atspi_buf_write(dev, buf, strlen(msg)+2);
atspi_buf_write(dsc, buf, strlen(msg)+2);
/* @@@ should wait for clear channel */
atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TX_START);
atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
/* @@@ should wait for TX done */
}
@ -170,7 +170,7 @@ int main(int argc, char *const *argv)
int trim = 0;
char *end;
int c;
usb_dev_handle *dev;
struct atspi_dsc *dsc;
while ((c = getopt(argc, argv, "c:p:t:")) != EOF)
switch (c) {
@ -199,15 +199,15 @@ int main(int argc, char *const *argv)
switch (argc-optind) {
case 0:
dev = init_txrx(trim);
set_channel(dev, channel);
receive(dev);
dsc = init_txrx(trim);
set_channel(dsc, channel);
receive(dsc);
break;
case 1:
dev = init_txrx(trim);
set_channel(dev, channel);
set_power(dev, power);
transmit(dev, argv[optind]);
dsc = init_txrx(trim);
set_channel(dsc, channel);
set_power(dsc, power);
transmit(dsc, argv[optind]);
break;
default:
usage(*argv);

View File

@ -19,12 +19,14 @@
struct atspi_dsc;
int atspi_error(void);
int atspi_clear_error(void);
void *atspi_usb_handle(struct atspi_dsc *dsc); /* hack for atspi-id */
struct atspi_dsc *atspi_open(void);
void atspi_close(struct atspi_dsc *dsc);
int atspi_error(struct atspi_dsc *dsc);
int atspi_clear_error(struct atspi_dsc *dsc);
void atspi_reset(struct atspi_dsc *dsc);
void atspi_reset_rf(struct atspi_dsc *dsc);

View File

@ -11,12 +11,14 @@
#
F32XBASE = ../../../f32xbase
LIB = libatspi.a
CFLAGS = -Wall -I$(F32XBASE)/include -I../../atrf/fw/include -I../include
OBJS = $(F32XBASE)/lib/usb.o atspi.o atusb.o
include ../Makefile.common
CFLAGS += -Wall -I$(F32XBASE)/include
OBJS_host = atusb.o
OBJS_ben = atusd.o
OBJS = $(F32XBASE)/lib/usb.o atspi.o $(OBJS_$(TARGET))
.PHONY: all clean spotless

View File

@ -19,6 +19,7 @@
extern struct atspi_driver atusb_driver;
extern struct atspi_driver atusd_driver;
struct atspi_dsc {
@ -27,13 +28,42 @@ struct atspi_dsc {
};
void *atspi_usb_handle(struct atspi_dsc *dsc)
{
#ifdef HAVE_USB
return dsc->handle;
#else
return NULL;
#endif
}
int atspi_error(struct atspi_dsc *dsc)
{
return dsc->driver->error ? dsc->driver->error(dsc->handle) : 0;
}
int atspi_clear_error(struct atspi_dsc *dsc)
{
return dsc->driver->clear_error ?
dsc->driver->clear_error(dsc->handle) : 0;
}
struct atspi_dsc *atspi_open(void)
{
struct atspi_dsc *dsc;
struct atspi_driver *driver;
void *handle;
#ifdef HAVE_USB
driver = &atusb_driver;
#elif HAVE_USD
driver = &atusd_driver;
#else
#error Need either HAVE_USB or HAVE_USD
#endif
handle = driver->open();
if (!handle)
return NULL;

View File

@ -31,13 +31,13 @@
static int error;
int atusb_error(void)
static int atusb_error(void *dsc)
{
return error;
}
int atusb_clear_error(void)
static int atusb_clear_error(void *dsc)
{
int ret;
@ -191,9 +191,11 @@ static int atusb_buf_read(void *dsc, void *buf, int size)
struct atspi_driver atusb_driver = {
.name = "atusb",
.name = "USB",
.open = atusb_open,
.close = atusb_close,
.error = atusb_error,
.clear_error = atusb_clear_error,
.reset = atusb_reset,
.reset_rf = atusb_reset_rf,
.reg_write = atusb_reg_write,

View File

@ -1,3 +1,16 @@
/*
* lib/atusd.c - ATSPI access functions library (uSD version)
*
* Written 2010 by Werner Almesberger
* Copyright 2010 Werner Almesberger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
@ -6,7 +19,7 @@
#include <sys/mman.h>
#include "at86rf230.h"
#include "atusd.h"
#include "driver.h"
enum {
@ -52,73 +65,10 @@ struct atusd_dsc {
};
struct atusd_dsc *atusd_open(void)
{
struct atusd_dsc *dsc;
dsc = malloc(sizeof(*dsc));
if (!dsc) {
perror("malloc");
exit(1);
}
dsc->fd = open("/dev/mem", O_RDWR);
if (dsc->fd < 0) {
perror("/dev/mem");
exit(1);
}
dsc->mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE,
MAP_SHARED, dsc->fd, SOC_BASE);
if (dsc->mem == MAP_FAILED) {
perror("mmap");
exit(1);
}
/* set the output levels */
PDDATS = nSEL | VDD_OFF;
PDDATC = SCLK | SLP_TR;
/* take the GPIOs away from the MMC controller */
PDFUNC = MxSx | SCLK | SLP_TR | IRQ | nSEL;
PDFUNS = CLK;
/* set the pin directions */
PDDIRC = IRQ;
PDDIRS = MxSx | CLK | SCLK | SLP_TR | nSEL;
/* enable power */
PDDATC = VDD_OFF;
/* set the MSC clock to 316 MHz / 21 = 16 MHz */
MSCCDR = 20;
/*
* Enable the MSC clock. We need to do this before accessing any
* registers of the MSC block !
*/
CLKGR &= ~(1 << 7);
/* bus clock = MSC clock / 1 */
MSC_CLKRT = 0;
/* start MMC clock output */
MSC_STRPCL = 2;
return dsc;
}
/* ----- Reset functions --------------------------------------------------- */
void atusd_close(struct atusd_dsc *dsc)
{
/* stop the MMC bus clock */
MSC_STRPCL = 1;
/* cut the power */
PDDATS = VDD_OFF;
/* make all MMC pins inputs */
PDDIRC = MxSx | CLK | SCLK | SLP_TR | IRQ | nSEL;
}
void atusd_cycle(struct atusd_dsc *dsc)
static void atusd_cycle(struct atusd_dsc *dsc)
{
/* stop the MMC bus clock */
MSC_STRPCL = 1;
@ -155,7 +105,8 @@ void atusd_cycle(struct atusd_dsc *dsc)
}
void atusd_reset(struct atusd_dsc *dsc)
#if 0 /* we probably won't need this anymore */
static void atusd_reset(struct atusd_dsc *dsc)
{
/* activate reset */
PDDATS = SLP_TR;
@ -171,6 +122,10 @@ void atusd_reset(struct atusd_dsc *dsc)
PDDATS = nSEL;
PDDATC = SLP_TR;
}
#endif
/* ----- Low-level SPI operations ------------------------------------------ */
static void spi_begin(struct atusd_dsc *dsc)
@ -247,8 +202,89 @@ static void spi_send(struct atusd_dsc *dsc, uint8_t v)
}
void atusd_reg_write(struct atusd_dsc *dsc, uint8_t reg, uint8_t v)
/* ----- Driver operations ------------------------------------------------- */
static void *atusd_open(void)
{
struct atusd_dsc *dsc;
dsc = malloc(sizeof(*dsc));
if (!dsc) {
perror("malloc");
exit(1);
}
dsc->fd = open("/dev/mem", O_RDWR);
if (dsc->fd < 0) {
perror("/dev/mem");
exit(1);
}
dsc->mem = mmap(NULL, PAGE_SIZE*3*16, PROT_READ | PROT_WRITE,
MAP_SHARED, dsc->fd, SOC_BASE);
if (dsc->mem == MAP_FAILED) {
perror("mmap");
exit(1);
}
/* set the output levels */
PDDATS = nSEL | VDD_OFF;
PDDATC = SCLK | SLP_TR;
/* take the GPIOs away from the MMC controller */
PDFUNC = MxSx | SCLK | SLP_TR | IRQ | nSEL;
PDFUNS = CLK;
/* set the pin directions */
PDDIRC = IRQ;
PDDIRS = MxSx | CLK | SCLK | SLP_TR | nSEL;
/* enable power */
PDDATC = VDD_OFF;
/* set the MSC clock to 316 MHz / 21 = 16 MHz */
MSCCDR = 20;
/*
* Enable the MSC clock. We need to do this before accessing any
* registers of the MSC block !
*/
CLKGR &= ~(1 << 7);
/* bus clock = MSC clock / 1 */
MSC_CLKRT = 0;
/* start MMC clock output */
MSC_STRPCL = 2;
return dsc;
}
static void atusd_close(void *arg)
{
struct atusd_dsc *dsc = arg;
/* stop the MMC bus clock */
MSC_STRPCL = 1;
/* cut the power */
PDDATS = VDD_OFF;
/* make all MMC pins inputs */
PDDIRC = MxSx | CLK | SCLK | SLP_TR | IRQ | nSEL;
}
static void atusd_reset_rf(void *handle)
{
struct atusd_dsc *dsc = handle;
atusd_cycle(dsc);
}
static void atusd_reg_write(void *handle, uint8_t reg, uint8_t v)
{
struct atusd_dsc *dsc = handle;
spi_begin(dsc);
spi_send(dsc, AT86RF230_REG_WRITE | reg);
spi_send(dsc, v);
@ -256,8 +292,9 @@ void atusd_reg_write(struct atusd_dsc *dsc, uint8_t reg, uint8_t v)
}
uint8_t atusd_reg_read(struct atusd_dsc *dsc, uint8_t reg)
static uint8_t atusd_reg_read(void *handle, uint8_t reg)
{
struct atusd_dsc *dsc = handle;
uint8_t res;
spi_begin(dsc);
@ -269,3 +306,21 @@ uint8_t atusd_reg_read(struct atusd_dsc *dsc, uint8_t reg)
spi_end(dsc);
return res;
}
/* ----- Driver interface -------------------------------------------------- */
struct atspi_driver atusd_driver = {
.name = "uSD",
.open = atusd_open,
.close = atusd_close,
.reset = NULL,
.reset_rf = atusd_reset_rf,
.reg_write = atusd_reg_write,
.reg_read = atusd_reg_read,
#if 0
.buf_write = atusd_buf_write,
.buf_read = atusd_buf_read,
#endif
};

View File

@ -21,6 +21,8 @@ struct atspi_driver {
const char *name;
void *(*open)(void);
void (*close)(void *dsc);
int (*error)(void *dsc);
int (*clear_error)(void *dsc);
void (*reset)(void *dsc);
void (*reset_rf)(void *dsc);
void (*reg_write)(void *dsc, uint8_t reg, uint8_t value);