mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-25 21:30:37 +02: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:
parent
a18d5969bd
commit
9ad96bd5f9
@ -6,3 +6,7 @@
|
||||
|
||||
- the footprint of the transistor (Q1) is reversed :-( It works after
|
||||
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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
CC=mipsel-openwrt-linux-gcc
|
||||
CFLAGS=-Wall
|
||||
CFLAGS=-Wall -I../../atrf/fw/include
|
||||
|
||||
MAIN = try
|
||||
OBJS = $(MAIN).c lib/atusd.o
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "at86rf230.h"
|
||||
#include "atusd.h"
|
||||
|
||||
|
||||
enum {
|
||||
VDD_OFF = 1 << 6, /* VDD disable, PD06 */
|
||||
@ -25,6 +28,7 @@ enum {
|
||||
#define GPIO(n) REG(0x10000+(n))
|
||||
#define MSC(n) REG(0x21000+(n))
|
||||
|
||||
#define PDPIN GPIO(0x300) /* port D pin level */
|
||||
#define PDDATS GPIO(0x314) /* port D data set */
|
||||
#define PDDATC GPIO(0x318) /* port D data clear */
|
||||
#define PDFUNS GPIO(0x344) /* port D function set */
|
||||
@ -142,6 +146,12 @@ void atusd_cycle(struct atusd_dsc *dsc)
|
||||
|
||||
/* start MMC clock output */
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
#ifndef ATUSD_H
|
||||
#define ATUSD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
struct atusd_dsc;
|
||||
|
||||
|
||||
@ -5,3 +11,7 @@ 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 */
|
||||
|
@ -1,19 +1,28 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "at86rf230.h"
|
||||
#include "lib/atusd.h"
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct atusd_dsc *dsc;
|
||||
char tmp;
|
||||
uint8_t part, version, man_id_0, man_id_1;
|
||||
|
||||
dsc = atusd_open();
|
||||
read(1, &tmp, 1);
|
||||
fprintf(stderr, "cycling\n");
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user