mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-19 09:51:52 +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
|
- 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.
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user