1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-11-29 19:00:16 +02:00

atusb/fw/: added free-running 48 bit 8 MHz counter for clock measurements

- atusb.c (main): poll the 16 bit timer for overflows
- board.h (timer_poll, timer_read), (board.c (timer_h, timer_poll,
  timer_read, board_init): added support for a free-running 48 bit timer
  (16 bits in hardware, 32 bits in software)
- include/atusb/ep0.h (ATUSB_TIMER), ep0.c (my_setup): new request
  ATUSB_TIMER to retrieve the value of the 8 MHz counter
- include/atusb/ep0.h (enum atspi_requests): describe what the groups
  of requests do
This commit is contained in:
Werner Almesberger 2011-05-29 21:05:28 -03:00
parent 40d78b2d07
commit 8c57277953
5 changed files with 62 additions and 5 deletions

View File

@ -36,6 +36,8 @@ int main(void)
usb_init(); usb_init();
ep0_init(); ep0_init();
while (1) while (1) {
usb_poll(); usb_poll();
timer_poll();
}
} }

View File

@ -29,6 +29,9 @@
uint8_t board_sernum[42] = { 42, USB_DT_STRING }; uint8_t board_sernum[42] = { 42, USB_DT_STRING };
static uint32_t timer_h = 0; /* 2^(16+32) / 8 MHz = ~1.1 years */
static void set_clkm(void) static void set_clkm(void)
{ {
/* switch CLKM to 8 MHz */ /* switch CLKM to 8 MHz */
@ -99,6 +102,36 @@ void panic(void)
} }
void timer_poll(void)
{
if (!(TIFR1 & (1 << TOV1)))
return;
TIFR1 = 1 << TOV1;
timer_h++;
}
uint64_t timer_read(void)
{
uint32_t high;
uint8_t low, mid;
do {
timer_poll();
high = timer_h;
low = TCNT1L;
mid = TCNT1H;
}
while (TIFR1 & (1 << TOV1));
/*
* We need all these casts because the intermediate results are handled
* as if they were signed and thus get sign-expanded. Sounds wrong-ish.
*/
return (uint64_t) high << 16 | (uint64_t) mid << 8 | (uint64_t) low;
}
static char hex(uint8_t nibble) static char hex(uint8_t nibble)
{ {
return nibble < 10 ? '0'+nibble : 'a'+nibble-10; return nibble < 10 ? '0'+nibble : 'a'+nibble-10;
@ -138,5 +171,10 @@ void board_init(void)
OUT(nRST_RF); /* this also resets the transceiver */ OUT(nRST_RF); /* this also resets the transceiver */
OUT(SLP_TR); OUT(SLP_TR);
/* configure timer 1 as a free-running CLK counter */
TCCR1A = 0;
TCCR1B = 1 << CS10;
get_sernum(); get_sernum();
} }

View File

@ -74,6 +74,9 @@ uint8_t read_irq(void);
void led(int on); void led(int on);
void panic(void); void panic(void);
void timer_poll(void);
uint64_t timer_read(void);
void board_init(void); void board_init(void);
#endif /* !BOARD_H */ #endif /* !BOARD_H */

View File

@ -12,6 +12,7 @@
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <avr/io.h> #include <avr/io.h>
@ -57,6 +58,7 @@ static int my_setup(const struct setup_request *setup)
{ {
unsigned tmp; unsigned tmp;
uint8_t i; uint8_t i;
uint64_t tmp64;
switch (setup->bmRequestType | setup->bRequest << 8) { switch (setup->bmRequestType | setup->bRequest << 8) {
case ATUSB_FROM_DEV(ATUSB_ID): case ATUSB_FROM_DEV(ATUSB_ID):
@ -101,6 +103,16 @@ static int my_setup(const struct setup_request *setup)
usb_send(&eps[0], buf, 1, NULL, NULL); usb_send(&eps[0], buf, 1, NULL, NULL);
return 1; return 1;
case ATUSB_FROM_DEV(ATUSB_TIMER):
debug("ATUSB_TIMER\n");
size = setup->wLength;
if (size > sizeof(tmp64))
size = sizeof(tmp64);
tmp64 = timer_read();
memcpy(buf, &tmp64, sizeof(tmp64));
usb_send(&eps[0], buf, size, NULL, NULL);
return 1;
case ATUSB_TO_DEV(ATUSB_REG_WRITE): case ATUSB_TO_DEV(ATUSB_REG_WRITE):
debug("ATUSB_REG_WRITE\n"); debug("ATUSB_REG_WRITE\n");
spi_begin(); spi_begin();

View File

@ -24,6 +24,7 @@
* host-> ATUSB_RF_RESET - - 0 * host-> ATUSB_RF_RESET - - 0
* ->host ATUSB_POLL_INT - - 1 * ->host ATUSB_POLL_INT - - 1
* host-> ATUSB_TEST - - 0 * host-> ATUSB_TEST - - 0
* ->host ATUSB_TIMER - - #bytes (6)
* *
* host-> ATUSB_REG_WRITE value addr 0 * host-> ATUSB_REG_WRITE value addr 0
* ->host ATUSB_REG_READ - addr 1 * ->host ATUSB_REG_READ - addr 1
@ -64,13 +65,14 @@
enum atspi_requests { enum atspi_requests {
ATUSB_ID = 0x00, ATUSB_ID = 0x00, /* system status/control grp */
ATUSB_BUILD, ATUSB_BUILD,
ATUSB_RESET, ATUSB_RESET,
ATUSB_RF_RESET = 0x10, ATUSB_RF_RESET = 0x10, /* debug/test group */
ATUSB_POLL_INT, ATUSB_POLL_INT,
ATUSB_TEST, ATUSB_TEST, /* atusb-sil only */
ATUSB_REG_WRITE = 0x20, ATUSB_TIMER,
ATUSB_REG_WRITE = 0x20, /* transceiver group */
ATUSB_REG_READ, ATUSB_REG_READ,
ATUSB_BUF_WRITE, ATUSB_BUF_WRITE,
ATUSB_BUF_READ, ATUSB_BUF_READ,