1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-10-01 16:26:19 +03:00

Board bringup: talk to the chip and read IDs.

- atusd/ERRATA: mention that the reset circuit can go, as expected
- atusd/tools/Makefile: add include path to at86rf230.h
- atusd/tools/lib/atusd.c: include atusd.h, for consistency checking
- atusd/tools/lib/atusd.c (spi_begin, spi_end, spi_data_in, spi_data_out,
  spi_send_partial, spi_recv, spi_finish, spi_send): low-level functions
  to access our modified SPI
- atusd/tools/lib/atusd.h, atusd/tools/lib/atusd.c (atusd_reg_write,
  atusd_reg_read): register read and write access
- atusd/tools/try.c: read and print chip IDs
This commit is contained in:
Werner Almesberger 2010-09-05 16:59:59 -03:00
parent a18d5969bd
commit 9ad96bd5f9
5 changed files with 136 additions and 5 deletions

View File

@ -6,3 +6,7 @@
- the footprint of the transistor (Q1) is reversed :-( It works after - the footprint of the transistor (Q1) is reversed :-( It works after
converting the chip from SOT to PLCC. converting the chip from SOT to PLCC.
- not an erratum, but with experiments showing power-on reset to be
reliable, we can consider removing the hardware reset circuit. This will
also simplify the layout.

View File

@ -1,5 +1,5 @@
CC=mipsel-openwrt-linux-gcc CC=mipsel-openwrt-linux-gcc
CFLAGS=-Wall CFLAGS=-Wall -I../../atrf/fw/include
MAIN = try MAIN = try
OBJS = $(MAIN).c lib/atusd.o OBJS = $(MAIN).c lib/atusd.o

View File

@ -5,6 +5,9 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "at86rf230.h"
#include "atusd.h"
enum { enum {
VDD_OFF = 1 << 6, /* VDD disable, PD06 */ VDD_OFF = 1 << 6, /* VDD disable, PD06 */
@ -25,6 +28,7 @@ enum {
#define GPIO(n) REG(0x10000+(n)) #define GPIO(n) REG(0x10000+(n))
#define MSC(n) REG(0x21000+(n)) #define MSC(n) REG(0x21000+(n))
#define PDPIN GPIO(0x300) /* port D pin level */
#define PDDATS GPIO(0x314) /* port D data set */ #define PDDATS GPIO(0x314) /* port D data set */
#define PDDATC GPIO(0x318) /* port D data clear */ #define PDDATC GPIO(0x318) /* port D data clear */
#define PDFUNS GPIO(0x344) /* port D function set */ #define PDFUNS GPIO(0x344) /* port D function set */
@ -142,6 +146,12 @@ void atusd_cycle(struct atusd_dsc *dsc)
/* start MMC clock output */ /* start MMC clock output */
MSC_STRPCL = 2; MSC_STRPCL = 2;
/*
* Give power time to stabilize and the chip time to reset.
* Experiments show that even usleep(0) is long enough.
*/
usleep(10*1000);
} }
@ -161,3 +171,101 @@ void atusd_reset(struct atusd_dsc *dsc)
PDDATS = nSEL; PDDATS = nSEL;
PDDATC = SLP_TR; PDDATC = SLP_TR;
} }
static void spi_begin(struct atusd_dsc *dsc)
{
PDDATC = nSEL;
}
static void spi_end(struct atusd_dsc *dsc)
{
PDDATS = nSEL;
}
static void spi_data_in(struct atusd_dsc *dsc)
{
PDDIRC = MxSx;
}
static void spi_data_out(struct atusd_dsc *dsc)
{
PDDIRS = MxSx;
}
/*
* Send a sequence of bytes but leave the clock high on the last bit, so that
* we can turn around the data line for reads.
*/
static void spi_send_partial(struct atusd_dsc *dsc, uint8_t v)
{
uint8_t mask;
for (mask = 0x80; mask; mask >>= 1) {
PDDATC = SCLK;
if (v & mask)
PDDATS = MxSx;
else
PDDATC = MxSx;
PDDATS = SCLK;
}
}
static uint8_t spi_recv(struct atusd_dsc *dsc)
{
uint8_t res = 0;
uint8_t mask;
for (mask = 0x80; mask; mask >>= 1) {
PDDATC = SCLK;
if (PDPIN & MxSx)
res |= mask;
PDDATS = SCLK;
}
PDDATC = SCLK;
return res;
}
static void spi_finish(struct atusd_dsc *dsc)
{
PDDATC = SCLK;
}
static void spi_send(struct atusd_dsc *dsc, uint8_t v)
{
spi_send_partial(dsc, v);
spi_finish(dsc);
}
void atusd_reg_write(struct atusd_dsc *dsc, uint8_t reg, uint8_t v)
{
spi_begin(dsc);
spi_send(dsc, AT86RF230_REG_WRITE | reg);
spi_send(dsc, v);
spi_end(dsc);
}
uint8_t atusd_reg_read(struct atusd_dsc *dsc, uint8_t reg)
{
uint8_t res;
spi_begin(dsc);
spi_send_partial(dsc, AT86RF230_REG_READ| reg);
spi_data_in(dsc);
res = spi_recv(dsc);
spi_finish(dsc);
spi_data_out(dsc);
spi_end(dsc);
return res;
}

View File

@ -1,3 +1,9 @@
#ifndef ATUSD_H
#define ATUSD_H
#include <stdint.h>
struct atusd_dsc; struct atusd_dsc;
@ -5,3 +11,7 @@ struct atusd_dsc *atusd_open(void);
void atusd_close(struct atusd_dsc *dsc); void atusd_close(struct atusd_dsc *dsc);
void atusd_cycle(struct atusd_dsc *dsc); void atusd_cycle(struct atusd_dsc *dsc);
void atusd_reset(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 */

View File

@ -1,19 +1,28 @@
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include "at86rf230.h"
#include "lib/atusd.h" #include "lib/atusd.h"
int main(void) int main(void)
{ {
struct atusd_dsc *dsc; struct atusd_dsc *dsc;
char tmp; uint8_t part, version, man_id_0, man_id_1;
dsc = atusd_open(); dsc = atusd_open();
read(1, &tmp, 1);
fprintf(stderr, "cycling\n");
atusd_cycle(dsc); atusd_cycle(dsc);
read(1, &tmp, 1); // atusd_reset(dsc);
part = atusd_reg_read(dsc, REG_PART_NUM);
version = atusd_reg_read(dsc, REG_VERSION_NUM);
man_id_0 = atusd_reg_read(dsc, REG_MAN_ID_0);
man_id_1 = atusd_reg_read(dsc, REG_MAN_ID_1);
printf("part 0x%02x version %u manufacturer xxxx%02x%02x\n",
part, version, man_id_1, man_id_0);
atusd_close(dsc); atusd_close(dsc);
return 0; return 0;