From 6b05089700bdd19d081583bb75e55ff865f29efe Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Fri, 28 Jun 2013 21:30:46 -0400 Subject: [PATCH 001/200] usb: Add usb_endpoint_append_td This implements the procedure for adding a TD to the end of an active queue described in UM10503 Section 23.10.11.3. --- firmware/hackrf_usb/usb.c | 33 +++++++++++++++++++++++++++++++++ firmware/hackrf_usb/usb.h | 6 ++++++ 2 files changed, 39 insertions(+) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 8396e1bf..02fb81c3 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -195,6 +195,39 @@ void usb_endpoint_prime( USB0_ENDPTPRIME = USB0_ENDPTPRIME_PERB(1 << endpoint_number); } } + +// Schedule an already filled-up transfer descriptor for execution on +// the given endpoint. Note that this requires that one knows the tail +// of the endpoint's TD queue +void usb_endpoint_append_td( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const tail_td, + usb_transfer_descriptor_t* const new_td +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + bool done; + + tail_td->next_dtd_pointer = new_td; + + do { + if( usb_endpoint_is_in(endpoint->address) ) { + if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number) ) + return; + } else { + if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number) ) + return; + } + + USB0_USBCMD_D |= USB0_USBCMD_D_ATDTW; + done = usb_endpoint_is_ready(endpoint); + } while (!(USB0_USBCMD_D & USB0_USBCMD_D_ATDTW)); + + USB0_USBCMD_D &= ~USB0_USBCMD_D_ATDTW; + if(!done) { + usb_endpoint_prime(endpoint, new_td); + } +} + /* static bool usb_endpoint_is_priming( const usb_endpoint_t* const endpoint diff --git a/firmware/hackrf_usb/usb.h b/firmware/hackrf_usb/usb.h index 4b1d50f4..94372e0c 100644 --- a/firmware/hackrf_usb/usb.h +++ b/firmware/hackrf_usb/usb.h @@ -92,4 +92,10 @@ void usb_endpoint_prime( usb_transfer_descriptor_t* const first_td ); +void usb_endpoint_append_td( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const tail_td, + usb_transfer_descriptor_t* const new_td +); + #endif//__USB_H__ From 42b73919180eebbb5930eacfaaafc62bdc8a3dae Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Fri, 28 Jun 2013 21:53:59 -0400 Subject: [PATCH 002/200] usb: Begin shuffling transfer management to usb_queue --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/hackrf_usb.c | 1 + firmware/hackrf_usb/usb.c | 43 ------------- firmware/hackrf_usb/usb.h | 10 --- firmware/hackrf_usb/usb_queue.c | 71 ++++++++++++++++++++++ firmware/hackrf_usb/usb_queue.h | 46 ++++++++++++++ firmware/hackrf_usb/usb_standard_request.c | 1 + 7 files changed, 120 insertions(+), 53 deletions(-) create mode 100644 firmware/hackrf_usb/usb_queue.c create mode 100644 firmware/hackrf_usb/usb_queue.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 3d2b4d53..20a97295 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -27,6 +27,7 @@ SRC = $(BINARY).c \ usb_request.c \ usb_standard_request.c \ usb_descriptor.c \ + usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ ../common/sgpio.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index a175ea3d..439f88cf 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -39,6 +39,7 @@ #include "usb.h" #include "usb_type.h" +#include "usb_queue.h" #include "usb_request.h" #include "usb_descriptor.h" #include "usb_standard_request.h" diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 02fb81c3..0487ef43 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -34,10 +34,8 @@ usb_device_t* usb_device_usb0 = 0; usb_queue_head_t usb_qh[12] ATTR_ALIGNED(2048); -usb_transfer_descriptor_t usb_td[12] ATTR_ALIGNED(64); #define USB_QH_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) -#define USB_TD_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) usb_queue_head_t* usb_queue_head( const uint_fast8_t endpoint_address @@ -45,12 +43,6 @@ usb_queue_head_t* usb_queue_head( return &usb_qh[USB_QH_INDEX(endpoint_address)]; } -usb_transfer_descriptor_t* usb_transfer_descriptor( - const uint_fast8_t endpoint_address -) { - return &usb_td[USB_TD_INDEX(endpoint_address)]; -} - static usb_endpoint_t* usb_endpoint_from_address( const uint_fast8_t endpoint_address ) { @@ -543,41 +535,6 @@ void usb_endpoint_init( usb_endpoint_enable(endpoint); } -void usb_endpoint_schedule( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length -) { - usb_transfer_descriptor_t* const td = usb_transfer_descriptor(endpoint->address); - - // Ensure that endpoint is ready to be primed. - // It may have been flushed due to an aborted transaction. - // TODO: This should be preceded by a flush? - while( usb_endpoint_is_ready(endpoint) ); - - // Configure a transfer. - td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - td->total_bytes = - USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) - | USB_TD_DTD_TOKEN_IOC - | USB_TD_DTD_TOKEN_MULTO(0) - | USB_TD_DTD_TOKEN_STATUS_ACTIVE - ; - td->buffer_pointer_page[0] = (uint32_t)data; - td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; - td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; - td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; - td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; - - usb_endpoint_prime(endpoint, td); -} - -void usb_endpoint_schedule_ack( - const usb_endpoint_t* const endpoint -) { - usb_endpoint_schedule(endpoint, 0, 0); -} - static void usb_check_for_setup_events() { const uint32_t endptsetupstat = usb_get_endpoint_setup_status(); if( endptsetupstat ) { diff --git a/firmware/hackrf_usb/usb.h b/firmware/hackrf_usb/usb.h index 94372e0c..7d64f358 100644 --- a/firmware/hackrf_usb/usb.h +++ b/firmware/hackrf_usb/usb.h @@ -61,16 +61,6 @@ void usb_endpoint_init( const usb_endpoint_t* const endpoint ); -void usb_endpoint_schedule( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length -); - -void usb_endpoint_schedule_ack( - const usb_endpoint_t* const endpoint -); - void usb_endpoint_stall( const usb_endpoint_t* const endpoint ); diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c new file mode 100644 index 00000000..8be95a22 --- /dev/null +++ b/firmware/hackrf_usb/usb_queue.c @@ -0,0 +1,71 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Ben Gamari + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include "usb.h" + +usb_transfer_descriptor_t usb_td[12] ATTR_ALIGNED(64); + +#define USB_TD_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) + +usb_transfer_descriptor_t* usb_transfer_descriptor( + const uint_fast8_t endpoint_address +) { + return &usb_td[USB_TD_INDEX(endpoint_address)]; +} + +void usb_endpoint_schedule( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +) { + usb_transfer_descriptor_t* const td = usb_transfer_descriptor(endpoint->address); + + // Ensure that endpoint is ready to be primed. + // It may have been flushed due to an aborted transaction. + // TODO: This should be preceded by a flush? + while( usb_endpoint_is_ready(endpoint) ); + + // Configure a transfer. + td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + td->total_bytes = + USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) + | USB_TD_DTD_TOKEN_IOC + | USB_TD_DTD_TOKEN_MULTO(0) + | USB_TD_DTD_TOKEN_STATUS_ACTIVE + ; + td->buffer_pointer_page[0] = (uint32_t)data; + td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; + td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; + td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; + td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; + + usb_endpoint_prime(endpoint, td); +} + +void usb_endpoint_schedule_ack( + const usb_endpoint_t* const endpoint +) { + usb_endpoint_schedule(endpoint, 0, 0); +} diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h new file mode 100644 index 00000000..f07b8146 --- /dev/null +++ b/firmware/hackrf_usb/usb_queue.h @@ -0,0 +1,46 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Ben Gamari + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_QUEUE_H__ +#define __USB_QUEUE_H__ + +#include + +#include "usb_type.h" + +void usb_endpoint_schedule( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +); + +void usb_endpoint_schedule_ack( + const usb_endpoint_t* const endpoint +); + +void usb_endpoint_schedule( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +); + +#endif//__USB_QUEUE_H__ diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index cfb58ee0..59991ef1 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -27,6 +27,7 @@ #include "usb.h" #include "usb_type.h" #include "usb_descriptor.h" +#include "usb_queue.h" const uint8_t* usb_endpoint_descriptor( const usb_endpoint_t* const endpoint From e6bf90af23548684e247e1e674898e3a0053978a Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 2 Jul 2013 19:31:51 -0400 Subject: [PATCH 003/200] usb: Shuffle endpoint_schedule into endpoint_schedule_wait --- firmware/hackrf_usb/usb.c | 28 ++++++++++++++++++++++++++++ firmware/hackrf_usb/usb_queue.c | 28 +++++----------------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 0487ef43..c057b5c3 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -188,6 +188,34 @@ void usb_endpoint_prime( } } +void usb_endpoint_schedule_wait( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const td, + void* const data, + const uint32_t maximum_length +) { + // Ensure that endpoint is ready to be primed. + // It may have been flushed due to an aborted transaction. + // TODO: This should be preceded by a flush? + while( usb_endpoint_is_ready(endpoint) ); + + // Configure a transfer. + td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + td->total_bytes = + USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) + | USB_TD_DTD_TOKEN_IOC + | USB_TD_DTD_TOKEN_MULTO(0) + | USB_TD_DTD_TOKEN_STATUS_ACTIVE + ; + td->buffer_pointer_page[0] = (uint32_t)data; + td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; + td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; + td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; + td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; + + usb_endpoint_prime(endpoint, td); +} + // Schedule an already filled-up transfer descriptor for execution on // the given endpoint. Note that this requires that one knows the tail // of the endpoint's TD queue diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 8be95a22..5792bcae 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -40,30 +40,12 @@ void usb_endpoint_schedule( void* const data, const uint32_t maximum_length ) { - usb_transfer_descriptor_t* const td = usb_transfer_descriptor(endpoint->address); - - // Ensure that endpoint is ready to be primed. - // It may have been flushed due to an aborted transaction. - // TODO: This should be preceded by a flush? - while( usb_endpoint_is_ready(endpoint) ); - - // Configure a transfer. - td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - td->total_bytes = - USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) - | USB_TD_DTD_TOKEN_IOC - | USB_TD_DTD_TOKEN_MULTO(0) - | USB_TD_DTD_TOKEN_STATUS_ACTIVE - ; - td->buffer_pointer_page[0] = (uint32_t)data; - td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; - td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; - td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; - td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; - - usb_endpoint_prime(endpoint, td); + usb_endpoint_schedule_wait(endpoint, + usb_transfer_descriptor(endpoint->address), + data, + maximum_length); } - + void usb_endpoint_schedule_ack( const usb_endpoint_t* const endpoint ) { From 6142c828df49eebf4db418cb963dad964f20ab3b Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 2 Jul 2013 22:39:26 -0400 Subject: [PATCH 004/200] usb: Refactor queue management --- firmware/hackrf_usb/usb.c | 27 ++-- firmware/hackrf_usb/usb.h | 7 +- firmware/hackrf_usb/usb_queue.c | 139 +++++++++++++++++++-- firmware/hackrf_usb/usb_queue.h | 22 +++- firmware/hackrf_usb/usb_standard_request.c | 12 +- 5 files changed, 166 insertions(+), 41 deletions(-) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index c057b5c3..14a94397 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -188,38 +188,27 @@ void usb_endpoint_prime( } } +// Schedule an already filled-in transfer descriptor for execution on +// the given endpoint, waiting until the endpoint has finished. void usb_endpoint_schedule_wait( const usb_endpoint_t* const endpoint, - usb_transfer_descriptor_t* const td, - void* const data, - const uint32_t maximum_length + usb_transfer_descriptor_t* const td ) { // Ensure that endpoint is ready to be primed. // It may have been flushed due to an aborted transaction. // TODO: This should be preceded by a flush? while( usb_endpoint_is_ready(endpoint) ); - // Configure a transfer. td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - td->total_bytes = - USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) - | USB_TD_DTD_TOKEN_IOC - | USB_TD_DTD_TOKEN_MULTO(0) - | USB_TD_DTD_TOKEN_STATUS_ACTIVE - ; - td->buffer_pointer_page[0] = (uint32_t)data; - td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; - td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; - td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; - td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; usb_endpoint_prime(endpoint, td); } -// Schedule an already filled-up transfer descriptor for execution on -// the given endpoint. Note that this requires that one knows the tail -// of the endpoint's TD queue -void usb_endpoint_append_td( +// Schedule an already filled-in transfer descriptor for execution on +// the given endpoint, appending to the end of the endpoint's queue if +// there are pending TDs. Note that this requires that one knows the +// tail of the endpoint's TD queue +void usb_endpoint_schedule_append( const usb_endpoint_t* const endpoint, usb_transfer_descriptor_t* const tail_td, usb_transfer_descriptor_t* const new_td diff --git a/firmware/hackrf_usb/usb.h b/firmware/hackrf_usb/usb.h index 7d64f358..a6fa6a92 100644 --- a/firmware/hackrf_usb/usb.h +++ b/firmware/hackrf_usb/usb.h @@ -82,7 +82,12 @@ void usb_endpoint_prime( usb_transfer_descriptor_t* const first_td ); -void usb_endpoint_append_td( +void usb_endpoint_schedule_wait( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const td +); + +void usb_endpoint_schedule_append( const usb_endpoint_t* const endpoint, usb_transfer_descriptor_t* const tail_td, usb_transfer_descriptor_t* const new_td diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 5792bcae..0fc833d1 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -22,32 +22,145 @@ #include #include +#include #include "usb.h" +#include "usb_queue.h" -usb_transfer_descriptor_t usb_td[12] ATTR_ALIGNED(64); +struct _usb_transfer_t { + struct _usb_transfer_t* next; + usb_transfer_descriptor_t td ATTR_ALIGNED(64); + unsigned int actual_length; + usb_endpoint_t* endpoint; + bool finished; + transfer_completion_cb completion_cb; +}; -#define USB_TD_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) +usb_transfer_t transfer_pool[16]; -usb_transfer_descriptor_t* usb_transfer_descriptor( - const uint_fast8_t endpoint_address -) { - return &usb_td[USB_TD_INDEX(endpoint_address)]; +// Available transfer list +usb_transfer_t* free_transfers; + +#define USB_ENDPOINT_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) + +// Pending transfer heads +usb_transfer_t* endpoint_transfers[12] = {}; + +void init_transfers() { + usb_transfer_t* t = &transfer_pool[0]; + free_transfers = t; + for (unsigned int i=0; i < sizeof(transfer_pool) / sizeof(usb_transfer_t); i++, t++) { + t->next = t+1; + } + t->next = NULL; } -void usb_endpoint_schedule( +static bool usb_endpoint_is_in(const uint_fast8_t endpoint_address) { + return (endpoint_address & 0x80) ? true : false; +} + +#if 0 +static usb_transfer_t* usb_transfer( + const uint_fast8_t endpoint_address +) { + return endpoint_transfers[USB_ENDPOINT_INDEX(endpoint_address)]; +} +#endif + +static void fill_in_transfer(usb_transfer_t* transfer, + void* const data, + const uint32_t maximum_length +) { + usb_transfer_descriptor_t* const td = &transfer->td; + + // Configure a transfer. + td->total_bytes = + USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) + | USB_TD_DTD_TOKEN_IOC + | USB_TD_DTD_TOKEN_MULTO(0) + | USB_TD_DTD_TOKEN_STATUS_ACTIVE + ; + td->buffer_pointer_page[0] = (uint32_t)data; + td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; + td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; + td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; + td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; +} + +static usb_transfer_t* allocate_transfer() +{ + while (free_transfers == NULL); + //disable_irqs(); // FIXME + usb_transfer_t* const transfer = free_transfers; + free_transfers = transfer->next; + //enable_irqs(); + transfer->finished = false; + return transfer; +} + +static void endpoint_add_transfer( + const usb_endpoint_t* const endpoint, + usb_transfer_t* const transfer +) { + uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); + //FIXME disable_irqs(); + usb_transfer_t* t = endpoint_transfers[index]; + transfer->next = NULL; + for (; t->next != NULL; t = t->next); + t->next = transfer; + //enable_irqs(); +} + +static usb_transfer_t* endpoint_pop_transfer( + const usb_endpoint_t* const endpoint +) { + uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); + //FIXME disable_irqs(); + usb_transfer_t* transfer = endpoint_transfers[index]; + endpoint_transfers[index] = transfer->next; + //enable_irqs(); + return transfer; +} + +void usb_transfer_schedule_wait( const usb_endpoint_t* const endpoint, void* const data, const uint32_t maximum_length ) { - usb_endpoint_schedule_wait(endpoint, - usb_transfer_descriptor(endpoint->address), - data, - maximum_length); + usb_transfer_t* const transfer = allocate_transfer(); + fill_in_transfer(transfer, data, maximum_length); + endpoint_add_transfer(endpoint, transfer); + usb_endpoint_schedule_wait(endpoint, &transfer->td); +} + +void usb_transfer_schedule_append( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +) { + usb_transfer_t* const transfer = allocate_transfer(); + uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); + fill_in_transfer(transfer, data, maximum_length); + // TODO: disable_interrupts(); + usb_transfer_t* tail = endpoint_transfers[index]; + for (; tail->next != NULL; tail = tail->next); + endpoint_add_transfer(endpoint, transfer); + usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); + //enable_interrupts(); } -void usb_endpoint_schedule_ack( +void usb_transfer_schedule_ack( const usb_endpoint_t* const endpoint ) { - usb_endpoint_schedule(endpoint, 0, 0); + usb_transfer_schedule_wait(endpoint, 0, 0); +} + +void transfer_complete(const usb_endpoint_t* const endpoint) +{ + usb_transfer_t* transfer = endpoint_pop_transfer(endpoint); + unsigned int transferred = transfer->actual_length - transfer->td.total_bytes; + if (transfer->completion_cb) + transfer->completion_cb(transfer, transferred); + else if (usb_endpoint_is_in(transfer->endpoint->address)) + transfer->finished = true; } diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index f07b8146..5e10b33e 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -27,20 +27,38 @@ #include "usb_type.h" +typedef struct _usb_transfer_t usb_transfer_t; + +typedef void (*transfer_completion_cb)(struct _usb_transfer_t*, unsigned int); + void usb_endpoint_schedule( const usb_endpoint_t* const endpoint, void* const data, const uint32_t maximum_length ); -void usb_endpoint_schedule_ack( +void usb_transfer_schedule_wait( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +); + +void usb_transfer_schedule_append( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +); + +void usb_transfer_schedule_ack( const usb_endpoint_t* const endpoint ); -void usb_endpoint_schedule( +void usb_transfer_schedule( const usb_endpoint_t* const endpoint, void* const data, const uint32_t maximum_length ); +void init_transfers(void); + #endif//__USB_QUEUE_H__ diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index 59991ef1..db9a0940 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -115,12 +115,12 @@ static usb_request_status_t usb_send_descriptor( if( descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION ) { descriptor_length = (descriptor_data[3] << 8) | descriptor_data[2]; } - usb_endpoint_schedule( + usb_transfer_schedule_wait( endpoint->in, descriptor_data, (setup_length > descriptor_length) ? descriptor_length : setup_length ); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } @@ -196,7 +196,7 @@ static usb_request_status_t usb_standard_request_set_address_setup( usb_endpoint_t* const endpoint ) { usb_set_address_deferred(endpoint->device, endpoint->setup.value_l); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } @@ -232,7 +232,7 @@ static usb_request_status_t usb_standard_request_set_configuration_setup( // TODO: Should this be done immediately? usb_set_address_immediate(endpoint->device, 0); } - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } else { return USB_REQUEST_STATUS_STALL; @@ -266,8 +266,8 @@ static usb_request_status_t usb_standard_request_get_configuration_setup( if( endpoint->device->configuration ) { endpoint->buffer[0] = endpoint->device->configuration->number; } - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } else { return USB_REQUEST_STATUS_STALL; From f015fd7640a204f90a22bd3c8792e7df004c9956 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 13:38:59 -0400 Subject: [PATCH 005/200] usb: Things enumerate --- firmware/hackrf_usb/usb_queue.c | 18 ++++++++++++------ firmware/hackrf_usb/usb_queue.h | 6 +++++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 0fc833d1..ed0e4a6e 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "usb.h" #include "usb_queue.h" @@ -46,10 +47,10 @@ usb_transfer_t* free_transfers; // Pending transfer heads usb_transfer_t* endpoint_transfers[12] = {}; -void init_transfers() { +void usb_queue_init() { usb_transfer_t* t = &transfer_pool[0]; free_transfers = t; - for (unsigned int i=0; i < sizeof(transfer_pool) / sizeof(usb_transfer_t); i++, t++) { + for (unsigned int i=0; i < sizeof(transfer_pool) / sizeof(usb_transfer_t) - 1; i++, t++) { t->next = t+1; } t->next = NULL; @@ -104,10 +105,14 @@ static void endpoint_add_transfer( ) { uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); //FIXME disable_irqs(); - usb_transfer_t* t = endpoint_transfers[index]; transfer->next = NULL; - for (; t->next != NULL; t = t->next); - t->next = transfer; + if (endpoint_transfers[index] != NULL) { + usb_transfer_t* t = endpoint_transfers[index]; + for (; t->next != NULL; t = t->next); + t->next = transfer; + } else { + endpoint_transfers[index] = transfer; + } //enable_irqs(); } @@ -117,6 +122,7 @@ static usb_transfer_t* endpoint_pop_transfer( uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); //FIXME disable_irqs(); usb_transfer_t* transfer = endpoint_transfers[index]; + assert(transfer != NULL); endpoint_transfers[index] = transfer->next; //enable_irqs(); return transfer; @@ -155,7 +161,7 @@ void usb_transfer_schedule_ack( usb_transfer_schedule_wait(endpoint, 0, 0); } -void transfer_complete(const usb_endpoint_t* const endpoint) +void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) { usb_transfer_t* transfer = endpoint_pop_transfer(endpoint); unsigned int transferred = transfer->actual_length - transfer->td.total_bytes; diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index 5e10b33e..3963f15d 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -59,6 +59,10 @@ void usb_transfer_schedule( const uint32_t maximum_length ); -void init_transfers(void); +void usb_queue_init(void); + +void usb_queue_transfer_complete( + usb_endpoint_t* const endpoint +); #endif//__USB_QUEUE_H__ From bd4e39d3796ec49c68bb06b5fd41cfddc8f300b3 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 14:08:46 -0400 Subject: [PATCH 006/200] usb_queue: Add completion_cb arguments --- firmware/hackrf_usb/usb_queue.c | 10 +++++++--- firmware/hackrf_usb/usb_queue.h | 6 ++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index ed0e4a6e..91511885 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -131,10 +131,12 @@ static usb_transfer_t* endpoint_pop_transfer( void usb_transfer_schedule_wait( const usb_endpoint_t* const endpoint, void* const data, - const uint32_t maximum_length + const uint32_t maximum_length, + const transfer_completion_cb completion_cb ) { usb_transfer_t* const transfer = allocate_transfer(); fill_in_transfer(transfer, data, maximum_length); + transfer->completion_cb = completion_cb; endpoint_add_transfer(endpoint, transfer); usb_endpoint_schedule_wait(endpoint, &transfer->td); } @@ -142,11 +144,13 @@ void usb_transfer_schedule_wait( void usb_transfer_schedule_append( const usb_endpoint_t* const endpoint, void* const data, - const uint32_t maximum_length + const uint32_t maximum_length, + const transfer_completion_cb completion_cb ) { usb_transfer_t* const transfer = allocate_transfer(); uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); fill_in_transfer(transfer, data, maximum_length); + transfer->completion_cb = completion_cb; // TODO: disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; for (; tail->next != NULL; tail = tail->next); @@ -158,7 +162,7 @@ void usb_transfer_schedule_append( void usb_transfer_schedule_ack( const usb_endpoint_t* const endpoint ) { - usb_transfer_schedule_wait(endpoint, 0, 0); + usb_transfer_schedule_wait(endpoint, 0, 0, NULL); } void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index 3963f15d..cec51fb3 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -40,13 +40,15 @@ void usb_endpoint_schedule( void usb_transfer_schedule_wait( const usb_endpoint_t* const endpoint, void* const data, - const uint32_t maximum_length + const uint32_t maximum_length, + const transfer_completion_cb completion_cb ); void usb_transfer_schedule_append( const usb_endpoint_t* const endpoint, void* const data, - const uint32_t maximum_length + const uint32_t maximum_length, + const transfer_completion_cb completion_cb ); void usb_transfer_schedule_ack( From c62798d31fa4114c3ae23bb43d5496fe7b134abd Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 14:18:06 -0400 Subject: [PATCH 007/200] usb_queue: Kill old declaration --- firmware/hackrf_usb/usb_queue.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index cec51fb3..1498be46 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -55,12 +55,6 @@ void usb_transfer_schedule_ack( const usb_endpoint_t* const endpoint ); -void usb_transfer_schedule( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length -); - void usb_queue_init(void); void usb_queue_transfer_complete( From dfdfad2bf018d38aa092ba813f7bb2ade3b06fbb Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 14:18:28 -0400 Subject: [PATCH 008/200] hackrf_usb: Port to usb_queue --- firmware/hackrf_usb/hackrf_usb.c | 76 +++++++++++----------- firmware/hackrf_usb/usb_standard_request.c | 5 +- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 439f88cf..ff952b69 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -353,7 +353,7 @@ usb_request_status_t usb_vendor_request_set_transceiver_mode( case TRANSCEIVER_MODE_RX: case TRANSCEIVER_MODE_TX: set_transceiver_mode(endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; @@ -371,7 +371,7 @@ usb_request_status_t usb_vendor_request_write_max2837( if( endpoint->setup.index < MAX2837_NUM_REGS ) { if( endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE ) { max2837_reg_write(endpoint->setup.index, endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } } @@ -390,8 +390,8 @@ usb_request_status_t usb_vendor_request_read_max2837( const uint16_t value = max2837_reg_read(endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 2); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 2, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -408,7 +408,7 @@ usb_request_status_t usb_vendor_request_write_si5351c( if( endpoint->setup.index < 256 ) { if( endpoint->setup.value < 256 ) { si5351c_write_single(endpoint->setup.index, endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } } @@ -426,8 +426,8 @@ usb_request_status_t usb_vendor_request_read_si5351c( if( endpoint->setup.index < 256 ) { const uint8_t value = si5351c_read_single(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -443,7 +443,7 @@ usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint32_t bandwidth = (endpoint->setup.index << 16) | endpoint->setup.value; if( baseband_filter_bandwidth_set(bandwidth) ) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -461,7 +461,7 @@ usb_request_status_t usb_vendor_request_write_rffc5071( if( endpoint->setup.index < RFFC5071_NUM_REGS ) { rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -482,8 +482,8 @@ usb_request_status_t usb_vendor_request_read_rffc5071( value = rffc5071_reg_read(endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 2); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 2, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -501,7 +501,7 @@ usb_request_status_t usb_vendor_request_erase_spiflash( w25q80bv_setup(); /* only chip erase is implemented */ w25q80bv_chip_erase(); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); //FIXME probably should undo w25q80bv_setup() } return USB_REQUEST_STATUS_OK; @@ -522,7 +522,7 @@ usb_request_status_t usb_vendor_request_write_spiflash( || ((addr + len) > W25Q80BV_NUM_BYTES)) { return USB_REQUEST_STATUS_STALL; } else { - usb_endpoint_schedule(endpoint->out, &spiflash_buffer[0], len); + usb_transfer_schedule_wait(endpoint->out, &spiflash_buffer[0], len, NULL); w25q80bv_setup(); return USB_REQUEST_STATUS_OK; } @@ -535,7 +535,7 @@ usb_request_status_t usb_vendor_request_write_spiflash( return USB_REQUEST_STATUS_STALL; } else { w25q80bv_program(addr, len, &spiflash_buffer[0]); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); //FIXME probably should undo w25q80bv_setup() return USB_REQUEST_STATUS_OK; } @@ -566,7 +566,7 @@ usb_request_status_t usb_vendor_request_read_spiflash( { spiflash_buffer[i] = u8_addr_pt[i]; } - usb_endpoint_schedule(endpoint->in, &spiflash_buffer[0], len); + usb_transfer_schedule_wait(endpoint->in, &spiflash_buffer[0], len, NULL); return USB_REQUEST_STATUS_OK; } } else if (stage == USB_TRANSFER_STAGE_DATA) @@ -580,7 +580,7 @@ usb_request_status_t usb_vendor_request_read_spiflash( return USB_REQUEST_STATUS_STALL; } else { - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } } else @@ -604,7 +604,7 @@ usb_request_status_t usb_vendor_request_write_cpld( // len is limited to 64KB 16bits no overflow can happen total_len = endpoint->setup.value; len = endpoint->setup.length; - usb_endpoint_schedule(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len); + usb_transfer_schedule_wait(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len, NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { @@ -620,7 +620,7 @@ usb_request_status_t usb_vendor_request_write_cpld( // TO FIX ACK shall be not delayed so much as cpld prog can take up to 5s. if(error == 0) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); /* blink LED1, LED2, and LED3 on success */ while (1) @@ -642,7 +642,7 @@ usb_request_status_t usb_vendor_request_write_cpld( } }else { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } } else @@ -656,8 +656,8 @@ usb_request_status_t usb_vendor_request_read_board_id( { if (stage == USB_TRANSFER_STAGE_SETUP) { endpoint->buffer[0] = BOARD_ID; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; } @@ -669,8 +669,8 @@ usb_request_status_t usb_vendor_request_read_version_string( if (stage == USB_TRANSFER_STAGE_SETUP) { length = (uint8_t)strlen(version_string); - usb_endpoint_schedule(endpoint->in, version_string, length); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, version_string, length, NULL); + usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; } @@ -681,13 +681,13 @@ usb_request_status_t usb_vendor_request_set_freq( { if (stage == USB_TRANSFER_STAGE_SETUP) { - usb_endpoint_schedule(endpoint->out, &set_freq_params, sizeof(set_freq_params_t)); + usb_transfer_schedule_wait(endpoint->out, &set_freq_params, sizeof(set_freq_params_t), NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { if( set_freq(set_freq_params.freq_mhz, set_freq_params.freq_hz) ) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -703,13 +703,13 @@ usb_request_status_t usb_vendor_request_set_sample_rate_frac( { if (stage == USB_TRANSFER_STAGE_SETUP) { - usb_endpoint_schedule(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t)); + usb_transfer_schedule_wait(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t), NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { if( sample_rate_frac_set(set_sample_r_params.freq_hz * 2, set_sample_r_params.divider ) ) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -727,12 +727,12 @@ usb_request_status_t usb_vendor_request_set_amp_enable( case 0: switchctrl |= SWITCHCTRL_AMP_BYPASS; update_switches(); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; case 1: switchctrl &= ~SWITCHCTRL_AMP_BYPASS; update_switches(); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; @@ -777,8 +777,8 @@ usb_request_status_t usb_vendor_request_read_partid_serialno( read_partid_serialno.serial_no[3] = iap_cmd_res.status_res.iap_result[3]; length = (uint8_t)sizeof(read_partid_serialno_t); - usb_endpoint_schedule(endpoint->in, &read_partid_serialno, length); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &read_partid_serialno, length, NULL); + usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; } @@ -789,8 +789,8 @@ usb_request_status_t usb_vendor_request_set_lna_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_lna_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_OK; @@ -802,8 +802,8 @@ usb_request_status_t usb_vendor_request_set_vga_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_vga_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_OK; @@ -815,8 +815,8 @@ usb_request_status_t usb_vendor_request_set_txvga_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_txvga_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_OK; @@ -828,7 +828,7 @@ usb_request_status_t usb_vendor_request_set_if_freq( if( stage == USB_TRANSFER_STAGE_SETUP ) { MAX2837_FREQ_NOMINAL_HZ = (uint32_t)endpoint->setup.index * 1000 * 1000; set_freq(freq_mhz_cache, freq_hz_cache); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); } return USB_REQUEST_STATUS_OK; } diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index db9a0940..78ae7f3d 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -118,7 +118,8 @@ static usb_request_status_t usb_send_descriptor( usb_transfer_schedule_wait( endpoint->in, descriptor_data, - (setup_length > descriptor_length) ? descriptor_length : setup_length + (setup_length > descriptor_length) ? descriptor_length : setup_length, + NULL ); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; @@ -266,7 +267,7 @@ static usb_request_status_t usb_standard_request_get_configuration_setup( if( endpoint->device->configuration ) { endpoint->buffer[0] = endpoint->device->configuration->number; } - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1); + usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } else { From ac29621a36d87171b23d16551b188a31a6ee8b37 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 14:32:04 -0400 Subject: [PATCH 009/200] usb_queue: Use typedef --- firmware/hackrf_usb/usb_queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index 1498be46..74a6323d 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -29,7 +29,7 @@ typedef struct _usb_transfer_t usb_transfer_t; -typedef void (*transfer_completion_cb)(struct _usb_transfer_t*, unsigned int); +typedef void (*transfer_completion_cb)(usb_transfer_t*, unsigned int); void usb_endpoint_schedule( const usb_endpoint_t* const endpoint, From ee46cf1fc42603a1ef0e9badd85f982e8a65297c Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 14:51:41 -0400 Subject: [PATCH 010/200] usb_queue: Cleanup --- firmware/hackrf_usb/usb_queue.c | 39 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 91511885..38d00f3e 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -31,9 +31,8 @@ struct _usb_transfer_t { struct _usb_transfer_t* next; usb_transfer_descriptor_t td ATTR_ALIGNED(64); - unsigned int actual_length; + unsigned int maximum_length; usb_endpoint_t* endpoint; - bool finished; transfer_completion_cb completion_cb; }; @@ -56,25 +55,13 @@ void usb_queue_init() { t->next = NULL; } -static bool usb_endpoint_is_in(const uint_fast8_t endpoint_address) { - return (endpoint_address & 0x80) ? true : false; -} - -#if 0 -static usb_transfer_t* usb_transfer( - const uint_fast8_t endpoint_address -) { - return endpoint_transfers[USB_ENDPOINT_INDEX(endpoint_address)]; -} -#endif - static void fill_in_transfer(usb_transfer_t* transfer, void* const data, const uint32_t maximum_length ) { usb_transfer_descriptor_t* const td = &transfer->td; - // Configure a transfer. + // Configure the transfer. descriptor td->total_bytes = USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) | USB_TD_DTD_TOKEN_IOC @@ -86,8 +73,11 @@ static void fill_in_transfer(usb_transfer_t* transfer, td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; + + transfer->maximum_length = maximum_length; } +/* Allocate a transfer */ static usb_transfer_t* allocate_transfer() { while (free_transfers == NULL); @@ -95,10 +85,19 @@ static usb_transfer_t* allocate_transfer() usb_transfer_t* const transfer = free_transfers; free_transfers = transfer->next; //enable_irqs(); - transfer->finished = false; return transfer; } +/* Place a transfer in the free list */ +static void free_transfer(usb_transfer_t* const transfer) +{ + //disable_irqs(); // FIXME + transfer->next = free_transfers; + free_transfers = transfer; + //enable_irqs(); +} + +/* Add a transfer to the end of an endpoint's queue */ static void endpoint_add_transfer( const usb_endpoint_t* const endpoint, usb_transfer_t* const transfer @@ -116,6 +115,7 @@ static void endpoint_add_transfer( //enable_irqs(); } +/* Pop off the transfer at the top of an endpoint's queue */ static usb_transfer_t* endpoint_pop_transfer( const usb_endpoint_t* const endpoint ) { @@ -162,15 +162,14 @@ void usb_transfer_schedule_append( void usb_transfer_schedule_ack( const usb_endpoint_t* const endpoint ) { - usb_transfer_schedule_wait(endpoint, 0, 0, NULL); + usb_transfer_schedule_wait(endpoint, 0, 0, NULL); } void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) { usb_transfer_t* transfer = endpoint_pop_transfer(endpoint); - unsigned int transferred = transfer->actual_length - transfer->td.total_bytes; + unsigned int transferred = transfer->maximum_length - transfer->td.total_bytes; if (transfer->completion_cb) transfer->completion_cb(transfer, transferred); - else if (usb_endpoint_is_in(transfer->endpoint->address)) - transfer->finished = true; + free_transfer(transfer); } From ccfdd8350d73d50c8733a7fe18da23a85628a125 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 14:51:50 -0400 Subject: [PATCH 011/200] usb_request: Ensure control endpoint transfers get freed --- firmware/hackrf_usb/usb_request.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/firmware/hackrf_usb/usb_request.c b/firmware/hackrf_usb/usb_request.c index 25132fd4..f9226c7f 100644 --- a/firmware/hackrf_usb/usb_request.c +++ b/firmware/hackrf_usb/usb_request.c @@ -21,6 +21,7 @@ #include "usb.h" #include "usb_request.h" +#include "usb_queue.h" #include @@ -75,6 +76,7 @@ void usb_control_out_complete( } else { usb_request(endpoint, USB_TRANSFER_STAGE_DATA); } + usb_queue_transfer_complete(endpoint); } void usb_control_in_complete( @@ -87,5 +89,6 @@ void usb_control_in_complete( } else { usb_request(endpoint, USB_TRANSFER_STAGE_STATUS); } + usb_queue_transfer_complete(endpoint); } From ecd9b2e73169691391fb4d19bdcb41f92fa79eec Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 16:23:30 -0400 Subject: [PATCH 012/200] usb_queue: Kill usb_transfer_schedule_wait --- firmware/hackrf_usb/usb_queue.c | 27 +++++++++------------------ firmware/hackrf_usb/usb_queue.h | 9 +-------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 38d00f3e..0aa3a3c3 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -128,20 +128,7 @@ static usb_transfer_t* endpoint_pop_transfer( return transfer; } -void usb_transfer_schedule_wait( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length, - const transfer_completion_cb completion_cb -) { - usb_transfer_t* const transfer = allocate_transfer(); - fill_in_transfer(transfer, data, maximum_length); - transfer->completion_cb = completion_cb; - endpoint_add_transfer(endpoint, transfer); - usb_endpoint_schedule_wait(endpoint, &transfer->td); -} - -void usb_transfer_schedule_append( +void usb_transfer_schedule( const usb_endpoint_t* const endpoint, void* const data, const uint32_t maximum_length, @@ -153,16 +140,20 @@ void usb_transfer_schedule_append( transfer->completion_cb = completion_cb; // TODO: disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; - for (; tail->next != NULL; tail = tail->next); - endpoint_add_transfer(endpoint, transfer); - usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); + if (tail == NULL) { + usb_endpoint_schedule_wait(endpoint, &transfer->td); + } else { + for (; tail->next != NULL; tail = tail->next); + endpoint_add_transfer(endpoint, transfer); + usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); + } //enable_interrupts(); } void usb_transfer_schedule_ack( const usb_endpoint_t* const endpoint ) { - usb_transfer_schedule_wait(endpoint, 0, 0, NULL); + usb_transfer_schedule(endpoint, 0, 0, NULL); } void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index 74a6323d..f6dc0203 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -37,14 +37,7 @@ void usb_endpoint_schedule( const uint32_t maximum_length ); -void usb_transfer_schedule_wait( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length, - const transfer_completion_cb completion_cb -); - -void usb_transfer_schedule_append( +void usb_transfer_schedule( const usb_endpoint_t* const endpoint, void* const data, const uint32_t maximum_length, From 96f8621ad99238f06f33d1dbec06e95513f5cc66 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 16:25:17 -0400 Subject: [PATCH 013/200] hackrf_usb: Port things away from schedule_wait --- firmware/hackrf_usb/hackrf_usb.c | 28 +++++++++++----------- firmware/hackrf_usb/usb_standard_request.c | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index ff952b69..14d1722b 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -390,7 +390,7 @@ usb_request_status_t usb_vendor_request_read_max2837( const uint16_t value = max2837_reg_read(endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 2, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 2, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } @@ -426,7 +426,7 @@ usb_request_status_t usb_vendor_request_read_si5351c( if( endpoint->setup.index < 256 ) { const uint8_t value = si5351c_read_single(endpoint->setup.index); endpoint->buffer[0] = value; - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 1, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } @@ -482,7 +482,7 @@ usb_request_status_t usb_vendor_request_read_rffc5071( value = rffc5071_reg_read(endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 2, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 2, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } @@ -522,7 +522,7 @@ usb_request_status_t usb_vendor_request_write_spiflash( || ((addr + len) > W25Q80BV_NUM_BYTES)) { return USB_REQUEST_STATUS_STALL; } else { - usb_transfer_schedule_wait(endpoint->out, &spiflash_buffer[0], len, NULL); + usb_transfer_schedule(endpoint->out, &spiflash_buffer[0], len, NULL); w25q80bv_setup(); return USB_REQUEST_STATUS_OK; } @@ -566,7 +566,7 @@ usb_request_status_t usb_vendor_request_read_spiflash( { spiflash_buffer[i] = u8_addr_pt[i]; } - usb_transfer_schedule_wait(endpoint->in, &spiflash_buffer[0], len, NULL); + usb_transfer_schedule(endpoint->in, &spiflash_buffer[0], len, NULL); return USB_REQUEST_STATUS_OK; } } else if (stage == USB_TRANSFER_STAGE_DATA) @@ -604,7 +604,7 @@ usb_request_status_t usb_vendor_request_write_cpld( // len is limited to 64KB 16bits no overflow can happen total_len = endpoint->setup.value; len = endpoint->setup.length; - usb_transfer_schedule_wait(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len, NULL); + usb_transfer_schedule(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len, NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { @@ -656,7 +656,7 @@ usb_request_status_t usb_vendor_request_read_board_id( { if (stage == USB_TRANSFER_STAGE_SETUP) { endpoint->buffer[0] = BOARD_ID; - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 1, NULL); usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; @@ -669,7 +669,7 @@ usb_request_status_t usb_vendor_request_read_version_string( if (stage == USB_TRANSFER_STAGE_SETUP) { length = (uint8_t)strlen(version_string); - usb_transfer_schedule_wait(endpoint->in, version_string, length, NULL); + usb_transfer_schedule(endpoint->in, version_string, length, NULL); usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; @@ -681,7 +681,7 @@ usb_request_status_t usb_vendor_request_set_freq( { if (stage == USB_TRANSFER_STAGE_SETUP) { - usb_transfer_schedule_wait(endpoint->out, &set_freq_params, sizeof(set_freq_params_t), NULL); + usb_transfer_schedule(endpoint->out, &set_freq_params, sizeof(set_freq_params_t), NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { @@ -703,7 +703,7 @@ usb_request_status_t usb_vendor_request_set_sample_rate_frac( { if (stage == USB_TRANSFER_STAGE_SETUP) { - usb_transfer_schedule_wait(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t), NULL); + usb_transfer_schedule(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t), NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { @@ -777,7 +777,7 @@ usb_request_status_t usb_vendor_request_read_partid_serialno( read_partid_serialno.serial_no[3] = iap_cmd_res.status_res.iap_result[3]; length = (uint8_t)sizeof(read_partid_serialno_t); - usb_transfer_schedule_wait(endpoint->in, &read_partid_serialno, length, NULL); + usb_transfer_schedule(endpoint->in, &read_partid_serialno, length, NULL); usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; @@ -789,7 +789,7 @@ usb_request_status_t usb_vendor_request_set_lna_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_lna_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 1, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } @@ -802,7 +802,7 @@ usb_request_status_t usb_vendor_request_set_vga_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_vga_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 1, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } @@ -815,7 +815,7 @@ usb_request_status_t usb_vendor_request_set_txvga_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_txvga_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 1, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index 78ae7f3d..43f2379f 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -115,7 +115,7 @@ static usb_request_status_t usb_send_descriptor( if( descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION ) { descriptor_length = (descriptor_data[3] << 8) | descriptor_data[2]; } - usb_transfer_schedule_wait( + usb_transfer_schedule( endpoint->in, descriptor_data, (setup_length > descriptor_length) ? descriptor_length : setup_length, @@ -267,7 +267,7 @@ static usb_request_status_t usb_standard_request_get_configuration_setup( if( endpoint->device->configuration ) { endpoint->buffer[0] = endpoint->device->configuration->number; } - usb_transfer_schedule_wait(endpoint->in, &endpoint->buffer, 1, NULL); + usb_transfer_schedule(endpoint->in, &endpoint->buffer, 1, NULL); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } else { From af34a7a0416c5a8125bd99f39319e94d8c803e3f Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 16:35:26 -0400 Subject: [PATCH 014/200] usb: Use usb_endpoint_is_priming helper --- firmware/hackrf_usb/usb.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 14a94397..09e3d127 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -188,6 +188,17 @@ void usb_endpoint_prime( } } +static bool usb_endpoint_is_priming( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number); + } else { + return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number); + } +} + // Schedule an already filled-in transfer descriptor for execution on // the given endpoint, waiting until the endpoint has finished. void usb_endpoint_schedule_wait( @@ -213,18 +224,13 @@ void usb_endpoint_schedule_append( usb_transfer_descriptor_t* const tail_td, usb_transfer_descriptor_t* const new_td ) { - const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); bool done; tail_td->next_dtd_pointer = new_td; do { - if( usb_endpoint_is_in(endpoint->address) ) { - if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number) ) - return; - } else { - if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number) ) - return; + if (usb_endpoint_is_priming(endpoint)) { + return; } USB0_USBCMD_D |= USB0_USBCMD_D_ATDTW; @@ -237,18 +243,6 @@ void usb_endpoint_schedule_append( } } -/* -static bool usb_endpoint_is_priming( - const usb_endpoint_t* const endpoint -) { - const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); - if( usb_endpoint_is_in(endpoint->address) ) { - return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number); - } else { - return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number); - } -} -*/ void usb_endpoint_flush( const usb_endpoint_t* const endpoint ) { From a88b2ad349429879205e0c47df21392911efea58 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 16:40:53 -0400 Subject: [PATCH 015/200] usb_queue: Transfer needs to be added to queue in both paths --- firmware/hackrf_usb/usb_queue.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 0aa3a3c3..c0b5f7d7 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -139,13 +139,13 @@ void usb_transfer_schedule( fill_in_transfer(transfer, data, maximum_length); transfer->completion_cb = completion_cb; // TODO: disable_interrupts(); + endpoint_add_transfer(endpoint, transfer); usb_transfer_t* tail = endpoint_transfers[index]; if (tail == NULL) { usb_endpoint_schedule_wait(endpoint, &transfer->td); } else { - for (; tail->next != NULL; tail = tail->next); - endpoint_add_transfer(endpoint, transfer); - usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); + for (; tail->next != NULL; tail = tail->next); + usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); } //enable_interrupts(); } From 0d1ea071515eda1ff97fd0d21542fe4f7a606f29 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 16:41:39 -0400 Subject: [PATCH 016/200] usb: Check is_priming before loop --- firmware/hackrf_usb/usb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 09e3d127..5a151aec 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -228,11 +228,11 @@ void usb_endpoint_schedule_append( tail_td->next_dtd_pointer = new_td; - do { - if (usb_endpoint_is_priming(endpoint)) { - return; - } + if (usb_endpoint_is_priming(endpoint)) { + return; + } + do { USB0_USBCMD_D |= USB0_USBCMD_D_ATDTW; done = usb_endpoint_is_ready(endpoint); } while (!(USB0_USBCMD_D & USB0_USBCMD_D_ATDTW)); From eef6a0f0566e13289d08a8d7654316771c20fc06 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 16:51:18 -0400 Subject: [PATCH 017/200] usb_queue: Assert that transaction succeeded --- firmware/hackrf_usb/usb_queue.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index c0b5f7d7..10fd1ef8 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -160,6 +160,13 @@ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) { usb_transfer_t* transfer = endpoint_pop_transfer(endpoint); unsigned int transferred = transfer->maximum_length - transfer->td.total_bytes; + uint8_t status = transfer->td.total_bytes; + if (status & USB_TD_DTD_TOKEN_STATUS_ACTIVE + || status & USB_TD_DTD_TOKEN_STATUS_HALTED + || status & USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR + || status & USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR) { + assert(0); + } if (transfer->completion_cb) transfer->completion_cb(transfer, transferred); free_transfer(transfer); From f36943df627acf58e00d0698c348a93b0e417043 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 16:51:48 -0400 Subject: [PATCH 018/200] usb: Whitespace cleanup --- firmware/hackrf_usb/usb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 5a151aec..a44d9164 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -90,25 +90,25 @@ static void usb_clear_all_pending_interrupts() { static void usb_wait_for_endpoint_priming_to_finish(const uint32_t mask) { // Wait until controller has parsed new transfer descriptors and prepared // receive buffers. - while( USB0_ENDPTPRIME & mask ); + while( USB0_ENDPTPRIME & mask ); } static void usb_flush_endpoints(const uint32_t mask) { // Clear any primed buffers. If a packet is in progress, that transfer // will continue until completion. - USB0_ENDPTFLUSH = mask; + USB0_ENDPTFLUSH = mask; } static void usb_wait_for_endpoint_flushing_to_finish(const uint32_t mask) { // Wait until controller has flushed all endpoints / cleared any primed // buffers. - while( USB0_ENDPTFLUSH & mask ); + while( USB0_ENDPTFLUSH & mask ); } static void usb_flush_primed_endpoints(const uint32_t mask) { - usb_wait_for_endpoint_priming_to_finish(mask); + usb_wait_for_endpoint_priming_to_finish(mask); usb_flush_endpoints(mask); - usb_wait_for_endpoint_flushing_to_finish(mask); + usb_wait_for_endpoint_flushing_to_finish(mask); } static void usb_flush_all_primed_endpoints() { From f3a36d06fd4befd0b8e99d96df30f697ce9a18ec Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 17:11:29 -0400 Subject: [PATCH 019/200] usb_queue: Add new transfer after finding tail --- firmware/hackrf_usb/usb_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 10fd1ef8..4dcd57c6 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -139,8 +139,8 @@ void usb_transfer_schedule( fill_in_transfer(transfer, data, maximum_length); transfer->completion_cb = completion_cb; // TODO: disable_interrupts(); - endpoint_add_transfer(endpoint, transfer); usb_transfer_t* tail = endpoint_transfers[index]; + endpoint_add_transfer(endpoint, transfer); if (tail == NULL) { usb_endpoint_schedule_wait(endpoint, &transfer->td); } else { From 2ad4cbe087eed22840015c708e8380b8584060d4 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 17:48:43 -0400 Subject: [PATCH 020/200] usb_queue: Fix calculation of transferred --- firmware/hackrf_usb/usb_queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 4dcd57c6..853ace75 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -159,7 +159,8 @@ void usb_transfer_schedule_ack( void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) { usb_transfer_t* transfer = endpoint_pop_transfer(endpoint); - unsigned int transferred = transfer->maximum_length - transfer->td.total_bytes; + unsigned int total_bytes = (transfer->td.total_bytes & USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK) >> USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT; + unsigned int transferred = transfer->maximum_length - total_bytes; uint8_t status = transfer->td.total_bytes; if (status & USB_TD_DTD_TOKEN_STATUS_ACTIVE || status & USB_TD_DTD_TOKEN_STATUS_HALTED From 1d9119fd8acf2b0c12501620dd2d826e9acb7867 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 17:48:55 -0400 Subject: [PATCH 021/200] usb: Ensure TERMINATE bit gets set --- firmware/hackrf_usb/usb.c | 3 ++- firmware/hackrf_usb/usb_queue.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index a44d9164..472e5eb5 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -218,7 +218,8 @@ void usb_endpoint_schedule_wait( // Schedule an already filled-in transfer descriptor for execution on // the given endpoint, appending to the end of the endpoint's queue if // there are pending TDs. Note that this requires that one knows the -// tail of the endpoint's TD queue +// tail of the endpoint's TD queue. Moreover, the user is responsible +// for setting the TERMINATE bit of next_dtd_pointer if needed. void usb_endpoint_schedule_append( const usb_endpoint_t* const endpoint, usb_transfer_descriptor_t* const tail_td, diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 853ace75..dc8ec2eb 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -137,6 +137,7 @@ void usb_transfer_schedule( usb_transfer_t* const transfer = allocate_transfer(); uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); fill_in_transfer(transfer, data, maximum_length); + transfer->td.next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; transfer->completion_cb = completion_cb; // TODO: disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; From 28fcb2a961dd2bdfcd114d8d01f4abc38a8a98d3 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 17:51:42 -0400 Subject: [PATCH 022/200] usb_queue: Merge fill_in_transfer into schedule --- firmware/hackrf_usb/usb_queue.c | 44 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index dc8ec2eb..64822840 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -54,28 +54,6 @@ void usb_queue_init() { } t->next = NULL; } - -static void fill_in_transfer(usb_transfer_t* transfer, - void* const data, - const uint32_t maximum_length -) { - usb_transfer_descriptor_t* const td = &transfer->td; - - // Configure the transfer. descriptor - td->total_bytes = - USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) - | USB_TD_DTD_TOKEN_IOC - | USB_TD_DTD_TOKEN_MULTO(0) - | USB_TD_DTD_TOKEN_STATUS_ACTIVE - ; - td->buffer_pointer_page[0] = (uint32_t)data; - td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; - td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; - td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; - td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; - - transfer->maximum_length = maximum_length; -} /* Allocate a transfer */ static usb_transfer_t* allocate_transfer() @@ -135,16 +113,36 @@ void usb_transfer_schedule( const transfer_completion_cb completion_cb ) { usb_transfer_t* const transfer = allocate_transfer(); + assert(transfer != NULL); + usb_transfer_descriptor_t* const td = &transfer->td; uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); - fill_in_transfer(transfer, data, maximum_length); + + // Configure the transfer descriptor + td->total_bytes = + USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) + | USB_TD_DTD_TOKEN_IOC + | USB_TD_DTD_TOKEN_MULTO(0) + | USB_TD_DTD_TOKEN_STATUS_ACTIVE + ; + td->buffer_pointer_page[0] = (uint32_t)data; + td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; + td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; + td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; + td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; + + // Fill in transfer fields + transfer->maximum_length = maximum_length; transfer->td.next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; transfer->completion_cb = completion_cb; + // TODO: disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; endpoint_add_transfer(endpoint, transfer); if (tail == NULL) { + // The queue is currently empty, we need to re-prime usb_endpoint_schedule_wait(endpoint, &transfer->td); } else { + // The queue is currently running, try to append for (; tail->next != NULL; tail = tail->next); usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); } From 13589b86958143757eeed128b61118b20937f8f7 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 18:14:15 -0400 Subject: [PATCH 023/200] usb_queue: Ensure fields get set --- firmware/hackrf_usb/usb_queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 64822840..7c7fa6f9 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -118,6 +118,7 @@ void usb_transfer_schedule( uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); // Configure the transfer descriptor + td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; td->total_bytes = USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) | USB_TD_DTD_TOKEN_IOC @@ -132,8 +133,8 @@ void usb_transfer_schedule( // Fill in transfer fields transfer->maximum_length = maximum_length; - transfer->td.next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; transfer->completion_cb = completion_cb; + transfer->endpoint = endpoint; // TODO: disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; From f1fc4a6d73d40034b2bb457fc3a191be28b0ecb5 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 3 Jul 2013 19:11:26 -0400 Subject: [PATCH 024/200] usb_queue: Account for completion of multiple transfers --- firmware/hackrf_usb/usb_queue.c | 58 ++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 7c7fa6f9..1768b0a5 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -93,19 +93,6 @@ static void endpoint_add_transfer( //enable_irqs(); } -/* Pop off the transfer at the top of an endpoint's queue */ -static usb_transfer_t* endpoint_pop_transfer( - const usb_endpoint_t* const endpoint -) { - uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); - //FIXME disable_irqs(); - usb_transfer_t* transfer = endpoint_transfers[index]; - assert(transfer != NULL); - endpoint_transfers[index] = transfer->next; - //enable_irqs(); - return transfer; -} - void usb_transfer_schedule( const usb_endpoint_t* const endpoint, void* const data, @@ -134,12 +121,12 @@ void usb_transfer_schedule( // Fill in transfer fields transfer->maximum_length = maximum_length; transfer->completion_cb = completion_cb; - transfer->endpoint = endpoint; + transfer->endpoint = (usb_endpoint_t*) endpoint; // TODO: disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; endpoint_add_transfer(endpoint, transfer); - if (tail == NULL) { + if (1 || tail == NULL) { // The queue is currently empty, we need to re-prime usb_endpoint_schedule_wait(endpoint, &transfer->td); } else { @@ -156,19 +143,36 @@ void usb_transfer_schedule_ack( usb_transfer_schedule(endpoint, 0, 0, NULL); } +/* Called when an endpoint might have completed a transfer */ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) { - usb_transfer_t* transfer = endpoint_pop_transfer(endpoint); - unsigned int total_bytes = (transfer->td.total_bytes & USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK) >> USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT; - unsigned int transferred = transfer->maximum_length - total_bytes; - uint8_t status = transfer->td.total_bytes; - if (status & USB_TD_DTD_TOKEN_STATUS_ACTIVE - || status & USB_TD_DTD_TOKEN_STATUS_HALTED - || status & USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR - || status & USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR) { - assert(0); + uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); + usb_transfer_t* transfer = endpoint_transfers[index]; + + while (transfer != NULL) { + uint8_t status = transfer->td.total_bytes; + + // Check for failures + if ( status & USB_TD_DTD_TOKEN_STATUS_HALTED + || status & USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR + || status & USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR) { + assert(0); + } + + // Still not finished + if (status & USB_TD_DTD_TOKEN_STATUS_ACTIVE) + break; + + // Invoke completion callback + unsigned int total_bytes = (transfer->td.total_bytes & USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK) >> USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT; + unsigned int transferred = transfer->maximum_length - total_bytes; + if (transfer->completion_cb) + transfer->completion_cb(transfer, transferred); + + // Advance head and free + endpoint_transfers[index] = transfer->next; + usb_transfer_t* next = transfer->next; + free_transfer(transfer); + transfer = next; } - if (transfer->completion_cb) - transfer->completion_cb(transfer, transferred); - free_transfer(transfer); } From 63ce57b30632e0bbd92c8b74257806b0807bb9ba Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 4 Jul 2013 11:26:22 -0400 Subject: [PATCH 025/200] usb_queue: Clarify comment --- firmware/hackrf_usb/usb_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 1768b0a5..27053c35 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -169,7 +169,7 @@ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) if (transfer->completion_cb) transfer->completion_cb(transfer, transferred); - // Advance head and free + // Advance head and free transfer endpoint_transfers[index] = transfer->next; usb_transfer_t* next = transfer->next; free_transfer(transfer); From b6f9a3699a544ca505c5bccb335733b90bb41ee9 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 4 Jul 2013 11:35:32 -0400 Subject: [PATCH 026/200] usb_queue: Kill assert reference --- firmware/hackrf_usb/usb_queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 27053c35..ea9e6e69 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -156,7 +156,8 @@ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) if ( status & USB_TD_DTD_TOKEN_STATUS_HALTED || status & USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR || status & USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR) { - assert(0); + // TODO: Uh oh, do something useful here + while (1); } // Still not finished From df97b6584bbd50c5bd225dea51618ff738953888 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 4 Jul 2013 11:53:09 -0400 Subject: [PATCH 027/200] hackrf_usb: Port to usb_queue --- firmware/hackrf_usb/hackrf_usb.c | 65 +++++--------------------------- 1 file changed, 10 insertions(+), 55 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 14d1722b..acfe0c53 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -50,9 +50,6 @@ uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; static volatile uint32_t usb_bulk_buffer_offset = 0; static const uint32_t usb_bulk_buffer_mask = 32768 - 1; -usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64); -const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]); - /* TODO remove this big buffer and use streaming for CPLD */ #define CPLD_XSVF_MAX_LEN (65536) uint8_t cpld_xsvf_buffer[CPLD_XSVF_MAX_LEN]; @@ -182,50 +179,6 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) return success; } -static void usb_init_buffers_bulk() { - usb_td_bulk[0].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - usb_td_bulk[0].total_bytes - = USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) - | USB_TD_DTD_TOKEN_MULTO(0) - ; - usb_td_bulk[0].buffer_pointer_page[0] = (uint32_t)&usb_bulk_buffer[0x0000]; - usb_td_bulk[0].buffer_pointer_page[1] = (uint32_t)&usb_bulk_buffer[0x1000]; - usb_td_bulk[0].buffer_pointer_page[2] = (uint32_t)&usb_bulk_buffer[0x2000]; - usb_td_bulk[0].buffer_pointer_page[3] = (uint32_t)&usb_bulk_buffer[0x3000]; - usb_td_bulk[0].buffer_pointer_page[4] = (uint32_t)&usb_bulk_buffer[0x4000]; - - usb_td_bulk[1].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - usb_td_bulk[1].total_bytes - = USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) - | USB_TD_DTD_TOKEN_MULTO(0) - ; - usb_td_bulk[1].buffer_pointer_page[0] = (uint32_t)&usb_bulk_buffer[0x4000]; - usb_td_bulk[1].buffer_pointer_page[1] = (uint32_t)&usb_bulk_buffer[0x5000]; - usb_td_bulk[1].buffer_pointer_page[2] = (uint32_t)&usb_bulk_buffer[0x6000]; - usb_td_bulk[1].buffer_pointer_page[3] = (uint32_t)&usb_bulk_buffer[0x7000]; - usb_td_bulk[1].buffer_pointer_page[4] = (uint32_t)&usb_bulk_buffer[0x8000]; -} - -void usb_endpoint_schedule_no_int( - const usb_endpoint_t* const endpoint, - usb_transfer_descriptor_t* const td -) { - // Ensure that endpoint is ready to be primed. - // It may have been flushed due to an aborted transaction. - // TODO: This should be preceded by a flush? - while( usb_endpoint_is_ready(endpoint) ); - - // Configure a transfer. - td->total_bytes = - USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) - /*| USB_TD_DTD_TOKEN_IOC*/ - | USB_TD_DTD_TOKEN_MULTO(0) - | USB_TD_DTD_TOKEN_STATUS_ACTIVE - ; - - usb_endpoint_prime(endpoint, td); -} - usb_configuration_t usb_configuration_high_speed = { .number = 1, .speed = USB_SPEED_HIGH, @@ -281,7 +234,7 @@ usb_endpoint_t usb_endpoint_bulk_in = { .in = &usb_endpoint_bulk_in, .out = 0, .setup_complete = 0, - .transfer_complete = 0, + .transfer_complete = usb_queue_transfer_complete }; usb_endpoint_t usb_endpoint_bulk_out = { @@ -290,7 +243,7 @@ usb_endpoint_t usb_endpoint_bulk_out = { .in = 0, .out = &usb_endpoint_bulk_out, .setup_complete = 0, - .transfer_complete = 0, + .transfer_complete = usb_queue_transfer_complete }; void baseband_streaming_disable() { @@ -307,8 +260,6 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { transceiver_mode = new_transceiver_mode; - usb_init_buffers_bulk(); - if( transceiver_mode == TRANSCEIVER_MODE_RX ) { gpio_clear(PORT_LED1_3, PIN_LED3); gpio_set(PORT_LED1_3, PIN_LED2); @@ -997,20 +948,24 @@ int main(void) { while( usb_bulk_buffer_offset < 16384 ); // Set up IN transfer of buffer 0. - usb_endpoint_schedule_no_int( + usb_transfer_schedule( (transceiver_mode == TRANSCEIVER_MODE_RX) ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_td_bulk[0] + &usb_bulk_buffer[0x0000], + 0x4000, + NULL ); // Wait until buffer 1 is transmitted/received. while( usb_bulk_buffer_offset >= 16384 ); // Set up IN transfer of buffer 1. - usb_endpoint_schedule_no_int( + usb_transfer_schedule( (transceiver_mode == TRANSCEIVER_MODE_RX) ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_td_bulk[1] + &usb_bulk_buffer[0x4000], + 0x4000, + NULL ); } From dd81921650fab8bd5c4da28925a5f3ad3049e774 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 4 Jul 2013 13:36:25 -0400 Subject: [PATCH 028/200] usb_queue: Reduce transfer_pool size --- firmware/hackrf_usb/usb_queue.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index ea9e6e69..b68d3fc5 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -36,7 +36,8 @@ struct _usb_transfer_t { transfer_completion_cb completion_cb; }; -usb_transfer_t transfer_pool[16]; +usb_transfer_t transfer_pool[8]; +const unsigned int transfer_pool_size = sizeof(transfer_pool) / sizeof(usb_transfer_t); // Available transfer list usb_transfer_t* free_transfers; @@ -49,7 +50,7 @@ usb_transfer_t* endpoint_transfers[12] = {}; void usb_queue_init() { usb_transfer_t* t = &transfer_pool[0]; free_transfers = t; - for (unsigned int i=0; i < sizeof(transfer_pool) / sizeof(usb_transfer_t) - 1; i++, t++) { + for (unsigned int i=0; i < transfer_pool_size - 1; i++, t++) { t->next = t+1; } t->next = NULL; From abb0b3f928c70c9b4f8f107e0db661f7e734ba30 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 4 Jul 2013 14:01:32 -0400 Subject: [PATCH 029/200] hackrf_usb: Forgotten initialization --- firmware/hackrf_usb/hackrf_usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index acfe0c53..5ece18a6 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -918,6 +918,8 @@ int main(void) { enable_1v8_power(); cpu_clock_init(); + usb_queue_init(); + usb_set_configuration_changed_cb(usb_configuration_changed); usb_peripheral_reset(); usb_device_init(0, &usb_device); From 3e3a57e3ced46b6663ef97093d3d425509d50fbf Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 4 Jul 2013 15:30:15 -0400 Subject: [PATCH 030/200] hackrf_usb: Don't attempt to schedule transfers when OFF The endpoints are disabled so no good will come of this --- firmware/hackrf_usb/hackrf_usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 5ece18a6..348b9236 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -946,6 +946,9 @@ int main(void) { #endif while(true) { + if (transceiver_mode == TRANSCEIVER_MODE_OFF) + continue; + // Wait until buffer 0 is transmitted/received. while( usb_bulk_buffer_offset < 16384 ); From 5a70772295bb670215dd4d36fdf3e5985af99f71 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Thu, 4 Jul 2013 15:30:43 -0400 Subject: [PATCH 031/200] usb_queue: Enable transfer chaining Unfortunately this seems to be slightly broken. While hackrf_transfer streams fine, things fall apart when disabling streaming. Not sure why yet. --- firmware/hackrf_usb/usb_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index b68d3fc5..7492eb92 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -127,7 +127,7 @@ void usb_transfer_schedule( // TODO: disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; endpoint_add_transfer(endpoint, transfer); - if (1 || tail == NULL) { + if (tail == NULL) { // The queue is currently empty, we need to re-prime usb_endpoint_schedule_wait(endpoint, &transfer->td); } else { From 969647dbef657f254724cc185a956a6ca695a457 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Fri, 5 Jul 2013 11:15:23 -0400 Subject: [PATCH 032/200] usb_queue: Update queue before calling completion callback --- firmware/hackrf_usb/usb_queue.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 7492eb92..79e00095 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -165,6 +165,11 @@ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) if (status & USB_TD_DTD_TOKEN_STATUS_ACTIVE) break; + // Advance the head. We need to do this before invoking the completion + // callback as it might attempt to schedule a new transfer + endpoint_transfers[index] = transfer->next; + usb_transfer_t* next = transfer->next; + // Invoke completion callback unsigned int total_bytes = (transfer->td.total_bytes & USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK) >> USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT; unsigned int transferred = transfer->maximum_length - total_bytes; @@ -172,8 +177,6 @@ void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) transfer->completion_cb(transfer, transferred); // Advance head and free transfer - endpoint_transfers[index] = transfer->next; - usb_transfer_t* next = transfer->next; free_transfer(transfer); transfer = next; } From 8fdc22f8c8605fe576327b6ac61f0804fe18ee20 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 6 Jul 2013 17:00:23 -0400 Subject: [PATCH 033/200] usb-queue: Add flush utility --- firmware/hackrf_usb/usb_queue.c | 13 ++++++++++++- firmware/hackrf_usb/usb_queue.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 79e00095..b595b4e7 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -55,7 +55,7 @@ void usb_queue_init() { } t->next = NULL; } - + /* Allocate a transfer */ static usb_transfer_t* allocate_transfer() { @@ -93,6 +93,17 @@ static void endpoint_add_transfer( } //enable_irqs(); } + +void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint) +{ + uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); + //FIXME disable_irqs(); + while (endpoint_transfers[index]) { + usb_transfer_t * transfer = endpoint_transfers[index]; + endpoint_transfers[index] = transfer->next; + free_transfer(transfer); + } +} void usb_transfer_schedule( const usb_endpoint_t* const endpoint, diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index f6dc0203..90d59567 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -31,6 +31,8 @@ typedef struct _usb_transfer_t usb_transfer_t; typedef void (*transfer_completion_cb)(usb_transfer_t*, unsigned int); +void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint); + void usb_endpoint_schedule( const usb_endpoint_t* const endpoint, void* const data, From f12defebc65953a0d2c6860d8deeaf217681a323 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 6 Jul 2013 17:08:51 -0400 Subject: [PATCH 034/200] usb: Ensure endpoint queue is flushed on disable/init --- firmware/hackrf_usb/usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 472e5eb5..8a02eb0e 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -24,6 +24,7 @@ #include "usb.h" #include "usb_type.h" +#include "usb_queue.h" #include "usb_standard_request.h" #include @@ -163,6 +164,7 @@ void usb_endpoint_disable( } else { USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_RXE); } + usb_queue_flush_endpoint(endpoint); usb_endpoint_clear_pending_interrupts(endpoint); usb_endpoint_flush(endpoint); } @@ -248,6 +250,7 @@ void usb_endpoint_flush( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + usb_queue_flush_endpoint(endpoint); if( usb_endpoint_is_in(endpoint->address) ) { usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FETB(1 << endpoint_number)); } else { From 9f2dca3e4e2c2aa042f6b94cc1fe308bc1e22bc0 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 6 Jul 2013 17:01:12 -0400 Subject: [PATCH 035/200] usb_standard_request: Always call configuration_changed_cb For reasons I don't entirely understand, bulk requests are suddenly ignored after a SET_CONFIGURATION request (even if the configuration did not change) unless the endpoints are reinitialized. This is done by configuration_changed_cb, therefore we call it for every request. --- firmware/hackrf_usb/usb_standard_request.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index 43f2379f..43c23ada 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -100,9 +100,11 @@ bool usb_set_configuration( if( new_configuration != device->configuration ) { // Configuration changed. device->configuration = new_configuration; - if (usb_configuration_changed_cb) - usb_configuration_changed_cb(device); } + + if (usb_configuration_changed_cb) + usb_configuration_changed_cb(device); + return true; } From 14526cd1c278f7ee6709ad19cefa1ff937bbf5d5 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 6 Jul 2013 19:15:17 -0400 Subject: [PATCH 036/200] hackrf_usb: Be more careful in transceiver_mode check --- firmware/hackrf_usb/hackrf_usb.c | 35 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 348b9236..b04fb9ae 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -946,32 +946,33 @@ int main(void) { #endif while(true) { - if (transceiver_mode == TRANSCEIVER_MODE_OFF) - continue; - // Wait until buffer 0 is transmitted/received. while( usb_bulk_buffer_offset < 16384 ); // Set up IN transfer of buffer 0. - usb_transfer_schedule( - (transceiver_mode == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_bulk_buffer[0x0000], - 0x4000, - NULL - ); + if (transceiver_mode != TRANSCEIVER_MODE_OFF) { + usb_transfer_schedule( + (transceiver_mode == TRANSCEIVER_MODE_RX) + ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, + &usb_bulk_buffer[0x0000], + 0x4000, + NULL + ); + } // Wait until buffer 1 is transmitted/received. while( usb_bulk_buffer_offset >= 16384 ); // Set up IN transfer of buffer 1. - usb_transfer_schedule( - (transceiver_mode == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_bulk_buffer[0x4000], - 0x4000, - NULL - ); + if (transceiver_mode != TRANSCEIVER_MODE_OFF) { + usb_transfer_schedule( + (transceiver_mode == TRANSCEIVER_MODE_RX) + ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, + &usb_bulk_buffer[0x4000], + 0x4000, + NULL + ); + } } return 0; From 36cf222ef498258d1c0f81d63f66d3c810b255c3 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 6 Jul 2013 19:17:38 -0400 Subject: [PATCH 037/200] usb_queue: Add some interrupt disabling around critical sections --- firmware/hackrf_usb/usb_queue.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index b595b4e7..cb90959a 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -25,6 +25,8 @@ #include #include +#include + #include "usb.h" #include "usb_queue.h" @@ -60,20 +62,16 @@ void usb_queue_init() { static usb_transfer_t* allocate_transfer() { while (free_transfers == NULL); - //disable_irqs(); // FIXME usb_transfer_t* const transfer = free_transfers; free_transfers = transfer->next; - //enable_irqs(); return transfer; } /* Place a transfer in the free list */ static void free_transfer(usb_transfer_t* const transfer) { - //disable_irqs(); // FIXME transfer->next = free_transfers; free_transfers = transfer; - //enable_irqs(); } /* Add a transfer to the end of an endpoint's queue */ @@ -82,7 +80,6 @@ static void endpoint_add_transfer( usb_transfer_t* const transfer ) { uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); - //FIXME disable_irqs(); transfer->next = NULL; if (endpoint_transfers[index] != NULL) { usb_transfer_t* t = endpoint_transfers[index]; @@ -91,18 +88,18 @@ static void endpoint_add_transfer( } else { endpoint_transfers[index] = transfer; } - //enable_irqs(); } void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint) { uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); - //FIXME disable_irqs(); + cc_disable_interrupts(); while (endpoint_transfers[index]) { usb_transfer_t * transfer = endpoint_transfers[index]; endpoint_transfers[index] = transfer->next; free_transfer(transfer); } + cc_enable_interrupts(); } void usb_transfer_schedule( @@ -135,7 +132,7 @@ void usb_transfer_schedule( transfer->completion_cb = completion_cb; transfer->endpoint = (usb_endpoint_t*) endpoint; - // TODO: disable_interrupts(); + cc_disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; endpoint_add_transfer(endpoint, transfer); if (tail == NULL) { @@ -146,7 +143,7 @@ void usb_transfer_schedule( for (; tail->next != NULL; tail = tail->next); usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); } - //enable_interrupts(); + cc_enable_interrupts(); } void usb_transfer_schedule_ack( From d30d7309d9c09f6862239322d970033e3c07a352 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 6 Jul 2013 19:17:57 -0400 Subject: [PATCH 038/200] usb_queue: Mark queues as volatile --- firmware/hackrf_usb/usb_queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index cb90959a..8253e0b6 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -42,12 +42,12 @@ usb_transfer_t transfer_pool[8]; const unsigned int transfer_pool_size = sizeof(transfer_pool) / sizeof(usb_transfer_t); // Available transfer list -usb_transfer_t* free_transfers; +usb_transfer_t* volatile free_transfers; #define USB_ENDPOINT_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) // Pending transfer heads -usb_transfer_t* endpoint_transfers[12] = {}; +usb_transfer_t* volatile endpoint_transfers[12] = {}; void usb_queue_init() { usb_transfer_t* t = &transfer_pool[0]; From a9f8103fec7c6a58472465b7147fe340517a489b Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 6 Jul 2013 19:21:12 -0400 Subject: [PATCH 039/200] hackrf_stop_rx: First set mode, then kill transfer thread Killing the transfer thread first means that the host stops polling the device for reads, causing the device to hang while scheduling the dTD --- host/libhackrf/src/hackrf.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 7e36dc55..f03f19aa 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1141,14 +1141,13 @@ int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn cal int ADDCALL hackrf_stop_rx(hackrf_device* device) { - int result1, result2; - result1 = kill_transfer_thread(device); - result2 = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF); - if (result2 != HACKRF_SUCCESS) + int result; + result = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF); + if (result != HACKRF_SUCCESS) { return result2; } - return result1; + return kill_transfer_thread(device); } int ADDCALL hackrf_start_tx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* tx_ctx) From df400eced6568a783456187356d3bfd9cfd48ec6 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 21:08:57 -0400 Subject: [PATCH 040/200] Bump libopencm3 --- firmware/libopencm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index 87690732..e0040d7c 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 87690732661dd049657967d3951cb8f4674ede00 +Subproject commit e0040d7c82d174c3ef1c4d3e860aa2ab765a9ab7 From cce17c42fd16ed7cf74c9653ddaf06cd7fafd61c Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 21:24:13 -0400 Subject: [PATCH 041/200] libopencm3: Update --- firmware/hackrf_usb/usb_queue.c | 8 ++++---- firmware/libopencm3 | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 8253e0b6..0341150a 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -93,13 +93,13 @@ static void endpoint_add_transfer( void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint) { uint_fast8_t index = USB_ENDPOINT_INDEX(endpoint->address); - cc_disable_interrupts(); + cm_disable_interrupts(); while (endpoint_transfers[index]) { usb_transfer_t * transfer = endpoint_transfers[index]; endpoint_transfers[index] = transfer->next; free_transfer(transfer); } - cc_enable_interrupts(); + cm_enable_interrupts(); } void usb_transfer_schedule( @@ -132,7 +132,7 @@ void usb_transfer_schedule( transfer->completion_cb = completion_cb; transfer->endpoint = (usb_endpoint_t*) endpoint; - cc_disable_interrupts(); + cm_disable_interrupts(); usb_transfer_t* tail = endpoint_transfers[index]; endpoint_add_transfer(endpoint, transfer); if (tail == NULL) { @@ -143,7 +143,7 @@ void usb_transfer_schedule( for (; tail->next != NULL; tail = tail->next); usb_endpoint_schedule_append(endpoint, &tail->td, &transfer->td); } - cc_enable_interrupts(); + cm_enable_interrupts(); } void usb_transfer_schedule_ack( diff --git a/firmware/libopencm3 b/firmware/libopencm3 index e0040d7c..0aabbbe3 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit e0040d7c82d174c3ef1c4d3e860aa2ab765a9ab7 +Subproject commit 0aabbbe366565d25f7cd817b57b2f2eab7f1911c From e23cc9bd6c5434f36dd7a3de7437c7316e97f265 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 21:25:31 -0400 Subject: [PATCH 042/200] usb_queue: Disable interrupts when allocating transfer --- firmware/hackrf_usb/usb_queue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 0341150a..ea6c2980 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -62,8 +62,10 @@ void usb_queue_init() { static usb_transfer_t* allocate_transfer() { while (free_transfers == NULL); + cm_disable_interrupts(); usb_transfer_t* const transfer = free_transfers; free_transfers = transfer->next; + cm_enable_interrupts(); return transfer; } From f50253eaa38ae33bf4dbda5050a22f48660a58f8 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 21:54:25 -0400 Subject: [PATCH 043/200] usb_queue: Use ldrex/strex to avoid disabling interrupts --- firmware/hackrf_usb/usb_queue.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index ea6c2980..683b3b96 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -26,6 +26,7 @@ #include #include +#include #include "usb.h" #include "usb_queue.h" @@ -61,19 +62,25 @@ void usb_queue_init() { /* Allocate a transfer */ static usb_transfer_t* allocate_transfer() { + bool aborted; + usb_transfer_t* transfer; while (free_transfers == NULL); - cm_disable_interrupts(); - usb_transfer_t* const transfer = free_transfers; - free_transfers = transfer->next; - cm_enable_interrupts(); + do { + transfer = (void *) __ldrex((uint32_t *) &free_transfers); + aborted = __strex((uint32_t) transfer->next, (uint32_t *) &free_transfers); + } while (aborted); + transfer->next = NULL; return transfer; } /* Place a transfer in the free list */ static void free_transfer(usb_transfer_t* const transfer) { - transfer->next = free_transfers; - free_transfers = transfer; + bool aborted; + do { + transfer->next = (void *) __ldrex((uint32_t *) &free_transfers); + aborted = __strex((uint32_t) transfer, (uint32_t *) &free_transfers); + } while (aborted); } /* Add a transfer to the end of an endpoint's queue */ From bb69f655b11187b8cf61ac51ca37045c1b0017df Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 21:58:06 -0400 Subject: [PATCH 044/200] usb_queue: Use while instead of for --- firmware/hackrf_usb/usb_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c index 683b3b96..afb6c7e8 100644 --- a/firmware/hackrf_usb/usb_queue.c +++ b/firmware/hackrf_usb/usb_queue.c @@ -92,7 +92,7 @@ static void endpoint_add_transfer( transfer->next = NULL; if (endpoint_transfers[index] != NULL) { usb_transfer_t* t = endpoint_transfers[index]; - for (; t->next != NULL; t = t->next); + while (t->next != NULL) t = t->next; t->next = transfer; } else { endpoint_transfers[index] = transfer; From b738cd52940090b58c642cf85223cb212185bcca Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 23:21:11 -0400 Subject: [PATCH 045/200] fix1 --- firmware/hackrf_usb/usb_standard_request.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index 43c23ada..9263a5bb 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -102,8 +102,8 @@ bool usb_set_configuration( device->configuration = new_configuration; } - if (usb_configuration_changed_cb) - usb_configuration_changed_cb(device); + if (usb_configuration_changed_cb) + usb_configuration_changed_cb(device); return true; } From f6b41dbda50cbe58f953a6213d9806600ac5f799 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 23:21:18 -0400 Subject: [PATCH 046/200] fix2 --- firmware/hackrf_usb/usb_standard_request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index 9263a5bb..98e50142 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -121,7 +121,7 @@ static usb_request_status_t usb_send_descriptor( endpoint->in, descriptor_data, (setup_length > descriptor_length) ? descriptor_length : setup_length, - NULL + NULL ); usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; From 0e14a3840314a6f58739b0e4a32ea7c9ade58bd0 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 7 Jul 2013 23:22:34 -0400 Subject: [PATCH 047/200] fix3 --- host/libhackrf/src/hackrf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index f03f19aa..3fd8051c 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1141,7 +1141,7 @@ int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn cal int ADDCALL hackrf_stop_rx(hackrf_device* device) { - int result; + int result; result = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF); if (result != HACKRF_SUCCESS) { From 3642fe9bc62033bfa5123c141854bcfe94d0f1e9 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 9 Jul 2013 20:57:37 -0400 Subject: [PATCH 048/200] usb_queue: Kill dead declaration --- firmware/hackrf_usb/usb_queue.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h index 90d59567..8c776d3e 100644 --- a/firmware/hackrf_usb/usb_queue.h +++ b/firmware/hackrf_usb/usb_queue.h @@ -33,12 +33,6 @@ typedef void (*transfer_completion_cb)(usb_transfer_t*, unsigned int); void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint); -void usb_endpoint_schedule( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length -); - void usb_transfer_schedule( const usb_endpoint_t* const endpoint, void* const data, From 24ed48d93a71b0a7d6a27f3492efa80429dc1278 Mon Sep 17 00:00:00 2001 From: TitanMKD Date: Wed, 28 Aug 2013 22:01:57 +0200 Subject: [PATCH 049/200] Fix for "issues/62 fix PLL1 overclock bug" see hackrf_core.c -> cpu_clock_init() Fix for "issues/78 startup current too high" see hackrf_core.c -> New functions cpu_clock_pll1_low_speed()/cpu_clock_pll1_max_speed() & hackrf_usb.c to switch low_speed/max_speed. --- firmware/common/hackrf_core.c | 160 +++++++++++++++++++++++++++---- firmware/common/hackrf_core.h | 2 + firmware/hackrf_usb/hackrf_usb.c | 11 ++- 3 files changed, 151 insertions(+), 22 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index ef8d118d..e6d2aa24 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -31,6 +31,8 @@ #include #include +#define WAIT_CPU_CLOCK_INIT_DELAY (10000) + void delay(uint32_t duration) { uint32_t i; @@ -232,9 +234,13 @@ bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) { return max2837_set_lpf_bandwidth(bandwidth_hz); } -/* clock startup for Jellybean with Lemondrop attached */ +/* clock startup for Jellybean with Lemondrop attached +Configure PLL1 to max speed (204MHz). +Note: PLL1 clock is used by M4/M0 core, Peripheral, APB1. */ void cpu_clock_init(void) { + uint32_t pll_reg; + /* use IRC as clock source for APB1 (including I2C0) */ CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_IRC); @@ -328,36 +334,59 @@ void cpu_clock_init(void) /* power on the oscillator and wait until stable */ CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_ENABLE; + /* Wait about 100us after Crystal Power ON */ + delay(WAIT_CPU_CLOCK_INIT_DELAY); + /* use XTAL_OSC as clock source for BASE_M4_CLK (CPU) */ - CGU_BASE_M4_CLK = CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_XTAL); + CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_XTAL) | CGU_BASE_M4_CLK_AUTOBLOCK); /* use XTAL_OSC as clock source for APB1 */ CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL); - /* use XTAL_OSC as clock source for PLL1 */ - /* Start PLL1 at 12MHz * 17 / (2+2) = 51MHz. */ - CGU_PLL1_CTRL = CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) - | CGU_PLL1_CTRL_PSEL(1) - | CGU_PLL1_CTRL_NSEL(0) - | CGU_PLL1_CTRL_MSEL(16) - | CGU_PLL1_CTRL_PD; - - /* power on PLL1 and wait until stable */ - CGU_PLL1_CTRL &= ~CGU_PLL1_CTRL_PD; + /* Configure PLL1 to Intermediate Clock (between 90 MHz and 110 MHz) */ + /* Integer mode: + FCLKOUT = M*(FCLKIN/N) + FCCO = 2*P*FCLKOUT = 2*P*M*(FCLKIN/N) + */ + pll_reg = CGU_PLL1_CTRL; + /* Clear PLL1 bits */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ + /* Set PLL1 up to 12MHz * 8 = 96MHz. */ + pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) + | CGU_PLL1_CTRL_PSEL(0) + | CGU_PLL1_CTRL_NSEL(0) + | CGU_PLL1_CTRL_MSEL(7) + | CGU_PLL1_CTRL_FBSEL; + CGU_PLL1_CTRL = pll_reg; + /* wait until stable */ while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); /* use PLL1 as clock source for BASE_M4_CLK (CPU) */ - CGU_BASE_M4_CLK = CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1); + CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1) | CGU_BASE_M4_CLK_AUTOBLOCK); - /* Move PLL1 up to 12MHz * 17 = 204MHz. */ - CGU_PLL1_CTRL = CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) - | CGU_PLL1_CTRL_PSEL(0) - | CGU_PLL1_CTRL_NSEL(0) + /* Wait before to switch to max speed */ + delay(WAIT_CPU_CLOCK_INIT_DELAY); + + /* Configure PLL1 Max Speed */ + /* Direct mode: FCLKOUT = FCCO = M*(FCLKIN/N) */ + pll_reg = CGU_PLL1_CTRL; + /* Clear PLL1 bits */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ + /* Set PLL1 up to 12MHz * 17 = 204MHz. */ + pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) + | CGU_PLL1_CTRL_PSEL(0) + | CGU_PLL1_CTRL_NSEL(0) | CGU_PLL1_CTRL_MSEL(16) - | CGU_PLL1_CTRL_FBSEL; - //| CGU_PLL1_CTRL_DIRECT; - + | CGU_PLL1_CTRL_FBSEL + | CGU_PLL1_CTRL_DIRECT; + CGU_PLL1_CTRL = pll_reg; /* wait until stable */ while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); @@ -393,6 +422,97 @@ void cpu_clock_init(void) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); } + +/* +Configure PLL1 to low speed (48MHz). +Note: PLL1 clock is used by M4/M0 core, Peripheral, APB1. +This function shall be called after cpu_clock_init(). +This function is mainly used to lower power consumption. +*/ +void cpu_clock_pll1_low_speed(void) +{ + uint32_t pll_reg; + + /* Configure PLL1 Clock (48MHz) */ + /* Integer mode: + FCLKOUT = M*(FCLKIN/N) + FCCO = 2*P*FCLKOUT = 2*P*M*(FCLKIN/N) + */ + pll_reg = CGU_PLL1_CTRL; + /* Clear PLL1 bits */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ + /* Set PLL1 up to 12MHz * 7 = 48MHz. */ + pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) + | CGU_PLL1_CTRL_PSEL(0) + | CGU_PLL1_CTRL_NSEL(0) + | CGU_PLL1_CTRL_MSEL(6) + | CGU_PLL1_CTRL_FBSEL + | CGU_PLL1_CTRL_DIRECT; + CGU_PLL1_CTRL = pll_reg; + /* wait until stable */ + while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + + /* Wait a delay after switch to new frequency with Direct mode */ + delay(WAIT_CPU_CLOCK_INIT_DELAY); +} + +/* +Configure PLL1 (Main MCU Clock) to max speed (204MHz). +Note: PLL1 clock is used by M4/M0 core, Peripheral, APB1. +This function shall be called after cpu_clock_init(). +*/ +void cpu_clock_pll1_max_speed(void) +{ + uint32_t pll_reg; + + /* Configure PLL1 to Intermediate Clock (between 90 MHz and 110 MHz) */ + /* Integer mode: + FCLKOUT = M*(FCLKIN/N) + FCCO = 2*P*FCLKOUT = 2*P*M*(FCLKIN/N) + */ + pll_reg = CGU_PLL1_CTRL; + /* Clear PLL1 bits */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ + /* Set PLL1 up to 12MHz * 8 = 96MHz. */ + pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) + | CGU_PLL1_CTRL_PSEL(0) + | CGU_PLL1_CTRL_NSEL(0) + | CGU_PLL1_CTRL_MSEL(7) + | CGU_PLL1_CTRL_FBSEL; + CGU_PLL1_CTRL = pll_reg; + /* wait until stable */ + while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + + /* Wait before to switch to max speed */ + delay(WAIT_CPU_CLOCK_INIT_DELAY); + + /* Configure PLL1 Max Speed */ + /* Direct mode: FCLKOUT = FCCO = M*(FCLKIN/N) */ + pll_reg = CGU_PLL1_CTRL; + /* Clear PLL1 bits */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ + /* Set PLL1 up to 12MHz * 17 = 204MHz. */ + pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) + | CGU_PLL1_CTRL_PSEL(0) + | CGU_PLL1_CTRL_NSEL(0) + | CGU_PLL1_CTRL_MSEL(16) + | CGU_PLL1_CTRL_FBSEL + | CGU_PLL1_CTRL_DIRECT; + CGU_PLL1_CTRL = pll_reg; + /* wait until stable */ + while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + +} + void ssp1_init(void) { /* diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 5752da00..cc772293 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -251,6 +251,8 @@ typedef enum { void delay(uint32_t duration); void cpu_clock_init(void); +void cpu_clock_pll1_low_speed(void); +void cpu_clock_pll1_max_speed(void); void ssp1_init(void); void ssp1_set_mode_max2837(void); void ssp1_set_mode_max5864(void); diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index e4cd3da3..986992dd 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -911,11 +911,17 @@ bool usb_set_configuration( if( new_configuration == 0 ) { return false; } - } + }else + { + /* Configuration number equal 0 means usb bus reset, + set MCU freq to low power consumption */ + cpu_clock_pll1_low_speed(); + } if( new_configuration != device->configuration ) { // Configuration changed. device->configuration = new_configuration; + cpu_clock_pll1_max_speed(); /* Switch MCU clock to max speed */ set_transceiver_mode(transceiver_mode); if( device->configuration ) { @@ -997,7 +1003,8 @@ int main(void) { pin_setup(); enable_1v8_power(); cpu_clock_init(); - + cpu_clock_pll1_low_speed(); + usb_peripheral_reset(); usb_device_init(0, &usb_device); From 237bf6ecdbbebddc09c6ed1b7ff39a65a357e4e4 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 4 Sep 2013 16:22:41 -0700 Subject: [PATCH 050/200] Pulled redundant PLL1 initialization code from cpu_clock_init(). Called cpu_clock_pll1_low_speed() instead. --- firmware/common/hackrf_core.c | 43 +---------------------------------- 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index e6d2aa24..ee786aea 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -344,52 +344,11 @@ void cpu_clock_init(void) CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL); - /* Configure PLL1 to Intermediate Clock (between 90 MHz and 110 MHz) */ - /* Integer mode: - FCLKOUT = M*(FCLKIN/N) - FCCO = 2*P*FCLKOUT = 2*P*M*(FCLKIN/N) - */ - pll_reg = CGU_PLL1_CTRL; - /* Clear PLL1 bits */ - pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ - CGU_PLL1_CTRL_BYPASS | /* BYPASS */ - CGU_PLL1_CTRL_DIRECT | /* DIRECT */ - CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ - /* Set PLL1 up to 12MHz * 8 = 96MHz. */ - pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) - | CGU_PLL1_CTRL_PSEL(0) - | CGU_PLL1_CTRL_NSEL(0) - | CGU_PLL1_CTRL_MSEL(7) - | CGU_PLL1_CTRL_FBSEL; - CGU_PLL1_CTRL = pll_reg; - /* wait until stable */ - while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + cpu_clock_pll1_low_speed(); /* use PLL1 as clock source for BASE_M4_CLK (CPU) */ CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1) | CGU_BASE_M4_CLK_AUTOBLOCK); - /* Wait before to switch to max speed */ - delay(WAIT_CPU_CLOCK_INIT_DELAY); - - /* Configure PLL1 Max Speed */ - /* Direct mode: FCLKOUT = FCCO = M*(FCLKIN/N) */ - pll_reg = CGU_PLL1_CTRL; - /* Clear PLL1 bits */ - pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ - CGU_PLL1_CTRL_BYPASS | /* BYPASS */ - CGU_PLL1_CTRL_DIRECT | /* DIRECT */ - CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ - /* Set PLL1 up to 12MHz * 17 = 204MHz. */ - pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) - | CGU_PLL1_CTRL_PSEL(0) - | CGU_PLL1_CTRL_NSEL(0) - | CGU_PLL1_CTRL_MSEL(16) - | CGU_PLL1_CTRL_FBSEL - | CGU_PLL1_CTRL_DIRECT; - CGU_PLL1_CTRL = pll_reg; - /* wait until stable */ - while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); - /* use XTAL_OSC as clock source for PLL0USB */ CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD | CGU_PLL0USB_CTRL_AUTOBLOCK From d76d72665e94206d3e3726683f5beeb56c85489f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 4 Sep 2013 16:23:32 -0700 Subject: [PATCH 051/200] Adjusted cpu_clock_pll1_low_speed() to operate at 48MHz, as per several comments with the code. The actual MSEL value was previously selecting 84MHz. --- firmware/common/hackrf_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index ee786aea..66529a34 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -403,11 +403,11 @@ void cpu_clock_pll1_low_speed(void) CGU_PLL1_CTRL_BYPASS | /* BYPASS */ CGU_PLL1_CTRL_DIRECT | /* DIRECT */ CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ - /* Set PLL1 up to 12MHz * 7 = 48MHz. */ + /* Set PLL1 up to 12MHz * 4 = 48MHz. */ pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) | CGU_PLL1_CTRL_PSEL(0) | CGU_PLL1_CTRL_NSEL(0) - | CGU_PLL1_CTRL_MSEL(6) + | CGU_PLL1_CTRL_MSEL(3) | CGU_PLL1_CTRL_FBSEL | CGU_PLL1_CTRL_DIRECT; CGU_PLL1_CTRL = pll_reg; From 1f5b979fd967dea9db747db1207584b66d8a2f9f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 4 Sep 2013 16:24:19 -0700 Subject: [PATCH 052/200] Added usb_set_configuration_changed_cb() call that bgamari fixed in his as-yet-unmerged USB branch. --- firmware/hackrf_usb/hackrf_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 8b711e42..83531a58 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -969,6 +969,7 @@ int main(void) { enable_1v8_power(); cpu_clock_init(); + usb_set_configuration_changed_cb(usb_configuration_changed); usb_peripheral_reset(); usb_device_init(0, &usb_device); From 6c0d8036479d32d6bcbcb2d45982d0b49580e5b9 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 4 Sep 2013 16:27:43 -0700 Subject: [PATCH 053/200] Cleaned up management of SGPIO and transceiver mode state vs. USB configuration state. This should help with power management. It may also be necessary when operating at low speed (48MHz), to keep the SGPIO interrupts from chewing up ALL available CPU cycles. --- firmware/hackrf_usb/hackrf_usb.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 83531a58..eff351a4 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -335,11 +335,13 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { sgpio_configure(transceiver_mode, true); - nvic_set_priority(NVIC_SGPIO_IRQ, 0); - nvic_enable_irq(NVIC_SGPIO_IRQ); - SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); + if( transceiver_mode != TRANSCEIVER_MODE_OFF ) { + nvic_set_priority(NVIC_SGPIO_IRQ, 0); + nvic_enable_irq(NVIC_SGPIO_IRQ); + SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); - sgpio_cpld_stream_enable(); + sgpio_cpld_stream_enable(); + } } usb_request_status_t usb_vendor_request_set_transceiver_mode( @@ -887,17 +889,17 @@ const usb_request_handlers_t usb_request_handlers = { void usb_configuration_changed( usb_device_t* const device ) { - set_transceiver_mode(transceiver_mode); - if( device->configuration->number ) { cpu_clock_pll1_max_speed(); + set_transceiver_mode(transceiver_mode); gpio_set(PORT_LED1_3, PIN_LED1); } else { /* Configuration number equal 0 means usb bus reset. */ + set_transceiver_mode(TRANSCEIVER_MODE_OFF); cpu_clock_pll1_low_speed(); gpio_clear(PORT_LED1_3, PIN_LED1); } -}; +} void sgpio_isr() { SGPIO_CLR_STATUS_1 = (1 << SGPIO_SLICE_A); From 266003f3af6877f4626abb3e827a399eaae39880 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 4 Sep 2013 16:34:20 -0700 Subject: [PATCH 054/200] Added two CGU debugging tools: - check_clock.py to decode the frequency monitor result. - dump_cgu.py to display selected CGU registers in a legible format. --- firmware/tools/check_clock.py | 73 +++++++++++++++++ firmware/tools/dump_cgu.py | 145 ++++++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100755 firmware/tools/check_clock.py create mode 100755 firmware/tools/dump_cgu.py diff --git a/firmware/tools/check_clock.py b/firmware/tools/check_clock.py new file mode 100755 index 00000000..c2c422b0 --- /dev/null +++ b/firmware/tools/check_clock.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +# Copyright 2013 Jared Boone +# +# Interpret the LPC43xx Clock Generation Unit (CGU) FREQ_MON register +# and display the estimated clock frequency. +# +# This file is part of HackRF. +# +# 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, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +""" +Inside GDB: + (gdb) set {int}0x40050014 = 0x09800000 + (gdb) x 0x40050014 + 0x40050014: 0x091bd000 +This script: + ./check_clock.py 0x 0x +""" + +import sys + +clock_source_names = { + 0x00: '32 kHz oscillator', + 0x01: 'IRC', + 0x02: 'ENET_RX_CLK', + 0x03: 'ENET_TX_CLK', + 0x04: 'GP_CLKIN', + 0x06: 'Crystal oscillator', + 0x07: 'PLL0USB', + 0x08: 'PLL0AUDIO', + 0x09: 'PLL1', + 0x0c: 'IDIVA', + 0x0d: 'IDIVB', + 0x0e: 'IDIVC', + 0x0f: 'IDIVD', + 0x10: 'IDIVE', +} + +reg_value = int(sys.argv[1], 16) +rcnt = int(sys.argv[2], 16) + +print('0x%08x' % reg_value) + +rcnt_final = reg_value & 0x1ff +fcnt = (reg_value >> 9) & 0x3fff +clock_source = (reg_value >> 24) & 0x1f +fref = 12e6 + +if rcnt_final != 0: + raise RuntimeError('RCNT did not reach 0') + +print('RCNT: %d' % rcnt) +print('FCNT: %d' % fcnt) +print('Fref: %d' % fref) + +clock_hz = fcnt / float(rcnt) * fref +clock_mhz = clock_hz / 1e6 +clock_name = clock_source_names[clock_source] if clock_source in clock_source_names else 'Reserved' +print('%s: %.3f MHz' % (clock_name, clock_mhz)) diff --git a/firmware/tools/dump_cgu.py b/firmware/tools/dump_cgu.py new file mode 100755 index 00000000..b452e485 --- /dev/null +++ b/firmware/tools/dump_cgu.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python + +# Copyright 2013 Jared Boone +# +# Display the LPC43xx Clock Generation Unit (CGU) registers in an +# easy-to-read format. +# +# This file is part of HackRF. +# +# 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, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +""" +In GDB: + dump binary memory cgu.bin 0x40050014 0x400500cc +""" + +import sys +from struct import unpack + +address = 0x40050014 + +f = open('cgu.bin', 'read') +d = '\x00' * 20 + f.read() +length = len(d) +f.close() + +def print_data(d): + for i in range(0, length, 16): + values = unpack('> low_bit) & ((1 << count) - 1) + field_bits = bin(field_value)[2:].zfill(count) + ' ' * low_bit + field_bits = field_bits.rjust(32) + print('%03s %20s %s = %8x %s' % ('', '', field_bits, field_value, name)) From 5143456d6daf41345d60182f6c3bb4aba4576e79 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 15:25:34 -0700 Subject: [PATCH 055/200] Update libopencm3 submodule commit. --- firmware/libopencm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index d7fdcefb..f92dbcdf 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit d7fdcefbd7565e59aaaf2dea99bee8e0157ff1d7 +Subproject commit f92dbcdf6028687f705c71134f51d5b4061daf7a From 5cad831075786e424549ebb35458afaa82d80b2d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 15:37:24 -0700 Subject: [PATCH 056/200] Fixed cut-and-paste oops in variable name. --- host/libhackrf/src/hackrf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 3fd8051c..47ff055a 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1145,7 +1145,7 @@ int ADDCALL hackrf_stop_rx(hackrf_device* device) result = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF); if (result != HACKRF_SUCCESS) { - return result2; + return result; } return kill_transfer_thread(device); } From 1ac3d59875b04a107a1bf8836758c5ae643730e3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 16:02:01 -0700 Subject: [PATCH 057/200] Update libopencm3 submodule commit. --- firmware/libopencm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index d7fdcefb..f92dbcdf 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit d7fdcefbd7565e59aaaf2dea99bee8e0157ff1d7 +Subproject commit f92dbcdf6028687f705c71134f51d5b4061daf7a From 7c5db57f02d0e4f1d9441617855585287a83da07 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 16:28:19 -0700 Subject: [PATCH 058/200] Hide the MAX2837 intermediate frequency behind a function. It also prevents leakage of the freq_*_cache variables. --- firmware/hackrf_usb/hackrf_usb.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index eff351a4..48955d35 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -96,8 +96,8 @@ void update_switches(void) #define MIN_HP_FREQ_MHZ (2700) #define MAX_HP_FREQ_MHZ (6800) -static uint32_t MAX2837_FREQ_NOMINAL_HZ=2600000000; -#define MAX2837_FREQ_NOMINAL_MHZ (MAX2837_FREQ_NOMINAL_HZ / FREQ_ONE_MHZ) +static uint32_t max2837_freq_nominal_hz=2600000000; +#define MAX2837_FREQ_NOMINAL_MHZ (max2837_freq_nominal_hz / FREQ_ONE_MHZ) uint32_t freq_mhz_cache=100, freq_hz_cache=0; /* @@ -132,7 +132,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) { tmp_hz = (real_RFFC5071_freq_hz - RFFC5071_freq_mhz * FREQ_ONE_MHZ); } - MAX2837_freq_hz = MAX2837_FREQ_NOMINAL_HZ + tmp_hz + freq_hz; + MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; max2837_set_frequency(MAX2837_freq_hz); update_switches(); }else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) @@ -158,7 +158,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) { tmp_hz = -(real_RFFC5071_freq_hz - RFFC5071_freq_mhz * FREQ_ONE_MHZ); } - MAX2837_freq_hz = MAX2837_FREQ_NOMINAL_HZ + tmp_hz + freq_hz; + MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; max2837_set_frequency(MAX2837_freq_hz); update_switches(); }else @@ -181,6 +181,15 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) return success; } +bool set_freq_if(const uint32_t freq_if_hz) { + bool success = false; + if( (freq_if_hz >= MIN_BYPASS_FREQ_MHZ) && (freq_if_hz <= MAX_BYPASS_FREQ_MHZ) ) { + max2837_freq_nominal_hz = freq_if_hz; + success = set_freq(freq_mhz_cache, freq_hz_cache); + } + return success; +} + static void usb_init_buffers_bulk() { usb_td_bulk[0].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; usb_td_bulk[0].total_bytes @@ -827,9 +836,11 @@ usb_request_status_t usb_vendor_request_set_if_freq( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage ) { if( stage == USB_TRANSFER_STAGE_SETUP ) { - MAX2837_FREQ_NOMINAL_HZ = (uint32_t)endpoint->setup.index * 1000 * 1000; - set_freq(freq_mhz_cache, freq_hz_cache); - usb_endpoint_schedule_ack(endpoint->in); + if( set_freq_if((uint32_t)endpoint->setup.index * 1000 * 1000) ) { + usb_endpoint_schedule_ack(endpoint->in); + } else { + return USB_REQUEST_STATUS_STALL; + } } return USB_REQUEST_STATUS_OK; } From a5c0b5deeb60a6844e4db5672366d296ae01546d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 21:29:31 -0700 Subject: [PATCH 059/200] Add MAX2837 functions to control operating mode. Replace direct manipulation of GPIOs controlling MAX2837 with operating mode functions. --- firmware/common/max2837.c | 53 ++++++++++++++++++++++++++------ firmware/common/max2837.h | 5 +++ firmware/hackrf_usb/hackrf_usb.c | 7 ++--- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/firmware/common/max2837.c b/firmware/common/max2837.c index c3d6d5cf..5473c6a6 100644 --- a/firmware/common/max2837.c +++ b/firmware/common/max2837.c @@ -220,14 +220,53 @@ void max2837_regs_commit(void) } } +void max2837_mode_shutdown(void) { + /* All circuit blocks are powered down, except the 4-wire serial bus + * and its internal programmable registers. + */ + gpio_clear(PORT_XCVR_ENABLE, + (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); +} + +void max2837_mode_standby(void) { + /* Used to enable the frequency synthesizer block while the rest of the + * device is powered down. In this mode, PLL, VCO, and LO generator + * are on, so that Tx or Rx modes can be quickly enabled from this mode. + * These and other blocks can be selectively enabled in this mode. + */ + gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); + gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE); +} + +void max2837_mode_tx(void) { + /* All Tx circuit blocks are powered on. The external PA is powered on + * after a programmable delay using the on-chip PA bias DAC. The slow- + * charging Rx circuits are in a precharged “idle-off” state for fast + * Tx-to-Rx turnaround time. + */ + gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE); + gpio_set(PORT_XCVR_ENABLE, + (PIN_XCVR_ENABLE | PIN_XCVR_TXENABLE)); +} + +void max2837_mode_rx(void) { + /* All Rx circuit blocks are powered on and active. Antenna signal is + * applied; RF is downconverted, filtered, and buffered at Rx BB I and Q + * outputs. The slow- charging Tx circuits are in a precharged “idle-off” + * state for fast Rx-to-Tx turnaround time. + */ + gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE); + gpio_set(PORT_XCVR_ENABLE, + (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE)); +} + void max2837_start(void) { LOG("# max2837_start\n"); set_MAX2837_EN_SPI(1); max2837_regs_commit(); #if !defined TEST - gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); - gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE); + max2837_mode_standby(); #endif } @@ -238,9 +277,7 @@ void max2837_tx(void) set_MAX2837_ModeCtrl(MAX2837_ModeCtrl_TxLPF); max2837_regs_commit(); - - gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE); - gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE); + max2837_mode_tx(); #endif } @@ -252,8 +289,7 @@ void max2837_rx(void) max2837_regs_commit(); #if !defined TEST - gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE); - gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE); + max2837_mode_rx(); #endif } @@ -263,8 +299,7 @@ void max2837_stop(void) set_MAX2837_EN_SPI(0); max2837_regs_commit(); #if !defined TEST - gpio_clear(PORT_XCVR_ENABLE, - (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); + max2837_mode_shutdown(); #endif } diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index 4c7d4f1e..0a09a497 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -37,6 +37,11 @@ extern void max2837_regs_read(void); * provided routines for those operations. */ extern void max2837_regs_commit(void); +void max2837_mode_shutdown(void); +void max2837_mode_standby(void); +void max2837_mode_tx(void); +void max2837_mode_rx(void); + /* Turn on/off all chip functions. Does not control oscillator and CLKOUT */ extern void max2837_start(void); extern void max2837_stop(void); diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 48955d35..858d1093 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -115,7 +115,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) success = true; - gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); + max2837_mode_standby(); if(freq_mhz >= MIN_LP_FREQ_MHZ) { if(freq_mhz < MAX_LP_FREQ_MHZ) @@ -172,10 +172,9 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) success = false; } if(transceiver_mode == TRANSCEIVER_MODE_RX) - gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE); + max2837_mode_rx(); else if(transceiver_mode == TRANSCEIVER_MODE_TX) - gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE); - + max2837_mode_tx(); freq_mhz_cache = freq_mhz; freq_hz_cache = freq_hz; return success; From a367f84d151dfac212d3cffe2ecba949363884f6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 22:29:57 -0700 Subject: [PATCH 060/200] Add MAX2837 mode set/get functions. --- firmware/common/max2837.c | 37 +++++++++++++++++++++++++++++++++++++ firmware/common/max2837.h | 10 ++++++++++ 2 files changed, 47 insertions(+) diff --git a/firmware/common/max2837.c b/firmware/common/max2837.c index 5473c6a6..da0d51d9 100644 --- a/firmware/common/max2837.c +++ b/firmware/common/max2837.c @@ -260,6 +260,43 @@ void max2837_mode_rx(void) { (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE)); } +max2837_mode_t max2837_mode(void) { + if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE) ) { + if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE) ) { + return MAX2837_MODE_TX; + } else if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE) ) { + return MAX2837_MODE_RX; + } else { + return MAX2837_MODE_STANDBY; + } + } else { + return MAX2837_MODE_SHUTDOWN; + } +} + +void max2837_set_mode(const max2837_mode_t new_mode) { + switch(new_mode) { + case MAX2837_MODE_SHUTDOWN: + max2837_mode_shutdown(); + break; + + case MAX2837_MODE_STANDBY: + max2837_mode_standby(); + break; + + case MAX2837_MODE_TX: + max2837_mode_tx(); + break; + + case MAX2837_MODE_RX: + max2837_mode_rx(); + break; + + default: + break; + } +} + void max2837_start(void) { LOG("# max2837_start\n"); diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index 0a09a497..582a0966 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -37,11 +37,21 @@ extern void max2837_regs_read(void); * provided routines for those operations. */ extern void max2837_regs_commit(void); +typedef enum { + MAX2837_MODE_SHUTDOWN, + MAX2837_MODE_STANDBY, + MAX2837_MODE_TX, + MAX2837_MODE_RX +} max2837_mode_t; + void max2837_mode_shutdown(void); void max2837_mode_standby(void); void max2837_mode_tx(void); void max2837_mode_rx(void); +max2837_mode_t max2837_mode(void); +void max2837_set_mode(const max2837_mode_t new_mode); + /* Turn on/off all chip functions. Does not control oscillator and CLKOUT */ extern void max2837_start(void); extern void max2837_stop(void); From b89f43e97effd2af1806cf37acdb3b6c348e58c6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 22:50:04 -0700 Subject: [PATCH 061/200] Replace transceiver_mode dependent MAX2837 mode management with max2837_mode() -> max2837_set_mode() calls. --- firmware/hackrf_usb/hackrf_usb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 858d1093..4940414d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -115,6 +115,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) success = true; + const max2837_mode_t prior_max2837_mode = max2837_mode(); max2837_mode_standby(); if(freq_mhz >= MIN_LP_FREQ_MHZ) { @@ -171,10 +172,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) /* Error freq_mhz too low */ success = false; } - if(transceiver_mode == TRANSCEIVER_MODE_RX) - max2837_mode_rx(); - else if(transceiver_mode == TRANSCEIVER_MODE_TX) - max2837_mode_tx(); + max2837_set_mode(prior_max2837_mode); freq_mhz_cache = freq_mhz; freq_hz_cache = freq_hz; return success; From 518c46a1113edc4064e57992af0e6639526db713 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 6 Sep 2013 23:01:40 -0700 Subject: [PATCH 062/200] Oops, missed a spot where I should've called a MAX2837 mode function. --- firmware/common/max2837.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/firmware/common/max2837.c b/firmware/common/max2837.c index da0d51d9..55c93050 100644 --- a/firmware/common/max2837.c +++ b/firmware/common/max2837.c @@ -116,9 +116,7 @@ void max2837_setup(void) ; #endif - /* disable everything */ - gpio_clear(PORT_XCVR_ENABLE, - (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); + max2837_mode_shutdown(); #ifdef JELLYBEAN gpio_set(PORT_XCVR_RXHP, PIN_XCVR_RXHP); gpio_set(PORT_XCVR_B, From 6dee455ef2de99d8cd8d9abe82dc9e36b0589780 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 12:40:09 -0700 Subject: [PATCH 063/200] Contain calls to rffc5071_(rx|tr) to a single location. --- firmware/hackrf_usb/hackrf_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 4940414d..ede7866d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -319,7 +319,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_set(PORT_LED1_3, PIN_LED2); usb_endpoint_init(&usb_endpoint_bulk_in); - rffc5071_rx(switchctrl); + update_switches(); //rffc5071_set_frequency(1700, 0); // 2600 MHz IF - 1700 MHz LO = 900 MHz RF max2837_start(); max2837_rx(); @@ -328,7 +328,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_set(PORT_LED1_3, PIN_LED3); usb_endpoint_init(&usb_endpoint_bulk_out); - rffc5071_tx(switchctrl); + update_switches(); //rffc5071_set_frequency(1700, 0); // 2600 MHz IF - 1700 MHz LO = 900 MHz RF max2837_start(); max2837_tx(); From bafe97e302094a87fc84456f039c30794b180553 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 12:59:57 -0700 Subject: [PATCH 064/200] Extract knowledge of RF path configurations from the RFFC5071 driver. Change initial RF path mode to SWITCHCTRL_SAFE. (Previously started at SWITCHCTRL_SAFE and then immediately switched to SWITCHCTRL_AMP_BYPASS.) --- firmware/common/rffc5071.c | 45 ++--------------------- firmware/common/rffc5071.h | 23 ++---------- firmware/hackrf_usb/hackrf_usb.c | 61 +++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 69 deletions(-) diff --git a/firmware/common/rffc5071.c b/firmware/common/rffc5071.c index ad77eccc..67bbd023 100644 --- a/firmware/common/rffc5071.c +++ b/firmware/common/rffc5071.c @@ -145,11 +145,6 @@ void rffc5071_setup(void) * not control pins. */ set_RFFC5071_SIPIN(1); -#ifdef JAWBREAKER - /* initial safe switch control settings */ - rffc5071_set_gpo(SWITCHCTRL_SAFE); -#endif - /* GPOs are active at all times */ set_RFFC5071_GATE(1); @@ -367,56 +362,20 @@ void rffc5071_regs_commit(void) } } -void rffc5071_tx(uint8_t gpo) { +void rffc5071_tx(void) { LOG("# rffc5071_tx\n"); set_RFFC5071_ENBL(0); set_RFFC5071_FULLD(0); set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */ -#ifdef JAWBREAKER - /* honor SWITCHCTRL_AMP_BYPASS and SWITCHCTRL_HP settings from caller */ - gpo &= (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - if ((gpo & SWITCHCTRL_AMP_BYPASS) == SWITCHCTRL_AMP_BYPASS) - gpo |= SWITCHCTRL_NO_TX_AMP_PWR; - gpo |= (SWITCHCTRL_TX | SWITCHCTRL_NO_RX_AMP_PWR); - rffc5071_set_gpo(gpo); -#else - (void)gpo; -#endif rffc5071_regs_commit(); - -#ifdef JAWBREAKER - /* honor SWITCHCTRL_MIX_BYPASS setting from caller */ - if ((gpo & SWITCHCTRL_MIX_BYPASS) == SWITCHCTRL_MIX_BYPASS) - rffc5071_disable(); - else -#endif - rffc5071_enable(); } -void rffc5071_rx(uint8_t gpo) { +void rffc5071_rx(void) { LOG("# rfc5071_rx\n"); set_RFFC5071_ENBL(0); set_RFFC5071_FULLD(0); set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */ -#ifdef JAWBREAKER - /* honor SWITCHCTRL_AMP_BYPASS and SWITCHCTRL_HP settings from caller */ - gpo &= (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - if ((gpo & SWITCHCTRL_AMP_BYPASS) == SWITCHCTRL_AMP_BYPASS) - gpo |= SWITCHCTRL_NO_RX_AMP_PWR; - gpo |= SWITCHCTRL_NO_TX_AMP_PWR; - rffc5071_set_gpo(gpo); -#else - (void)gpo; -#endif rffc5071_regs_commit(); - -#ifdef JAWBREAKER - /* honor SWITCHCTRL_MIX_BYPASS setting from caller */ - if ((gpo & SWITCHCTRL_MIX_BYPASS) == SWITCHCTRL_MIX_BYPASS) - rffc5071_disable(); - else -#endif - rffc5071_enable(); } /* diff --git a/firmware/common/rffc5071.h b/firmware/common/rffc5071.h index 510cf510..cd403771 100644 --- a/firmware/common/rffc5071.h +++ b/firmware/common/rffc5071.h @@ -31,25 +31,6 @@ extern uint32_t rffc5071_regs_dirty; #define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL< Date: Sat, 7 Sep 2013 20:20:48 -0700 Subject: [PATCH 065/200] Clean up switchctrl code a bit -- redundant #ifdefs and complex if conditions. --- firmware/hackrf_usb/hackrf_usb.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 525ce912..82092887 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -102,15 +102,13 @@ void update_switches(void) #ifdef JAWBREAKER /* honor SWITCHCTRL_AMP_BYPASS and SWITCHCTRL_HP settings from caller */ switchctrl &= (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - if ((switchctrl & SWITCHCTRL_AMP_BYPASS) == SWITCHCTRL_AMP_BYPASS) + if (switchctrl & SWITCHCTRL_AMP_BYPASS) switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; rffc5071_set_gpo(switchctrl); -#endif -#ifdef JAWBREAKER /* honor SWITCHCTRL_MIX_BYPASS setting from caller */ - if ((switchctrl & SWITCHCTRL_MIX_BYPASS) == SWITCHCTRL_MIX_BYPASS) + if (switchctrl & SWITCHCTRL_MIX_BYPASS) rffc5071_disable(); else #endif @@ -120,15 +118,13 @@ void update_switches(void) #ifdef JAWBREAKER /* honor SWITCHCTRL_AMP_BYPASS and SWITCHCTRL_HP settings from caller */ switchctrl &= (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - if ((switchctrl & SWITCHCTRL_AMP_BYPASS) == SWITCHCTRL_AMP_BYPASS) + if (switchctrl & SWITCHCTRL_AMP_BYPASS) switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; switchctrl |= (SWITCHCTRL_TX | SWITCHCTRL_NO_RX_AMP_PWR); rffc5071_set_gpo(switchctrl); -#endif -#ifdef JAWBREAKER /* honor SWITCHCTRL_MIX_BYPASS setting from caller */ - if ((switchctrl & SWITCHCTRL_MIX_BYPASS) == SWITCHCTRL_MIX_BYPASS) + if (switchctrl & SWITCHCTRL_MIX_BYPASS) rffc5071_disable(); else #endif From e7c6408473260167f23bb70c89eb7dbef885f2a6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 20:21:43 -0700 Subject: [PATCH 066/200] Add comment describing SWITCHCTRL pins vs. RF path configurations. --- firmware/hackrf_usb/hackrf_usb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 82092887..43cfee92 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -86,6 +86,23 @@ set_sample_r_params_t set_sample_r_params; #define SWITCHCTRL_HP (1 << 4) /* GPO5 1 for high-pass, 0 for low-pass */ #define SWITCHCTRL_NO_RX_AMP_PWR (1 << 5) /* GPO6 turn off RX amp power */ +/* + GPO6 GPO5 GPO4 GPO3 GPO2 GPO1 +!RXAMP HP MIXBP TX AMPBP !TXAMP Mix mode Amp mode + 1 X 1 1 1 1 TX bypass Bypass + 1 X 1 1 0 0 TX bypass TX amplified + 1 1 0 1 1 1 TX high Bypass + 1 1 0 1 0 0 TX high TX amplified + 1 0 0 1 1 1 TX low Bypass + 1 0 0 1 0 0 TX low TX amplified + 1 X 1 0 1 1 RX bypass Bypass + 0 X 1 0 0 1 RX bypass RX amplified + 1 1 0 0 1 1 RX high Bypass + 0 1 0 0 0 1 RX high RX amplified + 1 0 0 0 1 1 RX low Bypass + 0 0 0 0 0 1 RX low RX amplified +*/ + /* * Safe (initial) switch settings turn off both amplifiers and enable both amp * bypass and mixer bypass. From 4ad36804282a830409f5c568697b711cfc472c9f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 20:58:08 -0700 Subject: [PATCH 067/200] Break SGPIO interrupt handlers in two -- RX and TX. Assign an SGPIO interrupt handler function at runtime, based on RX or TX mode. NOTE: This is incompatible with placing the vector table in ROM, which is fine on a device with no internal flash). Remove SGPIO interrupt-time dependency on volatile transceiver_mode variable. Side effect is that a few cycles are probably saved inside the SGPIO interrupt. --- firmware/hackrf_usb/hackrf_usb.c | 130 +++++++++++++++++-------------- 1 file changed, 72 insertions(+), 58 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 43cfee92..d5985455 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -22,6 +22,8 @@ #include +#include + #include #include #include @@ -43,7 +45,10 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" -static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; +static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; + +void sgpio_isr_rx(); +void sgpio_isr_tx(); uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; static volatile uint32_t usb_bulk_buffer_offset = 0; @@ -406,6 +411,12 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { sgpio_configure(transceiver_mode, true); if( transceiver_mode != TRANSCEIVER_MODE_OFF ) { + vector_table_entry_t sgpio_isr_fn = sgpio_isr_rx; + if( transceiver_mode == TRANSCEIVER_MODE_TX ) { + sgpio_isr_fn = sgpio_isr_tx; + } + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_fn; + nvic_set_priority(NVIC_SGPIO_IRQ, 0); nvic_enable_irq(NVIC_SGPIO_IRQ); SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); @@ -973,66 +984,69 @@ void usb_configuration_changed( } } -void sgpio_isr() { +void sgpio_isr_rx() { SGPIO_CLR_STATUS_1 = (1 << SGPIO_SLICE_A); uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; - if( transceiver_mode == TRANSCEIVER_MODE_RX ) { - __asm__( - "ldr r0, [%[SGPIO_REG_SS], #44]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #0]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #20]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #4]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #40]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #8]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #8]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #12]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #36]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #16]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #16]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #20]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #32]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #24]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #0]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #28]\n\t" - : - : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), - [p] "l" (p) - : "r0" - ); - } else { - __asm__( - "ldr r0, [%[p], #0]\n\t" - "str r0, [%[SGPIO_REG_SS], #44]\n\t" - "ldr r0, [%[p], #4]\n\t" - "str r0, [%[SGPIO_REG_SS], #20]\n\t" - "ldr r0, [%[p], #8]\n\t" - "str r0, [%[SGPIO_REG_SS], #40]\n\t" - "ldr r0, [%[p], #12]\n\t" - "str r0, [%[SGPIO_REG_SS], #8]\n\t" - "ldr r0, [%[p], #16]\n\t" - "str r0, [%[SGPIO_REG_SS], #36]\n\t" - "ldr r0, [%[p], #20]\n\t" - "str r0, [%[SGPIO_REG_SS], #16]\n\t" - "ldr r0, [%[p], #24]\n\t" - "str r0, [%[SGPIO_REG_SS], #32]\n\t" - "ldr r0, [%[p], #28]\n\t" - "str r0, [%[SGPIO_REG_SS], #0]\n\t" - : - : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), - [p] "l" (p) - : "r0" - ); - } - + __asm__( + "ldr r0, [%[SGPIO_REG_SS], #44]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #0]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #20]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #4]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #40]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #8]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #8]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #12]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #36]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #16]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #16]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #20]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #32]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #24]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #0]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #28]\n\t" + : + : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), + [p] "l" (p) + : "r0" + ); + usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; +} + +void sgpio_isr_tx() { + SGPIO_CLR_STATUS_1 = (1 << SGPIO_SLICE_A); + + uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; + __asm__( + "ldr r0, [%[p], #0]\n\t" + "str r0, [%[SGPIO_REG_SS], #44]\n\t" + "ldr r0, [%[p], #4]\n\t" + "str r0, [%[SGPIO_REG_SS], #20]\n\t" + "ldr r0, [%[p], #8]\n\t" + "str r0, [%[SGPIO_REG_SS], #40]\n\t" + "ldr r0, [%[p], #12]\n\t" + "str r0, [%[SGPIO_REG_SS], #8]\n\t" + "ldr r0, [%[p], #16]\n\t" + "str r0, [%[SGPIO_REG_SS], #36]\n\t" + "ldr r0, [%[p], #20]\n\t" + "str r0, [%[SGPIO_REG_SS], #16]\n\t" + "ldr r0, [%[p], #24]\n\t" + "str r0, [%[SGPIO_REG_SS], #32]\n\t" + "ldr r0, [%[p], #28]\n\t" + "str r0, [%[SGPIO_REG_SS], #0]\n\t" + : + : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), + [p] "l" (p) + : "r0" + ); usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; } From bf297e0e08665aa225a2b43cea5232c3465b9e85 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 22:01:46 -0700 Subject: [PATCH 068/200] I might've been a bit hasty removing volatile from transceiver_mode. --- firmware/hackrf_usb/hackrf_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index d5985455..980d849d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -45,7 +45,7 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" -static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; +static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; void sgpio_isr_rx(); void sgpio_isr_tx(); From 7cf40583722798b41ea95df281fc3093e2e8eb43 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 22:06:01 -0700 Subject: [PATCH 069/200] Move various switchctrl manipulation into clearly-defined rf_path_*() implementations. --- firmware/hackrf_usb/hackrf_usb.c | 127 +++++++++++++++++++------------ 1 file changed, 78 insertions(+), 49 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 980d849d..737bc013 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -117,41 +117,79 @@ set_sample_r_params_t set_sample_r_params; uint8_t switchctrl = SWITCHCTRL_SAFE; -void update_switches(void) -{ - if (transceiver_mode == TRANSCEIVER_MODE_RX) { - rffc5071_rx(); -#ifdef JAWBREAKER - /* honor SWITCHCTRL_AMP_BYPASS and SWITCHCTRL_HP settings from caller */ - switchctrl &= (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - if (switchctrl & SWITCHCTRL_AMP_BYPASS) - switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; - switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; - rffc5071_set_gpo(switchctrl); - - /* honor SWITCHCTRL_MIX_BYPASS setting from caller */ - if (switchctrl & SWITCHCTRL_MIX_BYPASS) - rffc5071_disable(); - else -#endif - rffc5071_enable(); - } else if (transceiver_mode == TRANSCEIVER_MODE_TX) { +typedef enum { + RF_PATH_DIRECTION_RX, + RF_PATH_DIRECTION_TX, +} rf_path_direction_t; + +void rf_path_set_direction(const rf_path_direction_t direction) { + /* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */ + switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; + if( direction == RF_PATH_DIRECTION_TX ) { + switchctrl |= SWITCHCTRL_TX; + if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { + /* TX amplifier is in path, be sure to enable TX amplifier. */ + switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; + } rffc5071_tx(); -#ifdef JAWBREAKER - /* honor SWITCHCTRL_AMP_BYPASS and SWITCHCTRL_HP settings from caller */ - switchctrl &= (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - if (switchctrl & SWITCHCTRL_AMP_BYPASS) - switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; - switchctrl |= (SWITCHCTRL_TX | SWITCHCTRL_NO_RX_AMP_PWR); - rffc5071_set_gpo(switchctrl); - - /* honor SWITCHCTRL_MIX_BYPASS setting from caller */ - if (switchctrl & SWITCHCTRL_MIX_BYPASS) - rffc5071_disable(); - else -#endif - rffc5071_enable(); + } else { + switchctrl &= ~SWITCHCTRL_TX; + if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { + /* RX amplifier is in path, be sure to enable RX amplifier. */ + switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; + } + rffc5071_rx(); } + + rffc5071_set_gpo(switchctrl); +} + +typedef enum { + RF_PATH_FILTER_BYPASS, + RF_PATH_FILTER_LOW_PASS, + RF_PATH_FILTER_HIGH_PASS, +} rf_path_filter_t; + +void rf_path_set_filter(const rf_path_filter_t filter) { + switch(filter) { + default: + case RF_PATH_FILTER_BYPASS: + switchctrl |= SWITCHCTRL_MIX_BYPASS; + rffc5071_disable(); + break; + + case RF_PATH_FILTER_LOW_PASS: + switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); + rffc5071_enable(); + break; + + case RF_PATH_FILTER_HIGH_PASS: + switchctrl &= ~SWITCHCTRL_MIX_BYPASS; + switchctrl |= SWITCHCTRL_HP; + rffc5071_enable(); + break; + } + + rffc5071_set_gpo(switchctrl); +} + +void rf_path_set_lna(const uint_fast8_t enable) { + if( enable ) { + if( switchctrl & SWITCHCTRL_TX ) { + /* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */ + switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; + switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR); + } else { + /* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */ + switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; + switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR); + } + } else { + /* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */ + switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; + } + + rffc5071_set_gpo(switchctrl); } #define FREQ_ONE_MHZ (1000*1000) @@ -190,8 +228,6 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) { if(freq_mhz < MAX_LP_FREQ_MHZ) { - switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - RFFC5071_freq_mhz = MAX2837_FREQ_NOMINAL_MHZ - freq_mhz; /* Set Freq and read real freq */ real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); @@ -204,20 +240,15 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) } MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; max2837_set_frequency(MAX2837_freq_hz); - update_switches(); + rf_path_set_filter(RF_PATH_FILTER_LOW_PASS); }else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) { - switchctrl |= SWITCHCTRL_MIX_BYPASS; - MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz; /* RFFC5071_freq_mhz <= not used in Bypass mode */ max2837_set_frequency(MAX2837_freq_hz); - update_switches(); + rf_path_set_filter(RF_PATH_FILTER_BYPASS); }else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz < MAX_HP_FREQ_MHZ) ) { - switchctrl &= ~SWITCHCTRL_MIX_BYPASS; - switchctrl |= SWITCHCTRL_HP; - RFFC5071_freq_mhz = freq_mhz - MAX2837_FREQ_NOMINAL_MHZ; /* Set Freq and read real freq */ real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); @@ -230,7 +261,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) } MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; max2837_set_frequency(MAX2837_freq_hz); - update_switches(); + rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS); }else { /* Error freq_mhz too high */ @@ -388,7 +419,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_set(PORT_LED1_3, PIN_LED2); usb_endpoint_init(&usb_endpoint_bulk_in); - update_switches(); + rf_path_set_direction(RF_PATH_DIRECTION_RX); //rffc5071_set_frequency(1700, 0); // 2600 MHz IF - 1700 MHz LO = 900 MHz RF max2837_start(); max2837_rx(); @@ -397,7 +428,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_set(PORT_LED1_3, PIN_LED3); usb_endpoint_init(&usb_endpoint_bulk_out); - update_switches(); + rf_path_set_direction(RF_PATH_DIRECTION_TX); //rffc5071_set_frequency(1700, 0); // 2600 MHz IF - 1700 MHz LO = 900 MHz RF max2837_start(); max2837_tx(); @@ -807,13 +838,11 @@ usb_request_status_t usb_vendor_request_set_amp_enable( if (stage == USB_TRANSFER_STAGE_SETUP) { switch (endpoint->setup.value) { case 0: - switchctrl |= SWITCHCTRL_AMP_BYPASS; - update_switches(); + rf_path_set_lna(0); usb_endpoint_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; case 1: - switchctrl &= ~SWITCHCTRL_AMP_BYPASS; - update_switches(); + rf_path_set_lna(1); usb_endpoint_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; default: From b5dc264d220e508cf9ec44990824e17179550dc3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 22:22:03 -0700 Subject: [PATCH 070/200] Extract rf_path code into a separate .c/.h. Add an rf_path_init() function to do initial, idle configuration during start-up. --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/Makefile_rom_to_ram | 1 + firmware/hackrf_usb/hackrf_usb.c | 121 +----------------------- firmware/hackrf_usb/rf_path.c | 109 +++++++++++++++++++++ firmware/hackrf_usb/rf_path.h | 25 +++++ firmware/hackrf_usb_rom_to_ram/Makefile | 1 + 6 files changed, 141 insertions(+), 117 deletions(-) create mode 100644 firmware/hackrf_usb/rf_path.c create mode 100644 firmware/hackrf_usb/rf_path.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 3d2b4d53..1b6fe51e 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -23,6 +23,7 @@ BINARY = hackrf_usb SRC = $(BINARY).c \ + rf_path.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram index bd71216d..7ab7af69 100644 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ b/firmware/hackrf_usb/Makefile_rom_to_ram @@ -23,6 +23,7 @@ BINARY = hackrf_usb_rom_to_ram SRC = hackrf_usb.c \ + rf_path.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 737bc013..1fccaaf9 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -45,6 +45,8 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" +#include "rf_path.h" + static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; void sgpio_isr_rx(); @@ -79,119 +81,6 @@ typedef struct { set_sample_r_params_t set_sample_r_params; -#ifdef JAWBREAKER -/* - * RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on - * the RFFC5072. - */ -#define SWITCHCTRL_NO_TX_AMP_PWR (1 << 0) /* GPO1 turn off TX amp power */ -#define SWITCHCTRL_AMP_BYPASS (1 << 1) /* GPO2 bypass amp section */ -#define SWITCHCTRL_TX (1 << 2) /* GPO3 1 for TX mode, 0 for RX mode */ -#define SWITCHCTRL_MIX_BYPASS (1 << 3) /* GPO4 bypass RFFC5072 mixer section */ -#define SWITCHCTRL_HP (1 << 4) /* GPO5 1 for high-pass, 0 for low-pass */ -#define SWITCHCTRL_NO_RX_AMP_PWR (1 << 5) /* GPO6 turn off RX amp power */ - -/* - GPO6 GPO5 GPO4 GPO3 GPO2 GPO1 -!RXAMP HP MIXBP TX AMPBP !TXAMP Mix mode Amp mode - 1 X 1 1 1 1 TX bypass Bypass - 1 X 1 1 0 0 TX bypass TX amplified - 1 1 0 1 1 1 TX high Bypass - 1 1 0 1 0 0 TX high TX amplified - 1 0 0 1 1 1 TX low Bypass - 1 0 0 1 0 0 TX low TX amplified - 1 X 1 0 1 1 RX bypass Bypass - 0 X 1 0 0 1 RX bypass RX amplified - 1 1 0 0 1 1 RX high Bypass - 0 1 0 0 0 1 RX high RX amplified - 1 0 0 0 1 1 RX low Bypass - 0 0 0 0 0 1 RX low RX amplified -*/ - -/* - * Safe (initial) switch settings turn off both amplifiers and enable both amp - * bypass and mixer bypass. - */ -#define SWITCHCTRL_SAFE (SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_TX | SWITCHCTRL_MIX_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_NO_RX_AMP_PWR) -#endif - -uint8_t switchctrl = SWITCHCTRL_SAFE; - -typedef enum { - RF_PATH_DIRECTION_RX, - RF_PATH_DIRECTION_TX, -} rf_path_direction_t; - -void rf_path_set_direction(const rf_path_direction_t direction) { - /* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */ - switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; - if( direction == RF_PATH_DIRECTION_TX ) { - switchctrl |= SWITCHCTRL_TX; - if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { - /* TX amplifier is in path, be sure to enable TX amplifier. */ - switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; - } - rffc5071_tx(); - } else { - switchctrl &= ~SWITCHCTRL_TX; - if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { - /* RX amplifier is in path, be sure to enable RX amplifier. */ - switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; - } - rffc5071_rx(); - } - - rffc5071_set_gpo(switchctrl); -} - -typedef enum { - RF_PATH_FILTER_BYPASS, - RF_PATH_FILTER_LOW_PASS, - RF_PATH_FILTER_HIGH_PASS, -} rf_path_filter_t; - -void rf_path_set_filter(const rf_path_filter_t filter) { - switch(filter) { - default: - case RF_PATH_FILTER_BYPASS: - switchctrl |= SWITCHCTRL_MIX_BYPASS; - rffc5071_disable(); - break; - - case RF_PATH_FILTER_LOW_PASS: - switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - rffc5071_enable(); - break; - - case RF_PATH_FILTER_HIGH_PASS: - switchctrl &= ~SWITCHCTRL_MIX_BYPASS; - switchctrl |= SWITCHCTRL_HP; - rffc5071_enable(); - break; - } - - rffc5071_set_gpo(switchctrl); -} - -void rf_path_set_lna(const uint_fast8_t enable) { - if( enable ) { - if( switchctrl & SWITCHCTRL_TX ) { - /* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */ - switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; - switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR); - } else { - /* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */ - switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; - switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR); - } - } else { - /* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */ - switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; - } - - rffc5071_set_gpo(switchctrl); -} - #define FREQ_ONE_MHZ (1000*1000) #define MIN_LP_FREQ_MHZ (5) @@ -1107,10 +996,8 @@ int main(void) { max2837_set_frequency(ifreq); rffc5071_setup(); -#ifdef JAWBREAKER - /* initial safe switch control settings */ - rffc5071_set_gpo(switchctrl); -#endif + + rf_path_init(); while(true) { // Wait until buffer 0 is transmitted/received. diff --git a/firmware/hackrf_usb/rf_path.c b/firmware/hackrf_usb/rf_path.c new file mode 100644 index 00000000..e511bf41 --- /dev/null +++ b/firmware/hackrf_usb/rf_path.c @@ -0,0 +1,109 @@ +#include "rf_path.h" + +#include + +#ifdef JAWBREAKER +/* + * RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on + * the RFFC5072. + */ +#define SWITCHCTRL_NO_TX_AMP_PWR (1 << 0) /* GPO1 turn off TX amp power */ +#define SWITCHCTRL_AMP_BYPASS (1 << 1) /* GPO2 bypass amp section */ +#define SWITCHCTRL_TX (1 << 2) /* GPO3 1 for TX mode, 0 for RX mode */ +#define SWITCHCTRL_MIX_BYPASS (1 << 3) /* GPO4 bypass RFFC5072 mixer section */ +#define SWITCHCTRL_HP (1 << 4) /* GPO5 1 for high-pass, 0 for low-pass */ +#define SWITCHCTRL_NO_RX_AMP_PWR (1 << 5) /* GPO6 turn off RX amp power */ + +/* + GPO6 GPO5 GPO4 GPO3 GPO2 GPO1 +!RXAMP HP MIXBP TX AMPBP !TXAMP Mix mode Amp mode + 1 X 1 1 1 1 TX bypass Bypass + 1 X 1 1 0 0 TX bypass TX amplified + 1 1 0 1 1 1 TX high Bypass + 1 1 0 1 0 0 TX high TX amplified + 1 0 0 1 1 1 TX low Bypass + 1 0 0 1 0 0 TX low TX amplified + 1 X 1 0 1 1 RX bypass Bypass + 0 X 1 0 0 1 RX bypass RX amplified + 1 1 0 0 1 1 RX high Bypass + 0 1 0 0 0 1 RX high RX amplified + 1 0 0 0 1 1 RX low Bypass + 0 0 0 0 0 1 RX low RX amplified +*/ + +/* + * Safe (initial) switch settings turn off both amplifiers and enable both amp + * bypass and mixer bypass. + */ +#define SWITCHCTRL_SAFE (SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_TX | SWITCHCTRL_MIX_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_NO_RX_AMP_PWR) +#endif + +uint8_t switchctrl = SWITCHCTRL_SAFE; + +void rf_path_init(void) { + rffc5071_set_gpo(switchctrl); +} + +void rf_path_set_direction(const rf_path_direction_t direction) { + /* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */ + switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; + if( direction == RF_PATH_DIRECTION_TX ) { + switchctrl |= SWITCHCTRL_TX; + if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { + /* TX amplifier is in path, be sure to enable TX amplifier. */ + switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; + } + rffc5071_tx(); + } else { + switchctrl &= ~SWITCHCTRL_TX; + if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { + /* RX amplifier is in path, be sure to enable RX amplifier. */ + switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; + } + rffc5071_rx(); + } + + rffc5071_set_gpo(switchctrl); +} + +void rf_path_set_filter(const rf_path_filter_t filter) { + switch(filter) { + default: + case RF_PATH_FILTER_BYPASS: + switchctrl |= SWITCHCTRL_MIX_BYPASS; + rffc5071_disable(); + break; + + case RF_PATH_FILTER_LOW_PASS: + switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); + rffc5071_enable(); + break; + + case RF_PATH_FILTER_HIGH_PASS: + switchctrl &= ~SWITCHCTRL_MIX_BYPASS; + switchctrl |= SWITCHCTRL_HP; + rffc5071_enable(); + break; + } + + rffc5071_set_gpo(switchctrl); +} + +void rf_path_set_lna(const uint_fast8_t enable) { + if( enable ) { + if( switchctrl & SWITCHCTRL_TX ) { + /* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */ + switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; + switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR); + } else { + /* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */ + switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; + switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR); + } + } else { + /* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */ + switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; + } + + rffc5071_set_gpo(switchctrl); +} diff --git a/firmware/hackrf_usb/rf_path.h b/firmware/hackrf_usb/rf_path.h new file mode 100644 index 00000000..fea572f7 --- /dev/null +++ b/firmware/hackrf_usb/rf_path.h @@ -0,0 +1,25 @@ +#ifndef __RFPATH_H__ +#define __RFPATH_H__ + +#include + +void rf_path_init(void); + +typedef enum { + RF_PATH_DIRECTION_RX, + RF_PATH_DIRECTION_TX, +} rf_path_direction_t; + +void rf_path_set_direction(const rf_path_direction_t direction); + +typedef enum { + RF_PATH_FILTER_BYPASS, + RF_PATH_FILTER_LOW_PASS, + RF_PATH_FILTER_HIGH_PASS, +} rf_path_filter_t; + +void rf_path_set_filter(const rf_path_filter_t filter); + +void rf_path_set_lna(const uint_fast8_t enable); + +#endif/*__RFPATH_H__*/ diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index 0d2ea0e2..ac5fda3f 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -25,6 +25,7 @@ BINARY = hackrf_usb_rom_to_ram SRC_DIR = hackrf_usb SRC = hackrf_usb.c \ + rf_path.c \ usb.c \ usb_request.c \ usb_standard_request.c \ From 14eba3d94749b8c6080d467c525858b41af72992 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 22:30:13 -0700 Subject: [PATCH 071/200] Extract tuning code into separate .c/.h file. --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/Makefile_rom_to_ram | 1 + firmware/hackrf_usb/hackrf_usb.c | 96 +----------------- firmware/hackrf_usb/tuning.c | 123 ++++++++++++++++++++++++ firmware/hackrf_usb/tuning.h | 32 ++++++ firmware/hackrf_usb_rom_to_ram/Makefile | 1 + 6 files changed, 159 insertions(+), 95 deletions(-) create mode 100644 firmware/hackrf_usb/tuning.c create mode 100644 firmware/hackrf_usb/tuning.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 1b6fe51e..38dcc67e 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -24,6 +24,7 @@ BINARY = hackrf_usb SRC = $(BINARY).c \ rf_path.c \ + tuning.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram index 7ab7af69..0b38b0c1 100644 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ b/firmware/hackrf_usb/Makefile_rom_to_ram @@ -24,6 +24,7 @@ BINARY = hackrf_usb_rom_to_ram SRC = hackrf_usb.c \ rf_path.c \ + tuning.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 1fccaaf9..a4d43862 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -46,6 +46,7 @@ #include "usb_standard_request.h" #include "rf_path.h" +#include "tuning.h" static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; @@ -81,101 +82,6 @@ typedef struct { set_sample_r_params_t set_sample_r_params; -#define FREQ_ONE_MHZ (1000*1000) - -#define MIN_LP_FREQ_MHZ (5) -#define MAX_LP_FREQ_MHZ (2300) - -#define MIN_BYPASS_FREQ_MHZ (2300) -#define MAX_BYPASS_FREQ_MHZ (2700) - -#define MIN_HP_FREQ_MHZ (2700) -#define MAX_HP_FREQ_MHZ (6800) - -static uint32_t max2837_freq_nominal_hz=2600000000; -#define MAX2837_FREQ_NOMINAL_MHZ (max2837_freq_nominal_hz / FREQ_ONE_MHZ) - -uint32_t freq_mhz_cache=100, freq_hz_cache=0; -/* - * Set freq/tuning between 5MHz to 6800 MHz (less than 16bits really used) - * hz between 0 to 999999 Hz (not checked) - * return false on error or true if success. - */ -bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) -{ - bool success; - uint32_t RFFC5071_freq_mhz; - uint32_t MAX2837_freq_hz; - uint32_t real_RFFC5071_freq_hz; - uint32_t tmp_hz; - - success = true; - - const max2837_mode_t prior_max2837_mode = max2837_mode(); - max2837_mode_standby(); - if(freq_mhz >= MIN_LP_FREQ_MHZ) - { - if(freq_mhz < MAX_LP_FREQ_MHZ) - { - RFFC5071_freq_mhz = MAX2837_FREQ_NOMINAL_MHZ - freq_mhz; - /* Set Freq and read real freq */ - real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); - if(real_RFFC5071_freq_hz < RFFC5071_freq_mhz * FREQ_ONE_MHZ) - { - tmp_hz = -(RFFC5071_freq_mhz * FREQ_ONE_MHZ - real_RFFC5071_freq_hz); - }else - { - tmp_hz = (real_RFFC5071_freq_hz - RFFC5071_freq_mhz * FREQ_ONE_MHZ); - } - MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; - max2837_set_frequency(MAX2837_freq_hz); - rf_path_set_filter(RF_PATH_FILTER_LOW_PASS); - }else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) - { - MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz; - /* RFFC5071_freq_mhz <= not used in Bypass mode */ - max2837_set_frequency(MAX2837_freq_hz); - rf_path_set_filter(RF_PATH_FILTER_BYPASS); - }else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz < MAX_HP_FREQ_MHZ) ) - { - RFFC5071_freq_mhz = freq_mhz - MAX2837_FREQ_NOMINAL_MHZ; - /* Set Freq and read real freq */ - real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); - if(real_RFFC5071_freq_hz < RFFC5071_freq_mhz * FREQ_ONE_MHZ) - { - tmp_hz = (RFFC5071_freq_mhz * FREQ_ONE_MHZ - real_RFFC5071_freq_hz); - }else - { - tmp_hz = -(real_RFFC5071_freq_hz - RFFC5071_freq_mhz * FREQ_ONE_MHZ); - } - MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; - max2837_set_frequency(MAX2837_freq_hz); - rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS); - }else - { - /* Error freq_mhz too high */ - success = false; - } - }else - { - /* Error freq_mhz too low */ - success = false; - } - max2837_set_mode(prior_max2837_mode); - freq_mhz_cache = freq_mhz; - freq_hz_cache = freq_hz; - return success; -} - -bool set_freq_if(const uint32_t freq_if_hz) { - bool success = false; - if( (freq_if_hz >= MIN_BYPASS_FREQ_MHZ) && (freq_if_hz <= MAX_BYPASS_FREQ_MHZ) ) { - max2837_freq_nominal_hz = freq_if_hz; - success = set_freq(freq_mhz_cache, freq_hz_cache); - } - return success; -} - static void usb_init_buffers_bulk() { usb_td_bulk[0].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; usb_td_bulk[0].total_bytes diff --git a/firmware/hackrf_usb/tuning.c b/firmware/hackrf_usb/tuning.c new file mode 100644 index 00000000..ea7db767 --- /dev/null +++ b/firmware/hackrf_usb/tuning.c @@ -0,0 +1,123 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "tuning.h" + +#include +#include + +#include "rf_path.h" + +#define FREQ_ONE_MHZ (1000*1000) + +#define MIN_LP_FREQ_MHZ (5) +#define MAX_LP_FREQ_MHZ (2300) + +#define MIN_BYPASS_FREQ_MHZ (2300) +#define MAX_BYPASS_FREQ_MHZ (2700) + +#define MIN_HP_FREQ_MHZ (2700) +#define MAX_HP_FREQ_MHZ (6800) + +static uint32_t max2837_freq_nominal_hz=2600000000; +#define MAX2837_FREQ_NOMINAL_MHZ (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + +uint32_t freq_mhz_cache=100, freq_hz_cache=0; +/* + * Set freq/tuning between 5MHz to 6800 MHz (less than 16bits really used) + * hz between 0 to 999999 Hz (not checked) + * return false on error or true if success. + */ +bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) +{ + bool success; + uint32_t RFFC5071_freq_mhz; + uint32_t MAX2837_freq_hz; + uint32_t real_RFFC5071_freq_hz; + uint32_t tmp_hz; + + success = true; + + const max2837_mode_t prior_max2837_mode = max2837_mode(); + max2837_mode_standby(); + if(freq_mhz >= MIN_LP_FREQ_MHZ) + { + if(freq_mhz < MAX_LP_FREQ_MHZ) + { + RFFC5071_freq_mhz = MAX2837_FREQ_NOMINAL_MHZ - freq_mhz; + /* Set Freq and read real freq */ + real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); + if(real_RFFC5071_freq_hz < RFFC5071_freq_mhz * FREQ_ONE_MHZ) + { + tmp_hz = -(RFFC5071_freq_mhz * FREQ_ONE_MHZ - real_RFFC5071_freq_hz); + }else + { + tmp_hz = (real_RFFC5071_freq_hz - RFFC5071_freq_mhz * FREQ_ONE_MHZ); + } + MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; + max2837_set_frequency(MAX2837_freq_hz); + rf_path_set_filter(RF_PATH_FILTER_LOW_PASS); + }else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) + { + MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz; + /* RFFC5071_freq_mhz <= not used in Bypass mode */ + max2837_set_frequency(MAX2837_freq_hz); + rf_path_set_filter(RF_PATH_FILTER_BYPASS); + }else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz < MAX_HP_FREQ_MHZ) ) + { + RFFC5071_freq_mhz = freq_mhz - MAX2837_FREQ_NOMINAL_MHZ; + /* Set Freq and read real freq */ + real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); + if(real_RFFC5071_freq_hz < RFFC5071_freq_mhz * FREQ_ONE_MHZ) + { + tmp_hz = (RFFC5071_freq_mhz * FREQ_ONE_MHZ - real_RFFC5071_freq_hz); + }else + { + tmp_hz = -(real_RFFC5071_freq_hz - RFFC5071_freq_mhz * FREQ_ONE_MHZ); + } + MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; + max2837_set_frequency(MAX2837_freq_hz); + rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS); + }else + { + /* Error freq_mhz too high */ + success = false; + } + }else + { + /* Error freq_mhz too low */ + success = false; + } + max2837_set_mode(prior_max2837_mode); + freq_mhz_cache = freq_mhz; + freq_hz_cache = freq_hz; + return success; +} + +bool set_freq_if(const uint32_t freq_if_hz) { + bool success = false; + if( (freq_if_hz >= MIN_BYPASS_FREQ_MHZ) && (freq_if_hz <= MAX_BYPASS_FREQ_MHZ) ) { + max2837_freq_nominal_hz = freq_if_hz; + success = set_freq(freq_mhz_cache, freq_hz_cache); + } + return success; +} diff --git a/firmware/hackrf_usb/tuning.h b/firmware/hackrf_usb/tuning.h new file mode 100644 index 00000000..0c1a99d9 --- /dev/null +++ b/firmware/hackrf_usb/tuning.h @@ -0,0 +1,32 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __TUNING_H__ +#define __TUNING_H__ + +#include +#include + +bool set_freq(uint32_t freq_mhz, uint32_t freq_hz); +bool set_freq_if(const uint32_t freq_if_hz); + +#endif/*__TUNING_H__*/ diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index ac5fda3f..2effde20 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -26,6 +26,7 @@ SRC_DIR = hackrf_usb SRC = hackrf_usb.c \ rf_path.c \ + tuning.c \ usb.c \ usb_request.c \ usb_standard_request.c \ From ddf4c01f668c7ce88df6af672d9a1357736c1b3d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 22:30:48 -0700 Subject: [PATCH 072/200] Forgot to propagate license to rf_path.[ch]. --- firmware/hackrf_usb/rf_path.c | 22 ++++++++++++++++++++++ firmware/hackrf_usb/rf_path.h | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/firmware/hackrf_usb/rf_path.c b/firmware/hackrf_usb/rf_path.c index e511bf41..32cb9989 100644 --- a/firmware/hackrf_usb/rf_path.c +++ b/firmware/hackrf_usb/rf_path.c @@ -1,3 +1,25 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include "rf_path.h" #include diff --git a/firmware/hackrf_usb/rf_path.h b/firmware/hackrf_usb/rf_path.h index fea572f7..aec7a974 100644 --- a/firmware/hackrf_usb/rf_path.h +++ b/firmware/hackrf_usb/rf_path.h @@ -1,3 +1,25 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #ifndef __RFPATH_H__ #define __RFPATH_H__ From 1c81fa895cb04ea7106c58a7c5e579b1ec1db957 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Sep 2013 22:34:36 -0700 Subject: [PATCH 073/200] Bump mossmann/libopencm3 commit. --- firmware/libopencm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index f92dbcdf..0b14b17f 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit f92dbcdf6028687f705c71134f51d5b4061daf7a +Subproject commit 0b14b17fc539247598946465f2f78c5d23cbd4ee From 9b2b7b08176011d6f21a0320bdf81dc1fa340e4e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Sep 2013 15:10:19 -0700 Subject: [PATCH 074/200] Move SGPIO ISRs to separate .c/.h files. Move usb_bulk_buffer* to separate .c/.h files. --- firmware/hackrf_usb/Makefile | 2 + firmware/hackrf_usb/Makefile_rom_to_ram | 2 + firmware/hackrf_usb/hackrf_usb.c | 75 +------------------- firmware/hackrf_usb/sgpio_isr.c | 93 +++++++++++++++++++++++++ firmware/hackrf_usb/sgpio_isr.h | 29 ++++++++ firmware/hackrf_usb/usb_bulk_buffer.c | 27 +++++++ firmware/hackrf_usb/usb_bulk_buffer.h | 33 +++++++++ firmware/hackrf_usb_rom_to_ram/Makefile | 2 + 8 files changed, 190 insertions(+), 73 deletions(-) create mode 100644 firmware/hackrf_usb/sgpio_isr.c create mode 100644 firmware/hackrf_usb/sgpio_isr.h create mode 100644 firmware/hackrf_usb/usb_bulk_buffer.c create mode 100644 firmware/hackrf_usb/usb_bulk_buffer.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 38dcc67e..e429af21 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -25,6 +25,8 @@ BINARY = hackrf_usb SRC = $(BINARY).c \ rf_path.c \ tuning.c \ + sgpio_isr.c \ + usb_bulk_buffer.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram index 0b38b0c1..a574692b 100644 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ b/firmware/hackrf_usb/Makefile_rom_to_ram @@ -25,6 +25,8 @@ BINARY = hackrf_usb_rom_to_ram SRC = hackrf_usb.c \ rf_path.c \ tuning.c \ + sgpio_isr.c \ + usb_bulk_buffer.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index a4d43862..e211d7d6 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -47,16 +47,11 @@ #include "rf_path.h" #include "tuning.h" +#include "sgpio_isr.h" +#include "usb_bulk_buffer.h" static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; -void sgpio_isr_rx(); -void sgpio_isr_tx(); - -uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; -static volatile uint32_t usb_bulk_buffer_offset = 0; -static const uint32_t usb_bulk_buffer_mask = 32768 - 1; - usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64); const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]); @@ -808,72 +803,6 @@ void usb_configuration_changed( } } -void sgpio_isr_rx() { - SGPIO_CLR_STATUS_1 = (1 << SGPIO_SLICE_A); - - uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; - __asm__( - "ldr r0, [%[SGPIO_REG_SS], #44]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #0]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #20]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #4]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #40]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #8]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #8]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #12]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #36]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #16]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #16]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #20]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #32]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #24]\n\t" - "ldr r0, [%[SGPIO_REG_SS], #0]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ - "str r0, [%[p], #28]\n\t" - : - : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), - [p] "l" (p) - : "r0" - ); - usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; -} - -void sgpio_isr_tx() { - SGPIO_CLR_STATUS_1 = (1 << SGPIO_SLICE_A); - - uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; - __asm__( - "ldr r0, [%[p], #0]\n\t" - "str r0, [%[SGPIO_REG_SS], #44]\n\t" - "ldr r0, [%[p], #4]\n\t" - "str r0, [%[SGPIO_REG_SS], #20]\n\t" - "ldr r0, [%[p], #8]\n\t" - "str r0, [%[SGPIO_REG_SS], #40]\n\t" - "ldr r0, [%[p], #12]\n\t" - "str r0, [%[SGPIO_REG_SS], #8]\n\t" - "ldr r0, [%[p], #16]\n\t" - "str r0, [%[SGPIO_REG_SS], #36]\n\t" - "ldr r0, [%[p], #20]\n\t" - "str r0, [%[SGPIO_REG_SS], #16]\n\t" - "ldr r0, [%[p], #24]\n\t" - "str r0, [%[SGPIO_REG_SS], #32]\n\t" - "ldr r0, [%[p], #28]\n\t" - "str r0, [%[SGPIO_REG_SS], #0]\n\t" - : - : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), - [p] "l" (p) - : "r0" - ); - usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; -} - int main(void) { const uint32_t ifreq = 2600000000U; diff --git a/firmware/hackrf_usb/sgpio_isr.c b/firmware/hackrf_usb/sgpio_isr.c new file mode 100644 index 00000000..76eebf0f --- /dev/null +++ b/firmware/hackrf_usb/sgpio_isr.c @@ -0,0 +1,93 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "sgpio_isr.h" + +#include + +#include "usb_bulk_buffer.h" + +void sgpio_isr_rx() { + SGPIO_CLR_STATUS_1 = (1 << SGPIO_SLICE_A); + + uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; + __asm__( + "ldr r0, [%[SGPIO_REG_SS], #44]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #0]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #20]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #4]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #40]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #8]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #8]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #12]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #36]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #16]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #16]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #20]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #32]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #24]\n\t" + "ldr r0, [%[SGPIO_REG_SS], #0]\n\t" + "rev16 r0, r0\n\t" /* Swap QI -> IQ */ + "str r0, [%[p], #28]\n\t" + : + : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), + [p] "l" (p) + : "r0" + ); + usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; +} + +void sgpio_isr_tx() { + SGPIO_CLR_STATUS_1 = (1 << SGPIO_SLICE_A); + + uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; + __asm__( + "ldr r0, [%[p], #0]\n\t" + "str r0, [%[SGPIO_REG_SS], #44]\n\t" + "ldr r0, [%[p], #4]\n\t" + "str r0, [%[SGPIO_REG_SS], #20]\n\t" + "ldr r0, [%[p], #8]\n\t" + "str r0, [%[SGPIO_REG_SS], #40]\n\t" + "ldr r0, [%[p], #12]\n\t" + "str r0, [%[SGPIO_REG_SS], #8]\n\t" + "ldr r0, [%[p], #16]\n\t" + "str r0, [%[SGPIO_REG_SS], #36]\n\t" + "ldr r0, [%[p], #20]\n\t" + "str r0, [%[SGPIO_REG_SS], #16]\n\t" + "ldr r0, [%[p], #24]\n\t" + "str r0, [%[SGPIO_REG_SS], #32]\n\t" + "ldr r0, [%[p], #28]\n\t" + "str r0, [%[SGPIO_REG_SS], #0]\n\t" + : + : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), + [p] "l" (p) + : "r0" + ); + usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; +} diff --git a/firmware/hackrf_usb/sgpio_isr.h b/firmware/hackrf_usb/sgpio_isr.h new file mode 100644 index 00000000..31162440 --- /dev/null +++ b/firmware/hackrf_usb/sgpio_isr.h @@ -0,0 +1,29 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SGPIO_ISR_H__ +#define __SGPIO_ISR_H__ + +void sgpio_isr_rx(); +void sgpio_isr_tx(); + +#endif/*__SGPIO_ISR_H__*/ diff --git a/firmware/hackrf_usb/usb_bulk_buffer.c b/firmware/hackrf_usb/usb_bulk_buffer.c new file mode 100644 index 00000000..3e6d0320 --- /dev/null +++ b/firmware/hackrf_usb/usb_bulk_buffer.c @@ -0,0 +1,27 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_bulk_buffer.h" + +uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; +const uint32_t usb_bulk_buffer_mask = 32768 - 1; +volatile uint32_t usb_bulk_buffer_offset = 0; diff --git a/firmware/hackrf_usb/usb_bulk_buffer.h b/firmware/hackrf_usb/usb_bulk_buffer.h new file mode 100644 index 00000000..fe298e69 --- /dev/null +++ b/firmware/hackrf_usb/usb_bulk_buffer.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_BULK_BUFFER_H__ +#define __USB_BULK_BUFFER_H__ + +#include + +extern uint8_t* const usb_bulk_buffer; +extern const uint32_t usb_bulk_buffer_mask; + +extern volatile uint32_t usb_bulk_buffer_offset; + +#endif/*__USB_BULK_BUFFER_H__*/ diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index 2effde20..f09b0511 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -27,6 +27,8 @@ SRC_DIR = hackrf_usb SRC = hackrf_usb.c \ rf_path.c \ tuning.c \ + sgpio_isr.c \ + usb_bulk_buffer.c \ usb.c \ usb_request.c \ usb_standard_request.c \ From 217630d82cf97a725f55c8ed4ca64331dd38a6d0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Sep 2013 15:13:44 -0700 Subject: [PATCH 075/200] Convert rf_path_set_direction from if/else to switch/case. --- firmware/hackrf_usb/rf_path.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/rf_path.c b/firmware/hackrf_usb/rf_path.c index 32cb9989..c1e31cdd 100644 --- a/firmware/hackrf_usb/rf_path.c +++ b/firmware/hackrf_usb/rf_path.c @@ -69,20 +69,24 @@ void rf_path_init(void) { void rf_path_set_direction(const rf_path_direction_t direction) { /* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */ switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; - if( direction == RF_PATH_DIRECTION_TX ) { + switch(direction) { + case RF_PATH_DIRECTION_TX: switchctrl |= SWITCHCTRL_TX; if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { /* TX amplifier is in path, be sure to enable TX amplifier. */ switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; } rffc5071_tx(); - } else { + break; + + case RF_PATH_DIRECTION_RX: switchctrl &= ~SWITCHCTRL_TX; if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { /* RX amplifier is in path, be sure to enable RX amplifier. */ switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; } rffc5071_rx(); + break; } rffc5071_set_gpo(switchctrl); From a897c4f0168d9354f63be040a790227964dc40e7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Sep 2013 15:16:51 -0700 Subject: [PATCH 076/200] Add RF_PATH_DIRECTION_OFF enum and code. --- firmware/hackrf_usb/rf_path.c | 7 +++++++ firmware/hackrf_usb/rf_path.h | 1 + 2 files changed, 8 insertions(+) diff --git a/firmware/hackrf_usb/rf_path.c b/firmware/hackrf_usb/rf_path.c index c1e31cdd..6c5365ec 100644 --- a/firmware/hackrf_usb/rf_path.c +++ b/firmware/hackrf_usb/rf_path.c @@ -87,6 +87,13 @@ void rf_path_set_direction(const rf_path_direction_t direction) { } rffc5071_rx(); break; + + case RF_PATH_DIRECTION_OFF: + default: + /* Set RF path to receive direction when "off" */ + switchctrl &= ~SWITCHCTRL_TX; + rffc5071_disable(); + break; } rffc5071_set_gpo(switchctrl); diff --git a/firmware/hackrf_usb/rf_path.h b/firmware/hackrf_usb/rf_path.h index aec7a974..265dc7fc 100644 --- a/firmware/hackrf_usb/rf_path.h +++ b/firmware/hackrf_usb/rf_path.h @@ -28,6 +28,7 @@ void rf_path_init(void); typedef enum { + RF_PATH_DIRECTION_OFF, RF_PATH_DIRECTION_RX, RF_PATH_DIRECTION_TX, } rf_path_direction_t; From d00123ed24cee6cc6a0a841c8bb60eda680bfde2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Sep 2013 15:20:47 -0700 Subject: [PATCH 077/200] Update RFFC5071 enable state when switching RF path direction. TODO: There's some stuff here that needs refactoring -- duplicate code is showing up. --- firmware/hackrf_usb/rf_path.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/firmware/hackrf_usb/rf_path.c b/firmware/hackrf_usb/rf_path.c index 6c5365ec..0444ae0e 100644 --- a/firmware/hackrf_usb/rf_path.c +++ b/firmware/hackrf_usb/rf_path.c @@ -77,6 +77,11 @@ void rf_path_set_direction(const rf_path_direction_t direction) { switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; } rffc5071_tx(); + if( switchctrl & SWITCHCTRL_MIX_BYPASS ) { + rffc5071_disable(); + } else { + rffc5071_enable(); + } break; case RF_PATH_DIRECTION_RX: @@ -86,6 +91,11 @@ void rf_path_set_direction(const rf_path_direction_t direction) { switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; } rffc5071_rx(); + if( switchctrl & SWITCHCTRL_MIX_BYPASS ) { + rffc5071_disable(); + } else { + rffc5071_enable(); + } break; case RF_PATH_DIRECTION_OFF: From 98e33fbb5bcb628e67f7ed350f436a318cc7c0a1 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Sep 2013 15:36:25 -0700 Subject: [PATCH 078/200] Remove commented RFFC5071 code in set_transceiver_mode. --- firmware/hackrf_usb/hackrf_usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index e211d7d6..021ef86e 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -210,7 +210,6 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { usb_endpoint_init(&usb_endpoint_bulk_in); rf_path_set_direction(RF_PATH_DIRECTION_RX); - //rffc5071_set_frequency(1700, 0); // 2600 MHz IF - 1700 MHz LO = 900 MHz RF max2837_start(); max2837_rx(); } else if (transceiver_mode == TRANSCEIVER_MODE_TX) { @@ -219,7 +218,6 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { usb_endpoint_init(&usb_endpoint_bulk_out); rf_path_set_direction(RF_PATH_DIRECTION_TX); - //rffc5071_set_frequency(1700, 0); // 2600 MHz IF - 1700 MHz LO = 900 MHz RF max2837_start(); max2837_tx(); } else { From 0411ffe3f0ad031857c090ee8c18c85edacd8277 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Sep 2013 15:44:37 -0700 Subject: [PATCH 079/200] Set RF path direction to "off" when transceiver_mode is OFF. --- firmware/hackrf_usb/hackrf_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 021ef86e..c667263c 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -223,6 +223,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { } else { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_clear(PORT_LED1_3, PIN_LED3); + rf_path_set_direction(RF_PATH_DIRECTION_OFF); max2837_stop(); return; } From 042229ea19779bd02068de6d8b113d5dbfc5c97e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Sep 2013 15:52:36 -0700 Subject: [PATCH 080/200] Set transceiver mode to OFF whenever USB configuration changes. --- firmware/hackrf_usb/hackrf_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index c667263c..b33085d9 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -790,13 +790,13 @@ const usb_request_handlers_t usb_request_handlers = { void usb_configuration_changed( usb_device_t* const device ) { + /* Reset transceiver to idle state until other commands are received */ + set_transceiver_mode(TRANSCEIVER_MODE_OFF); if( device->configuration->number ) { cpu_clock_pll1_max_speed(); - set_transceiver_mode(transceiver_mode); gpio_set(PORT_LED1_3, PIN_LED1); } else { /* Configuration number equal 0 means usb bus reset. */ - set_transceiver_mode(TRANSCEIVER_MODE_OFF); cpu_clock_pll1_low_speed(); gpio_clear(PORT_LED1_3, PIN_LED1); } From d7e2a8d1334cadc30b6d1a521b1c631f4ec97515 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 Sep 2013 15:54:17 -0700 Subject: [PATCH 081/200] Added note on generating XSVF inside Xilinx tools. --- firmware/cpld/sgpio_if/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/firmware/cpld/sgpio_if/README.md b/firmware/cpld/sgpio_if/README.md index d4093020..44fe9a8c 100644 --- a/firmware/cpld/sgpio_if/README.md +++ b/firmware/cpld/sgpio_if/README.md @@ -22,6 +22,25 @@ To program the SVF file into the CPLD: required, and the "program" script below expects it to be at the relative path "bsdl/xc2c/xc2c64.bsd". +Generate an XSVF +================ + +After generating a programming file: + +* In the ISE Project Navigator, "Processes: top - Behavioral" pane, double-click "Configure Target Device". +* Click "OK" to open iMPACT. +* Ctrl-N to create a "New Project". +* "Yes" to automatically create and save a project file. +* Select "Prepare a Boundary-Scan File", choose "XSVF". +* Select file name "default.xsvf". +* Click "OK" to start adding devices. +* Assign new configuration file: "top.jed". +* Right-click the "xc2c64a top.jed" icon and select "Erase". Accept defaults. +* Right-click the "xc2c64a top.jed" icon and select "Program". +* Right-click the "xc2c64a top.jed" icon and select "Verify". +* Choose menu "Output" -> "XSVF File" -> "Stop Writing to XSVF File". +* Close iMPACT. + To Program ========== From 5a7b927db642a592075838dcb9321c863d38f63d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 Sep 2013 16:20:43 -0700 Subject: [PATCH 082/200] Change line endings in CPLD user constraints file license header to match the rest of the file. --- firmware/cpld/sgpio_if/top.ucf | 36 +++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/firmware/cpld/sgpio_if/top.ucf b/firmware/cpld/sgpio_if/top.ucf index 9e9387c5..b446469d 100755 --- a/firmware/cpld/sgpio_if/top.ucf +++ b/firmware/cpld/sgpio_if/top.ucf @@ -1,22 +1,22 @@ # -# Copyright 2012 Jared Boone -# -# This file is part of HackRF. -# -# 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, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# 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, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. NET "CODEC_CLK" LOC="23" |IOSTANDARD=LVCMOS33; NET "CODEC_X2_CLK" LOC="27" |IOSTANDARD=LVCMOS33; From e9236e50c2f6d5fb699e289ff95d1b264de4133d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 Sep 2013 16:21:16 -0700 Subject: [PATCH 083/200] Fix CPLD constraint to assume SGPIO frequency of 40MHz, not 20MHz. --- firmware/cpld/sgpio_if/top.ucf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/cpld/sgpio_if/top.ucf b/firmware/cpld/sgpio_if/top.ucf index b446469d..f3b7b65b 100755 --- a/firmware/cpld/sgpio_if/top.ucf +++ b/firmware/cpld/sgpio_if/top.ucf @@ -23,7 +23,7 @@ NET "CODEC_X2_CLK" LOC="27" |IOSTANDARD=LVCMOS33; #NET "GCLK0" LOC="22" |IOSTANDARD=LVCMOS33; NET "CODEC_X2_CLK" TNM_NET = CODEC_X2_CLK; -TIMESPEC TS_codec_x2_data = PERIOD "CODEC_X2_CLK" 50 ns; +TIMESPEC TS_codec_x2_data = PERIOD "CODEC_X2_CLK" 25 ns; NET "DA<7>" LOC="35" |IOSTANDARD=LVCMOS33; NET "DA<6>" LOC="36" |IOSTANDARD=LVCMOS33; From d628e2d09cfdd9b64b919cf1c48d7e279e06d12f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 Sep 2013 16:22:39 -0700 Subject: [PATCH 084/200] Add CODEC_CLK to adc_data constraint group. --- firmware/cpld/sgpio_if/top.ucf | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/cpld/sgpio_if/top.ucf b/firmware/cpld/sgpio_if/top.ucf index f3b7b65b..f4421b3f 100755 --- a/firmware/cpld/sgpio_if/top.ucf +++ b/firmware/cpld/sgpio_if/top.ucf @@ -96,6 +96,7 @@ INST "DA<4>" TNM=adc_data; INST "DA<5>" TNM=adc_data; INST "DA<6>" TNM=adc_data; INST "DA<7>" TNM=adc_data; +INST "CODEC_CLK" TNM=adc_data; TIMESPEC "TS_adc_data" = FROM "adc_data" TO "CODEC_X2_CLK" 16 ns; From 7075cc6c1cc5a935e7dd504018bc4e2afccae3cd Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 11 Sep 2013 16:52:11 -0700 Subject: [PATCH 085/200] More constraints clean-up: Associating timing specification groups on the NET declarations. Updated setup/hold constraints -- old constraints were incomplete and possibly incorrect, though I'm still not *positive*. --- firmware/cpld/sgpio_if/top.ucf | 122 ++++++++------------------------- firmware/cpld/sgpio_if/top.vhd | 8 +-- 2 files changed, 30 insertions(+), 100 deletions(-) diff --git a/firmware/cpld/sgpio_if/top.ucf b/firmware/cpld/sgpio_if/top.ucf index f4421b3f..db741928 100755 --- a/firmware/cpld/sgpio_if/top.ucf +++ b/firmware/cpld/sgpio_if/top.ucf @@ -18,110 +18,46 @@ # the Free Software Foundation, Inc., 51 Franklin Street, # Boston, MA 02110-1301, USA. -NET "CODEC_CLK" LOC="23" |IOSTANDARD=LVCMOS33; +NET "CODEC_CLK" LOC="23" |IOSTANDARD=LVCMOS33 | TNM=adc_data; NET "CODEC_X2_CLK" LOC="27" |IOSTANDARD=LVCMOS33; -#NET "GCLK0" LOC="22" |IOSTANDARD=LVCMOS33; NET "CODEC_X2_CLK" TNM_NET = CODEC_X2_CLK; TIMESPEC TS_codec_x2_data = PERIOD "CODEC_X2_CLK" 25 ns; -NET "DA<7>" LOC="35" |IOSTANDARD=LVCMOS33; -NET "DA<6>" LOC="36" |IOSTANDARD=LVCMOS33; -NET "DA<5>" LOC="37" |IOSTANDARD=LVCMOS33; -NET "DA<4>" LOC="39" |IOSTANDARD=LVCMOS33; -NET "DA<3>" LOC="40" |IOSTANDARD=LVCMOS33; -NET "DA<2>" LOC="41" |IOSTANDARD=LVCMOS33; -NET "DA<1>" LOC="42" |IOSTANDARD=LVCMOS33; -NET "DA<0>" LOC="43" |IOSTANDARD=LVCMOS33; +NET "DA<7>" LOC="35" |IOSTANDARD=LVCMOS33 | TNM=adc_data; +NET "DA<6>" LOC="36" |IOSTANDARD=LVCMOS33 | TNM=adc_data; +NET "DA<5>" LOC="37" |IOSTANDARD=LVCMOS33 | TNM=adc_data; +NET "DA<4>" LOC="39" |IOSTANDARD=LVCMOS33 | TNM=adc_data; +NET "DA<3>" LOC="40" |IOSTANDARD=LVCMOS33 | TNM=adc_data; +NET "DA<2>" LOC="41" |IOSTANDARD=LVCMOS33 | TNM=adc_data; +NET "DA<1>" LOC="42" |IOSTANDARD=LVCMOS33 | TNM=adc_data; +NET "DA<0>" LOC="43" |IOSTANDARD=LVCMOS33 | TNM=adc_data; -NET "DD<9>" LOC="17" |IOSTANDARD=LVCMOS33; -NET "DD<8>" LOC="18" |IOSTANDARD=LVCMOS33; -NET "DD<7>" LOC="19" |IOSTANDARD=LVCMOS33; -NET "DD<6>" LOC="24" |IOSTANDARD=LVCMOS33; -NET "DD<5>" LOC="28" |IOSTANDARD=LVCMOS33; -NET "DD<4>" LOC="29" |IOSTANDARD=LVCMOS33; -NET "DD<3>" LOC="30" |IOSTANDARD=LVCMOS33; -NET "DD<2>" LOC="32" |IOSTANDARD=LVCMOS33; +NET "DD<9>" LOC="17" |IOSTANDARD=LVCMOS33 | TNM=dac_data; +NET "DD<8>" LOC="18" |IOSTANDARD=LVCMOS33 | TNM=dac_data; +NET "DD<7>" LOC="19" |IOSTANDARD=LVCMOS33 | TNM=dac_data; +NET "DD<6>" LOC="24" |IOSTANDARD=LVCMOS33 | TNM=dac_data; +NET "DD<5>" LOC="28" |IOSTANDARD=LVCMOS33 | TNM=dac_data; +NET "DD<4>" LOC="29" |IOSTANDARD=LVCMOS33 | TNM=dac_data; +NET "DD<3>" LOC="30" |IOSTANDARD=LVCMOS33 | TNM=dac_data; +NET "DD<2>" LOC="32" |IOSTANDARD=LVCMOS33 | TNM=dac_data; NET "DD<1>" LOC="33" |IOSTANDARD=LVCMOS33; NET "DD<0>" LOC="34" |IOSTANDARD=LVCMOS33; -NET "B1AUX<16>" LOC="60" |IOSTANDARD=LVCMOS33; -NET "B1AUX<15>" LOC="58" |IOSTANDARD=LVCMOS33; -NET "B1AUX<14>" LOC="56" |IOSTANDARD=LVCMOS33; -NET "B1AUX<13>" LOC="55" |IOSTANDARD=LVCMOS33; -NET "B1AUX<12>" LOC="53" |IOSTANDARD=LVCMOS33; -NET "B1AUX<11>" LOC="52" |IOSTANDARD=LVCMOS33; -NET "B1AUX<10>" LOC="50" |IOSTANDARD=LVCMOS33; -NET "B1AUX<9>" LOC="49" |IOSTANDARD=LVCMOS33; - -#NET "SGPIO<15>" LOC="78" |IOSTANDARD=LVCMOS33; -#NET "SGPIO<14>" LOC="81" |IOSTANDARD=LVCMOS33; -#NET "SGPIO<13>" LOC="90" |IOSTANDARD=LVCMOS33; -#NET "SGPIO<12>" LOC="70" |IOSTANDARD=LVCMOS33; NET "HOST_DIRECTION" LOC="71" |IOSTANDARD=LVCMOS33; NET "HOST_DISABLE" LOC="76" |IOSTANDARD=LVCMOS33; -NET "HOST_CAPTURE" LOC="91" |IOSTANDARD=LVCMOS33; -#NET "HOST_CLK" LOC="68" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<7>" LOC="77" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<6>" LOC="61" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<5>" LOC="64" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<4>" LOC="67" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<3>" LOC="72" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<2>" LOC="74" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<1>" LOC="79" |IOSTANDARD=LVCMOS33; -NET "HOST_DATA<0>" LOC="89" |IOSTANDARD=LVCMOS33; +NET "HOST_CAPTURE" LOC="91" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<7>" LOC="77" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<6>" LOC="61" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<5>" LOC="64" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<4>" LOC="67" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<3>" LOC="72" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<2>" LOC="74" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<1>" LOC="79" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DATA<0>" LOC="89" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "B2AUX<16>" LOC="92" |IOSTANDARD=LVCMOS33; -NET "B2AUX<15>" LOC="94" |IOSTANDARD=LVCMOS33; -NET "B2AUX<14>" LOC="97" |IOSTANDARD=LVCMOS33; -NET "B2AUX<13>" LOC="99" |IOSTANDARD=LVCMOS33; -NET "B2AUX<12>" LOC="1" |IOSTANDARD=LVCMOS33; -NET "B2AUX<11>" LOC="2" |IOSTANDARD=LVCMOS33; -NET "B2AUX<10>" LOC="3" |IOSTANDARD=LVCMOS33; -NET "B2AUX<9>" LOC="4" |IOSTANDARD=LVCMOS33; -NET "B2AUX<8>" LOC="6" |IOSTANDARD=LVCMOS33; -NET "B2AUX<7>" LOC="7" |IOSTANDARD=LVCMOS33; -NET "B2AUX<6>" LOC="8" |IOSTANDARD=LVCMOS33; -NET "B2AUX<5>" LOC="9" |IOSTANDARD=LVCMOS33; -NET "B2AUX<4>" LOC="10" |IOSTANDARD=LVCMOS33; -NET "B2AUX<3>" LOC="11" |IOSTANDARD=LVCMOS33; -NET "B2AUX<2>" LOC="12" |IOSTANDARD=LVCMOS33; -NET "B2AUX<1>" LOC="13" |IOSTANDARD=LVCMOS33; +TIMEGRP "adc_data" OFFSET = IN 16 ns BEFORE "CODEC_X2_CLK"; -INST "DA<0>" TNM=adc_data; -INST "DA<1>" TNM=adc_data; -INST "DA<2>" TNM=adc_data; -INST "DA<3>" TNM=adc_data; -INST "DA<4>" TNM=adc_data; -INST "DA<5>" TNM=adc_data; -INST "DA<6>" TNM=adc_data; -INST "DA<7>" TNM=adc_data; -INST "CODEC_CLK" TNM=adc_data; +TIMEGRP "dac_data" OFFSET = OUT 15 ns AFTER "CODEC_X2_CLK"; -TIMESPEC "TS_adc_data" = FROM "adc_data" TO "CODEC_X2_CLK" 16 ns; - -INST "DD<0>" TNM=dac_data; -INST "DD<1>" TNM=dac_data; -INST "DD<2>" TNM=dac_data; -INST "DD<3>" TNM=dac_data; -INST "DD<4>" TNM=dac_data; -INST "DD<5>" TNM=dac_data; -INST "DD<6>" TNM=dac_data; -INST "DD<7>" TNM=dac_data; -INST "DD<8>" TNM=dac_data; -INST "DD<9>" TNM=dac_data; - -TIMESPEC "TS_dac_data" = FROM "CODEC_X2_CLK" TO "dac_data" 15 ns; - -INST "HOST_DATA<7>" TNM=to_host; -INST "HOST_DATA<6>" TNM=to_host; -INST "HOST_DATA<5>" TNM=to_host; -INST "HOST_DATA<4>" TNM=to_host; -INST "HOST_DATA<3>" TNM=to_host; -INST "HOST_DATA<2>" TNM=to_host; -INST "HOST_DATA<1>" TNM=to_host; -INST "HOST_DATA<0>" TNM=to_host; -INST "HOST_CAPTURE" TNM=to_host; - -#TIMESPEC "TS_to_host" = FROM "to_host" TO "HOST_CLK" 6 ns; -#TIMEGRP "to_host" OFFSET=OUT 6 ns AFTER "HOST_CLK"; +TIMEGRP "to_host" OFFSET = OUT 20 ns AFTER "CODEC_X2_CLK"; diff --git a/firmware/cpld/sgpio_if/top.vhd b/firmware/cpld/sgpio_if/top.vhd index cef6ff3a..a1507238 100755 --- a/firmware/cpld/sgpio_if/top.vhd +++ b/firmware/cpld/sgpio_if/top.vhd @@ -36,10 +36,7 @@ entity top is DD : out std_logic_vector(9 downto 0); CODEC_CLK : in std_logic; - CODEC_X2_CLK : in std_logic; - - B1AUX : inout std_logic_vector(16 downto 9); - B2AUX : inout std_logic_vector(16 downto 1) + CODEC_X2_CLK : in std_logic ); end top; @@ -62,9 +59,6 @@ architecture Behavioral of top is begin - B1AUX <= (others => '0'); - B2AUX <= (others => '0'); - ------------------------------------------------ -- Codec interface From 21ad0778d274e13ac16373373ceb310121c28a68 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 2 Sep 2013 19:40:29 -0400 Subject: [PATCH 086/200] usb_descriptor: Fix whitespace --- firmware/hackrf_usb/usb_descriptor.c | 188 +++++++++++++-------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index e27218bb..d0a9e9d8 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -38,117 +38,117 @@ #define USB_STRING_LANGID (0x0409) uint8_t usb_descriptor_device[] = { - 18, // bLength - USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType - USB_WORD(0x0200), // bcdUSB - 0x00, // bDeviceClass - 0x00, // bDeviceSubClass - 0x00, // bDeviceProtocol - USB_MAX_PACKET0, // bMaxPacketSize0 - USB_WORD(USB_VENDOR_ID), // idVendor - USB_WORD(USB_PRODUCT_ID), // idProduct - USB_WORD(0x0100), // bcdDevice - 0x01, // iManufacturer - 0x02, // iProduct - 0x00, // iSerialNumber - 0x01 // bNumConfigurations + 18, // bLength + USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType + USB_WORD(0x0200), // bcdUSB + 0x00, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + USB_MAX_PACKET0, // bMaxPacketSize0 + USB_WORD(USB_VENDOR_ID), // idVendor + USB_WORD(USB_PRODUCT_ID), // idProduct + USB_WORD(0x0100), // bcdDevice + 0x01, // iManufacturer + 0x02, // iProduct + 0x00, // iSerialNumber + 0x01 // bNumConfigurations }; uint8_t usb_descriptor_device_qualifier[] = { - 10, // bLength - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, // bDescriptorType - USB_WORD(0x0200), // bcdUSB - 0x00, // bDeviceClass - 0x00, // bDeviceSubClass - 0x00, // bDeviceProtocol - 64, // bMaxPacketSize0 - 0x01, // bNumOtherSpeedConfigurations - 0x00 // bReserved + 10, // bLength + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, // bDescriptorType + USB_WORD(0x0200), // bcdUSB + 0x00, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + 64, // bMaxPacketSize0 + 0x01, // bNumOtherSpeedConfigurations + 0x00 // bReserved }; uint8_t usb_descriptor_configuration_full_speed[] = { - 9, // bLength - USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType - USB_WORD(32), // wTotalLength - 0x01, // bNumInterfaces - 0x01, // bConfigurationValue - 0x00, // iConfiguration - 0x80, // bmAttributes: USB-powered - 250, // bMaxPower: 500mA - - 9, // bLength - USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints - 0xFF, // bInterfaceClass: vendor-specific - 0xFF, // bInterfaceSubClass - 0xFF, // bInterfaceProtocol: vendor-specific - 0x00, // iInterface - - 7, // bLength - USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType - USB_BULK_IN_EP_ADDR, // bEndpointAddress - 0x02, // bmAttributes: BULK - USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize - 0x00, // bInterval: no NAK - - 7, // bLength - USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType - USB_BULK_OUT_EP_ADDR, // bEndpointAddress - 0x02, // bmAttributes: BULK - USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize - 0x00, // bInterval: no NAK + 9, // bLength + USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType + USB_WORD(32), // wTotalLength + 0x01, // bNumInterfaces + 0x01, // bConfigurationValue + 0x00, // iConfiguration + 0x80, // bmAttributes: USB-powered + 250, // bMaxPower: 500mA + + 9, // bLength + USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0xFF, // bInterfaceClass: vendor-specific + 0xFF, // bInterfaceSubClass + 0xFF, // bInterfaceProtocol: vendor-specific + 0x00, // iInterface + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_IN_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_OUT_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize + 0x00, // bInterval: no NAK 0, // TERMINATOR }; uint8_t usb_descriptor_configuration_high_speed[] = { - 9, // bLength - USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType - USB_WORD(32), // wTotalLength - 0x01, // bNumInterfaces - 0x01, // bConfigurationValue - 0x00, // iConfiguration - 0x80, // bmAttributes: USB-powered - 250, // bMaxPower: 500mA - - 9, // bLength - USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints - 0xFF, // bInterfaceClass: vendor-specific - 0xFF, // bInterfaceSubClass - 0xFF, // bInterfaceProtocol: vendor-specific - 0x00, // iInterface - - 7, // bLength - USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType - USB_BULK_IN_EP_ADDR, // bEndpointAddress - 0x02, // bmAttributes: BULK - USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize - 0x00, // bInterval: no NAK - - 7, // bLength - USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType - USB_BULK_OUT_EP_ADDR, // bEndpointAddress - 0x02, // bmAttributes: BULK - USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize - 0x00, // bInterval: no NAK + 9, // bLength + USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType + USB_WORD(32), // wTotalLength + 0x01, // bNumInterfaces + 0x01, // bConfigurationValue + 0x00, // iConfiguration + 0x80, // bmAttributes: USB-powered + 250, // bMaxPower: 500mA + + 9, // bLength + USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0xFF, // bInterfaceClass: vendor-specific + 0xFF, // bInterfaceSubClass + 0xFF, // bInterfaceProtocol: vendor-specific + 0x00, // iInterface + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_IN_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_OUT_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize + 0x00, // bInterval: no NAK 0, // TERMINATOR }; uint8_t usb_descriptor_string_languages[] = { - 0x04, // bLength - USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType - USB_WORD(USB_STRING_LANGID), // wLANGID + 0x04, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + USB_WORD(USB_STRING_LANGID), // wLANGID }; uint8_t usb_descriptor_string_manufacturer[] = { - 40, // bLength - USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + 40, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType 'G', 0x00, 'r', 0x00, 'e', 0x00, @@ -171,8 +171,8 @@ uint8_t usb_descriptor_string_manufacturer[] = { }; uint8_t usb_descriptor_string_product[] = { - 14, // bLength - USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + 14, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType 'H', 0x00, 'a', 0x00, 'c', 0x00, From 1a448900954da1d51d80cd6b2879402e1218fcc8 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 12:47:08 -0400 Subject: [PATCH 087/200] usb_descriptor: Add description strings for configurations --- firmware/hackrf_usb/usb_descriptor.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index d0a9e9d8..c9f26ce7 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -72,7 +72,7 @@ uint8_t usb_descriptor_configuration_full_speed[] = { USB_WORD(32), // wTotalLength 0x01, // bNumInterfaces 0x01, // bConfigurationValue - 0x00, // iConfiguration + 0x03, // iConfiguration 0x80, // bmAttributes: USB-powered 250, // bMaxPower: 500mA @@ -109,7 +109,7 @@ uint8_t usb_descriptor_configuration_high_speed[] = { USB_WORD(32), // wTotalLength 0x01, // bNumInterfaces 0x01, // bConfigurationValue - 0x00, // iConfiguration + 0x03, // iConfiguration 0x80, // bmAttributes: USB-powered 250, // bMaxPower: 500mA @@ -181,10 +181,27 @@ uint8_t usb_descriptor_string_product[] = { 'F', 0x00, }; +uint8_t usb_descriptor_string_config1_description[] = { + 24, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + 'T', 0x00, + 'r', 0x00, + 'a', 0x00, + 'n', 0x00, + 's', 0x00, + 'c', 0x00, + 'e', 0x00, + 'i', 0x00, + 'v', 0x00, + 'e', 0x00, + 'r', 0x00, +}; + uint8_t* const usb_descriptor_strings[] = { usb_descriptor_string_languages, usb_descriptor_string_manufacturer, usb_descriptor_string_product, + usb_descriptor_string_config1_description, 0, // TERMINATOR }; From 24d5a5c4f1fae6d88b7c1569faa40c097b1299b9 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Fri, 28 Jun 2013 21:30:46 -0400 Subject: [PATCH 088/200] usb: Add usb_endpoint_append_td This implements the procedure for adding a TD to the end of an active queue described in UM10503 Section 23.10.11.3. --- firmware/hackrf_usb/usb.c | 33 +++++++++++++++++++++++++++++++++ firmware/hackrf_usb/usb.h | 6 ++++++ 2 files changed, 39 insertions(+) diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 8396e1bf..02fb81c3 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -195,6 +195,39 @@ void usb_endpoint_prime( USB0_ENDPTPRIME = USB0_ENDPTPRIME_PERB(1 << endpoint_number); } } + +// Schedule an already filled-up transfer descriptor for execution on +// the given endpoint. Note that this requires that one knows the tail +// of the endpoint's TD queue +void usb_endpoint_append_td( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const tail_td, + usb_transfer_descriptor_t* const new_td +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + bool done; + + tail_td->next_dtd_pointer = new_td; + + do { + if( usb_endpoint_is_in(endpoint->address) ) { + if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number) ) + return; + } else { + if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number) ) + return; + } + + USB0_USBCMD_D |= USB0_USBCMD_D_ATDTW; + done = usb_endpoint_is_ready(endpoint); + } while (!(USB0_USBCMD_D & USB0_USBCMD_D_ATDTW)); + + USB0_USBCMD_D &= ~USB0_USBCMD_D_ATDTW; + if(!done) { + usb_endpoint_prime(endpoint, new_td); + } +} + /* static bool usb_endpoint_is_priming( const usb_endpoint_t* const endpoint diff --git a/firmware/hackrf_usb/usb.h b/firmware/hackrf_usb/usb.h index 4b1d50f4..94372e0c 100644 --- a/firmware/hackrf_usb/usb.h +++ b/firmware/hackrf_usb/usb.h @@ -92,4 +92,10 @@ void usb_endpoint_prime( usb_transfer_descriptor_t* const first_td ); +void usb_endpoint_append_td( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const tail_td, + usb_transfer_descriptor_t* const new_td +); + #endif//__USB_H__ From 500aa5888c2ffef1540c2b15c7f2fd3d8d10cbb7 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 2 Sep 2013 19:22:27 -0400 Subject: [PATCH 089/200] usb_queue: Introduce queue management --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/usb_queue.c | 227 ++++++++++++++++++++++++++++++++ firmware/hackrf_usb/usb_queue.h | 90 +++++++++++++ 3 files changed, 318 insertions(+) create mode 100644 firmware/hackrf_usb/usb_queue.c create mode 100644 firmware/hackrf_usb/usb_queue.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 3d2b4d53..20a97295 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -27,6 +27,7 @@ SRC = $(BINARY).c \ usb_request.c \ usb_standard_request.c \ usb_descriptor.c \ + usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ ../common/sgpio.c \ diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/hackrf_usb/usb_queue.c new file mode 100644 index 00000000..1b79e829 --- /dev/null +++ b/firmware/hackrf_usb/usb_queue.c @@ -0,0 +1,227 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Ben Gamari + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include +#include + +#include "usb.h" +#include "usb_queue.h" + +usb_queue_t* endpoint_queues[12] = {}; + +#define USB_ENDPOINT_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) + +static usb_queue_t* endpoint_queue( + const usb_endpoint_t* const endpoint +) { + uint32_t index = USB_ENDPOINT_INDEX(endpoint->address); + if (endpoint_queues[index] == NULL) while (1); + return endpoint_queues[index]; +} + +void usb_queue_init( + usb_queue_t* const queue +) { + uint32_t index = USB_ENDPOINT_INDEX(queue->endpoint->address); + if (endpoint_queues[index] != NULL) while (1); + endpoint_queues[index] = queue; + + usb_transfer_t* t = queue->free_transfers; + for (unsigned int i=0; i < queue->pool_size - 1; i++, t++) { + t->next = t+1; + t->queue = queue; + } + t->next = NULL; + t->queue = queue; +} + +/* Allocate a transfer */ +static usb_transfer_t* allocate_transfer( + usb_queue_t* const queue +) { + bool aborted; + usb_transfer_t* transfer; + if (queue->free_transfers == NULL) + return NULL; + + do { + transfer = (void *) __ldrex((uint32_t *) &queue->free_transfers); + aborted = __strex((uint32_t) transfer->next, (uint32_t *) &queue->free_transfers); + } while (aborted); + transfer->next = NULL; + return transfer; +} + +/* Place a transfer in the free list */ +static void free_transfer(usb_transfer_t* const transfer) +{ + usb_queue_t* const queue = transfer->queue; + bool aborted; + do { + transfer->next = (void *) __ldrex((uint32_t *) &queue->free_transfers); + aborted = __strex((uint32_t) transfer, (uint32_t *) &queue->free_transfers); + } while (aborted); +} + +/* Add a transfer to the end of an endpoint's queue. Returns the old + * tail or NULL is the queue was empty + */ +static usb_transfer_t* endpoint_queue_transfer( + usb_transfer_t* const transfer +) { + usb_queue_t* const queue = transfer->queue; + transfer->next = NULL; + if (queue->active != NULL) { + usb_transfer_t* t = queue->active; + while (t->next != NULL) t = t->next; + t->next = transfer; + return t; + } else { + queue->active = transfer; + return NULL; + } +} + +static void usb_queue_flush_queue(usb_queue_t* const queue) +{ + cm_disable_interrupts(); + while (queue->active) { + usb_transfer_t* transfer = queue->active; + queue->active = transfer->next; + free_transfer(transfer); + } + cm_enable_interrupts(); +} + +void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint) +{ + usb_queue_flush_queue(endpoint_queue(endpoint)); +} + +int usb_transfer_schedule( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length, + const transfer_completion_cb completion_cb, + void* const user_data +) { + usb_queue_t* const queue = endpoint_queue(endpoint); + usb_transfer_t* const transfer = allocate_transfer(queue); + if (transfer == NULL) return -1; + usb_transfer_descriptor_t* const td = &transfer->td; + + // Configure the transfer descriptor + td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + td->total_bytes = + USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) + | USB_TD_DTD_TOKEN_IOC + | USB_TD_DTD_TOKEN_MULTO(0) + | USB_TD_DTD_TOKEN_STATUS_ACTIVE + ; + td->buffer_pointer_page[0] = (uint32_t)data; + td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; + td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; + td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; + td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; + + // Fill in transfer fields + transfer->maximum_length = maximum_length; + transfer->completion_cb = completion_cb; + transfer->user_data = user_data; + + cm_disable_interrupts(); + usb_transfer_t* tail = endpoint_queue_transfer(transfer); + if (tail == NULL) { + // The queue is currently empty, we need to re-prime + usb_endpoint_schedule_wait(queue->endpoint, &transfer->td); + } else { + // The queue is currently running, try to append + usb_endpoint_schedule_append(queue->endpoint, &tail->td, &transfer->td); + } + cm_enable_interrupts(); + return 0; +} + +int usb_transfer_schedule_block( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length, + const transfer_completion_cb completion_cb, + void* const user_data +) { + int ret; + do { + ret = usb_transfer_schedule(endpoint, data, maximum_length, + completion_cb, user_data); + } while (ret == -1); + return 0; +} + +int usb_transfer_schedule_ack( + const usb_endpoint_t* const endpoint +) { + return usb_transfer_schedule_block(endpoint, 0, 0, NULL, NULL); +} + +/* Called when an endpoint might have completed a transfer */ +void usb_queue_transfer_complete(usb_endpoint_t* const endpoint) +{ + usb_queue_t* const queue = endpoint_queue(endpoint); + if (queue == NULL) while(1); // Uh oh + usb_transfer_t* transfer = queue->active; + + while (transfer != NULL) { + uint8_t status = transfer->td.total_bytes; + + // Check for failures + if ( status & USB_TD_DTD_TOKEN_STATUS_HALTED + || status & USB_TD_DTD_TOKEN_STATUS_BUFFER_ERROR + || status & USB_TD_DTD_TOKEN_STATUS_TRANSACTION_ERROR) { + // TODO: Uh oh, do something useful here + while (1); + } + + // Still not finished + if (status & USB_TD_DTD_TOKEN_STATUS_ACTIVE) + break; + + // Advance the head. We need to do this before invoking the completion + // callback as it might attempt to schedule a new transfer + queue->active = transfer->next; + usb_transfer_t* next = transfer->next; + + // Invoke completion callback + unsigned int total_bytes = (transfer->td.total_bytes & USB_TD_DTD_TOKEN_TOTAL_BYTES_MASK) >> USB_TD_DTD_TOKEN_TOTAL_BYTES_SHIFT; + unsigned int transferred = transfer->maximum_length - total_bytes; + if (transfer->completion_cb) + transfer->completion_cb(transfer->user_data, transferred); + + // Advance head and free transfer + free_transfer(transfer); + transfer = next; + } +} diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/hackrf_usb/usb_queue.h new file mode 100644 index 00000000..2332022c --- /dev/null +++ b/firmware/hackrf_usb/usb_queue.h @@ -0,0 +1,90 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Ben Gamari + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_QUEUE_H__ +#define __USB_QUEUE_H__ + +#include + +#include "usb_type.h" + +typedef struct _usb_transfer_t usb_transfer_t; +typedef struct _usb_queue_t usb_queue_t; +typedef void (*transfer_completion_cb)(void*, unsigned int); + +// This is an opaque datatype. Thou shall not touch these members. +struct _usb_transfer_t { + struct _usb_transfer_t* next; + usb_transfer_descriptor_t td ATTR_ALIGNED(64); + unsigned int maximum_length; + struct _usb_queue_t* queue; + transfer_completion_cb completion_cb; + void* user_data; +}; + +// This is an opaque datatype. Thou shall not touch these members. +struct _usb_queue_t { + struct usb_endpoint_t* endpoint; + const unsigned int pool_size; + usb_transfer_t* volatile free_transfers; + usb_transfer_t* volatile active; +}; + +#define USB_DEFINE_QUEUE(endpoint_name, _pool_size) \ + struct _usb_transfer_t endpoint_name##_transfers[_pool_size]; \ + struct _usb_queue_t endpoint_name##_queue = { \ + .endpoint = &endpoint_name, \ + .free_transfers = endpoint_name##_transfers, \ + .pool_size = _pool_size \ + }; + +void usb_queue_flush_endpoint(const usb_endpoint_t* const endpoint); + +int usb_transfer_schedule( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length, + const transfer_completion_cb completion_cb, + void* const user_data +); + +int usb_transfer_schedule_block( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length, + const transfer_completion_cb completion_cb, + void* const user_data +); + +int usb_transfer_schedule_ack( + const usb_endpoint_t* const endpoint +); + +void usb_queue_init( + usb_queue_t* const queue +); + +void usb_queue_transfer_complete( + usb_endpoint_t* const endpoint +); + +#endif//__USB_QUEUE_H__ From 693c26213476f10ddecfe115563ad1b3b04f5227 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 13:54:25 -0400 Subject: [PATCH 090/200] libhackrf: Stop streaming before killing transfer thread --- host/libhackrf/src/hackrf.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 7e36dc55..47ff055a 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1141,14 +1141,13 @@ int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn cal int ADDCALL hackrf_stop_rx(hackrf_device* device) { - int result1, result2; - result1 = kill_transfer_thread(device); - result2 = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF); - if (result2 != HACKRF_SUCCESS) + int result; + result = hackrf_set_transceiver_mode(device, HACKRF_TRANSCEIVER_MODE_OFF); + if (result != HACKRF_SUCCESS) { - return result2; + return result; } - return result1; + return kill_transfer_thread(device); } int ADDCALL hackrf_start_tx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* tx_ctx) From 4773ee5a53bf1767185a45ae0c8a423c81e59eec Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 13:54:56 -0400 Subject: [PATCH 091/200] hackrf_usb: Port to use usb_queue --- firmware/hackrf_usb/hackrf_usb.c | 189 ++++++++++----------- firmware/hackrf_usb/usb.c | 138 ++++++--------- firmware/hackrf_usb/usb.h | 17 +- firmware/hackrf_usb/usb_request.c | 3 + firmware/hackrf_usb/usb_standard_request.c | 22 ++- firmware/libopencm3 | 2 +- 6 files changed, 164 insertions(+), 207 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index a175ea3d..f077a014 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -39,6 +39,7 @@ #include "usb.h" #include "usb_type.h" +#include "usb_queue.h" #include "usb_request.h" #include "usb_descriptor.h" #include "usb_standard_request.h" @@ -49,9 +50,6 @@ uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; static volatile uint32_t usb_bulk_buffer_offset = 0; static const uint32_t usb_bulk_buffer_mask = 32768 - 1; -usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64); -const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]); - /* TODO remove this big buffer and use streaming for CPLD */ #define CPLD_XSVF_MAX_LEN (65536) uint8_t cpld_xsvf_buffer[CPLD_XSVF_MAX_LEN]; @@ -181,50 +179,6 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) return success; } -static void usb_init_buffers_bulk() { - usb_td_bulk[0].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - usb_td_bulk[0].total_bytes - = USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) - | USB_TD_DTD_TOKEN_MULTO(0) - ; - usb_td_bulk[0].buffer_pointer_page[0] = (uint32_t)&usb_bulk_buffer[0x0000]; - usb_td_bulk[0].buffer_pointer_page[1] = (uint32_t)&usb_bulk_buffer[0x1000]; - usb_td_bulk[0].buffer_pointer_page[2] = (uint32_t)&usb_bulk_buffer[0x2000]; - usb_td_bulk[0].buffer_pointer_page[3] = (uint32_t)&usb_bulk_buffer[0x3000]; - usb_td_bulk[0].buffer_pointer_page[4] = (uint32_t)&usb_bulk_buffer[0x4000]; - - usb_td_bulk[1].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - usb_td_bulk[1].total_bytes - = USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) - | USB_TD_DTD_TOKEN_MULTO(0) - ; - usb_td_bulk[1].buffer_pointer_page[0] = (uint32_t)&usb_bulk_buffer[0x4000]; - usb_td_bulk[1].buffer_pointer_page[1] = (uint32_t)&usb_bulk_buffer[0x5000]; - usb_td_bulk[1].buffer_pointer_page[2] = (uint32_t)&usb_bulk_buffer[0x6000]; - usb_td_bulk[1].buffer_pointer_page[3] = (uint32_t)&usb_bulk_buffer[0x7000]; - usb_td_bulk[1].buffer_pointer_page[4] = (uint32_t)&usb_bulk_buffer[0x8000]; -} - -void usb_endpoint_schedule_no_int( - const usb_endpoint_t* const endpoint, - usb_transfer_descriptor_t* const td -) { - // Ensure that endpoint is ready to be primed. - // It may have been flushed due to an aborted transaction. - // TODO: This should be preceded by a flush? - while( usb_endpoint_is_ready(endpoint) ); - - // Configure a transfer. - td->total_bytes = - USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) - /*| USB_TD_DTD_TOKEN_IOC*/ - | USB_TD_DTD_TOKEN_MULTO(0) - | USB_TD_DTD_TOKEN_STATUS_ACTIVE - ; - - usb_endpoint_prime(endpoint, td); -} - usb_configuration_t usb_configuration_high_speed = { .number = 1, .speed = USB_SPEED_HIGH, @@ -260,6 +214,7 @@ usb_endpoint_t usb_endpoint_control_out = { .setup_complete = usb_setup_complete, .transfer_complete = usb_control_out_complete, }; +USB_DEFINE_QUEUE(usb_endpoint_control_out, 4); usb_endpoint_t usb_endpoint_control_in = { .address = 0x80, @@ -269,6 +224,7 @@ usb_endpoint_t usb_endpoint_control_in = { .setup_complete = 0, .transfer_complete = usb_control_in_complete, }; +static USB_DEFINE_QUEUE(usb_endpoint_control_in, 4); // NOTE: Endpoint number for IN and OUT are different. I wish I had some // evidence that having BULK IN and OUT on separate endpoint numbers was @@ -280,8 +236,9 @@ usb_endpoint_t usb_endpoint_bulk_in = { .in = &usb_endpoint_bulk_in, .out = 0, .setup_complete = 0, - .transfer_complete = 0, + .transfer_complete = usb_queue_transfer_complete }; +static USB_DEFINE_QUEUE(usb_endpoint_bulk_in, 4); usb_endpoint_t usb_endpoint_bulk_out = { .address = 0x02, @@ -289,8 +246,9 @@ usb_endpoint_t usb_endpoint_bulk_out = { .in = 0, .out = &usb_endpoint_bulk_out, .setup_complete = 0, - .transfer_complete = 0, + .transfer_complete = usb_queue_transfer_complete }; +static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 4); void baseband_streaming_disable() { sgpio_cpld_stream_disable(); @@ -306,8 +264,6 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { transceiver_mode = new_transceiver_mode; - usb_init_buffers_bulk(); - if( transceiver_mode == TRANSCEIVER_MODE_RX ) { gpio_clear(PORT_LED1_3, PIN_LED3); gpio_set(PORT_LED1_3, PIN_LED2); @@ -339,7 +295,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { nvic_enable_irq(NVIC_SGPIO_IRQ); SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); - sgpio_cpld_stream_enable(); + sgpio_cpld_stream_enable(); } usb_request_status_t usb_vendor_request_set_transceiver_mode( @@ -352,7 +308,7 @@ usb_request_status_t usb_vendor_request_set_transceiver_mode( case TRANSCEIVER_MODE_RX: case TRANSCEIVER_MODE_TX: set_transceiver_mode(endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; @@ -370,7 +326,7 @@ usb_request_status_t usb_vendor_request_write_max2837( if( endpoint->setup.index < MAX2837_NUM_REGS ) { if( endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE ) { max2837_reg_write(endpoint->setup.index, endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } } @@ -389,8 +345,9 @@ usb_request_status_t usb_vendor_request_read_max2837( const uint16_t value = max2837_reg_read(endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 2); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -407,7 +364,7 @@ usb_request_status_t usb_vendor_request_write_si5351c( if( endpoint->setup.index < 256 ) { if( endpoint->setup.value < 256 ) { si5351c_write_single(endpoint->setup.index, endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } } @@ -425,8 +382,9 @@ usb_request_status_t usb_vendor_request_read_si5351c( if( endpoint->setup.index < 256 ) { const uint8_t value = si5351c_read_single(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -442,7 +400,7 @@ usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint32_t bandwidth = (endpoint->setup.index << 16) | endpoint->setup.value; if( baseband_filter_bandwidth_set(bandwidth) ) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -460,7 +418,7 @@ usb_request_status_t usb_vendor_request_write_rffc5071( if( endpoint->setup.index < RFFC5071_NUM_REGS ) { rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -481,8 +439,9 @@ usb_request_status_t usb_vendor_request_read_rffc5071( value = rffc5071_reg_read(endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 2); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -500,7 +459,7 @@ usb_request_status_t usb_vendor_request_erase_spiflash( w25q80bv_setup(); /* only chip erase is implemented */ w25q80bv_chip_erase(); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); //FIXME probably should undo w25q80bv_setup() } return USB_REQUEST_STATUS_OK; @@ -521,7 +480,8 @@ usb_request_status_t usb_vendor_request_write_spiflash( || ((addr + len) > W25Q80BV_NUM_BYTES)) { return USB_REQUEST_STATUS_STALL; } else { - usb_endpoint_schedule(endpoint->out, &spiflash_buffer[0], len); + usb_transfer_schedule_block(endpoint->out, &spiflash_buffer[0], len, + NULL, NULL); w25q80bv_setup(); return USB_REQUEST_STATUS_OK; } @@ -534,7 +494,7 @@ usb_request_status_t usb_vendor_request_write_spiflash( return USB_REQUEST_STATUS_STALL; } else { w25q80bv_program(addr, len, &spiflash_buffer[0]); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); //FIXME probably should undo w25q80bv_setup() return USB_REQUEST_STATUS_OK; } @@ -556,7 +516,7 @@ usb_request_status_t usb_vendor_request_read_spiflash( addr = (endpoint->setup.value << 16) | endpoint->setup.index; len = endpoint->setup.length; if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) - || ((addr + len) > W25Q80BV_NUM_BYTES)) { + || ((addr + len) > W25Q80BV_NUM_BYTES)) { return USB_REQUEST_STATUS_STALL; } else { /* TODO flush SPIFI "cache" before to read the SPIFI memory */ @@ -565,7 +525,8 @@ usb_request_status_t usb_vendor_request_read_spiflash( { spiflash_buffer[i] = u8_addr_pt[i]; } - usb_endpoint_schedule(endpoint->in, &spiflash_buffer[0], len); + usb_transfer_schedule_block(endpoint->in, &spiflash_buffer[0], len, + NULL, NULL); return USB_REQUEST_STATUS_OK; } } else if (stage == USB_TRANSFER_STAGE_DATA) @@ -579,7 +540,7 @@ usb_request_status_t usb_vendor_request_read_spiflash( return USB_REQUEST_STATUS_STALL; } else { - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } } else @@ -603,7 +564,8 @@ usb_request_status_t usb_vendor_request_write_cpld( // len is limited to 64KB 16bits no overflow can happen total_len = endpoint->setup.value; len = endpoint->setup.length; - usb_endpoint_schedule(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len); + usb_transfer_schedule_block(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len, + NULL, NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { @@ -619,7 +581,7 @@ usb_request_status_t usb_vendor_request_write_cpld( // TO FIX ACK shall be not delayed so much as cpld prog can take up to 5s. if(error == 0) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); /* blink LED1, LED2, and LED3 on success */ while (1) @@ -641,7 +603,7 @@ usb_request_status_t usb_vendor_request_write_cpld( } }else { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } } else @@ -655,8 +617,8 @@ usb_request_status_t usb_vendor_request_read_board_id( { if (stage == USB_TRANSFER_STAGE_SETUP) { endpoint->buffer[0] = BOARD_ID; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; } @@ -668,8 +630,8 @@ usb_request_status_t usb_vendor_request_read_version_string( if (stage == USB_TRANSFER_STAGE_SETUP) { length = (uint8_t)strlen(version_string); - usb_endpoint_schedule(endpoint->in, version_string, length); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, version_string, length, NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; } @@ -680,13 +642,14 @@ usb_request_status_t usb_vendor_request_set_freq( { if (stage == USB_TRANSFER_STAGE_SETUP) { - usb_endpoint_schedule(endpoint->out, &set_freq_params, sizeof(set_freq_params_t)); + usb_transfer_schedule_block(endpoint->out, &set_freq_params, sizeof(set_freq_params_t), + NULL, NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { if( set_freq(set_freq_params.freq_mhz, set_freq_params.freq_hz) ) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -702,13 +665,14 @@ usb_request_status_t usb_vendor_request_set_sample_rate_frac( { if (stage == USB_TRANSFER_STAGE_SETUP) { - usb_endpoint_schedule(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t)); + usb_transfer_schedule_block(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t), + NULL, NULL); return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { if( sample_rate_frac_set(set_sample_r_params.freq_hz * 2, set_sample_r_params.divider ) ) { - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_STALL; @@ -726,12 +690,12 @@ usb_request_status_t usb_vendor_request_set_amp_enable( case 0: switchctrl |= SWITCHCTRL_AMP_BYPASS; update_switches(); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; case 1: switchctrl &= ~SWITCHCTRL_AMP_BYPASS; update_switches(); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; @@ -776,20 +740,23 @@ usb_request_status_t usb_vendor_request_read_partid_serialno( read_partid_serialno.serial_no[3] = iap_cmd_res.status_res.iap_result[3]; length = (uint8_t)sizeof(read_partid_serialno_t); - usb_endpoint_schedule(endpoint->in, &read_partid_serialno, length); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &read_partid_serialno, length, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); } return USB_REQUEST_STATUS_OK; } usb_request_status_t usb_vendor_request_set_lna_gain( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) { if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_lna_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_OK; @@ -801,8 +768,9 @@ usb_request_status_t usb_vendor_request_set_vga_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_vga_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_OK; @@ -814,8 +782,9 @@ usb_request_status_t usb_vendor_request_set_txvga_gain( if( stage == USB_TRANSFER_STAGE_SETUP ) { const uint8_t value = max2837_set_txvga_gain(endpoint->setup.index); endpoint->buffer[0] = value; - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_OK; @@ -827,7 +796,7 @@ usb_request_status_t usb_vendor_request_set_if_freq( if( stage == USB_TRANSFER_STAGE_SETUP ) { MAX2837_FREQ_NOMINAL_HZ = (uint32_t)endpoint->setup.index * 1000 * 1000; set_freq(freq_mhz_cache, freq_hz_cache); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); } return USB_REQUEST_STATUS_OK; } @@ -966,10 +935,16 @@ int main(void) { enable_1v8_power(); cpu_clock_init(); + usb_set_configuration_changed_cb(usb_configuration_changed); usb_peripheral_reset(); usb_device_init(0, &usb_device); + usb_queue_init(&usb_endpoint_control_out_queue); + usb_queue_init(&usb_endpoint_control_in_queue); + usb_queue_init(&usb_endpoint_bulk_out_queue); + usb_queue_init(&usb_endpoint_bulk_in_queue); + usb_endpoint_init(&usb_endpoint_control_out); usb_endpoint_init(&usb_endpoint_control_in); @@ -977,7 +952,7 @@ int main(void) { usb_run(&usb_device); - ssp1_init(); + ssp1_init(); ssp1_set_mode_max5864(); max5864_xcvr(); @@ -996,21 +971,29 @@ int main(void) { while( usb_bulk_buffer_offset < 16384 ); // Set up IN transfer of buffer 0. - usb_endpoint_schedule_no_int( - (transceiver_mode == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_td_bulk[0] - ); + if (transceiver_mode != TRANSCEIVER_MODE_OFF) { + usb_transfer_schedule_block( + (transceiver_mode == TRANSCEIVER_MODE_RX) + ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, + &usb_bulk_buffer[0x0000], + 0x4000, + NULL, NULL + ); + } // Wait until buffer 1 is transmitted/received. while( usb_bulk_buffer_offset >= 16384 ); // Set up IN transfer of buffer 1. - usb_endpoint_schedule_no_int( - (transceiver_mode == TRANSCEIVER_MODE_RX) - ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, - &usb_td_bulk[1] - ); + if (transceiver_mode != TRANSCEIVER_MODE_OFF) { + usb_transfer_schedule_block( + (transceiver_mode == TRANSCEIVER_MODE_RX) + ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, + &usb_bulk_buffer[0x4000], + 0x4000, + NULL, NULL + ); + } } return 0; diff --git a/firmware/hackrf_usb/usb.c b/firmware/hackrf_usb/usb.c index 02fb81c3..3444e1c2 100644 --- a/firmware/hackrf_usb/usb.c +++ b/firmware/hackrf_usb/usb.c @@ -24,6 +24,7 @@ #include "usb.h" #include "usb_type.h" +#include "usb_queue.h" #include "usb_standard_request.h" #include @@ -34,10 +35,8 @@ usb_device_t* usb_device_usb0 = 0; usb_queue_head_t usb_qh[12] ATTR_ALIGNED(2048); -usb_transfer_descriptor_t usb_td[12] ATTR_ALIGNED(64); #define USB_QH_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) -#define USB_TD_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) usb_queue_head_t* usb_queue_head( const uint_fast8_t endpoint_address @@ -45,12 +44,6 @@ usb_queue_head_t* usb_queue_head( return &usb_qh[USB_QH_INDEX(endpoint_address)]; } -usb_transfer_descriptor_t* usb_transfer_descriptor( - const uint_fast8_t endpoint_address -) { - return &usb_td[USB_TD_INDEX(endpoint_address)]; -} - static usb_endpoint_t* usb_endpoint_from_address( const uint_fast8_t endpoint_address ) { @@ -98,25 +91,25 @@ static void usb_clear_all_pending_interrupts() { static void usb_wait_for_endpoint_priming_to_finish(const uint32_t mask) { // Wait until controller has parsed new transfer descriptors and prepared // receive buffers. - while( USB0_ENDPTPRIME & mask ); + while( USB0_ENDPTPRIME & mask ); } static void usb_flush_endpoints(const uint32_t mask) { // Clear any primed buffers. If a packet is in progress, that transfer // will continue until completion. - USB0_ENDPTFLUSH = mask; + USB0_ENDPTFLUSH = mask; } static void usb_wait_for_endpoint_flushing_to_finish(const uint32_t mask) { // Wait until controller has flushed all endpoints / cleared any primed // buffers. - while( USB0_ENDPTFLUSH & mask ); + while( USB0_ENDPTFLUSH & mask ); } static void usb_flush_primed_endpoints(const uint32_t mask) { - usb_wait_for_endpoint_priming_to_finish(mask); + usb_wait_for_endpoint_priming_to_finish(mask); usb_flush_endpoints(mask); - usb_wait_for_endpoint_flushing_to_finish(mask); + usb_wait_for_endpoint_flushing_to_finish(mask); } static void usb_flush_all_primed_endpoints() { @@ -171,6 +164,7 @@ void usb_endpoint_disable( } else { USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_RXE); } + usb_queue_flush_endpoint(endpoint); usb_endpoint_clear_pending_interrupts(endpoint); usb_endpoint_flush(endpoint); } @@ -196,39 +190,6 @@ void usb_endpoint_prime( } } -// Schedule an already filled-up transfer descriptor for execution on -// the given endpoint. Note that this requires that one knows the tail -// of the endpoint's TD queue -void usb_endpoint_append_td( - const usb_endpoint_t* const endpoint, - usb_transfer_descriptor_t* const tail_td, - usb_transfer_descriptor_t* const new_td -) { - const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); - bool done; - - tail_td->next_dtd_pointer = new_td; - - do { - if( usb_endpoint_is_in(endpoint->address) ) { - if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number) ) - return; - } else { - if (USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number) ) - return; - } - - USB0_USBCMD_D |= USB0_USBCMD_D_ATDTW; - done = usb_endpoint_is_ready(endpoint); - } while (!(USB0_USBCMD_D & USB0_USBCMD_D_ATDTW)); - - USB0_USBCMD_D &= ~USB0_USBCMD_D_ATDTW; - if(!done) { - usb_endpoint_prime(endpoint, new_td); - } -} - -/* static bool usb_endpoint_is_priming( const usb_endpoint_t* const endpoint ) { @@ -239,11 +200,57 @@ static bool usb_endpoint_is_priming( return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number); } } -*/ + +// Schedule an already filled-in transfer descriptor for execution on +// the given endpoint, waiting until the endpoint has finished. +void usb_endpoint_schedule_wait( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const td +) { + // Ensure that endpoint is ready to be primed. + // It may have been flushed due to an aborted transaction. + // TODO: This should be preceded by a flush? + while( usb_endpoint_is_ready(endpoint) ); + + td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + + usb_endpoint_prime(endpoint, td); +} + +// Schedule an already filled-in transfer descriptor for execution on +// the given endpoint, appending to the end of the endpoint's queue if +// there are pending TDs. Note that this requires that one knows the +// tail of the endpoint's TD queue. Moreover, the user is responsible +// for setting the TERMINATE bit of next_dtd_pointer if needed. +void usb_endpoint_schedule_append( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const tail_td, + usb_transfer_descriptor_t* const new_td +) { + bool done; + + tail_td->next_dtd_pointer = new_td; + + if (usb_endpoint_is_priming(endpoint)) { + return; + } + + do { + USB0_USBCMD_D |= USB0_USBCMD_D_ATDTW; + done = usb_endpoint_is_ready(endpoint); + } while (!(USB0_USBCMD_D & USB0_USBCMD_D_ATDTW)); + + USB0_USBCMD_D &= ~USB0_USBCMD_D_ATDTW; + if(!done) { + usb_endpoint_prime(endpoint, new_td); + } +} + void usb_endpoint_flush( const usb_endpoint_t* const endpoint ) { const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + usb_queue_flush_endpoint(endpoint); if( usb_endpoint_is_in(endpoint->address) ) { usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FETB(1 << endpoint_number)); } else { @@ -543,48 +550,13 @@ void usb_endpoint_init( usb_endpoint_enable(endpoint); } -void usb_endpoint_schedule( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length -) { - usb_transfer_descriptor_t* const td = usb_transfer_descriptor(endpoint->address); - - // Ensure that endpoint is ready to be primed. - // It may have been flushed due to an aborted transaction. - // TODO: This should be preceded by a flush? - while( usb_endpoint_is_ready(endpoint) ); - - // Configure a transfer. - td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; - td->total_bytes = - USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) - | USB_TD_DTD_TOKEN_IOC - | USB_TD_DTD_TOKEN_MULTO(0) - | USB_TD_DTD_TOKEN_STATUS_ACTIVE - ; - td->buffer_pointer_page[0] = (uint32_t)data; - td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; - td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; - td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; - td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; - - usb_endpoint_prime(endpoint, td); -} - -void usb_endpoint_schedule_ack( - const usb_endpoint_t* const endpoint -) { - usb_endpoint_schedule(endpoint, 0, 0); -} - static void usb_check_for_setup_events() { const uint32_t endptsetupstat = usb_get_endpoint_setup_status(); if( endptsetupstat ) { for( uint_fast8_t i=0; i<6; i++ ) { const uint32_t endptsetupstat_bit = USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT(1 << i); if( endptsetupstat & endptsetupstat_bit ) { - usb_endpoint_t* const endpoint = + usb_endpoint_t* const endpoint = usb_endpoint_from_address( usb_endpoint_address(USB_TRANSFER_DIRECTION_OUT, i) ); diff --git a/firmware/hackrf_usb/usb.h b/firmware/hackrf_usb/usb.h index 94372e0c..a6fa6a92 100644 --- a/firmware/hackrf_usb/usb.h +++ b/firmware/hackrf_usb/usb.h @@ -61,16 +61,6 @@ void usb_endpoint_init( const usb_endpoint_t* const endpoint ); -void usb_endpoint_schedule( - const usb_endpoint_t* const endpoint, - void* const data, - const uint32_t maximum_length -); - -void usb_endpoint_schedule_ack( - const usb_endpoint_t* const endpoint -); - void usb_endpoint_stall( const usb_endpoint_t* const endpoint ); @@ -92,7 +82,12 @@ void usb_endpoint_prime( usb_transfer_descriptor_t* const first_td ); -void usb_endpoint_append_td( +void usb_endpoint_schedule_wait( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const td +); + +void usb_endpoint_schedule_append( const usb_endpoint_t* const endpoint, usb_transfer_descriptor_t* const tail_td, usb_transfer_descriptor_t* const new_td diff --git a/firmware/hackrf_usb/usb_request.c b/firmware/hackrf_usb/usb_request.c index 25132fd4..f9226c7f 100644 --- a/firmware/hackrf_usb/usb_request.c +++ b/firmware/hackrf_usb/usb_request.c @@ -21,6 +21,7 @@ #include "usb.h" #include "usb_request.h" +#include "usb_queue.h" #include @@ -75,6 +76,7 @@ void usb_control_out_complete( } else { usb_request(endpoint, USB_TRANSFER_STAGE_DATA); } + usb_queue_transfer_complete(endpoint); } void usb_control_in_complete( @@ -87,5 +89,6 @@ void usb_control_in_complete( } else { usb_request(endpoint, USB_TRANSFER_STAGE_STATUS); } + usb_queue_transfer_complete(endpoint); } diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index cfb58ee0..6f589b3c 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -27,6 +27,7 @@ #include "usb.h" #include "usb_type.h" #include "usb_descriptor.h" +#include "usb_queue.h" const uint8_t* usb_endpoint_descriptor( const usb_endpoint_t* const endpoint @@ -99,9 +100,11 @@ bool usb_set_configuration( if( new_configuration != device->configuration ) { // Configuration changed. device->configuration = new_configuration; - if (usb_configuration_changed_cb) - usb_configuration_changed_cb(device); } + + if (usb_configuration_changed_cb) + usb_configuration_changed_cb(device); + return true; } @@ -114,12 +117,13 @@ static usb_request_status_t usb_send_descriptor( if( descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION ) { descriptor_length = (descriptor_data[3] << 8) | descriptor_data[2]; } - usb_endpoint_schedule( + usb_transfer_schedule_block( endpoint->in, descriptor_data, - (setup_length > descriptor_length) ? descriptor_length : setup_length + (setup_length > descriptor_length) ? descriptor_length : setup_length, + NULL, NULL ); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } @@ -195,7 +199,7 @@ static usb_request_status_t usb_standard_request_set_address_setup( usb_endpoint_t* const endpoint ) { usb_set_address_deferred(endpoint->device, endpoint->setup.value_l); - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } @@ -231,7 +235,7 @@ static usb_request_status_t usb_standard_request_set_configuration_setup( // TODO: Should this be done immediately? usb_set_address_immediate(endpoint->device, 0); } - usb_endpoint_schedule_ack(endpoint->in); + usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } else { return USB_REQUEST_STATUS_STALL; @@ -265,8 +269,8 @@ static usb_request_status_t usb_standard_request_get_configuration_setup( if( endpoint->device->configuration ) { endpoint->buffer[0] = endpoint->device->configuration->number; } - usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); - usb_endpoint_schedule_ack(endpoint->out); + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); return USB_REQUEST_STATUS_OK; } else { return USB_REQUEST_STATUS_STALL; diff --git a/firmware/libopencm3 b/firmware/libopencm3 index d7fdcefb..f04d6dd8 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit d7fdcefbd7565e59aaaf2dea99bee8e0157ff1d7 +Subproject commit f04d6dd82bf3cf89f55c3a85c4384d9375c34469 From 34fabad121a30c476e64c5cd6588cf55660bfe14 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 22:28:40 -0400 Subject: [PATCH 092/200] usb_standard_request: Sent descriptors can be const --- firmware/hackrf_usb/usb_standard_request.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index 6f589b3c..e6fd8974 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -110,16 +110,17 @@ bool usb_set_configuration( static usb_request_status_t usb_send_descriptor( usb_endpoint_t* const endpoint, - uint8_t* const descriptor_data + const uint8_t* const descriptor_data ) { const uint32_t setup_length = endpoint->setup.length; uint32_t descriptor_length = descriptor_data[0]; if( descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION ) { descriptor_length = (descriptor_data[3] << 8) | descriptor_data[2]; } + // We cast the const away but this shouldn't be a problem as this is a write transfer usb_transfer_schedule_block( endpoint->in, - descriptor_data, + (uint8_t* const) descriptor_data, (setup_length > descriptor_length) ? descriptor_length : setup_length, NULL, NULL ); From 8e897be9757aed03aafca3ef566b500fe4d2c836 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 22:29:56 -0400 Subject: [PATCH 093/200] usb_standard_request: Multiple config support GET_DESCRIPTOR would only return one configurations. This fixes that. --- firmware/hackrf_usb/usb_standard_request.c | 27 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/hackrf_usb/usb_standard_request.c index e6fd8974..fafc5c55 100644 --- a/firmware/hackrf_usb/usb_standard_request.c +++ b/firmware/hackrf_usb/usb_standard_request.c @@ -141,6 +141,25 @@ static usb_request_status_t usb_send_descriptor_string( return USB_REQUEST_STATUS_STALL; } +static usb_request_status_t usb_send_descriptor_config( + usb_endpoint_t* const endpoint, + usb_speed_t speed, + const uint8_t config_num +) { + usb_configuration_t** config = *(endpoint->device->configurations); + unsigned int i = 0; + for( ; *config != NULL; config++ ) { + if( (*config)->speed == speed) { + if (i == config_num) { + return usb_send_descriptor(endpoint, (*config)->descriptor); + } else { + i++; + } + } + } + return USB_REQUEST_STATUS_STALL; +} + static usb_request_status_t usb_standard_request_get_descriptor_setup( usb_endpoint_t* const endpoint ) { @@ -151,9 +170,9 @@ static usb_request_status_t usb_standard_request_get_descriptor_setup( case USB_DESCRIPTOR_TYPE_CONFIGURATION: // TODO: Duplicated code. Refactor. if( usb_speed(endpoint->device) == USB_SPEED_HIGH ) { - return usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); + return usb_send_descriptor_config(endpoint, USB_SPEED_HIGH, endpoint->setup.value_l); } else { - return usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); + return usb_send_descriptor_config(endpoint, USB_SPEED_FULL, endpoint->setup.value_l); } case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: @@ -162,9 +181,9 @@ static usb_request_status_t usb_standard_request_get_descriptor_setup( case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: // TODO: Duplicated code. Refactor. if( usb_speed(endpoint->device) == USB_SPEED_HIGH ) { - return usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); + return usb_send_descriptor_config(endpoint, USB_SPEED_FULL, endpoint->setup.value_l); } else { - return usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); + return usb_send_descriptor_config(endpoint, USB_SPEED_HIGH, endpoint->setup.value_l); } case USB_DESCRIPTOR_TYPE_STRING: From d2b2b1199840aeac3ac75cf809872d55d1591456 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 9 Jul 2013 19:05:00 -0400 Subject: [PATCH 094/200] xapp058/ports: Clean up comments and dead code It's still not pretty but it's an improvement --- firmware/common/xapp058/ports.c | 143 -------------------------------- 1 file changed, 143 deletions(-) diff --git a/firmware/common/xapp058/ports.c b/firmware/common/xapp058/ports.c index 3c7c6e44..029ee0ca 100644 --- a/firmware/common/xapp058/ports.c +++ b/firmware/common/xapp058/ports.c @@ -10,18 +10,11 @@ /* Add print in setPort for xapp058_example.exe.*/ /*******************************************************/ #include "ports.h" -/*#include "prgispx.h"*/ -//#include "stdio.h" #include "hackrf_core.h" #include "cpld_jtag.h" #include -//extern FILE *in; -//static int g_iTCK = 0; /* For xapp058_example .exe */ -//static int g_iTMS = 0; /* For xapp058_example .exe */ -//static int g_iTDI = 0; /* For xapp058_example .exe */ - void delay_jtag(uint32_t duration) { #define DIVISOR (1024) @@ -43,94 +36,10 @@ void delay_jtag(uint32_t duration) __asm__("nop"); } - -#ifdef WIN95PP -#include "conio.h" - -#define DATA_OFFSET (unsigned short) 0 -#define STATUS_OFFSET (unsigned short) 1 -#define CONTROL_OFFSET (unsigned short) 2 - -typedef union outPortUnion { - unsigned char value; - struct opBitsStr { - unsigned char tdi:1; - unsigned char tck:1; - unsigned char tms:1; - unsigned char zero:1; - unsigned char one:1; - unsigned char bit5:1; - unsigned char bit6:1; - unsigned char bit7:1; - } bits; -} outPortType; - -typedef union inPortUnion { - unsigned char value; - struct ipBitsStr { - unsigned char bit0:1; - unsigned char bit1:1; - unsigned char bit2:1; - unsigned char bit3:1; - unsigned char tdo:1; - unsigned char bit5:1; - unsigned char bit6:1; - unsigned char bit7:1; - } bits; -} inPortType; - -static inPortType in_word; -static outPortType out_word; -static unsigned short base_port = 0x378; -static int once = 0; -#endif - - -/*BYTE *xsvf_data=0;*/ - - /* setPort: Implement to set the named JTAG signal (p) to the new value (v).*/ /* if in debugging mode, then just set the variables */ void setPort(short p,short val) { -#ifdef WIN95PP - /* Old Win95 example that is similar to a GPIO register implementation. - The old Win95 example maps individual bits of the - 8-bit register (out_word) to the JTAG signals: TCK, TMS, TDI. - */ - - /* Initialize static out_word register bits just once */ - if (once == 0) { - out_word.bits.one = 1; - out_word.bits.zero = 0; - once = 1; - } - - /* Update the local out_word copy of the JTAG signal to the new value. */ - if (p==TMS) - out_word.bits.tms = (unsigned char) val; - if (p==TDI) - out_word.bits.tdi = (unsigned char) val; - if (p==TCK) { - out_word.bits.tck = (unsigned char) val; - (void) _outp( (unsigned short) (base_port + 0), out_word.value ); - /* To save HW write cycles, this example only writes the local copy - of the JTAG signal values to the HW register when TCK changes. */ - } -#endif - /* Printing code for the xapp058_example.exe. You must set the specified - JTAG signal (p) to the new value (v). See the above, old Win95 code - as an implementation example. */ -/* - if (p==TMS) - g_iTMS = val; - if (p==TDI) - g_iTDI = val; - if (p==TCK) { - g_iTCK = val; - printf( "TCK = %d; TMS = %d; TDI = %d\n", g_iTCK, g_iTMS, g_iTDI ); - } -*/ if (p==TMS) { if (val) gpio_set(PORT_CPLD_TMS, PIN_CPLD_TMS); @@ -167,9 +76,6 @@ void pulseClock() /* read in a byte of data from the prom */ void readByte(unsigned char *data) { - /* pretend reading using a file */ - //*data = (unsigned char)fgetc( in ); - /**data=*xsvf_data++;*/ *data = cpld_jtag_get_next_byte(); } @@ -177,20 +83,6 @@ void readByte(unsigned char *data) /* read the TDO bit from port */ unsigned char readTDOBit() { -#ifdef WIN95PP - /* Old Win95 example that is similar to a GPIO register implementation. - The old Win95 reads the hardware input register and extracts the TDO - value from the bit within the register that is assigned to the - physical JTAG TDO signal. - */ - in_word.value = (unsigned char) _inp( (unsigned short) (base_port + STATUS_OFFSET) ); - if (in_word.bits.tdo == 0x1) { - return( (unsigned char) 1 ); - } -#endif - /* You must return the current value of the JTAG TDO signal. */ - //return( (unsigned char) 0 ); - delay_jtag(2000); return CPLD_TDO_STATE; } @@ -218,39 +110,4 @@ void waitTime(long microsec) { pulseClock(); } - -#if 0 - /* Alternate implementation */ - /* For systems with TCK rates << 1 MHz; Consider this implementation. */ - /* This implementation does not work with Spartan-3AN or indirect flash - programming. */ - if ( microsec >= 50L ) - { - /* Make sure TCK is low during wait for XC18V00/XCFxxS */ - /* Or, a running TCK implementation as shown above is an OK alternate */ - setPort( TCK, 0 ); - - /* Use Windows Sleep(). Round up to the nearest millisec */ - _sleep( ( microsec + 999L ) / 1000L ); - } - else /* Satisfy FPGA JTAG configuration, startup TCK cycles */ - { - for ( i = 0; i < microsec; ++i ) - { - pulseClock(); - } - } -#endif - -#if 0 - /* Alternate implementation */ - /* This implementation is valid for only XC9500/XL/XV, CoolRunner/II CPLDs, - XC18V00 PROMs, or Platform Flash XCFxxS/XCFxxP PROMs. - This implementation does not work with FPGAs JTAG configuration. */ - /* Make sure TCK is low during wait for XC18V00/XCFxxS PROMs */ - /* Or, a running TCK implementation as shown above is an OK alternate */ - setPort( TCK, 0 ); - /* Use Windows Sleep(). Round up to the nearest millisec */ - _sleep( ( microsec + 999L ) / 1000L ); -#endif } From dc9c6c9667388b04ec126f5ccd58cb93007df6d1 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 2 Sep 2013 19:44:22 -0400 Subject: [PATCH 095/200] cpld: Stream CPLD data from host Previously CPLD programming involved a large 64kbyte buffer into which the the entire bitstream would be completely downloaded, and at which point the programming process would commence. This is needlessly wasteful of memory. Moreover, it could lead to USB timeouts as the firmware needs to wait the entire duration of the programming process before returning an ACK to the host after the final SETUP data phase packet. Instead, we now receive 512 byte chunks of the bitstream and stream them to the CPLD one at a time. We wait for each packet to be streamed out to the CPLD before ACKing the packet to prevent active data being overwritten. --- firmware/common/cpld_jtag.c | 28 +++-- firmware/common/cpld_jtag.h | 15 ++- firmware/hackrf_usb/hackrf_usb.c | 149 ++++++++++++++------------- firmware/hackrf_usb/usb_descriptor.c | 95 ++++++++++++++++- firmware/hackrf_usb/usb_descriptor.h | 2 + 5 files changed, 205 insertions(+), 84 deletions(-) diff --git a/firmware/common/cpld_jtag.c b/firmware/common/cpld_jtag.c index ddeb13d9..50430fee 100644 --- a/firmware/common/cpld_jtag.c +++ b/firmware/common/cpld_jtag.c @@ -26,8 +26,9 @@ #include #include -uint32_t xsvf_len; -unsigned char* xsvf_data; +static refill_buffer_cb refill_buffer; +static uint32_t xsvf_buffer_len, xsvf_pos; +static unsigned char* xsvf_buffer; void cpld_jtag_setup(void) { scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); @@ -58,11 +59,16 @@ void cpld_jtag_release(void) { } /* return 0 if success else return error code see xsvfExecute() */ -int cpld_jtag_program(const uint32_t len, unsigned char* const data) { +int cpld_jtag_program( + const uint32_t buffer_length, + unsigned char* const buffer, + refill_buffer_cb refill +) { int error; cpld_jtag_setup(); - xsvf_data = data; - xsvf_len = len; + xsvf_buffer = buffer; + xsvf_buffer_len = buffer_length; + refill_buffer = refill; error = xsvfExecute(); cpld_jtag_release(); @@ -71,12 +77,12 @@ int cpld_jtag_program(const uint32_t len, unsigned char* const data) { /* this gets called by the XAPP058 code */ unsigned char cpld_jtag_get_next_byte(void) { - unsigned char byte = *xsvf_data; - - if (xsvf_len > 1) { - xsvf_data++; - xsvf_len--; - } + if (xsvf_pos == xsvf_buffer_len) { + refill_buffer(); + xsvf_pos = 0; + } + unsigned char byte = xsvf_buffer[xsvf_pos]; + xsvf_pos++; return byte; } diff --git a/firmware/common/cpld_jtag.h b/firmware/common/cpld_jtag.h index ed42d782..56f55a2a 100644 --- a/firmware/common/cpld_jtag.h +++ b/firmware/common/cpld_jtag.h @@ -24,9 +24,20 @@ #include +typedef void (*refill_buffer_cb)(void); + void cpld_jtag_release(void); -/* return 0 if success else return error code see xsvfExecute() see micro.h */ -int cpld_jtag_program(const uint32_t len, unsigned char* const data); + +/* Return 0 if success else return error code see xsvfExecute() see micro.h. + * + * We expect the buffer to be initially full of data. After the entire + * contents of the buffer has been streamed to the CPLD the given + * refill_buffer callback will be called. */ +int cpld_jtag_program( + const uint32_t buffer_length, + unsigned char* const buffer, + refill_buffer_cb refill +); unsigned char cpld_jtag_get_next_byte(void); #endif//__CPLD_JTAG_H__ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index f077a014..2a14b5e8 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -50,10 +50,11 @@ uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; static volatile uint32_t usb_bulk_buffer_offset = 0; static const uint32_t usb_bulk_buffer_mask = 32768 - 1; -/* TODO remove this big buffer and use streaming for CPLD */ -#define CPLD_XSVF_MAX_LEN (65536) -uint8_t cpld_xsvf_buffer[CPLD_XSVF_MAX_LEN]; -uint16_t write_cpld_idx = 0; +usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64); +const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]); + +uint8_t cpld_xsvf_buffer[512]; +volatile bool cpld_wait = false; uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN]; char version_string[] = VERSION_STRING; @@ -191,9 +192,23 @@ usb_configuration_t usb_configuration_full_speed = { .descriptor = usb_descriptor_configuration_full_speed, }; +usb_configuration_t usb_configuration_cpld_update_full_speed = { + .number = 2, + .speed = USB_SPEED_FULL, + .descriptor = usb_descriptor_configuration_cpld_update_full_speed, +}; + +usb_configuration_t usb_configuration_cpld_update_high_speed = { + .number = 2, + .speed = USB_SPEED_HIGH, + .descriptor = usb_descriptor_configuration_cpld_update_high_speed, +}; + usb_configuration_t* usb_configurations[] = { &usb_configuration_high_speed, &usb_configuration_full_speed, + &usb_configuration_cpld_update_full_speed, + &usb_configuration_cpld_update_high_speed, 0, }; @@ -549,69 +564,6 @@ usb_request_status_t usb_vendor_request_read_spiflash( } } -usb_request_status_t usb_vendor_request_write_cpld( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage) -{ - int error, i; - uint16_t total_len; - uint16_t len; - #define WAIT_LOOP_DELAY (6000000) - #define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3) - - if (stage == USB_TRANSFER_STAGE_SETUP) - { - // len is limited to 64KB 16bits no overflow can happen - total_len = endpoint->setup.value; - len = endpoint->setup.length; - usb_transfer_schedule_block(endpoint->out, &cpld_xsvf_buffer[write_cpld_idx], len, - NULL, NULL); - return USB_REQUEST_STATUS_OK; - } else if (stage == USB_TRANSFER_STAGE_DATA) - { - // len is limited to 64KB 16bits no overflow can happen - total_len = endpoint->setup.value; - len = endpoint->setup.length; - write_cpld_idx = write_cpld_idx + len; - // Check if all bytes received and write CPLD - if(write_cpld_idx == total_len) - { - write_cpld_idx = 0; - error = cpld_jtag_program(total_len, &cpld_xsvf_buffer[write_cpld_idx]); - // TO FIX ACK shall be not delayed so much as cpld prog can take up to 5s. - if(error == 0) - { - usb_transfer_schedule_ack(endpoint->in); - - /* blink LED1, LED2, and LED3 on success */ - while (1) - { - gpio_set(PORT_LED1_3, ALL_LEDS); /* LEDs on */ - for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ - __asm__("nop"); - gpio_clear(PORT_LED1_3, ALL_LEDS); /* LEDs off */ - for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ - __asm__("nop"); - } - return USB_REQUEST_STATUS_OK; - }else - { - /* LED3 (Red) steady on error */ - gpio_set(PORT_LED1_3, PIN_LED3); /* LEDs on */ - while (1); - return USB_REQUEST_STATUS_STALL; - } - }else - { - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - } - } else - { - return USB_REQUEST_STATUS_OK; - } -} - usb_request_status_t usb_vendor_request_read_board_id( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { @@ -815,7 +767,7 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_erase_spiflash, usb_vendor_request_write_spiflash, usb_vendor_request_read_spiflash, - usb_vendor_request_write_cpld, + NULL, // used to be write_cpld usb_vendor_request_read_board_id, usb_vendor_request_read_version_string, usb_vendor_request_set_freq, @@ -853,13 +805,72 @@ const usb_request_handlers_t usb_request_handlers = { .reserved = 0, }; +static void cpld_buffer_refilled(void* user_data, unsigned int length) +{ + cpld_wait = false; +} + +static void refill_cpld_buffer(void) +{ + cpld_wait = true; + usb_transfer_schedule( + &usb_endpoint_bulk_out, + cpld_xsvf_buffer, + sizeof(cpld_xsvf_buffer), + cpld_buffer_refilled, + NULL + ); + + // Wait until transfer finishes + while (cpld_wait); +} + +static void cpld_update(void) +{ + #define WAIT_LOOP_DELAY (6000000) + #define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3) + int i; + int error; + + usb_queue_flush_endpoint(&usb_endpoint_bulk_in); + usb_queue_flush_endpoint(&usb_endpoint_bulk_out); + + refill_cpld_buffer(); + + error = cpld_jtag_program(sizeof(cpld_xsvf_buffer), + cpld_xsvf_buffer, + refill_cpld_buffer); + if(error == 0) + { + /* blink LED1, LED2, and LED3 on success */ + while (1) + { + gpio_set(PORT_LED1_3, ALL_LEDS); /* LEDs on */ + for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ + __asm__("nop"); + gpio_clear(PORT_LED1_3, ALL_LEDS); /* LEDs off */ + for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ + __asm__("nop"); + } + }else + { + /* LED3 (Red) steady on error */ + gpio_set(PORT_LED1_3, PIN_LED3); /* LEDs on */ + while (1); + } +} + void usb_configuration_changed( usb_device_t* const device ) { set_transceiver_mode(transceiver_mode); - if( device->configuration->number ) { + if( device->configuration->number == 1 ) { + // transceiver mode gpio_set(PORT_LED1_3, PIN_LED1); + } else if( device->configuration->number == 2 ) { + // CPLD update mode + cpld_update(); } else { gpio_clear(PORT_LED1_3, PIN_LED1); } diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index c9f26ce7..d97e1973 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -51,7 +51,7 @@ uint8_t usb_descriptor_device[] = { 0x01, // iManufacturer 0x02, // iProduct 0x00, // iSerialNumber - 0x01 // bNumConfigurations + 0x02 // bNumConfigurations }; uint8_t usb_descriptor_device_qualifier[] = { @@ -62,7 +62,7 @@ uint8_t usb_descriptor_device_qualifier[] = { 0x00, // bDeviceSubClass 0x00, // bDeviceProtocol 64, // bMaxPacketSize0 - 0x01, // bNumOtherSpeedConfigurations + 0x02, // bNumOtherSpeedConfigurations 0x00 // bReserved }; @@ -140,6 +140,80 @@ uint8_t usb_descriptor_configuration_high_speed[] = { 0, // TERMINATOR }; +uint8_t usb_descriptor_configuration_cpld_update_full_speed[] = { + 9, // bLength + USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType + USB_WORD(32), // wTotalLength + 0x01, // bNumInterfaces + 0x02, // bConfigurationValue + 0x04, // iConfiguration + 0x80, // bmAttributes: USB-powered + 250, // bMaxPower: 500mA + + 9, // bLength + USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0xFF, // bInterfaceClass: vendor-specific + 0xFF, // bInterfaceSubClass + 0xFF, // bInterfaceProtocol: vendor-specific + 0x00, // iInterface + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_IN_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_OUT_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 0, // TERMINATOR +}; + +uint8_t usb_descriptor_configuration_cpld_update_high_speed[] = { + 9, // bLength + USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType + USB_WORD(32), // wTotalLength + 0x01, // bNumInterfaces + 0x02, // bConfigurationValue + 0x04, // iConfiguration + 0x80, // bmAttributes: USB-powered + 250, // bMaxPower: 500mA + + 9, // bLength + USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0xFF, // bInterfaceClass: vendor-specific + 0xFF, // bInterfaceSubClass + 0xFF, // bInterfaceProtocol: vendor-specific + 0x00, // iInterface + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_IN_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_OUT_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 0, // TERMINATOR +}; + uint8_t usb_descriptor_string_languages[] = { 0x04, // bLength USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType @@ -197,11 +271,28 @@ uint8_t usb_descriptor_string_config1_description[] = { 'r', 0x00, }; +uint8_t usb_descriptor_string_config2_description[] = { + 24, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + 'C', 0x00, + 'P', 0x00, + 'L', 0x00, + 'D', 0x00, + ' ', 0x00, + 'u', 0x00, + 'p', 0x00, + 'd', 0x00, + 'a', 0x00, + 't', 0x00, + 'e', 0x00, +}; + uint8_t* const usb_descriptor_strings[] = { usb_descriptor_string_languages, usb_descriptor_string_manufacturer, usb_descriptor_string_product, usb_descriptor_string_config1_description, + usb_descriptor_string_config2_description, 0, // TERMINATOR }; diff --git a/firmware/hackrf_usb/usb_descriptor.h b/firmware/hackrf_usb/usb_descriptor.h index a1676f04..11e274a7 100644 --- a/firmware/hackrf_usb/usb_descriptor.h +++ b/firmware/hackrf_usb/usb_descriptor.h @@ -25,6 +25,8 @@ extern uint8_t usb_descriptor_device[]; extern uint8_t usb_descriptor_device_qualifier[]; extern uint8_t usb_descriptor_configuration_full_speed[]; extern uint8_t usb_descriptor_configuration_high_speed[]; +extern uint8_t usb_descriptor_configuration_cpld_update_full_speed[]; +extern uint8_t usb_descriptor_configuration_cpld_update_high_speed[]; extern uint8_t usb_descriptor_string_languages[]; extern uint8_t usb_descriptor_string_manufacturer[]; extern uint8_t usb_descriptor_string_product[]; From 3ba8d33de897c222367b68de080ffdb9baaaa95f Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 23:47:18 -0400 Subject: [PATCH 096/200] hackrf: Enter cpld_update from main loop Otherwise we never respond to SET_CONFIGURATION --- firmware/hackrf_usb/hackrf_usb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 2a14b5e8..68b2b86d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -53,6 +53,7 @@ static const uint32_t usb_bulk_buffer_mask = 32768 - 1; usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64); const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]); +static volatile bool start_cpld_update = false; uint8_t cpld_xsvf_buffer[512]; volatile bool cpld_wait = false; @@ -870,7 +871,7 @@ void usb_configuration_changed( gpio_set(PORT_LED1_3, PIN_LED1); } else if( device->configuration->number == 2 ) { // CPLD update mode - cpld_update(); + start_cpld_update = true; } else { gpio_clear(PORT_LED1_3, PIN_LED1); } @@ -978,6 +979,10 @@ int main(void) { #endif while(true) { + // Check whether we need to initiate a CPLD update + if (start_cpld_update) + cpld_update(); + // Wait until buffer 0 is transmitted/received. while( usb_bulk_buffer_offset < 16384 ); From 64ef3f71c04644809731e07ae9d06e33c6a9d41f Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 9 Sep 2013 00:53:41 -0400 Subject: [PATCH 097/200] hackrf_usb: Make main loop non-blocking --- firmware/hackrf_usb/hackrf_usb.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 68b2b86d..1ba0b9be 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -978,16 +978,16 @@ int main(void) { switchctrl = SWITCHCTRL_AMP_BYPASS; #endif + unsigned int phase = 0; while(true) { // Check whether we need to initiate a CPLD update if (start_cpld_update) cpld_update(); - // Wait until buffer 0 is transmitted/received. - while( usb_bulk_buffer_offset < 16384 ); - // Set up IN transfer of buffer 0. - if (transceiver_mode != TRANSCEIVER_MODE_OFF) { + if ( usb_bulk_buffer_offset >= 16384 + && phase == 1 + && transceiver_mode != TRANSCEIVER_MODE_OFF) { usb_transfer_schedule_block( (transceiver_mode == TRANSCEIVER_MODE_RX) ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, @@ -995,13 +995,13 @@ int main(void) { 0x4000, NULL, NULL ); + phase = 0; } - // Wait until buffer 1 is transmitted/received. - while( usb_bulk_buffer_offset >= 16384 ); - // Set up IN transfer of buffer 1. - if (transceiver_mode != TRANSCEIVER_MODE_OFF) { + if ( usb_bulk_buffer_offset < 16384 + && phase == 0 + && transceiver_mode != TRANSCEIVER_MODE_OFF) { usb_transfer_schedule_block( (transceiver_mode == TRANSCEIVER_MODE_RX) ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, @@ -1009,6 +1009,7 @@ int main(void) { 0x4000, NULL, NULL ); + phase = 1; } } From 67a181ac365c8da3659b81c8f300020a5ba5d113 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 9 Sep 2013 00:54:24 -0400 Subject: [PATCH 098/200] hackrf_usb: Update transceiver_mode on all configuration changes --- firmware/hackrf_usb/hackrf_usb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 1ba0b9be..e7a487eb 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -864,15 +864,17 @@ static void cpld_update(void) void usb_configuration_changed( usb_device_t* const device ) { - set_transceiver_mode(transceiver_mode); - if( device->configuration->number == 1 ) { - // transceiver mode + // transceiver configuration + set_transceiver_mode(transceiver_mode); gpio_set(PORT_LED1_3, PIN_LED1); } else if( device->configuration->number == 2 ) { - // CPLD update mode + // CPLD update configuration + set_transceiver_mode(TRANSCEIVER_MODE_OFF); + usb_endpoint_init(&usb_endpoint_bulk_out); start_cpld_update = true; } else { + set_transceiver_mode(TRANSCEIVER_MODE_OFF); gpio_clear(PORT_LED1_3, PIN_LED1); } }; From d21d6165764feca4e20a2c61a4a94b5132a2b107 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 13:43:29 -0400 Subject: [PATCH 099/200] libhackrf: Rework hackrf_cpld_write to use new firmware interface We now use a separate USB configuration for CPLD updates. To avoid misuse of the interface, hackrf_cpld_write is now a one-shot call, expecting the entire CPLD buffer. The library will then take care that the device is placed in the CPLD update configuration and the entire buffer uploaded. Unfortunately, this means that users of the interface will have substantially fewer opportunities to provide status updates to the user. --- host/libhackrf/src/hackrf.c | 52 +++++++++++++++++++++++++------------ host/libhackrf/src/hackrf.h | 5 ++-- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 47ff055a..ea5596e4 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -55,7 +55,6 @@ typedef enum { HACKRF_VENDOR_REQUEST_SPIFLASH_ERASE = 10, HACKRF_VENDOR_REQUEST_SPIFLASH_WRITE = 11, HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 12, - HACKRF_VENDOR_REQUEST_CPLD_WRITE = 13, HACKRF_VENDOR_REQUEST_BOARD_ID_READ = 14, HACKRF_VENDOR_REQUEST_VERSION_STRING_READ = 15, HACKRF_VENDOR_REQUEST_SET_FREQ = 16, @@ -632,25 +631,44 @@ int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, } } -int ADDCALL hackrf_cpld_write(hackrf_device* device, const uint16_t length, - unsigned char* const data, const uint16_t total_length) +int ADDCALL hackrf_cpld_write(hackrf_device* device, + unsigned char* const data, const unsigned int total_length) { - int result = libusb_control_transfer( - device->usb_device, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - HACKRF_VENDOR_REQUEST_CPLD_WRITE, - total_length, - 0, - data, - length, - 0 - ); - - if (result < length) { + int result = libusb_release_interface(device->usb_device, 0); + if (result != LIBUSB_SUCCESS) { return HACKRF_ERROR_LIBUSB; - } else { - return HACKRF_SUCCESS; } + + result = libusb_set_configuration(device->usb_device, 2); + if (result != LIBUSB_SUCCESS) { + return HACKRF_ERROR_LIBUSB; + } + + result = libusb_claim_interface(device->usb_device, 0); + if (result != LIBUSB_SUCCESS) { + return HACKRF_ERROR_LIBUSB; + } + + const unsigned int chunk_size = 512; + unsigned int i; + int transferred = 0; + for (i = 0; i < total_length; i += chunk_size) + { + result = libusb_bulk_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | 2, + &data[i], + chunk_size, + &transferred, + 10000 // long timeout to allow for CPLD programming + ); + + if (result != LIBUSB_SUCCESS) { + return HACKRF_ERROR_LIBUSB; + } + } + + return HACKRF_SUCCESS; } int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value) diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 08317ec2..8c127839 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -121,8 +121,9 @@ extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data); extern ADDAPI int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* data); -extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, const uint16_t length, - unsigned char* const data, const uint16_t total_length); +/* device will need to be reset after hackrf_cpld_write */ +extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, + unsigned char* const data, const unsigned int total_length); extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value); extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length); From b3f6134fc105703d142b15660783945f2eb3dc65 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 8 Sep 2013 13:46:03 -0400 Subject: [PATCH 100/200] hackrf_cpldjtag: Update for new hackrf_cpld_write interface --- host/hackrf-tools/src/hackrf_cpldjtag.c | 34 ++++++++++--------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_cpldjtag.c b/host/hackrf-tools/src/hackrf_cpldjtag.c index fe3bce23..d032812b 100644 --- a/host/hackrf-tools/src/hackrf_cpldjtag.c +++ b/host/hackrf-tools/src/hackrf_cpldjtag.c @@ -93,8 +93,7 @@ int main(int argc, char** argv) int option_index = 0; FILE* fd = NULL; ssize_t bytes_read; - uint16_t xfer_len = 0; - uint8_t* pdata = &data[0]; + uint8_t* pdata = &data[0]; while ((opt = getopt_long(argc, argv, "x:", long_options, &option_index)) != EOF) { @@ -127,20 +126,20 @@ int main(int argc, char** argv) { fprintf(stderr, "Failed to open file: %s\n", path); return EXIT_FAILURE; - } + } /* Get size of the file */ fseek(fd, 0, SEEK_END); /* Not really portable but work on major OS Linux/Win32 */ length = ftell(fd); /* Move to start */ rewind(fd); - printf("File size %d bytes.\n", length); + printf("File size %d bytes.\n", length); if (length > MAX_XSVF_LENGTH) { fprintf(stderr, "XSVF file too large.\n"); usage(); return EXIT_FAILURE; } - + total_length = length; bytes_read = fread(data, 1, total_length, fd); if (bytes_read != total_length) @@ -168,27 +167,20 @@ int main(int argc, char** argv) printf("LED1/2/3 blinking means CPLD program success.\nLED3/RED steady means error.\n"); printf("Wait message 'Write finished' or in case of LED3/RED steady, Power OFF/Disconnect the Jawbreaker.\n"); - while( length ) + result = hackrf_cpld_write(device, pdata, total_length); + if (result != HACKRF_SUCCESS) { - xfer_len = (length > PACKET_LEN) ? PACKET_LEN : length; - result = hackrf_cpld_write(device, xfer_len, pdata, total_length); - if (result != HACKRF_SUCCESS) - { - fprintf(stderr, "hackrf_cpld_write() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; - return EXIT_FAILURE; - } - pdata += xfer_len; - length -= xfer_len; - printf("hackrf_cpld_write() Writing %d bytes, remaining %d bytes.\n", - xfer_len, length); + fprintf(stderr, "hackrf_cpld_write() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; } + printf("Write finished.\n"); printf("Please Power OFF/Disconnect the Jawbreaker.\n"); fflush(stdout); - + result = hackrf_close(device); if( result != HACKRF_SUCCESS ) { From 4cd7662f7c98bfbc54df168003a657169d75be63 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sun, 15 Sep 2013 18:29:33 -0400 Subject: [PATCH 101/200] hackrf_usb_rom_to_ram: Add usb_queue to Makefile --- firmware/hackrf_usb_rom_to_ram/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index 0d2ea0e2..460d2f6c 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -29,6 +29,7 @@ SRC = hackrf_usb.c \ usb_request.c \ usb_standard_request.c \ usb_descriptor.c \ + usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ ../common/sgpio.c \ From 0a46aae5b9b76a3550d77b3e89f0c536b2808657 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 16 Sep 2013 14:59:14 -0700 Subject: [PATCH 102/200] Convert from unsigned to two's complement inside CPLD. TODO: This requires changes to gr-osmosdr and software that uses hackrf_transfer files directly. --- firmware/cpld/sgpio_if/top.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/cpld/sgpio_if/top.vhd b/firmware/cpld/sgpio_if/top.vhd index a1507238..ce3bbfa8 100755 --- a/firmware/cpld/sgpio_if/top.vhd +++ b/firmware/cpld/sgpio_if/top.vhd @@ -93,7 +93,7 @@ begin process(host_clk_i) begin if rising_edge(host_clk_i) then - data_to_host_o <= adc_data_i; + data_to_host_o <= adc_data_i xor X"80"; end if; end process; @@ -101,7 +101,7 @@ begin begin if rising_edge(host_clk_i) then if transfer_direction_i = to_dac then - dac_data_o <= data_from_host_i & "00"; + dac_data_o <= (data_from_host_i xor X"80") & "00"; else dac_data_o <= (dac_data_o'high => '1', others => '0'); end if; From d13e80b5205163618107f377df633821f709fc17 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Mon, 16 Sep 2013 15:21:28 -0700 Subject: [PATCH 103/200] With bgamari's new USB configuration for CPLD, be sure to turn up CPU clock to maximum. --- firmware/hackrf_usb/hackrf_usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 6a81b7ad..9dca7f4a 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -870,6 +870,7 @@ void usb_configuration_changed( gpio_set(PORT_LED1_3, PIN_LED1); } else if( device->configuration->number == 2 ) { // CPLD update configuration + cpu_clock_pll1_max_speed(); set_transceiver_mode(TRANSCEIVER_MODE_OFF); usb_endpoint_init(&usb_endpoint_bulk_out); start_cpld_update = true; From 4984a8b681352c10f8e6cce020e1cc65c68aa061 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 12:18:33 -0700 Subject: [PATCH 104/200] Fix to SPIFI addressing during hackrf_spiflash read operation. This fixes mismatches between programmed and read-back data. --- firmware/hackrf_usb/hackrf_usb.c | 2 +- firmware/libopencm3 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index b33085d9..5f720bf0 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -463,7 +463,7 @@ usb_request_status_t usb_vendor_request_read_spiflash( return USB_REQUEST_STATUS_STALL; } else { /* TODO flush SPIFI "cache" before to read the SPIFI memory */ - u8_addr_pt = (uint8_t*)addr; + u8_addr_pt = (uint8_t*)(addr + SPIFI_DATA_UNCACHED_BASE); for(i=0; i Date: Tue, 17 Sep 2013 15:10:46 -0700 Subject: [PATCH 105/200] Move files that have no application-specific bits (e.g. USB stack, tuning, and RF path APIs) to ../common/. --- firmware/{hackrf_usb => common}/rf_path.c | 0 firmware/{hackrf_usb => common}/rf_path.h | 0 firmware/{hackrf_usb => common}/tuning.c | 0 firmware/{hackrf_usb => common}/tuning.h | 0 firmware/{hackrf_usb => common}/usb.c | 0 firmware/{hackrf_usb => common}/usb.h | 0 firmware/{hackrf_usb => common}/usb_queue.c | 0 firmware/{hackrf_usb => common}/usb_queue.h | 0 firmware/{hackrf_usb => common}/usb_request.c | 0 firmware/{hackrf_usb => common}/usb_request.h | 0 .../{hackrf_usb => common}/usb_standard_request.c | 0 .../{hackrf_usb => common}/usb_standard_request.h | 0 firmware/{hackrf_usb => common}/usb_type.h | 0 firmware/hackrf_usb/Makefile | 12 ++++++------ firmware/hackrf_usb/Makefile_rom_to_ram | 11 ++++++----- firmware/hackrf_usb_rom_to_ram/Makefile | 12 ++++++------ 16 files changed, 18 insertions(+), 17 deletions(-) rename firmware/{hackrf_usb => common}/rf_path.c (100%) rename firmware/{hackrf_usb => common}/rf_path.h (100%) rename firmware/{hackrf_usb => common}/tuning.c (100%) rename firmware/{hackrf_usb => common}/tuning.h (100%) rename firmware/{hackrf_usb => common}/usb.c (100%) rename firmware/{hackrf_usb => common}/usb.h (100%) rename firmware/{hackrf_usb => common}/usb_queue.c (100%) rename firmware/{hackrf_usb => common}/usb_queue.h (100%) rename firmware/{hackrf_usb => common}/usb_request.c (100%) rename firmware/{hackrf_usb => common}/usb_request.h (100%) rename firmware/{hackrf_usb => common}/usb_standard_request.c (100%) rename firmware/{hackrf_usb => common}/usb_standard_request.h (100%) rename firmware/{hackrf_usb => common}/usb_type.h (100%) diff --git a/firmware/hackrf_usb/rf_path.c b/firmware/common/rf_path.c similarity index 100% rename from firmware/hackrf_usb/rf_path.c rename to firmware/common/rf_path.c diff --git a/firmware/hackrf_usb/rf_path.h b/firmware/common/rf_path.h similarity index 100% rename from firmware/hackrf_usb/rf_path.h rename to firmware/common/rf_path.h diff --git a/firmware/hackrf_usb/tuning.c b/firmware/common/tuning.c similarity index 100% rename from firmware/hackrf_usb/tuning.c rename to firmware/common/tuning.c diff --git a/firmware/hackrf_usb/tuning.h b/firmware/common/tuning.h similarity index 100% rename from firmware/hackrf_usb/tuning.h rename to firmware/common/tuning.h diff --git a/firmware/hackrf_usb/usb.c b/firmware/common/usb.c similarity index 100% rename from firmware/hackrf_usb/usb.c rename to firmware/common/usb.c diff --git a/firmware/hackrf_usb/usb.h b/firmware/common/usb.h similarity index 100% rename from firmware/hackrf_usb/usb.h rename to firmware/common/usb.h diff --git a/firmware/hackrf_usb/usb_queue.c b/firmware/common/usb_queue.c similarity index 100% rename from firmware/hackrf_usb/usb_queue.c rename to firmware/common/usb_queue.c diff --git a/firmware/hackrf_usb/usb_queue.h b/firmware/common/usb_queue.h similarity index 100% rename from firmware/hackrf_usb/usb_queue.h rename to firmware/common/usb_queue.h diff --git a/firmware/hackrf_usb/usb_request.c b/firmware/common/usb_request.c similarity index 100% rename from firmware/hackrf_usb/usb_request.c rename to firmware/common/usb_request.c diff --git a/firmware/hackrf_usb/usb_request.h b/firmware/common/usb_request.h similarity index 100% rename from firmware/hackrf_usb/usb_request.h rename to firmware/common/usb_request.h diff --git a/firmware/hackrf_usb/usb_standard_request.c b/firmware/common/usb_standard_request.c similarity index 100% rename from firmware/hackrf_usb/usb_standard_request.c rename to firmware/common/usb_standard_request.c diff --git a/firmware/hackrf_usb/usb_standard_request.h b/firmware/common/usb_standard_request.h similarity index 100% rename from firmware/hackrf_usb/usb_standard_request.h rename to firmware/common/usb_standard_request.h diff --git a/firmware/hackrf_usb/usb_type.h b/firmware/common/usb_type.h similarity index 100% rename from firmware/hackrf_usb/usb_type.h rename to firmware/common/usb_type.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index acc2160a..e614197b 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -23,15 +23,15 @@ BINARY = hackrf_usb SRC = $(BINARY).c \ - rf_path.c \ - tuning.c \ + ../common/rf_path.c \ + ../common/tuning.c \ sgpio_isr.c \ usb_bulk_buffer.c \ - usb.c \ - usb_request.c \ - usb_standard_request.c \ + ../common/usb.c \ + ../common/usb_request.c \ + ../common/usb_standard_request.c \ usb_descriptor.c \ - usb_queue.c \ + ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ ../common/sgpio.c \ diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram index a574692b..da116198 100644 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ b/firmware/hackrf_usb/Makefile_rom_to_ram @@ -23,14 +23,15 @@ BINARY = hackrf_usb_rom_to_ram SRC = hackrf_usb.c \ - rf_path.c \ - tuning.c \ + ../common/rf_path.c \ + ../common/tuning.c \ sgpio_isr.c \ usb_bulk_buffer.c \ - usb.c \ - usb_request.c \ - usb_standard_request.c \ + ../common/usb.c \ + ../common/usb_request.c \ + ../common/usb_standard_request.c \ usb_descriptor.c \ + ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ ../common/sgpio.c \ diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index 22a45d9c..2a76c088 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -25,15 +25,15 @@ BINARY = hackrf_usb_rom_to_ram SRC_DIR = hackrf_usb SRC = hackrf_usb.c \ - rf_path.c \ - tuning.c \ + ../common/rf_path.c \ + ../common/tuning.c \ sgpio_isr.c \ usb_bulk_buffer.c \ - usb.c \ - usb_request.c \ - usb_standard_request.c \ + ../common/usb.c \ + ../common/usb_request.c \ + ../common/usb_standard_request.c \ usb_descriptor.c \ - usb_queue.c \ + ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ ../common/sgpio.c \ From e02d2f0325d001b2a2ae31876dc5f05e0c55afb0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 15:13:12 -0700 Subject: [PATCH 106/200] Remove dependencies on application-specific USB descriptors. --- firmware/common/usb_standard_request.c | 9 ++++----- firmware/common/usb_type.h | 2 ++ firmware/hackrf_usb/hackrf_usb.c | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/firmware/common/usb_standard_request.c b/firmware/common/usb_standard_request.c index fafc5c55..43b11151 100644 --- a/firmware/common/usb_standard_request.c +++ b/firmware/common/usb_standard_request.c @@ -26,7 +26,6 @@ #include "usb.h" #include "usb_type.h" -#include "usb_descriptor.h" #include "usb_queue.h" const uint8_t* usb_endpoint_descriptor( @@ -132,9 +131,9 @@ static usb_request_status_t usb_send_descriptor_string( usb_endpoint_t* const endpoint ) { uint_fast8_t index = endpoint->setup.value_l; - for( uint_fast8_t i=0; usb_descriptor_strings[i] != 0; i++ ) { + for( uint_fast8_t i=0; endpoint->device->descriptor_strings[i] != 0; i++ ) { if( i == index ) { - return usb_send_descriptor(endpoint, usb_descriptor_strings[i]); + return usb_send_descriptor(endpoint, endpoint->device->descriptor_strings[i]); } } @@ -165,7 +164,7 @@ static usb_request_status_t usb_standard_request_get_descriptor_setup( ) { switch( endpoint->setup.value_h ) { case USB_DESCRIPTOR_TYPE_DEVICE: - return usb_send_descriptor(endpoint, usb_descriptor_device); + return usb_send_descriptor(endpoint, endpoint->device->descriptor); case USB_DESCRIPTOR_TYPE_CONFIGURATION: // TODO: Duplicated code. Refactor. @@ -176,7 +175,7 @@ static usb_request_status_t usb_standard_request_get_descriptor_setup( } case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: - return usb_send_descriptor(endpoint, usb_descriptor_device_qualifier); + return usb_send_descriptor(endpoint, endpoint->device->qualifier_descriptor); case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: // TODO: Duplicated code. Refactor. diff --git a/firmware/common/usb_type.h b/firmware/common/usb_type.h index fed3172b..8f683fc6 100644 --- a/firmware/common/usb_type.h +++ b/firmware/common/usb_type.h @@ -123,6 +123,8 @@ typedef struct { typedef struct { const uint8_t* const descriptor; + uint8_t** descriptor_strings; + const uint8_t* const qualifier_descriptor; usb_configuration_t* (*configurations)[]; const usb_configuration_t* configuration; } usb_device_t; diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 4fbae2c6..61c70430 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -108,6 +108,8 @@ usb_configuration_t* usb_configurations[] = { usb_device_t usb_device = { .descriptor = usb_descriptor_device, + .descriptor_strings = usb_descriptor_strings, + .qualifier_descriptor = usb_descriptor_device_qualifier, .configurations = &usb_configurations, .configuration = 0, }; From 0e8e3c8d53d48f0174606593d5b9ec76894543c6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 15:27:16 -0700 Subject: [PATCH 107/200] Push MAX2837 state management into rf_path_set_direction(). --- firmware/common/rf_path.c | 5 +++++ firmware/hackrf_usb/hackrf_usb.c | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index 0444ae0e..a8e10417 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -82,6 +82,8 @@ void rf_path_set_direction(const rf_path_direction_t direction) { } else { rffc5071_enable(); } + max2837_start(); + max2837_tx(); break; case RF_PATH_DIRECTION_RX: @@ -96,6 +98,8 @@ void rf_path_set_direction(const rf_path_direction_t direction) { } else { rffc5071_enable(); } + max2837_start(); + max2837_rx(); break; case RF_PATH_DIRECTION_OFF: @@ -103,6 +107,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { /* Set RF path to receive direction when "off" */ switchctrl &= ~SWITCHCTRL_TX; rffc5071_disable(); + max2837_stop(); break; } diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 61c70430..dfa361a2 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -179,23 +179,16 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_clear(PORT_LED1_3, PIN_LED3); gpio_set(PORT_LED1_3, PIN_LED2); usb_endpoint_init(&usb_endpoint_bulk_in); - rf_path_set_direction(RF_PATH_DIRECTION_RX); - max2837_start(); - max2837_rx(); } else if (transceiver_mode == TRANSCEIVER_MODE_TX) { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_set(PORT_LED1_3, PIN_LED3); usb_endpoint_init(&usb_endpoint_bulk_out); - rf_path_set_direction(RF_PATH_DIRECTION_TX); - max2837_start(); - max2837_tx(); } else { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_clear(PORT_LED1_3, PIN_LED3); rf_path_set_direction(RF_PATH_DIRECTION_OFF); - max2837_stop(); return; } From 52dda32a1882f039f001eea5824d16b17fd8038e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 15:32:11 -0700 Subject: [PATCH 108/200] Adjust logic in sgpio_configure() to treat transceiver modes outside TX and RX as RX. "OFF", for example... --- firmware/common/sgpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index c78166fb..145ef4ad 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -181,10 +181,10 @@ void sgpio_configure( for(uint_fast8_t i=0; i Date: Tue, 17 Sep 2013 15:33:07 -0700 Subject: [PATCH 109/200] Allow set_transceiver_mode(OFF) to fall through the rest of the function, now that sgpio_configure() is expecting OFF as a value. --- firmware/hackrf_usb/hackrf_usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index dfa361a2..04ec8dc8 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -189,7 +189,6 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_clear(PORT_LED1_3, PIN_LED3); rf_path_set_direction(RF_PATH_DIRECTION_OFF); - return; } sgpio_configure(transceiver_mode, true); From b92e916b21eb3bec19066ca209c37da2072828cc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 15:36:59 -0700 Subject: [PATCH 110/200] Forgot an #include in rf_path.c, from moving MAX2837 code. --- firmware/common/rf_path.c | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index a8e10417..c241067f 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -23,6 +23,7 @@ #include "rf_path.h" #include +#include #ifdef JAWBREAKER /* From 1ec9f560b48eb8e32a696b2480c859063ffa2e38 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 17:25:00 -0700 Subject: [PATCH 111/200] Move more RF path stuff (initialization and MAX5864 state management) into rf_path.c. Changed initial RF path mode to lowest power (OFF). Remove initial MAX2837 IF setting -- it's a waste of effort when the first (and necessary) tuning operation will reset it anyway (perhaps to a different value). --- firmware/common/rf_path.c | 21 ++++++++++++++++++++- firmware/hackrf_usb/hackrf_usb.c | 10 ---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index c241067f..556f15e5 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -22,8 +22,11 @@ #include "rf_path.h" +#include + #include #include +#include #ifdef JAWBREAKER /* @@ -64,7 +67,14 @@ uint8_t switchctrl = SWITCHCTRL_SAFE; void rf_path_init(void) { - rffc5071_set_gpo(switchctrl); + ssp1_set_mode_max5864(); + max5864_shutdown(); + + ssp1_set_mode_max2837(); + max2837_setup(); + max2837_mode_shutdown(); + + rffc5071_setup(); } void rf_path_set_direction(const rf_path_direction_t direction) { @@ -83,6 +93,9 @@ void rf_path_set_direction(const rf_path_direction_t direction) { } else { rffc5071_enable(); } + ssp1_set_mode_max5864(); + max5864_tx(); + ssp1_set_mode_max2837(); max2837_start(); max2837_tx(); break; @@ -99,6 +112,9 @@ void rf_path_set_direction(const rf_path_direction_t direction) { } else { rffc5071_enable(); } + ssp1_set_mode_max5864(); + max5864_rx(); + ssp1_set_mode_max2837(); max2837_start(); max2837_rx(); break; @@ -108,6 +124,9 @@ void rf_path_set_direction(const rf_path_direction_t direction) { /* Set RF path to receive direction when "off" */ switchctrl &= ~SWITCHCTRL_TX; rffc5071_disable(); + ssp1_set_mode_max5864(); + max5864_shutdown(); + ssp1_set_mode_max2837(); max2837_stop(); break; } diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 04ec8dc8..064f1467 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -777,8 +777,6 @@ void usb_configuration_changed( } int main(void) { - const uint32_t ifreq = 2600000000U; - pin_setup(); enable_1v8_power(); cpu_clock_init(); @@ -801,15 +799,7 @@ int main(void) { usb_run(&usb_device); ssp1_init(); - ssp1_set_mode_max5864(); - max5864_xcvr(); - ssp1_set_mode_max2837(); - max2837_setup(); - max2837_set_frequency(ifreq); - - rffc5071_setup(); - rf_path_init(); unsigned int phase = 0; From 04e70483a212005bbf9c031d341180f7779098a0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 21:59:01 -0700 Subject: [PATCH 112/200] Move RF path configuration to early in the tuning process -- before the MAX2837 is tuned. --- firmware/common/tuning.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/common/tuning.c b/firmware/common/tuning.c index ea7db767..a73c2f0d 100644 --- a/firmware/common/tuning.c +++ b/firmware/common/tuning.c @@ -63,6 +63,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) { if(freq_mhz < MAX_LP_FREQ_MHZ) { + rf_path_set_filter(RF_PATH_FILTER_LOW_PASS); RFFC5071_freq_mhz = MAX2837_FREQ_NOMINAL_MHZ - freq_mhz; /* Set Freq and read real freq */ real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); @@ -75,15 +76,15 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) } MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; max2837_set_frequency(MAX2837_freq_hz); - rf_path_set_filter(RF_PATH_FILTER_LOW_PASS); }else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) { + rf_path_set_filter(RF_PATH_FILTER_BYPASS); MAX2837_freq_hz = (freq_mhz * FREQ_ONE_MHZ) + freq_hz; /* RFFC5071_freq_mhz <= not used in Bypass mode */ max2837_set_frequency(MAX2837_freq_hz); - rf_path_set_filter(RF_PATH_FILTER_BYPASS); }else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz < MAX_HP_FREQ_MHZ) ) { + rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS); RFFC5071_freq_mhz = freq_mhz - MAX2837_FREQ_NOMINAL_MHZ; /* Set Freq and read real freq */ real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); @@ -96,7 +97,6 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) } MAX2837_freq_hz = max2837_freq_nominal_hz + tmp_hz + freq_hz; max2837_set_frequency(MAX2837_freq_hz); - rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS); }else { /* Error freq_mhz too high */ From 76704be0087ec01c3d6b359869817ee72045528d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 22:21:11 -0700 Subject: [PATCH 113/200] Remove unused local variable causing a compiler warning. --- firmware/common/hackrf_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 66529a34..9c3681e6 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -239,8 +239,6 @@ Configure PLL1 to max speed (204MHz). Note: PLL1 clock is used by M4/M0 core, Peripheral, APB1. */ void cpu_clock_init(void) { - uint32_t pll_reg; - /* use IRC as clock source for APB1 (including I2C0) */ CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_IRC); From aebea16b0f19f4d7a3fd66eea4dacf96213d4aa5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 22:23:18 -0700 Subject: [PATCH 114/200] Remove USB endpoint fiddling from baseband_streaming_disable(). Create baseband_streaming_enable() to do SGPIO IRQ and stream enable. --- firmware/hackrf_usb/hackrf_usb.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 064f1467..342ec163 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -161,18 +161,26 @@ usb_endpoint_t usb_endpoint_bulk_out = { }; static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 4); +void baseband_streaming_enable() { + nvic_set_priority(NVIC_SGPIO_IRQ, 0); + nvic_enable_irq(NVIC_SGPIO_IRQ); + SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); + + sgpio_cpld_stream_enable(); +} + void baseband_streaming_disable() { sgpio_cpld_stream_disable(); nvic_disable_irq(NVIC_SGPIO_IRQ); - - usb_endpoint_disable(&usb_endpoint_bulk_in); - usb_endpoint_disable(&usb_endpoint_bulk_out); } void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { baseband_streaming_disable(); + usb_endpoint_disable(&usb_endpoint_bulk_in); + usb_endpoint_disable(&usb_endpoint_bulk_out); + transceiver_mode = new_transceiver_mode; if( transceiver_mode == TRANSCEIVER_MODE_RX ) { @@ -199,12 +207,7 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { sgpio_isr_fn = sgpio_isr_tx; } vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_fn; - - nvic_set_priority(NVIC_SGPIO_IRQ, 0); - nvic_enable_irq(NVIC_SGPIO_IRQ); - SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); - - sgpio_cpld_stream_enable(); + baseband_streaming_enable(); } } From 2e2275ed518419f0b549b8192996d38b54bfa317 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 22:29:41 -0700 Subject: [PATCH 115/200] Pull out leaky tri-state transceiver_mode value from sgpio_configure(), replace with SGPIO_DIRECTION_* #defines. --- firmware/common/sgpio.c | 12 +++++++----- firmware/common/sgpio.h | 7 ++++++- firmware/hackrf_usb/hackrf_usb.c | 5 +++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 145ef4ad..5e49c85c 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -25,6 +25,8 @@ #include +#include + void sgpio_configure_pin_functions() { scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); @@ -104,7 +106,7 @@ void sgpio_test_interface() { SGPIO11 Direction Output (1/High=TX mode LPC43xx=>CPLD=>DAC, 0/Low=RX mode LPC43xx<=CPLD<=ADC) */ void sgpio_configure( - const transceiver_mode_t transceiver_mode, + const sgpio_direction_t direction, const bool multi_slice ) { // Disable all counters during configuration @@ -114,7 +116,7 @@ void sgpio_configure( // Set SGPIO output values. const uint_fast8_t cpld_direction = - (transceiver_mode == TRANSCEIVER_MODE_TX) ? 1 : 0; + (direction == SGPIO_DIRECTION_TX) ? 1 : 0; SGPIO_GPIO_OUTREG = (cpld_direction << 11) /* 1=Output SGPIO11 High(TX mode), 0=Output SGPIO11 Low(RX mode)*/ | (1L << 10) // disable codec data stream during configuration (Output SGPIO10 High) @@ -122,7 +124,7 @@ void sgpio_configure( // Enable SGPIO pin outputs. const uint_fast16_t sgpio_gpio_data_direction = - (transceiver_mode == TRANSCEIVER_MODE_TX) + (direction == SGPIO_DIRECTION_TX) ? (0xFF << 0) : (0x00 << 0); SGPIO_GPIO_OENREG = @@ -181,10 +183,10 @@ void sgpio_configure( for(uint_fast8_t i=0; i +typedef enum { + SGPIO_DIRECTION_RX, + SGPIO_DIRECTION_TX, +} sgpio_direction_t; + void sgpio_configure_pin_functions(); void sgpio_test_interface(); void sgpio_configure( - const transceiver_mode_t transceiver_mode, + const sgpio_direction_t direction, const bool multi_slice ); void sgpio_cpld_stream_enable(); diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 342ec163..85d01a94 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -188,19 +188,20 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_set(PORT_LED1_3, PIN_LED2); usb_endpoint_init(&usb_endpoint_bulk_in); rf_path_set_direction(RF_PATH_DIRECTION_RX); + sgpio_configure(SGPIO_DIRECTION_RX, true); } else if (transceiver_mode == TRANSCEIVER_MODE_TX) { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_set(PORT_LED1_3, PIN_LED3); usb_endpoint_init(&usb_endpoint_bulk_out); rf_path_set_direction(RF_PATH_DIRECTION_TX); + sgpio_configure(SGPIO_DIRECTION_TX, true); } else { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_clear(PORT_LED1_3, PIN_LED3); rf_path_set_direction(RF_PATH_DIRECTION_OFF); + sgpio_configure(SGPIO_DIRECTION_RX, true); } - sgpio_configure(transceiver_mode, true); - if( transceiver_mode != TRANSCEIVER_MODE_OFF ) { vector_table_entry_t sgpio_isr_fn = sgpio_isr_rx; if( transceiver_mode == TRANSCEIVER_MODE_TX ) { From c06facdd25773621855818fa9acb639fb7bc833a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 22:32:10 -0700 Subject: [PATCH 116/200] Push SGPIO configuration into RF path API. --- firmware/common/rf_path.c | 4 ++++ firmware/hackrf_usb/hackrf_usb.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index 556f15e5..95d55db2 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef JAWBREAKER /* @@ -98,6 +99,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { ssp1_set_mode_max2837(); max2837_start(); max2837_tx(); + sgpio_configure(SGPIO_DIRECTION_TX, true); break; case RF_PATH_DIRECTION_RX: @@ -117,6 +119,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { ssp1_set_mode_max2837(); max2837_start(); max2837_rx(); + sgpio_configure(SGPIO_DIRECTION_RX, true); break; case RF_PATH_DIRECTION_OFF: @@ -128,6 +131,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { max5864_shutdown(); ssp1_set_mode_max2837(); max2837_stop(); + sgpio_configure(SGPIO_DIRECTION_RX, true); break; } diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 85d01a94..e09647fa 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -188,18 +188,15 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_set(PORT_LED1_3, PIN_LED2); usb_endpoint_init(&usb_endpoint_bulk_in); rf_path_set_direction(RF_PATH_DIRECTION_RX); - sgpio_configure(SGPIO_DIRECTION_RX, true); } else if (transceiver_mode == TRANSCEIVER_MODE_TX) { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_set(PORT_LED1_3, PIN_LED3); usb_endpoint_init(&usb_endpoint_bulk_out); rf_path_set_direction(RF_PATH_DIRECTION_TX); - sgpio_configure(SGPIO_DIRECTION_TX, true); } else { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_clear(PORT_LED1_3, PIN_LED3); rf_path_set_direction(RF_PATH_DIRECTION_OFF); - sgpio_configure(SGPIO_DIRECTION_RX, true); } if( transceiver_mode != TRANSCEIVER_MODE_OFF ) { From 5b7b98be6c52989f980889d944d2db0985b2577c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 17 Sep 2013 22:37:40 -0700 Subject: [PATCH 117/200] Clean up SGPIO vector assignment code. --- firmware/hackrf_usb/hackrf_usb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index e09647fa..6f4d1fdf 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -188,23 +188,21 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { gpio_set(PORT_LED1_3, PIN_LED2); usb_endpoint_init(&usb_endpoint_bulk_in); rf_path_set_direction(RF_PATH_DIRECTION_RX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; } else if (transceiver_mode == TRANSCEIVER_MODE_TX) { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_set(PORT_LED1_3, PIN_LED3); usb_endpoint_init(&usb_endpoint_bulk_out); rf_path_set_direction(RF_PATH_DIRECTION_TX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx; } else { gpio_clear(PORT_LED1_3, PIN_LED2); gpio_clear(PORT_LED1_3, PIN_LED3); rf_path_set_direction(RF_PATH_DIRECTION_OFF); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; } if( transceiver_mode != TRANSCEIVER_MODE_OFF ) { - vector_table_entry_t sgpio_isr_fn = sgpio_isr_rx; - if( transceiver_mode == TRANSCEIVER_MODE_TX ) { - sgpio_isr_fn = sgpio_isr_tx; - } - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_fn; baseband_streaming_enable(); } } From 82ce660932e781e24b673e727a4fd9c977b38ca9 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 19 Sep 2013 19:51:32 -0700 Subject: [PATCH 118/200] Broke some application-specific USB code into separate files within hackrf_usb/. Hoping I can use them as necessary in other projects, or push them into a library eventually. --- firmware/common/usb_queue.h | 2 + firmware/hackrf_usb/Makefile | 2 + firmware/hackrf_usb/hackrf_usb.c | 91 ++---------------------------- firmware/hackrf_usb/usb_device.c | 67 ++++++++++++++++++++++ firmware/hackrf_usb/usb_device.h | 30 ++++++++++ firmware/hackrf_usb/usb_endpoint.c | 73 ++++++++++++++++++++++++ firmware/hackrf_usb/usb_endpoint.h | 41 ++++++++++++++ 7 files changed, 219 insertions(+), 87 deletions(-) create mode 100644 firmware/hackrf_usb/usb_device.c create mode 100644 firmware/hackrf_usb/usb_device.h create mode 100644 firmware/hackrf_usb/usb_endpoint.c create mode 100644 firmware/hackrf_usb/usb_endpoint.h diff --git a/firmware/common/usb_queue.h b/firmware/common/usb_queue.h index 2332022c..36663427 100644 --- a/firmware/common/usb_queue.h +++ b/firmware/common/usb_queue.h @@ -49,6 +49,8 @@ struct _usb_queue_t { usb_transfer_t* volatile active; }; +#define USB_DECLARE_QUEUE(endpoint_name) \ + struct _usb_queue_t endpoint_name##_queue; #define USB_DEFINE_QUEUE(endpoint_name, _pool_size) \ struct _usb_transfer_t endpoint_name##_transfers[_pool_size]; \ struct _usb_queue_t endpoint_name##_queue = { \ diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index e614197b..69d31197 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -31,6 +31,8 @@ SRC = $(BINARY).c \ ../common/usb_request.c \ ../common/usb_standard_request.c \ usb_descriptor.c \ + usb_device.c \ + usb_endpoint.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 6f4d1fdf..25c23866 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -46,6 +46,10 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" +#include "usb_device.h" +#include "usb_endpoint.h" +#include "usb_api_cpld.h" + #include "rf_path.h" #include "tuning.h" #include "sgpio_isr.h" @@ -74,93 +78,6 @@ typedef struct { set_sample_r_params_t set_sample_r_params; -usb_configuration_t usb_configuration_high_speed = { - .number = 1, - .speed = USB_SPEED_HIGH, - .descriptor = usb_descriptor_configuration_high_speed, -}; - -usb_configuration_t usb_configuration_full_speed = { - .number = 1, - .speed = USB_SPEED_FULL, - .descriptor = usb_descriptor_configuration_full_speed, -}; - -usb_configuration_t usb_configuration_cpld_update_full_speed = { - .number = 2, - .speed = USB_SPEED_FULL, - .descriptor = usb_descriptor_configuration_cpld_update_full_speed, -}; - -usb_configuration_t usb_configuration_cpld_update_high_speed = { - .number = 2, - .speed = USB_SPEED_HIGH, - .descriptor = usb_descriptor_configuration_cpld_update_high_speed, -}; - -usb_configuration_t* usb_configurations[] = { - &usb_configuration_high_speed, - &usb_configuration_full_speed, - &usb_configuration_cpld_update_full_speed, - &usb_configuration_cpld_update_high_speed, - 0, -}; - -usb_device_t usb_device = { - .descriptor = usb_descriptor_device, - .descriptor_strings = usb_descriptor_strings, - .qualifier_descriptor = usb_descriptor_device_qualifier, - .configurations = &usb_configurations, - .configuration = 0, -}; - -usb_endpoint_t usb_endpoint_control_out; -usb_endpoint_t usb_endpoint_control_in; - -usb_endpoint_t usb_endpoint_control_out = { - .address = 0x00, - .device = &usb_device, - .in = &usb_endpoint_control_in, - .out = &usb_endpoint_control_out, - .setup_complete = usb_setup_complete, - .transfer_complete = usb_control_out_complete, -}; -USB_DEFINE_QUEUE(usb_endpoint_control_out, 4); - -usb_endpoint_t usb_endpoint_control_in = { - .address = 0x80, - .device = &usb_device, - .in = &usb_endpoint_control_in, - .out = &usb_endpoint_control_out, - .setup_complete = 0, - .transfer_complete = usb_control_in_complete, -}; -static USB_DEFINE_QUEUE(usb_endpoint_control_in, 4); - -// NOTE: Endpoint number for IN and OUT are different. I wish I had some -// evidence that having BULK IN and OUT on separate endpoint numbers was -// actually a good idea. Seems like everybody does it that way, but why? - -usb_endpoint_t usb_endpoint_bulk_in = { - .address = 0x81, - .device = &usb_device, - .in = &usb_endpoint_bulk_in, - .out = 0, - .setup_complete = 0, - .transfer_complete = usb_queue_transfer_complete -}; -static USB_DEFINE_QUEUE(usb_endpoint_bulk_in, 4); - -usb_endpoint_t usb_endpoint_bulk_out = { - .address = 0x02, - .device = &usb_device, - .in = 0, - .out = &usb_endpoint_bulk_out, - .setup_complete = 0, - .transfer_complete = usb_queue_transfer_complete -}; -static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 4); - void baseband_streaming_enable() { nvic_set_priority(NVIC_SGPIO_IRQ, 0); nvic_enable_irq(NVIC_SGPIO_IRQ); diff --git a/firmware/hackrf_usb/usb_device.c b/firmware/hackrf_usb/usb_device.c new file mode 100644 index 00000000..6df358ed --- /dev/null +++ b/firmware/hackrf_usb/usb_device.c @@ -0,0 +1,67 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_device.h" + +#include + +#include "usb_descriptor.h" + +usb_configuration_t usb_configuration_high_speed = { + .number = 1, + .speed = USB_SPEED_HIGH, + .descriptor = usb_descriptor_configuration_high_speed, +}; + +usb_configuration_t usb_configuration_full_speed = { + .number = 1, + .speed = USB_SPEED_FULL, + .descriptor = usb_descriptor_configuration_full_speed, +}; + +usb_configuration_t usb_configuration_cpld_update_full_speed = { + .number = 2, + .speed = USB_SPEED_FULL, + .descriptor = usb_descriptor_configuration_cpld_update_full_speed, +}; + +usb_configuration_t usb_configuration_cpld_update_high_speed = { + .number = 2, + .speed = USB_SPEED_HIGH, + .descriptor = usb_descriptor_configuration_cpld_update_high_speed, +}; + +usb_configuration_t* usb_configurations[] = { + &usb_configuration_high_speed, + &usb_configuration_full_speed, + &usb_configuration_cpld_update_full_speed, + &usb_configuration_cpld_update_high_speed, + 0, +}; + +usb_device_t usb_device = { + .descriptor = usb_descriptor_device, + .descriptor_strings = usb_descriptor_strings, + .qualifier_descriptor = usb_descriptor_device_qualifier, + .configurations = &usb_configurations, + .configuration = 0, +}; diff --git a/firmware/hackrf_usb/usb_device.h b/firmware/hackrf_usb/usb_device.h new file mode 100644 index 00000000..8efada7d --- /dev/null +++ b/firmware/hackrf_usb/usb_device.h @@ -0,0 +1,30 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_DEVICE_H__ +#define __USB_DEVICE_H__ + +#include + +extern usb_device_t usb_device; + +#endif /* end of include guard: __USB_DEVICE_H__ */ diff --git a/firmware/hackrf_usb/usb_endpoint.c b/firmware/hackrf_usb/usb_endpoint.c new file mode 100644 index 00000000..c965287f --- /dev/null +++ b/firmware/hackrf_usb/usb_endpoint.c @@ -0,0 +1,73 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_endpoint.h" + +#include + +#include "usb_device.h" + +usb_endpoint_t usb_endpoint_control_out = { + .address = 0x00, + .device = &usb_device, + .in = &usb_endpoint_control_in, + .out = &usb_endpoint_control_out, + .setup_complete = usb_setup_complete, + .transfer_complete = usb_control_out_complete, +}; +USB_DEFINE_QUEUE(usb_endpoint_control_out, 4); + +usb_endpoint_t usb_endpoint_control_in = { + .address = 0x80, + .device = &usb_device, + .in = &usb_endpoint_control_in, + .out = &usb_endpoint_control_out, + .setup_complete = 0, + .transfer_complete = usb_control_in_complete, +}; +static USB_DEFINE_QUEUE(usb_endpoint_control_in, 4); + +// NOTE: Endpoint number for IN and OUT are different. I wish I had some +// evidence that having BULK IN and OUT on separate endpoint numbers was +// actually a good idea. Seems like everybody does it that way, but why? + +usb_endpoint_t usb_endpoint_bulk_in = { + .address = 0x81, + .device = &usb_device, + .in = &usb_endpoint_bulk_in, + .out = 0, + .setup_complete = 0, + .transfer_complete = usb_queue_transfer_complete +}; +static USB_DEFINE_QUEUE(usb_endpoint_bulk_in, 4); + +usb_endpoint_t usb_endpoint_bulk_out = { + .address = 0x02, + .device = &usb_device, + .in = 0, + .out = &usb_endpoint_bulk_out, + .setup_complete = 0, + .transfer_complete = usb_queue_transfer_complete +}; +static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 4); + + diff --git a/firmware/hackrf_usb/usb_endpoint.h b/firmware/hackrf_usb/usb_endpoint.h new file mode 100644 index 00000000..bed1d3ce --- /dev/null +++ b/firmware/hackrf_usb/usb_endpoint.h @@ -0,0 +1,41 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_ENDPOINT_H__ +#define __USB_ENDPOINT_H__ + +#include +#include + +extern usb_endpoint_t usb_endpoint_control_out; +extern USB_DECLARE_QUEUE(usb_endpoint_control_out); + +extern usb_endpoint_t usb_endpoint_control_in; +extern USB_DECLARE_QUEUE(usb_endpoint_control_in); + +extern usb_endpoint_t usb_endpoint_bulk_in; +extern USB_DECLARE_QUEUE(usb_endpoint_bulk_in); + +extern usb_endpoint_t usb_endpoint_bulk_out; +extern USB_DECLARE_QUEUE(usb_endpoint_bulk_out); + +#endif /* end of include guard: __USB_ENDPOINT_H__ */ From f7a42e074784d2e93715a7bb36721d0082d1abb4 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 19 Sep 2013 19:52:14 -0700 Subject: [PATCH 119/200] Move USB API for CPLD management into separate files. --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/hackrf_usb.c | 60 ------------------- firmware/hackrf_usb/usb_api_cpld.c | 94 ++++++++++++++++++++++++++++++ firmware/hackrf_usb/usb_api_cpld.h | 32 ++++++++++ 4 files changed, 127 insertions(+), 60 deletions(-) create mode 100644 firmware/hackrf_usb/usb_api_cpld.c create mode 100644 firmware/hackrf_usb/usb_api_cpld.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 69d31197..98f21440 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -33,6 +33,7 @@ SRC = $(BINARY).c \ usb_descriptor.c \ usb_device.c \ usb_endpoint.c \ + usb_api_cpld.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 25c23866..0b52613d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -57,10 +56,6 @@ static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; -static volatile bool start_cpld_update = false; -uint8_t cpld_xsvf_buffer[512]; -volatile bool cpld_wait = false; - uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN]; char version_string[] = VERSION_STRING; @@ -616,61 +611,6 @@ const usb_request_handlers_t usb_request_handlers = { .reserved = 0, }; -static void cpld_buffer_refilled(void* user_data, unsigned int length) -{ - cpld_wait = false; -} - -static void refill_cpld_buffer(void) -{ - cpld_wait = true; - usb_transfer_schedule( - &usb_endpoint_bulk_out, - cpld_xsvf_buffer, - sizeof(cpld_xsvf_buffer), - cpld_buffer_refilled, - NULL - ); - - // Wait until transfer finishes - while (cpld_wait); -} - -static void cpld_update(void) -{ - #define WAIT_LOOP_DELAY (6000000) - #define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3) - int i; - int error; - - usb_queue_flush_endpoint(&usb_endpoint_bulk_in); - usb_queue_flush_endpoint(&usb_endpoint_bulk_out); - - refill_cpld_buffer(); - - error = cpld_jtag_program(sizeof(cpld_xsvf_buffer), - cpld_xsvf_buffer, - refill_cpld_buffer); - if(error == 0) - { - /* blink LED1, LED2, and LED3 on success */ - while (1) - { - gpio_set(PORT_LED1_3, ALL_LEDS); /* LEDs on */ - for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ - __asm__("nop"); - gpio_clear(PORT_LED1_3, ALL_LEDS); /* LEDs off */ - for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ - __asm__("nop"); - } - }else - { - /* LED3 (Red) steady on error */ - gpio_set(PORT_LED1_3, PIN_LED3); /* LEDs on */ - while (1); - } -} - void usb_configuration_changed( usb_device_t* const device ) { diff --git a/firmware/hackrf_usb/usb_api_cpld.c b/firmware/hackrf_usb/usb_api_cpld.c new file mode 100644 index 00000000..e29007c5 --- /dev/null +++ b/firmware/hackrf_usb/usb_api_cpld.c @@ -0,0 +1,94 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_api_cpld.h" + +#include + +#include +#include +#include + +#include "usb_endpoint.h" + +#include +#include +#include + +volatile bool start_cpld_update = false; +uint8_t cpld_xsvf_buffer[512]; +volatile bool cpld_wait = false; + +static void cpld_buffer_refilled(void* user_data, unsigned int length) +{ + cpld_wait = false; +} + +static void refill_cpld_buffer(void) +{ + cpld_wait = true; + usb_transfer_schedule( + &usb_endpoint_bulk_out, + cpld_xsvf_buffer, + sizeof(cpld_xsvf_buffer), + cpld_buffer_refilled, + NULL + ); + + // Wait until transfer finishes + while (cpld_wait); +} + +void cpld_update(void) +{ + #define WAIT_LOOP_DELAY (6000000) + #define ALL_LEDS (PIN_LED1|PIN_LED2|PIN_LED3) + int i; + int error; + + usb_queue_flush_endpoint(&usb_endpoint_bulk_in); + usb_queue_flush_endpoint(&usb_endpoint_bulk_out); + + refill_cpld_buffer(); + + error = cpld_jtag_program(sizeof(cpld_xsvf_buffer), + cpld_xsvf_buffer, + refill_cpld_buffer); + if(error == 0) + { + /* blink LED1, LED2, and LED3 on success */ + while (1) + { + gpio_set(PORT_LED1_3, ALL_LEDS); /* LEDs on */ + for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ + __asm__("nop"); + gpio_clear(PORT_LED1_3, ALL_LEDS); /* LEDs off */ + for (i = 0; i < WAIT_LOOP_DELAY; i++) /* Wait a bit. */ + __asm__("nop"); + } + }else + { + /* LED3 (Red) steady on error */ + gpio_set(PORT_LED1_3, PIN_LED3); /* LEDs on */ + while (1); + } +} diff --git a/firmware/hackrf_usb/usb_api_cpld.h b/firmware/hackrf_usb/usb_api_cpld.h new file mode 100644 index 00000000..5bafdfef --- /dev/null +++ b/firmware/hackrf_usb/usb_api_cpld.h @@ -0,0 +1,32 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_API_CPLD_H__ +#define __USB_API_CPLD_H__ + +#include + +extern volatile bool start_cpld_update; + +void cpld_update(void); + +#endif /* end of include guard: __USB_API_CPLD_H__ */ From cde5e1af8a539d3f0ebf2c2118c3730472f96aca Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 19 Sep 2013 22:29:49 -0700 Subject: [PATCH 120/200] Extracted USB API for SPI flash erase/write/read into separate files. --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/hackrf_usb.c | 102 +------------------ firmware/hackrf_usb/usb_api_spiflash.c | 131 +++++++++++++++++++++++++ firmware/hackrf_usb/usb_api_spiflash.h | 36 +++++++ 4 files changed, 169 insertions(+), 101 deletions(-) create mode 100644 firmware/hackrf_usb/usb_api_spiflash.c create mode 100644 firmware/hackrf_usb/usb_api_spiflash.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 98f21440..491cd635 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -34,6 +34,7 @@ SRC = $(BINARY).c \ usb_device.c \ usb_endpoint.c \ usb_api_cpld.c \ + usb_api_spiflash.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 0b52613d..fb5eb0b6 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -48,6 +48,7 @@ #include "usb_device.h" #include "usb_endpoint.h" #include "usb_api_cpld.h" +#include "usb_api_spiflash.h" #include "rf_path.h" #include "tuning.h" @@ -56,7 +57,6 @@ static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; -uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN]; char version_string[] = VERSION_STRING; typedef struct { @@ -270,106 +270,6 @@ usb_request_status_t usb_vendor_request_read_rffc5071( return USB_REQUEST_STATUS_OK; } } - -usb_request_status_t usb_vendor_request_erase_spiflash( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - //FIXME This should refuse to run if executing from SPI flash. - - if (stage == USB_TRANSFER_STAGE_SETUP) { - w25q80bv_setup(); - /* only chip erase is implemented */ - w25q80bv_chip_erase(); - usb_transfer_schedule_ack(endpoint->in); - //FIXME probably should undo w25q80bv_setup() - } - return USB_REQUEST_STATUS_OK; -} - -usb_request_status_t usb_vendor_request_write_spiflash( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - uint32_t addr = 0; - uint16_t len = 0; - - //FIXME This should refuse to run if executing from SPI flash. - - if (stage == USB_TRANSFER_STAGE_SETUP) { - addr = (endpoint->setup.value << 16) | endpoint->setup.index; - len = endpoint->setup.length; - if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) - || ((addr + len) > W25Q80BV_NUM_BYTES)) { - return USB_REQUEST_STATUS_STALL; - } else { - usb_transfer_schedule_block(endpoint->out, &spiflash_buffer[0], len, - NULL, NULL); - w25q80bv_setup(); - return USB_REQUEST_STATUS_OK; - } - } else if (stage == USB_TRANSFER_STAGE_DATA) { - addr = (endpoint->setup.value << 16) | endpoint->setup.index; - len = endpoint->setup.length; - /* This check is redundant but makes me feel better. */ - if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) - || ((addr + len) > W25Q80BV_NUM_BYTES)) { - return USB_REQUEST_STATUS_STALL; - } else { - w25q80bv_program(addr, len, &spiflash_buffer[0]); - usb_transfer_schedule_ack(endpoint->in); - //FIXME probably should undo w25q80bv_setup() - return USB_REQUEST_STATUS_OK; - } - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_read_spiflash( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - uint32_t i; - uint32_t addr; - uint16_t len; - uint8_t* u8_addr_pt; - - if (stage == USB_TRANSFER_STAGE_SETUP) - { - addr = (endpoint->setup.value << 16) | endpoint->setup.index; - len = endpoint->setup.length; - if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) - || ((addr + len) > W25Q80BV_NUM_BYTES)) { - return USB_REQUEST_STATUS_STALL; - } else { - /* TODO flush SPIFI "cache" before to read the SPIFI memory */ - u8_addr_pt = (uint8_t*)(addr + SPIFI_DATA_UNCACHED_BASE); - for(i=0; iin, &spiflash_buffer[0], len, - NULL, NULL); - return USB_REQUEST_STATUS_OK; - } - } else if (stage == USB_TRANSFER_STAGE_DATA) - { - addr = (endpoint->setup.value << 16) | endpoint->setup.index; - len = endpoint->setup.length; - /* This check is redundant but makes me feel better. */ - if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) - || ((addr + len) > W25Q80BV_NUM_BYTES)) - { - return USB_REQUEST_STATUS_STALL; - } else - { - usb_transfer_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; - } - } else - { - return USB_REQUEST_STATUS_OK; - } -} - usb_request_status_t usb_vendor_request_read_board_id( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { diff --git a/firmware/hackrf_usb/usb_api_spiflash.c b/firmware/hackrf_usb/usb_api_spiflash.c new file mode 100644 index 00000000..93c12065 --- /dev/null +++ b/firmware/hackrf_usb/usb_api_spiflash.c @@ -0,0 +1,131 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_api_spiflash.h" + +#include "usb_queue.h" + +#include + +#include + +uint8_t spiflash_buffer[W25Q80BV_PAGE_LEN]; + +usb_request_status_t usb_vendor_request_erase_spiflash( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + //FIXME This should refuse to run if executing from SPI flash. + + if (stage == USB_TRANSFER_STAGE_SETUP) { + w25q80bv_setup(); + /* only chip erase is implemented */ + w25q80bv_chip_erase(); + usb_transfer_schedule_ack(endpoint->in); + //FIXME probably should undo w25q80bv_setup() + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_write_spiflash( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + uint32_t addr = 0; + uint16_t len = 0; + + //FIXME This should refuse to run if executing from SPI flash. + + if (stage == USB_TRANSFER_STAGE_SETUP) { + addr = (endpoint->setup.value << 16) | endpoint->setup.index; + len = endpoint->setup.length; + if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) + || ((addr + len) > W25Q80BV_NUM_BYTES)) { + return USB_REQUEST_STATUS_STALL; + } else { + usb_transfer_schedule_block(endpoint->out, &spiflash_buffer[0], len, + NULL, NULL); + w25q80bv_setup(); + return USB_REQUEST_STATUS_OK; + } + } else if (stage == USB_TRANSFER_STAGE_DATA) { + addr = (endpoint->setup.value << 16) | endpoint->setup.index; + len = endpoint->setup.length; + /* This check is redundant but makes me feel better. */ + if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) + || ((addr + len) > W25Q80BV_NUM_BYTES)) { + return USB_REQUEST_STATUS_STALL; + } else { + w25q80bv_program(addr, len, &spiflash_buffer[0]); + usb_transfer_schedule_ack(endpoint->in); + //FIXME probably should undo w25q80bv_setup() + return USB_REQUEST_STATUS_OK; + } + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_read_spiflash( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + uint32_t i; + uint32_t addr; + uint16_t len; + uint8_t* u8_addr_pt; + + if (stage == USB_TRANSFER_STAGE_SETUP) + { + addr = (endpoint->setup.value << 16) | endpoint->setup.index; + len = endpoint->setup.length; + if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) + || ((addr + len) > W25Q80BV_NUM_BYTES)) { + return USB_REQUEST_STATUS_STALL; + } else { + /* TODO flush SPIFI "cache" before to read the SPIFI memory */ + u8_addr_pt = (uint8_t*)(addr + SPIFI_DATA_UNCACHED_BASE); + for(i=0; iin, &spiflash_buffer[0], len, + NULL, NULL); + return USB_REQUEST_STATUS_OK; + } + } else if (stage == USB_TRANSFER_STAGE_DATA) + { + addr = (endpoint->setup.value << 16) | endpoint->setup.index; + len = endpoint->setup.length; + /* This check is redundant but makes me feel better. */ + if ((len > W25Q80BV_PAGE_LEN) || (addr > W25Q80BV_NUM_BYTES) + || ((addr + len) > W25Q80BV_NUM_BYTES)) + { + return USB_REQUEST_STATUS_STALL; + } else + { + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + } else + { + return USB_REQUEST_STATUS_OK; + } +} + diff --git a/firmware/hackrf_usb/usb_api_spiflash.h b/firmware/hackrf_usb/usb_api_spiflash.h new file mode 100644 index 00000000..f8f9f52e --- /dev/null +++ b/firmware/hackrf_usb/usb_api_spiflash.h @@ -0,0 +1,36 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_API_SPIFLASH_H__ +#define __USB_API_SPIFLASH_H__ + +#include +#include + +usb_request_status_t usb_vendor_request_erase_spiflash( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_write_spiflash( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_read_spiflash( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); + +#endif /* end of include guard: __USB_API_SPIFLASH_H__ */ From aab36292dbf6920a316450c36c4aed7a34359bf6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 19 Sep 2013 22:37:36 -0700 Subject: [PATCH 121/200] Moved USB API for manipulating RF chip registers into separate files. --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/hackrf_usb.c | 118 +------------------- firmware/hackrf_usb/usb_api_register.c | 147 +++++++++++++++++++++++++ firmware/hackrf_usb/usb_api_register.h | 54 +++++++++ 4 files changed, 203 insertions(+), 117 deletions(-) create mode 100644 firmware/hackrf_usb/usb_api_register.c create mode 100644 firmware/hackrf_usb/usb_api_register.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 491cd635..97c65daf 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -34,6 +34,7 @@ SRC = $(BINARY).c \ usb_device.c \ usb_endpoint.c \ usb_api_cpld.c \ + usb_api_register.c \ usb_api_spiflash.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index fb5eb0b6..9b622ab2 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -30,10 +30,8 @@ #include #include -#include #include #include -#include #include #include #include @@ -48,6 +46,7 @@ #include "usb_device.h" #include "usb_endpoint.h" #include "usb_api_cpld.h" +#include "usb_api_register.h" #include "usb_api_spiflash.h" #include "rf_path.h" @@ -139,81 +138,6 @@ usb_request_status_t usb_vendor_request_set_transceiver_mode( } } -usb_request_status_t usb_vendor_request_write_max2837( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( endpoint->setup.index < MAX2837_NUM_REGS ) { - if( endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE ) { - max2837_reg_write(endpoint->setup.index, endpoint->setup.value); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - } - } - return USB_REQUEST_STATUS_STALL; - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_read_max2837( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( endpoint->setup.index < MAX2837_NUM_REGS ) { - const uint16_t value = max2837_reg_read(endpoint->setup.index); - endpoint->buffer[0] = value & 0xff; - endpoint->buffer[1] = value >> 8; - usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, - NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_STALL; - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_write_si5351c( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( endpoint->setup.index < 256 ) { - if( endpoint->setup.value < 256 ) { - si5351c_write_single(endpoint->setup.index, endpoint->setup.value); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - } - } - return USB_REQUEST_STATUS_STALL; - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_read_si5351c( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( endpoint->setup.index < 256 ) { - const uint8_t value = si5351c_read_single(endpoint->setup.index); - endpoint->buffer[0] = value; - usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, - NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_STALL; - } else { - return USB_REQUEST_STATUS_OK; - } -} - usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage @@ -230,46 +154,6 @@ usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( } } -usb_request_status_t usb_vendor_request_write_rffc5071( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) - { - if( endpoint->setup.index < RFFC5071_NUM_REGS ) - { - rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_STALL; - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_read_rffc5071( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - uint16_t value; - if( stage == USB_TRANSFER_STAGE_SETUP ) - { - if( endpoint->setup.index < RFFC5071_NUM_REGS ) - { - value = rffc5071_reg_read(endpoint->setup.index); - endpoint->buffer[0] = value & 0xff; - endpoint->buffer[1] = value >> 8; - usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, - NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_STALL; - } else { - return USB_REQUEST_STATUS_OK; - } -} usb_request_status_t usb_vendor_request_read_board_id( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { diff --git a/firmware/hackrf_usb/usb_api_register.c b/firmware/hackrf_usb/usb_api_register.c new file mode 100644 index 00000000..d822c924 --- /dev/null +++ b/firmware/hackrf_usb/usb_api_register.c @@ -0,0 +1,147 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_api_register.h" + +#include +#include +#include +#include + +#include +#include + +usb_request_status_t usb_vendor_request_write_max2837( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + if( endpoint->setup.index < MAX2837_NUM_REGS ) { + if( endpoint->setup.value < MAX2837_DATA_REGS_MAX_VALUE ) { + max2837_reg_write(endpoint->setup.index, endpoint->setup.value); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_read_max2837( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + if( endpoint->setup.index < MAX2837_NUM_REGS ) { + const uint16_t value = max2837_reg_read(endpoint->setup.index); + endpoint->buffer[0] = value & 0xff; + endpoint->buffer[1] = value >> 8; + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_write_si5351c( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + if( endpoint->setup.index < 256 ) { + if( endpoint->setup.value < 256 ) { + si5351c_write_single(endpoint->setup.index, endpoint->setup.value); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_read_si5351c( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + if( endpoint->setup.index < 256 ) { + const uint8_t value = si5351c_read_single(endpoint->setup.index); + endpoint->buffer[0] = value; + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_write_rffc5071( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) + { + if( endpoint->setup.index < RFFC5071_NUM_REGS ) + { + rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_read_rffc5071( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + uint16_t value; + if( stage == USB_TRANSFER_STAGE_SETUP ) + { + if( endpoint->setup.index < RFFC5071_NUM_REGS ) + { + value = rffc5071_reg_read(endpoint->setup.index); + endpoint->buffer[0] = value & 0xff; + endpoint->buffer[1] = value >> 8; + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} diff --git a/firmware/hackrf_usb/usb_api_register.h b/firmware/hackrf_usb/usb_api_register.h new file mode 100644 index 00000000..06eb8df7 --- /dev/null +++ b/firmware/hackrf_usb/usb_api_register.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_API_REGISTER_H__ +#define __USB_API_REGISTER_H__ + +#include +#include + +usb_request_status_t usb_vendor_request_write_max2837( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +); +usb_request_status_t usb_vendor_request_read_max2837( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +); +usb_request_status_t usb_vendor_request_write_si5351c( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +); +usb_request_status_t usb_vendor_request_read_si5351c( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +); +usb_request_status_t usb_vendor_request_write_rffc5071( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +); +usb_request_status_t usb_vendor_request_read_rffc5071( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +); + +#endif /* end of include guard: __USB_API_REGISTER_H__ */ From 9120e0b7baaea5c788b5aa549a928f4709225b88 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 19 Sep 2013 22:45:38 -0700 Subject: [PATCH 122/200] Extracted USB API for board information into separate files. --- firmware/hackrf_usb/Makefile | 1 + firmware/hackrf_usb/hackrf_usb.c | 70 +----------------- firmware/hackrf_usb/usb_api_board_info.c | 93 ++++++++++++++++++++++++ firmware/hackrf_usb/usb_api_board_info.h | 43 +++++++++++ 4 files changed, 138 insertions(+), 69 deletions(-) create mode 100644 firmware/hackrf_usb/usb_api_board_info.c create mode 100644 firmware/hackrf_usb/usb_api_board_info.h diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 97c65daf..73a2ea14 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -33,6 +33,7 @@ SRC = $(BINARY).c \ usb_descriptor.c \ usb_device.c \ usb_endpoint.c \ + usb_api_board_info.c \ usb_api_cpld.c \ usb_api_register.c \ usb_api_spiflash.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 9b622ab2..113b839d 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -34,7 +34,6 @@ #include #include #include -#include #include "usb.h" #include "usb_type.h" @@ -45,6 +44,7 @@ #include "usb_device.h" #include "usb_endpoint.h" +#include "usb_api_board_info.h" #include "usb_api_cpld.h" #include "usb_api_register.h" #include "usb_api_spiflash.h" @@ -56,8 +56,6 @@ static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; -char version_string[] = VERSION_STRING; - typedef struct { uint32_t freq_mhz; uint32_t freq_hz; @@ -154,30 +152,6 @@ usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( } } -usb_request_status_t usb_vendor_request_read_board_id( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - if (stage == USB_TRANSFER_STAGE_SETUP) { - endpoint->buffer[0] = BOARD_ID; - usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - } - return USB_REQUEST_STATUS_OK; -} - -usb_request_status_t usb_vendor_request_read_version_string( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - uint8_t length; - - if (stage == USB_TRANSFER_STAGE_SETUP) { - length = (uint8_t)strlen(version_string); - usb_transfer_schedule_block(endpoint->in, version_string, length, NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - } - return USB_REQUEST_STATUS_OK; -} - usb_request_status_t usb_vendor_request_set_freq( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) @@ -245,48 +219,6 @@ usb_request_status_t usb_vendor_request_set_amp_enable( } } -typedef struct { - uint32_t part_id[2]; - uint32_t serial_no[4]; -} read_partid_serialno_t; - -usb_request_status_t usb_vendor_request_read_partid_serialno( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - uint8_t length; - read_partid_serialno_t read_partid_serialno; - iap_cmd_res_t iap_cmd_res; - - if (stage == USB_TRANSFER_STAGE_SETUP) - { - /* Read IAP Part Number Identification */ - iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_PART_ID_NO; - iap_cmd_call(&iap_cmd_res); - if(iap_cmd_res.status_res.status_ret != CMD_SUCCESS) - return USB_REQUEST_STATUS_STALL; - - read_partid_serialno.part_id[0] = iap_cmd_res.status_res.iap_result[0]; - read_partid_serialno.part_id[1] = iap_cmd_res.status_res.iap_result[1]; - - /* Read IAP Serial Number Identification */ - iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_SERIAL_NO; - iap_cmd_call(&iap_cmd_res); - if(iap_cmd_res.status_res.status_ret != CMD_SUCCESS) - return USB_REQUEST_STATUS_STALL; - - read_partid_serialno.serial_no[0] = iap_cmd_res.status_res.iap_result[0]; - read_partid_serialno.serial_no[1] = iap_cmd_res.status_res.iap_result[1]; - read_partid_serialno.serial_no[2] = iap_cmd_res.status_res.iap_result[2]; - read_partid_serialno.serial_no[3] = iap_cmd_res.status_res.iap_result[3]; - - length = (uint8_t)sizeof(read_partid_serialno_t); - usb_transfer_schedule_block(endpoint->in, &read_partid_serialno, length, - NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - } - return USB_REQUEST_STATUS_OK; -} - usb_request_status_t usb_vendor_request_set_lna_gain( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) diff --git a/firmware/hackrf_usb/usb_api_board_info.c b/firmware/hackrf_usb/usb_api_board_info.c new file mode 100644 index 00000000..7cad222f --- /dev/null +++ b/firmware/hackrf_usb/usb_api_board_info.c @@ -0,0 +1,93 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_api_board_info.h" + +#include +#include +#include + +#include +#include + +char version_string[] = VERSION_STRING; + +usb_request_status_t usb_vendor_request_read_board_id( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + endpoint->buffer[0] = BOARD_ID; + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_read_version_string( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + uint8_t length; + + if (stage == USB_TRANSFER_STAGE_SETUP) { + length = (uint8_t)strlen(version_string); + usb_transfer_schedule_block(endpoint->in, version_string, length, NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_read_partid_serialno( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + uint8_t length; + read_partid_serialno_t read_partid_serialno; + iap_cmd_res_t iap_cmd_res; + + if (stage == USB_TRANSFER_STAGE_SETUP) + { + /* Read IAP Part Number Identification */ + iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_PART_ID_NO; + iap_cmd_call(&iap_cmd_res); + if(iap_cmd_res.status_res.status_ret != CMD_SUCCESS) + return USB_REQUEST_STATUS_STALL; + + read_partid_serialno.part_id[0] = iap_cmd_res.status_res.iap_result[0]; + read_partid_serialno.part_id[1] = iap_cmd_res.status_res.iap_result[1]; + + /* Read IAP Serial Number Identification */ + iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_SERIAL_NO; + iap_cmd_call(&iap_cmd_res); + if(iap_cmd_res.status_res.status_ret != CMD_SUCCESS) + return USB_REQUEST_STATUS_STALL; + + read_partid_serialno.serial_no[0] = iap_cmd_res.status_res.iap_result[0]; + read_partid_serialno.serial_no[1] = iap_cmd_res.status_res.iap_result[1]; + read_partid_serialno.serial_no[2] = iap_cmd_res.status_res.iap_result[2]; + read_partid_serialno.serial_no[3] = iap_cmd_res.status_res.iap_result[3]; + + length = (uint8_t)sizeof(read_partid_serialno_t); + usb_transfer_schedule_block(endpoint->in, &read_partid_serialno, length, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} diff --git a/firmware/hackrf_usb/usb_api_board_info.h b/firmware/hackrf_usb/usb_api_board_info.h new file mode 100644 index 00000000..90a76cb9 --- /dev/null +++ b/firmware/hackrf_usb/usb_api_board_info.h @@ -0,0 +1,43 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_API_BOARD_INFO_H__ +#define __USB_API_BOARD_INFO_H__ + +#include + +#include +#include + +typedef struct { + uint32_t part_id[2]; + uint32_t serial_no[4]; +} read_partid_serialno_t; + +usb_request_status_t usb_vendor_request_read_board_id( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_read_version_string( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_read_partid_serialno( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); + +#endif /* end of include guard: __USB_API_BOARD_INFO_H__ */ From db432842da5ae49924f548e2eeec37a2012db0ae Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 12:09:47 -0700 Subject: [PATCH 123/200] Sync related Makefiles with changes to hackrf_usb/Makefile. --- firmware/hackrf_usb/Makefile_rom_to_ram | 6 ++++++ firmware/hackrf_usb_rom_to_ram/Makefile | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram index da116198..e8748326 100644 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ b/firmware/hackrf_usb/Makefile_rom_to_ram @@ -31,6 +31,12 @@ SRC = hackrf_usb.c \ ../common/usb_request.c \ ../common/usb_standard_request.c \ usb_descriptor.c \ + usb_device.c \ + usb_endpoint.c \ + usb_api_board_info.c \ + usb_api_cpld.c \ + usb_api_register.c \ + usb_api_spiflash.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index 2a76c088..fe33b02a 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -33,6 +33,12 @@ SRC = hackrf_usb.c \ ../common/usb_request.c \ ../common/usb_standard_request.c \ usb_descriptor.c \ + usb_device.c \ + usb_endpoint.c \ + usb_api_board_info.c \ + usb_api_cpld.c \ + usb_api_register.c \ + usb_api_spiflash.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ From 7b50dfa12cf32e3e600350fd175a0623a91347e8 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 12:54:56 -0700 Subject: [PATCH 124/200] Factor out USB API for transceiver control into separate files. Pull out streaming control functions into common/streaming.[ch]. Remove excess #includes in hackrf_usb.c. --- firmware/common/streaming.c | 42 ++++ firmware/common/streaming.h | 29 +++ firmware/hackrf_usb/Makefile | 2 + firmware/hackrf_usb/Makefile_rom_to_ram | 2 + firmware/hackrf_usb/hackrf_usb.c | 248 +-------------------- firmware/hackrf_usb/usb_api_transceiver.c | 250 ++++++++++++++++++++++ firmware/hackrf_usb/usb_api_transceiver.h | 57 +++++ firmware/hackrf_usb_rom_to_ram/Makefile | 2 + 8 files changed, 390 insertions(+), 242 deletions(-) create mode 100644 firmware/common/streaming.c create mode 100644 firmware/common/streaming.h create mode 100644 firmware/hackrf_usb/usb_api_transceiver.c create mode 100644 firmware/hackrf_usb/usb_api_transceiver.h diff --git a/firmware/common/streaming.c b/firmware/common/streaming.c new file mode 100644 index 00000000..32dbb295 --- /dev/null +++ b/firmware/common/streaming.c @@ -0,0 +1,42 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include + +#include + +void baseband_streaming_enable() { + nvic_set_priority(NVIC_SGPIO_IRQ, 0); + nvic_enable_irq(NVIC_SGPIO_IRQ); + SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); + + sgpio_cpld_stream_enable(); +} + +void baseband_streaming_disable() { + sgpio_cpld_stream_disable(); + + nvic_disable_irq(NVIC_SGPIO_IRQ); +} \ No newline at end of file diff --git a/firmware/common/streaming.h b/firmware/common/streaming.h new file mode 100644 index 00000000..1f234127 --- /dev/null +++ b/firmware/common/streaming.h @@ -0,0 +1,29 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __STREAMING_H__ +#define __STREAMING_H__ + +void baseband_streaming_enable(); +void baseband_streaming_disable(); + +#endif/*__STREAMING_H__*/ diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 73a2ea14..8b1ae8bf 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -25,6 +25,7 @@ BINARY = hackrf_usb SRC = $(BINARY).c \ ../common/rf_path.c \ ../common/tuning.c \ + ../common/streaming.c \ sgpio_isr.c \ usb_bulk_buffer.c \ ../common/usb.c \ @@ -37,6 +38,7 @@ SRC = $(BINARY).c \ usb_api_cpld.c \ usb_api_register.c \ usb_api_spiflash.c \ + usb_api_transceiver.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram index e8748326..d5aea6c3 100644 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ b/firmware/hackrf_usb/Makefile_rom_to_ram @@ -25,6 +25,7 @@ BINARY = hackrf_usb_rom_to_ram SRC = hackrf_usb.c \ ../common/rf_path.c \ ../common/tuning.c \ + ../common/streaming.c \ sgpio_isr.c \ usb_bulk_buffer.c \ ../common/usb.c \ @@ -37,6 +38,7 @@ SRC = hackrf_usb.c \ usb_api_cpld.c \ usb_api_register.c \ usb_api_spiflash.c \ + usb_api_transceiver.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 113b839d..f25e7c9a 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -20,26 +20,12 @@ * Boston, MA 02110-1301, USA. */ -#include +#include -#include - -#include #include #include -#include - -#include -#include -#include -#include -#include #include "usb.h" -#include "usb_type.h" -#include "usb_queue.h" -#include "usb_request.h" -#include "usb_descriptor.h" #include "usb_standard_request.h" #include "usb_device.h" @@ -49,232 +35,10 @@ #include "usb_api_register.h" #include "usb_api_spiflash.h" +#include "usb_api_transceiver.h" #include "rf_path.h" -#include "tuning.h" -#include "sgpio_isr.h" #include "usb_bulk_buffer.h" -static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; - -typedef struct { - uint32_t freq_mhz; - uint32_t freq_hz; -} set_freq_params_t; - -set_freq_params_t set_freq_params; - -typedef struct { - uint32_t freq_hz; - uint32_t divider; -} set_sample_r_params_t; - -set_sample_r_params_t set_sample_r_params; - -void baseband_streaming_enable() { - nvic_set_priority(NVIC_SGPIO_IRQ, 0); - nvic_enable_irq(NVIC_SGPIO_IRQ); - SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); - - sgpio_cpld_stream_enable(); -} - -void baseband_streaming_disable() { - sgpio_cpld_stream_disable(); - - nvic_disable_irq(NVIC_SGPIO_IRQ); -} - -void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { - baseband_streaming_disable(); - - usb_endpoint_disable(&usb_endpoint_bulk_in); - usb_endpoint_disable(&usb_endpoint_bulk_out); - - transceiver_mode = new_transceiver_mode; - - if( transceiver_mode == TRANSCEIVER_MODE_RX ) { - gpio_clear(PORT_LED1_3, PIN_LED3); - gpio_set(PORT_LED1_3, PIN_LED2); - usb_endpoint_init(&usb_endpoint_bulk_in); - rf_path_set_direction(RF_PATH_DIRECTION_RX); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; - } else if (transceiver_mode == TRANSCEIVER_MODE_TX) { - gpio_clear(PORT_LED1_3, PIN_LED2); - gpio_set(PORT_LED1_3, PIN_LED3); - usb_endpoint_init(&usb_endpoint_bulk_out); - rf_path_set_direction(RF_PATH_DIRECTION_TX); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx; - } else { - gpio_clear(PORT_LED1_3, PIN_LED2); - gpio_clear(PORT_LED1_3, PIN_LED3); - rf_path_set_direction(RF_PATH_DIRECTION_OFF); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; - } - - if( transceiver_mode != TRANSCEIVER_MODE_OFF ) { - baseband_streaming_enable(); - } -} - -usb_request_status_t usb_vendor_request_set_transceiver_mode( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - switch( endpoint->setup.value ) { - case TRANSCEIVER_MODE_OFF: - case TRANSCEIVER_MODE_RX: - case TRANSCEIVER_MODE_TX: - set_transceiver_mode(endpoint->setup.value); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - default: - return USB_REQUEST_STATUS_STALL; - } - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - const uint32_t bandwidth = (endpoint->setup.index << 16) | endpoint->setup.value; - if( baseband_filter_bandwidth_set(bandwidth) ) { - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_STALL; - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_set_freq( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage) -{ - if (stage == USB_TRANSFER_STAGE_SETUP) - { - usb_transfer_schedule_block(endpoint->out, &set_freq_params, sizeof(set_freq_params_t), - NULL, NULL); - return USB_REQUEST_STATUS_OK; - } else if (stage == USB_TRANSFER_STAGE_DATA) - { - if( set_freq(set_freq_params.freq_mhz, set_freq_params.freq_hz) ) - { - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_STALL; - } else - { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_set_sample_rate_frac( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage) -{ - if (stage == USB_TRANSFER_STAGE_SETUP) - { - usb_transfer_schedule_block(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t), - NULL, NULL); - return USB_REQUEST_STATUS_OK; - } else if (stage == USB_TRANSFER_STAGE_DATA) - { - if( sample_rate_frac_set(set_sample_r_params.freq_hz * 2, set_sample_r_params.divider ) ) - { - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_STALL; - } else - { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_set_amp_enable( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - if (stage == USB_TRANSFER_STAGE_SETUP) { - switch (endpoint->setup.value) { - case 0: - rf_path_set_lna(0); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - case 1: - rf_path_set_lna(1); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - default: - return USB_REQUEST_STATUS_STALL; - } - } else { - return USB_REQUEST_STATUS_OK; - } -} - -usb_request_status_t usb_vendor_request_set_lna_gain( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage) -{ - if( stage == USB_TRANSFER_STAGE_SETUP ) { - const uint8_t value = max2837_set_lna_gain(endpoint->setup.index); - endpoint->buffer[0] = value; - usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, - NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_OK; -} - -usb_request_status_t usb_vendor_request_set_vga_gain( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - if( stage == USB_TRANSFER_STAGE_SETUP ) { - const uint8_t value = max2837_set_vga_gain(endpoint->setup.index); - endpoint->buffer[0] = value; - usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, - NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_OK; -} - -usb_request_status_t usb_vendor_request_set_txvga_gain( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) -{ - if( stage == USB_TRANSFER_STAGE_SETUP ) { - const uint8_t value = max2837_set_txvga_gain(endpoint->setup.index); - endpoint->buffer[0] = value; - usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, - NULL, NULL); - usb_transfer_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; - } - return USB_REQUEST_STATUS_OK; -} - -usb_request_status_t usb_vendor_request_set_if_freq( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - if( set_freq_if((uint32_t)endpoint->setup.index * 1000 * 1000) ) { - usb_transfer_schedule_ack(endpoint->in); - } else { - return USB_REQUEST_STATUS_STALL; - } - } - return USB_REQUEST_STATUS_OK; -} - static const usb_request_handler_fn vendor_request_handler[] = { NULL, usb_vendor_request_set_transceiver_mode, @@ -383,9 +147,9 @@ int main(void) { // Set up IN transfer of buffer 0. if ( usb_bulk_buffer_offset >= 16384 && phase == 1 - && transceiver_mode != TRANSCEIVER_MODE_OFF) { + && transceiver_mode() != TRANSCEIVER_MODE_OFF) { usb_transfer_schedule_block( - (transceiver_mode == TRANSCEIVER_MODE_RX) + (transceiver_mode() == TRANSCEIVER_MODE_RX) ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, &usb_bulk_buffer[0x0000], 0x4000, @@ -397,9 +161,9 @@ int main(void) { // Set up IN transfer of buffer 1. if ( usb_bulk_buffer_offset < 16384 && phase == 0 - && transceiver_mode != TRANSCEIVER_MODE_OFF) { + && transceiver_mode() != TRANSCEIVER_MODE_OFF) { usb_transfer_schedule_block( - (transceiver_mode == TRANSCEIVER_MODE_RX) + (transceiver_mode() == TRANSCEIVER_MODE_RX) ? &usb_endpoint_bulk_in : &usb_endpoint_bulk_out, &usb_bulk_buffer[0x4000], 0x4000, diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c new file mode 100644 index 00000000..4b24fcdf --- /dev/null +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -0,0 +1,250 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "usb_api_transceiver.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "sgpio_isr.h" +#include "usb_endpoint.h" + +static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF; + +void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { + baseband_streaming_disable(); + + usb_endpoint_disable(&usb_endpoint_bulk_in); + usb_endpoint_disable(&usb_endpoint_bulk_out); + + _transceiver_mode = new_transceiver_mode; + + if( _transceiver_mode == TRANSCEIVER_MODE_RX ) { + gpio_clear(PORT_LED1_3, PIN_LED3); + gpio_set(PORT_LED1_3, PIN_LED2); + usb_endpoint_init(&usb_endpoint_bulk_in); + rf_path_set_direction(RF_PATH_DIRECTION_RX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; + } else if (_transceiver_mode == TRANSCEIVER_MODE_TX) { + gpio_clear(PORT_LED1_3, PIN_LED2); + gpio_set(PORT_LED1_3, PIN_LED3); + usb_endpoint_init(&usb_endpoint_bulk_out); + rf_path_set_direction(RF_PATH_DIRECTION_TX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx; + } else { + gpio_clear(PORT_LED1_3, PIN_LED2); + gpio_clear(PORT_LED1_3, PIN_LED3); + rf_path_set_direction(RF_PATH_DIRECTION_OFF); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; + } + + if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) { + baseband_streaming_enable(); + } +} + +transceiver_mode_t transceiver_mode(void) { + return _transceiver_mode; +} + +typedef struct { + uint32_t freq_mhz; + uint32_t freq_hz; +} set_freq_params_t; + +set_freq_params_t set_freq_params; + +typedef struct { + uint32_t freq_hz; + uint32_t divider; +} set_sample_r_params_t; + +set_sample_r_params_t set_sample_r_params; + +usb_request_status_t usb_vendor_request_set_transceiver_mode( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + switch( endpoint->setup.value ) { + case TRANSCEIVER_MODE_OFF: + case TRANSCEIVER_MODE_RX: + case TRANSCEIVER_MODE_TX: + set_transceiver_mode(endpoint->setup.value); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + default: + return USB_REQUEST_STATUS_STALL; + } + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint32_t bandwidth = (endpoint->setup.index << 16) | endpoint->setup.value; + if( baseband_filter_bandwidth_set(bandwidth) ) { + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_set_freq( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) + { + usb_transfer_schedule_block(endpoint->out, &set_freq_params, sizeof(set_freq_params_t), + NULL, NULL); + return USB_REQUEST_STATUS_OK; + } else if (stage == USB_TRANSFER_STAGE_DATA) + { + if( set_freq(set_freq_params.freq_mhz, set_freq_params.freq_hz) ) + { + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else + { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_set_sample_rate_frac( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) + { + usb_transfer_schedule_block(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t), + NULL, NULL); + return USB_REQUEST_STATUS_OK; + } else if (stage == USB_TRANSFER_STAGE_DATA) + { + if( sample_rate_frac_set(set_sample_r_params.freq_hz * 2, set_sample_r_params.divider ) ) + { + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_STALL; + } else + { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_set_amp_enable( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + switch (endpoint->setup.value) { + case 0: + rf_path_set_lna(0); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + case 1: + rf_path_set_lna(1); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + default: + return USB_REQUEST_STATUS_STALL; + } + } else { + return USB_REQUEST_STATUS_OK; + } +} + +usb_request_status_t usb_vendor_request_set_lna_gain( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint8_t value = max2837_set_lna_gain(endpoint->setup.index); + endpoint->buffer[0] = value; + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_set_vga_gain( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint8_t value = max2837_set_vga_gain(endpoint->setup.index); + endpoint->buffer[0] = value; + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_set_txvga_gain( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if( stage == USB_TRANSFER_STAGE_SETUP ) { + const uint8_t value = max2837_set_txvga_gain(endpoint->setup.index); + endpoint->buffer[0] = value; + usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 1, + NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } + return USB_REQUEST_STATUS_OK; +} + +usb_request_status_t usb_vendor_request_set_if_freq( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + if( set_freq_if((uint32_t)endpoint->setup.index * 1000 * 1000) ) { + usb_transfer_schedule_ack(endpoint->in); + } else { + return USB_REQUEST_STATUS_STALL; + } + } + return USB_REQUEST_STATUS_OK; +} diff --git a/firmware/hackrf_usb/usb_api_transceiver.h b/firmware/hackrf_usb/usb_api_transceiver.h new file mode 100644 index 00000000..ce686640 --- /dev/null +++ b/firmware/hackrf_usb/usb_api_transceiver.h @@ -0,0 +1,57 @@ +/* + * Copyright 2012 Jared Boone + * Copyright 2013 Benjamin Vernoux + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __USB_API_TRANSCEIVER_H__ +#define __USB_API_TRANSCEIVER_H__ + +#include +#include +#include + +void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode); +transceiver_mode_t transceiver_mode(void); + +usb_request_status_t usb_vendor_request_set_transceiver_mode( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_freq( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_sample_rate_frac( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_amp_enable( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_lna_gain( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_vga_gain( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_txvga_gain( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_set_if_freq( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); + +#endif/*__USB_API_TRANSCEIVER_H__*/ diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index fe33b02a..de2b883b 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -27,6 +27,7 @@ SRC_DIR = hackrf_usb SRC = hackrf_usb.c \ ../common/rf_path.c \ ../common/tuning.c \ + ../common/streaming.c \ sgpio_isr.c \ usb_bulk_buffer.c \ ../common/usb.c \ @@ -39,6 +40,7 @@ SRC = hackrf_usb.c \ usb_api_cpld.c \ usb_api_register.c \ usb_api_spiflash.c \ + usb_api_transceiver.c \ ../common/usb_queue.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ From 5c76b0ff5059d46cbce13f3c1b4dd564414c0211 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 14:19:07 -0700 Subject: [PATCH 125/200] Add miscellaneous Jawbreaker pins SCU #defines. --- firmware/common/hackrf_core.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index cc772293..9df84472 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -147,6 +147,33 @@ extern "C" #define SCU_FLASH_WP (P3_5) /* GPIO1[15] on P3_5 */ /* TODO add other Pins */ +#define SCU_PINMUX_GPIO3_8 (P7_0) /* GPIO3[8] */ +#define SCU_PINMUX_GPIO3_9 (P7_1) /* GPIO3[9] */ +#define SCU_PINMUX_GPIO3_10 (P7_2) /* GPIO3[10] */ +#define SCU_PINMUX_GPIO3_11 (P7_3) /* GPIO3[11] */ +#define SCU_PINMUX_GPIO3_12 (P7_4) /* GPIO3[12] */ +#define SCU_PINMUX_GPIO3_13 (P7_5) /* GPIO3[13] */ +#define SCU_PINMUX_GPIO3_14 (P7_6) /* GPIO3[14] */ +#define SCU_PINMUX_GPIO3_15 (P7_7) /* GPIO3[15] */ + +#define SCU_PINMUX_SD_POW (P1_5) /* GPIO1[8] */ +#define SCU_PINMUX_SD_CMD (P1_6) /* GPIO1[9] */ +#define SCU_PINMUX_SD_VOLT0 (P1_8) /* GPIO1[1] */ +#define SCU_PINMUX_SD_DAT0 (P1_9) /* GPIO1[2] */ +#define SCU_PINMUX_SD_DAT1 (P1_10) /* GPIO1[3] */ +#define SCU_PINMUX_SD_DAT2 (P1_11) /* GPIO1[4] */ +#define SCU_PINMUX_SD_DAT3 (P1_12) /* GPIO1[5] */ +#define SCU_PINMUX_SD_CD (P1_13) /* GPIO1[6] */ + +#define SCU_PINMUX_U0_TXD (P2_0) /* GPIO5[0] */ +#define SCU_PINMUX_U0_RXD (P2_1) /* GPIO5[1] */ + +#define SCU_PINMUX_ISP (P2_7) /* GPIO0[7] */ + +#define SCU_PINMUX_I2S0_TX_SDA (P3_2) +#define SCU_PINMUX_I2S0_TX_WS (P3_1) +#define SCU_PINMUX_I2S0_TX_SCK (P3_0) +#define SCU_PINMUX_I2S0_TX_MCLK (CLK2) /* * GPIO Pins From 61a8d0f1d6e73833bdeb7f58163123a4c57f9bfb Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 14:24:05 -0700 Subject: [PATCH 126/200] Move set_transceiver stuff back hackrf_usb.c, since it seems to fit better there. --- firmware/hackrf_usb/hackrf_usb.c | 63 +++++++++++++++++++++++ firmware/hackrf_usb/usb_api_transceiver.c | 62 ---------------------- firmware/hackrf_usb/usb_api_transceiver.h | 3 -- 3 files changed, 63 insertions(+), 65 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index f25e7c9a..26bdbb34 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -22,9 +22,13 @@ #include +#include + #include #include +#include + #include "usb.h" #include "usb_standard_request.h" @@ -37,7 +41,66 @@ #include "usb_api_transceiver.h" #include "rf_path.h" +#include "sgpio_isr.h" #include "usb_bulk_buffer.h" + +static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF; + +void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { + baseband_streaming_disable(); + + usb_endpoint_disable(&usb_endpoint_bulk_in); + usb_endpoint_disable(&usb_endpoint_bulk_out); + + _transceiver_mode = new_transceiver_mode; + + if( _transceiver_mode == TRANSCEIVER_MODE_RX ) { + gpio_clear(PORT_LED1_3, PIN_LED3); + gpio_set(PORT_LED1_3, PIN_LED2); + usb_endpoint_init(&usb_endpoint_bulk_in); + rf_path_set_direction(RF_PATH_DIRECTION_RX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; + } else if (_transceiver_mode == TRANSCEIVER_MODE_TX) { + gpio_clear(PORT_LED1_3, PIN_LED2); + gpio_set(PORT_LED1_3, PIN_LED3); + usb_endpoint_init(&usb_endpoint_bulk_out); + rf_path_set_direction(RF_PATH_DIRECTION_TX); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx; + } else { + gpio_clear(PORT_LED1_3, PIN_LED2); + gpio_clear(PORT_LED1_3, PIN_LED3); + rf_path_set_direction(RF_PATH_DIRECTION_OFF); + vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; + } + + if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) { + baseband_streaming_enable(); + } +} + +transceiver_mode_t transceiver_mode(void) { + return _transceiver_mode; +} + +usb_request_status_t usb_vendor_request_set_transceiver_mode( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + if( stage == USB_TRANSFER_STAGE_SETUP ) { + switch( endpoint->setup.value ) { + case TRANSCEIVER_MODE_OFF: + case TRANSCEIVER_MODE_RX: + case TRANSCEIVER_MODE_TX: + set_transceiver_mode(endpoint->setup.value); + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; + default: + return USB_REQUEST_STATUS_STALL; + } + } else { + return USB_REQUEST_STATUS_OK; + } +} static const usb_request_handler_fn vendor_request_handler[] = { NULL, diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index 4b24fcdf..6566c9e2 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -22,60 +22,18 @@ #include "usb_api_transceiver.h" -#include - #include #include #include -#include #include #include #include #include -#include "sgpio_isr.h" #include "usb_endpoint.h" -static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF; - -void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { - baseband_streaming_disable(); - - usb_endpoint_disable(&usb_endpoint_bulk_in); - usb_endpoint_disable(&usb_endpoint_bulk_out); - - _transceiver_mode = new_transceiver_mode; - - if( _transceiver_mode == TRANSCEIVER_MODE_RX ) { - gpio_clear(PORT_LED1_3, PIN_LED3); - gpio_set(PORT_LED1_3, PIN_LED2); - usb_endpoint_init(&usb_endpoint_bulk_in); - rf_path_set_direction(RF_PATH_DIRECTION_RX); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; - } else if (_transceiver_mode == TRANSCEIVER_MODE_TX) { - gpio_clear(PORT_LED1_3, PIN_LED2); - gpio_set(PORT_LED1_3, PIN_LED3); - usb_endpoint_init(&usb_endpoint_bulk_out); - rf_path_set_direction(RF_PATH_DIRECTION_TX); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_tx; - } else { - gpio_clear(PORT_LED1_3, PIN_LED2); - gpio_clear(PORT_LED1_3, PIN_LED3); - rf_path_set_direction(RF_PATH_DIRECTION_OFF); - vector_table.irq[NVIC_SGPIO_IRQ] = sgpio_isr_rx; - } - - if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) { - baseband_streaming_enable(); - } -} - -transceiver_mode_t transceiver_mode(void) { - return _transceiver_mode; -} - typedef struct { uint32_t freq_mhz; uint32_t freq_hz; @@ -90,26 +48,6 @@ typedef struct { set_sample_r_params_t set_sample_r_params; -usb_request_status_t usb_vendor_request_set_transceiver_mode( - usb_endpoint_t* const endpoint, - const usb_transfer_stage_t stage -) { - if( stage == USB_TRANSFER_STAGE_SETUP ) { - switch( endpoint->setup.value ) { - case TRANSCEIVER_MODE_OFF: - case TRANSCEIVER_MODE_RX: - case TRANSCEIVER_MODE_TX: - set_transceiver_mode(endpoint->setup.value); - usb_transfer_schedule_ack(endpoint->in); - return USB_REQUEST_STATUS_OK; - default: - return USB_REQUEST_STATUS_STALL; - } - } else { - return USB_REQUEST_STATUS_OK; - } -} - usb_request_status_t usb_vendor_request_set_baseband_filter_bandwidth( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage diff --git a/firmware/hackrf_usb/usb_api_transceiver.h b/firmware/hackrf_usb/usb_api_transceiver.h index ce686640..4cc98dd4 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.h +++ b/firmware/hackrf_usb/usb_api_transceiver.h @@ -27,9 +27,6 @@ #include #include -void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode); -transceiver_mode_t transceiver_mode(void); - usb_request_status_t usb_vendor_request_set_transceiver_mode( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); From 322dea1884068ead2522236566c564f4e505cc60 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 15:07:42 -0700 Subject: [PATCH 127/200] Add make target for .s files. --- firmware/common/Makefile_inc.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 80f834d9..1bf6f02f 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -116,6 +116,10 @@ program: $(BINARY).dfu @#printf " CC $(subst $(shell pwd)/,,$(@))\n" $(Q)$(CC) $(CFLAGS) -o $@ -c $< +%.o: %.s Makefile + @#printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + clean: $(Q)rm -f *.o $(Q)rm -f *.d From e2d4a501be6f14fcc5a592b0e581248b2381b2e8 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 15:08:23 -0700 Subject: [PATCH 128/200] Link floating point library and related/required libraries. --- firmware/common/Makefile_inc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 1bf6f02f..bdabfbbd 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -110,7 +110,7 @@ program: $(BINARY).dfu %.elf: $(OBJ) $(LDSCRIPT) @#printf " LD $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJ) -lopencm3_lpc43xx + $(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJ) -lopencm3_lpc43xx -lm -lc -lnosys %.o: %.c Makefile @#printf " CC $(subst $(shell pwd)/,,$(@))\n" From 43596e07c5ffceed28b955eaf4d6769d8cc80a13 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 20:03:24 -0700 Subject: [PATCH 129/200] Break off a chunk of local RAM to serve the M0 processor. --- firmware/common/LPC4330_M4.ld | 3 ++- firmware/common/LPC4330_M4_rom_to_ram.ld | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index 694fd265..f2663957 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -27,7 +27,8 @@ MEMORY /* rom is really the shadow region that points to SPI flash or elsewhere */ rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K - ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 72K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K + ram_m0 (rwx) : ORIGIN = 0x10090000, LENGTH = 8K /* there are some additional RAM regions */ ram_ahb1 (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld index f6b1d008..a50ba638 100644 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ b/firmware/common/LPC4330_M4_rom_to_ram.ld @@ -30,7 +30,8 @@ MEMORY /* rom is really the shadow region that points to SPI flash or elsewhere */ rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K - ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 72K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K + ram_m0 (rwx) : ORIGIN = 0x10090000, LENGTH = 8K ram_ahb1 (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable From 6901107c7f98d989494740d6660978f982607025 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 20:04:28 -0700 Subject: [PATCH 130/200] Adjust Makefile_inc.mk to serve both M0 and M4 targets through the LPC43XX_TARGET variable. --- firmware/common/Makefile_inc.mk | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index bdabfbbd..48a7ced3 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -29,7 +29,9 @@ #BOARD ?= JELLYBEAN BOARD ?= JAWBREAKER -HACKRF_OPTS = -D$(BOARD) -DLPC43XX -DLPC43XX_M4 +LPC43XX_TARGET ?= M4 + +HACKRF_OPTS = -D$(BOARD) -DLPC43XX -DLPC43XX_$(LPC43XX_TARGET) # comment to disable RF transmission HACKRF_OPTS += -DTX_ENABLE @@ -38,8 +40,6 @@ HACKRF_OPTS += -DTX_ENABLE VERSION_STRING ?= -D'VERSION_STRING="git-$(shell git log -n 1 --format=%h)"' HACKRF_OPTS += $(VERSION_STRING) -LDSCRIPT ?= ../common/LPC4330_M4.ld - LIBOPENCM3 ?= ../libopencm3 PREFIX ?= arm-none-eabi @@ -51,14 +51,25 @@ GDB = $(PREFIX)-gdb TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) CFLAGS += -std=gnu99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \ - -fno-common -mcpu=cortex-m4 -mthumb -MD \ - -mfloat-abi=hard -mfpu=fpv4-sp-d16 \ - $(HACKRF_OPTS) -LDFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 \ - -L$(TOOLCHAIN_DIR)/lib/armv7e-m/fpu -L../common \ + $(HACKRF_OPTS) -fno-common -mthumb -MD +LDFLAGS += -mthumb \ + -L../common \ -L$(LIBOPENCM3)/lib -L$(LIBOPENCM3)/lib/lpc43xx \ -T$(LDSCRIPT) -nostartfiles \ - -Wl,--gc-sections -Xlinker -Map=$(BINARY).map + -Wl,--gc-sections -Xlinker -Map=$(BINARY).map \ + -lc -lnosys +ifeq ($(LPC43XX_TARGET),M0) + CFLAGS += -mcpu=cortex-m0 + LDFLAGS += -mcpu=cortex-m0 + LDFLAGS += -lopencm3_lpc43xx_m0 + LDSCRIPT ?= ../common/LPC4330_M0.ld +else + CFLAGS += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 + LDFLAGS += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 + LDFLAGS += -L$(TOOLCHAIN_DIR)/lib/armv7e-m/fpu + LDFLAGS += -lopencm3_lpc43xx -lm + LDSCRIPT ?= ../common/LPC4330_M4.ld +endif OBJ = $(SRC:.c=.o) # Be silent per default, but 'make V=1' will show all compiler calls. @@ -110,7 +121,7 @@ program: $(BINARY).dfu %.elf: $(OBJ) $(LDSCRIPT) @#printf " LD $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJ) -lopencm3_lpc43xx -lm -lc -lnosys + $(Q)$(LD) -o $(*).elf $(OBJ) $(LDFLAGS) %.o: %.c Makefile @#printf " CC $(subst $(shell pwd)/,,$(@))\n" From 2ed5c9d05742badbacae861113cc4065c5c6e326 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 20 Sep 2013 20:15:39 -0700 Subject: [PATCH 131/200] Consolidate hackrf_usb and hackrf_usb_rom_to_ram projects -- with generation of SPIFI binary by default. --- firmware/hackrf_usb/Makefile | 9 +++- firmware/hackrf_usb/Makefile_rom_to_ram | 58 ---------------------- firmware/hackrf_usb_rom_to_ram/Makefile | 66 ------------------------- 3 files changed, 7 insertions(+), 126 deletions(-) delete mode 100644 firmware/hackrf_usb/Makefile_rom_to_ram delete mode 100644 firmware/hackrf_usb_rom_to_ram/Makefile diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 8b1ae8bf..a22b90bc 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -20,9 +20,14 @@ # Boston, MA 02110-1301, USA. # -BINARY = hackrf_usb +ifeq ($(RUN_FROM),RAM) + BINARY = hackrf_usb_ram +else + BINARY = hackrf_usb_rom_to_ram + LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld +endif -SRC = $(BINARY).c \ +SRC = hackrf_usb.c \ ../common/rf_path.c \ ../common/tuning.c \ ../common/streaming.c \ diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram deleted file mode 100644 index d5aea6c3..00000000 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ /dev/null @@ -1,58 +0,0 @@ -# Hey Emacs, this is a -*- makefile -*- -# -# Copyright 2012 Jared Boone -# -# This file is part of HackRF. -# -# 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, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -BINARY = hackrf_usb_rom_to_ram - -SRC = hackrf_usb.c \ - ../common/rf_path.c \ - ../common/tuning.c \ - ../common/streaming.c \ - sgpio_isr.c \ - usb_bulk_buffer.c \ - ../common/usb.c \ - ../common/usb_request.c \ - ../common/usb_standard_request.c \ - usb_descriptor.c \ - usb_device.c \ - usb_endpoint.c \ - usb_api_board_info.c \ - usb_api_cpld.c \ - usb_api_register.c \ - usb_api_spiflash.c \ - usb_api_transceiver.c \ - ../common/usb_queue.c \ - ../common/fault_handler.c \ - ../common/hackrf_core.c \ - ../common/sgpio.c \ - ../common/si5351c.c \ - ../common/max2837.c \ - ../common/max5864.c \ - ../common/rffc5071.c \ - ../common/w25q80bv.c \ - ../common/cpld_jtag.c \ - ../common/xapp058/lenval.c \ - ../common/xapp058/micro.c \ - ../common/xapp058/ports.c \ - ../common/rom_iap.c - -LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld -include ../common/Makefile_inc.mk diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile deleted file mode 100644 index de2b883b..00000000 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -# Hey Emacs, this is a -*- makefile -*- -# -# Copyright 2013 Benjamin Vernoux -# -# This file is part of HackRF. -# -# 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, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -BINARY = hackrf_usb_rom_to_ram - -SRC_DIR = hackrf_usb - -SRC = hackrf_usb.c \ - ../common/rf_path.c \ - ../common/tuning.c \ - ../common/streaming.c \ - sgpio_isr.c \ - usb_bulk_buffer.c \ - ../common/usb.c \ - ../common/usb_request.c \ - ../common/usb_standard_request.c \ - usb_descriptor.c \ - usb_device.c \ - usb_endpoint.c \ - usb_api_board_info.c \ - usb_api_cpld.c \ - usb_api_register.c \ - usb_api_spiflash.c \ - usb_api_transceiver.c \ - ../common/usb_queue.c \ - ../common/fault_handler.c \ - ../common/hackrf_core.c \ - ../common/sgpio.c \ - ../common/si5351c.c \ - ../common/max2837.c \ - ../common/max5864.c \ - ../common/rffc5071.c \ - ../common/w25q80bv.c \ - ../common/cpld_jtag.c \ - ../common/xapp058/lenval.c \ - ../common/xapp058/micro.c \ - ../common/xapp058/ports.c \ - ../common/rom_iap.c - -LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld - -%.o: ../$(SRC_DIR)/%.c Makefile - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -include ../common/Makefile_inc.mk - From b4f883595f9cb1c6d5c3a83192e249c77f0f8042 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 21 Sep 2013 20:27:27 -0700 Subject: [PATCH 132/200] Remove MAX2837_FREQ_NOMINAL_MHZ #define -- it must be updated now that IF is adjustable. So I pushed the calculation directly into the two places it was used. --- firmware/common/tuning.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/firmware/common/tuning.c b/firmware/common/tuning.c index a73c2f0d..bab3b7f1 100644 --- a/firmware/common/tuning.c +++ b/firmware/common/tuning.c @@ -38,8 +38,7 @@ #define MIN_HP_FREQ_MHZ (2700) #define MAX_HP_FREQ_MHZ (6800) -static uint32_t max2837_freq_nominal_hz=2600000000; -#define MAX2837_FREQ_NOMINAL_MHZ (max2837_freq_nominal_hz / FREQ_ONE_MHZ) +static uint32_t max2837_freq_nominal_hz=2560000000; uint32_t freq_mhz_cache=100, freq_hz_cache=0; /* @@ -64,7 +63,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) if(freq_mhz < MAX_LP_FREQ_MHZ) { rf_path_set_filter(RF_PATH_FILTER_LOW_PASS); - RFFC5071_freq_mhz = MAX2837_FREQ_NOMINAL_MHZ - freq_mhz; + RFFC5071_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) - freq_mhz; /* Set Freq and read real freq */ real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); if(real_RFFC5071_freq_hz < RFFC5071_freq_mhz * FREQ_ONE_MHZ) @@ -85,7 +84,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) }else if( (freq_mhz >= MIN_HP_FREQ_MHZ) && (freq_mhz < MAX_HP_FREQ_MHZ) ) { rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS); - RFFC5071_freq_mhz = freq_mhz - MAX2837_FREQ_NOMINAL_MHZ; + RFFC5071_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ); /* Set Freq and read real freq */ real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); if(real_RFFC5071_freq_hz < RFFC5071_freq_mhz * FREQ_ONE_MHZ) From 314b3cdc7bc13f49d7fa6105161b8314d8d599c7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 22 Sep 2013 11:52:45 -0700 Subject: [PATCH 133/200] Don't put MAX2837 into shutdown mode -- powering up takes a bit too long (500us for PLL to stabilize). Will need to revisit, because the MAX2837 chews up significant current (35 to 45mA) when not in shutdown. Remove excess calls to max2837_start() and max2837_stop(). --- firmware/common/rf_path.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index 95d55db2..9aea7279 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -73,7 +73,7 @@ void rf_path_init(void) { ssp1_set_mode_max2837(); max2837_setup(); - max2837_mode_shutdown(); + max2837_start(); rffc5071_setup(); } @@ -97,7 +97,6 @@ void rf_path_set_direction(const rf_path_direction_t direction) { ssp1_set_mode_max5864(); max5864_tx(); ssp1_set_mode_max2837(); - max2837_start(); max2837_tx(); sgpio_configure(SGPIO_DIRECTION_TX, true); break; @@ -117,7 +116,6 @@ void rf_path_set_direction(const rf_path_direction_t direction) { ssp1_set_mode_max5864(); max5864_rx(); ssp1_set_mode_max2837(); - max2837_start(); max2837_rx(); sgpio_configure(SGPIO_DIRECTION_RX, true); break; @@ -128,9 +126,9 @@ void rf_path_set_direction(const rf_path_direction_t direction) { switchctrl &= ~SWITCHCTRL_TX; rffc5071_disable(); ssp1_set_mode_max5864(); - max5864_shutdown(); + max5864_standby(); ssp1_set_mode_max2837(); - max2837_stop(); + max2837_set_mode(MAX2837_MODE_STANDBY); sgpio_configure(SGPIO_DIRECTION_RX, true); break; } From 06da7fd83a9bdbd3dd1131ed22d49c6ccd297cf3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 22 Sep 2013 11:54:37 -0700 Subject: [PATCH 134/200] Reduce drive strength from clock generator (Si5351C) to first mixer (RFFC5072). This reduces every-50MHz spurs in RX by 10 to 15dB. --- firmware/common/si5351c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index e661fbc0..cca67a69 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -234,7 +234,7 @@ void si5351c_configure_clock_control() ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) ,SI5351C_CLK_POWERDOWN /*not connected, clock out*/ - ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) + ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /* pllb int mode*/| SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_B) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) From 4917c5019af1f51655656bdf8d4b420bf12ea707 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 2 Nov 2013 22:51:35 -0700 Subject: [PATCH 135/200] Additional CGU register decoding in dump_cgu.py. --- firmware/tools/dump_cgu.py | 239 ++++++++++++++++++++++++++++++++++++- 1 file changed, 238 insertions(+), 1 deletion(-) diff --git a/firmware/tools/dump_cgu.py b/firmware/tools/dump_cgu.py index b452e485..ced4ea44 100755 --- a/firmware/tools/dump_cgu.py +++ b/firmware/tools/dump_cgu.py @@ -32,7 +32,7 @@ from struct import unpack address = 0x40050014 -f = open('cgu.bin', 'read') +f = open(sys.argv[1], 'read') d = '\x00' * 20 + f.read() length = len(d) f.close() @@ -126,6 +126,243 @@ registers = { ('CLK_SEL', 24, 5), ), }, + 0x48: { + 'name': 'IDIVA_CTRL', + 'fields': ( + ('PD', 0, 1), + ('IDIV', 2, 2), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x4C: { + 'name': 'IDIVB_CTRL', + 'fields': ( + ('PD', 0, 1), + ('IDIV', 2, 4), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x50: { + 'name': 'IDIVC_CTRL', + 'fields': ( + ('PD', 0, 1), + ('IDIV', 2, 4), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x54: { + 'name': 'IDIVD_CTRL', + 'fields': ( + ('PD', 0, 1), + ('IDIV', 2, 4), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x58: { + 'name': 'IDIVE_CTRL', + 'fields': ( + ('PD', 0, 1), + ('IDIV', 2, 8), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x5C: { + 'name': 'BASE_SAFE_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x60: { + 'name': 'BASE_USB0_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x64: { + 'name': 'BASE_PERIPH_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x68: { + 'name': 'BASE_USB1_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x6C: { + 'name': 'BASE_M4_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x70: { + 'name': 'BASE_SPIFI_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x74: { + 'name': 'BASE_SPI_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x78: { + 'name': 'BASE_PHY_RX_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x7C: { + 'name': 'BASE_PHY_TX_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x80: { + 'name': 'BASE_APB1_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x84: { + 'name': 'BASE_APB3_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x88: { + 'name': 'BASE_LCD_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x8C: { + 'name': 'BASE_VADC_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x90: { + 'name': 'BASE_SDIO_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x94: { + 'name': 'BASE_SSP0_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x98: { + 'name': 'BASE_SSP1_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0x9C: { + 'name': 'BASE_UART0_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0xA0: { + 'name': 'BASE_UART1_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0xA4: { + 'name': 'BASE_UART2_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0xA8: { + 'name': 'BASE_UART3_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0xAC: { + 'name': 'BASE_OUT_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0xC0: { + 'name': 'BASE_APLL_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0xC4: { + 'name': 'BASE_CGU_OUT0_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, + 0xC8: { + 'name': 'BASE_CGU_OUT1_CLK', + 'fields': ( + ('PD', 0, 1), + ('AUTOBLOCK', 11, 1), + ('CLK_SEL', 24, 5), + ), + }, # TODO: Add other CGU registers. I did the ones that were # valuable to me to debug CPU clock issues. } From 9856ea3d14f2c80721a85a03e6a358b158e8019d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 15 Nov 2013 11:41:20 -0800 Subject: [PATCH 136/200] Changes due to CGU header API changes. --- firmware/common/hackrf_core.c | 68 +++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 9c3681e6..dc2f2013 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -327,55 +327,55 @@ void cpu_clock_init(void) #endif /* set xtal oscillator to low frequency mode */ - CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_HF; + CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_HF_MASK; /* power on the oscillator and wait until stable */ - CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_ENABLE; + CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_ENABLE_MASK; /* Wait about 100us after Crystal Power ON */ delay(WAIT_CPU_CLOCK_INIT_DELAY); /* use XTAL_OSC as clock source for BASE_M4_CLK (CPU) */ - CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_XTAL) | CGU_BASE_M4_CLK_AUTOBLOCK); + CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_XTAL) | CGU_BASE_M4_CLK_AUTOBLOCK(1)); /* use XTAL_OSC as clock source for APB1 */ - CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK + CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK(1) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL); cpu_clock_pll1_low_speed(); /* use PLL1 as clock source for BASE_M4_CLK (CPU) */ - CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1) | CGU_BASE_M4_CLK_AUTOBLOCK); + CGU_BASE_M4_CLK = (CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1) | CGU_BASE_M4_CLK_AUTOBLOCK(1)); /* use XTAL_OSC as clock source for PLL0USB */ - CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD - | CGU_PLL0USB_CTRL_AUTOBLOCK + CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD(1) + | CGU_PLL0USB_CTRL_AUTOBLOCK(1) | CGU_PLL0USB_CTRL_CLK_SEL(CGU_SRC_XTAL); - while (CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK); + while (CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK); /* configure PLL0USB to produce 480 MHz clock from 12 MHz XTAL_OSC */ /* Values from User Manual v1.4 Table 94, for 12MHz oscillator. */ CGU_PLL0USB_MDIV = 0x06167FFA; CGU_PLL0USB_NP_DIV = 0x00302062; - CGU_PLL0USB_CTRL |= (CGU_PLL0USB_CTRL_PD - | CGU_PLL0USB_CTRL_DIRECTI - | CGU_PLL0USB_CTRL_DIRECTO - | CGU_PLL0USB_CTRL_CLKEN); + CGU_PLL0USB_CTRL |= (CGU_PLL0USB_CTRL_PD(1) + | CGU_PLL0USB_CTRL_DIRECTI(1) + | CGU_PLL0USB_CTRL_DIRECTO(1) + | CGU_PLL0USB_CTRL_CLKEN(1)); /* power on PLL0USB and wait until stable */ - CGU_PLL0USB_CTRL &= ~CGU_PLL0USB_CTRL_PD; - while (!(CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK)); + CGU_PLL0USB_CTRL &= ~CGU_PLL0USB_CTRL_PD_MASK; + while (!(CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK_MASK)); /* use PLL0USB as clock source for USB0 */ - CGU_BASE_USB0_CLK = CGU_BASE_USB0_CLK_AUTOBLOCK + CGU_BASE_USB0_CLK = CGU_BASE_USB0_CLK_AUTOBLOCK(1) | CGU_BASE_USB0_CLK_CLK_SEL(CGU_SRC_PLL0USB); /* Switch peripheral clock over to use PLL1 (204MHz) */ - CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK + CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK(1) | CGU_BASE_PERIPH_CLK_CLK_SEL(CGU_SRC_PLL1); /* Switch APB1 clock over to use PLL1 (204MHz) */ - CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK + CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK(1) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); } @@ -397,20 +397,20 @@ void cpu_clock_pll1_low_speed(void) */ pll_reg = CGU_PLL1_CTRL; /* Clear PLL1 bits */ - pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ - CGU_PLL1_CTRL_BYPASS | /* BYPASS */ - CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD_MASK | CGU_PLL1_CTRL_FBSEL_MASK | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS_MASK | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT_MASK | /* DIRECT */ CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ /* Set PLL1 up to 12MHz * 4 = 48MHz. */ pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) | CGU_PLL1_CTRL_PSEL(0) | CGU_PLL1_CTRL_NSEL(0) | CGU_PLL1_CTRL_MSEL(3) - | CGU_PLL1_CTRL_FBSEL - | CGU_PLL1_CTRL_DIRECT; + | CGU_PLL1_CTRL_FBSEL(1) + | CGU_PLL1_CTRL_DIRECT(1); CGU_PLL1_CTRL = pll_reg; /* wait until stable */ - while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK_MASK)); /* Wait a delay after switch to new frequency with Direct mode */ delay(WAIT_CPU_CLOCK_INIT_DELAY); @@ -432,19 +432,19 @@ void cpu_clock_pll1_max_speed(void) */ pll_reg = CGU_PLL1_CTRL; /* Clear PLL1 bits */ - pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ - CGU_PLL1_CTRL_BYPASS | /* BYPASS */ - CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD_MASK | CGU_PLL1_CTRL_FBSEL_MASK | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS_MASK | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT_MASK | /* DIRECT */ CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ /* Set PLL1 up to 12MHz * 8 = 96MHz. */ pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) | CGU_PLL1_CTRL_PSEL(0) | CGU_PLL1_CTRL_NSEL(0) | CGU_PLL1_CTRL_MSEL(7) - | CGU_PLL1_CTRL_FBSEL; + | CGU_PLL1_CTRL_FBSEL(1); CGU_PLL1_CTRL = pll_reg; /* wait until stable */ - while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK_MASK)); /* Wait before to switch to max speed */ delay(WAIT_CPU_CLOCK_INIT_DELAY); @@ -453,20 +453,20 @@ void cpu_clock_pll1_max_speed(void) /* Direct mode: FCLKOUT = FCCO = M*(FCLKIN/N) */ pll_reg = CGU_PLL1_CTRL; /* Clear PLL1 bits */ - pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD | CGU_PLL1_CTRL_FBSEL | /* CLK SEL, PowerDown , FBSEL */ - CGU_PLL1_CTRL_BYPASS | /* BYPASS */ - CGU_PLL1_CTRL_DIRECT | /* DIRECT */ + pll_reg &= ~( CGU_PLL1_CTRL_CLK_SEL_MASK | CGU_PLL1_CTRL_PD_MASK | CGU_PLL1_CTRL_FBSEL_MASK | /* CLK SEL, PowerDown , FBSEL */ + CGU_PLL1_CTRL_BYPASS_MASK | /* BYPASS */ + CGU_PLL1_CTRL_DIRECT_MASK | /* DIRECT */ CGU_PLL1_CTRL_PSEL_MASK | CGU_PLL1_CTRL_MSEL_MASK | CGU_PLL1_CTRL_NSEL_MASK ); /* PSEL, MSEL, NSEL- divider ratios */ /* Set PLL1 up to 12MHz * 17 = 204MHz. */ pll_reg |= CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) | CGU_PLL1_CTRL_PSEL(0) | CGU_PLL1_CTRL_NSEL(0) | CGU_PLL1_CTRL_MSEL(16) - | CGU_PLL1_CTRL_FBSEL - | CGU_PLL1_CTRL_DIRECT; + | CGU_PLL1_CTRL_FBSEL(1) + | CGU_PLL1_CTRL_DIRECT(1); CGU_PLL1_CTRL = pll_reg; /* wait until stable */ - while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK_MASK)); } From 147f47a3f5686efdad65821b9affdc6e1cfcbf87 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 16 Nov 2013 13:29:00 -0800 Subject: [PATCH 137/200] Invert Q channel data coming from MAX5864, since MAX2837 Q differential pair is reversed. Do conversion from unsigned to two's-compliment inside FPGA. --- firmware/cpld/sgpio_if/top.vhd | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/firmware/cpld/sgpio_if/top.vhd b/firmware/cpld/sgpio_if/top.vhd index ce3bbfa8..f431b246 100755 --- a/firmware/cpld/sgpio_if/top.vhd +++ b/firmware/cpld/sgpio_if/top.vhd @@ -93,7 +93,13 @@ begin process(host_clk_i) begin if rising_edge(host_clk_i) then - data_to_host_o <= adc_data_i xor X"80"; + if codec_clk_i = '1' then + -- I: non-inverted between MAX2837 and MAX5864 + data_to_host_o <= adc_data_i xor X"80"; + else + -- Q: inverted between MAX2837 and MAX5864 + data_to_host_o <= adc_data_i xor X"7f"; + end if; end if; end process; @@ -101,14 +107,14 @@ begin begin if rising_edge(host_clk_i) then if transfer_direction_i = to_dac then - dac_data_o <= (data_from_host_i xor X"80") & "00"; + dac_data_o <= (data_from_host_i xor X"7f") & "11"; else - dac_data_o <= (dac_data_o'high => '1', others => '0'); + dac_data_o <= (dac_data_o'high => '0', others => '1'); end if; end if; end process; - process(host_clk_i, codec_clk_i) + process(host_clk_i) begin if rising_edge(host_clk_i) then if transfer_direction_i = to_dac then From 7ef9c1e932eacc9156fa7e310df1ee326cbd804e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 16 Nov 2013 13:31:19 -0800 Subject: [PATCH 138/200] Slow down edges of data lines coming from CPLD. --- firmware/cpld/sgpio_if/top.ucf | 42 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/firmware/cpld/sgpio_if/top.ucf b/firmware/cpld/sgpio_if/top.ucf index db741928..e03f0385 100755 --- a/firmware/cpld/sgpio_if/top.ucf +++ b/firmware/cpld/sgpio_if/top.ucf @@ -33,28 +33,28 @@ NET "DA<2>" LOC="41" |IOSTANDARD=LVCMOS33 | TNM=adc_data; NET "DA<1>" LOC="42" |IOSTANDARD=LVCMOS33 | TNM=adc_data; NET "DA<0>" LOC="43" |IOSTANDARD=LVCMOS33 | TNM=adc_data; -NET "DD<9>" LOC="17" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<8>" LOC="18" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<7>" LOC="19" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<6>" LOC="24" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<5>" LOC="28" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<4>" LOC="29" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<3>" LOC="30" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<2>" LOC="32" |IOSTANDARD=LVCMOS33 | TNM=dac_data; -NET "DD<1>" LOC="33" |IOSTANDARD=LVCMOS33; -NET "DD<0>" LOC="34" |IOSTANDARD=LVCMOS33; +NET "DD<9>" LOC="17" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<8>" LOC="18" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<7>" LOC="19" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<6>" LOC="24" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<5>" LOC="28" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<4>" LOC="29" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<3>" LOC="30" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<2>" LOC="32" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<1>" LOC="33" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; +NET "DD<0>" LOC="34" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=dac_data; -NET "HOST_DIRECTION" LOC="71" |IOSTANDARD=LVCMOS33; -NET "HOST_DISABLE" LOC="76" |IOSTANDARD=LVCMOS33; -NET "HOST_CAPTURE" LOC="91" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<7>" LOC="77" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<6>" LOC="61" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<5>" LOC="64" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<4>" LOC="67" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<3>" LOC="72" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<2>" LOC="74" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<1>" LOC="79" |IOSTANDARD=LVCMOS33 | TNM=to_host; -NET "HOST_DATA<0>" LOC="89" |IOSTANDARD=LVCMOS33 | TNM=to_host; +NET "HOST_DIRECTION" LOC="71" |IOSTANDARD=LVCMOS33 | SLEW=SLOW; +NET "HOST_DISABLE" LOC="76" |IOSTANDARD=LVCMOS33 | SLEW=SLOW; +NET "HOST_CAPTURE" LOC="91" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<7>" LOC="77" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<6>" LOC="61" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<5>" LOC="64" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<4>" LOC="67" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<3>" LOC="72" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<2>" LOC="74" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<1>" LOC="79" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<0>" LOC="89" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; TIMEGRP "adc_data" OFFSET = IN 16 ns BEFORE "CODEC_X2_CLK"; From 89eafaa79a1086854cf35a860570011bf5ec0fac Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 16 Nov 2013 13:32:41 -0800 Subject: [PATCH 139/200] Remove sample-pair reordering in SGPIO interrupt -- CPLD fixes address this. --- firmware/hackrf_usb/sgpio_isr.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/firmware/hackrf_usb/sgpio_isr.c b/firmware/hackrf_usb/sgpio_isr.c index 76eebf0f..e4ed539a 100644 --- a/firmware/hackrf_usb/sgpio_isr.c +++ b/firmware/hackrf_usb/sgpio_isr.c @@ -32,28 +32,20 @@ void sgpio_isr_rx() { uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; __asm__( "ldr r0, [%[SGPIO_REG_SS], #44]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #0]\n\t" "ldr r0, [%[SGPIO_REG_SS], #20]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #4]\n\t" "ldr r0, [%[SGPIO_REG_SS], #40]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #8]\n\t" "ldr r0, [%[SGPIO_REG_SS], #8]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #12]\n\t" "ldr r0, [%[SGPIO_REG_SS], #36]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #16]\n\t" "ldr r0, [%[SGPIO_REG_SS], #16]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #20]\n\t" "ldr r0, [%[SGPIO_REG_SS], #32]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #24]\n\t" "ldr r0, [%[SGPIO_REG_SS], #0]\n\t" - "rev16 r0, r0\n\t" /* Swap QI -> IQ */ "str r0, [%[p], #28]\n\t" : : [SGPIO_REG_SS] "l" (SGPIO_PORT_BASE + 0x100), From d006ec769cb531522995669216d6a6d4d2aa117d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 16 Nov 2013 13:41:54 -0800 Subject: [PATCH 140/200] Updated CPLD bitstream with two's complement I/O and sample ordering fix. --- firmware/cpld/sgpio_if/default.xsvf | Bin 37629 -> 37629 bytes firmware/cpld/sgpio_if/top.jed | 1514 +++++++++++++-------------- 2 files changed, 757 insertions(+), 757 deletions(-) diff --git a/firmware/cpld/sgpio_if/default.xsvf b/firmware/cpld/sgpio_if/default.xsvf index c767758ee6224d66b43577048345a7140f0cba53..7bcbb905b77db10166a445d5083fb6ac9752c25c 100755 GIT binary patch literal 37629 zcmeI5e~4676vywK(cRe;S7w&hQrjgXB|{~nLZyl97bzMUB`GPnl%%9&l;qk7LJ0*1 z{*we5_@_aCNE8&!F8yJWV9=jdCLvgoD+t!M_+IzDnVt9Mey?-ixxNGbap#Zqy|?p@ zpL4$V+;{KXduF>uMf8cXD9b`gmV^+4vNt>!PEkjqC;D;q{N+Q1QmB60etMyz?)bYR z$}`HnZ)`R#QKT{;t&g zO<8Ij()<;ht@cRz$}O6|4Sj;yF{}GdW0l@<#DUOnR@6} ze|6l(N6g>LR(rJgUCGy9xy#Bom(>1t>h{jR-!3t&e-`Vk{?hVyozB-zM}B_%WV1(W z&*JCNO*&EgIq`XP$i^4!rRXa^vf87y=Ssf%ib}qGVwTMwOR>{1m+J3@@i3W-NA}`LZ|Z-b`75`bypp=v#7FaY>p5kv znwUgBlD=ZqiSTM-&BR9=Z>$d2kKZx@; z@fr1?`FkMJx6_N5ztc{1GNyh^TB-kXYpaa z`ij$$9%0g+A(AwG<>`?+m}t8|d>*Yicd_kuIHBn)R!8~?kw9hx>n9AQ@4Op#9M1RLrdk(&A-Hit{f5qpzzq&=DzhC6rU&+OBe&|rC zbE3bC^7U7&(A!4}Ek2~_E35hXE9+K1(t3*c)@qN`KZ`JDe?u!D$zM5awMX-}mhBIqCD$eC;J``L3(`YE`_s zFn*~o-j>iUqwNT4#k#S@ps%rXErz0H^Rg_W`}&oh4DTu0d&PJ~MhqoTk1!)?9id@i z9*{QkB8l;8TW}3)`+zjai=+!@*d72#OPG1ZaOoPCR`k)^oMEz3b&dUNf!>< zQdk7xw(}y{g~Mmuz063Oa1bTK;ABNMq(IF(q-HP6*xM?cp)C#bBDn~+kr~M<++1kh zbFv~0{F{q#xU~w9)buUOJT4Fe`&^Lh!r?RSxvWTT&AVt74!g=Xd6BFcXXq;L=S3>o zx0yj(x+@!!)+NQKS^6craC-r1h!@E!oT00Hj2FozWHFOpR_L&iP9i{v8Q zE6hj^!rje_y~T{=Al&o3NG`(N%8TS8+#SqF4#K^}i{v8QySzv)!adB4 ztG^yhtv>tzkwwY#NWIt{H}KGkB2-wzd?aaJTRx7456KF!p|$7fC3M zEE|OZ=`~)YqJ6J1Al<`^a$BWb$oFpq0 zhHdPCbSE!T;~AHThs_&>dzlw0&bTDu@F>8Hdz2SRWnAZ%VZ2meMv9(sowxKuTPiXm z*@kci;a2h@S*HUA;kNK1xr{33@glio+|q1FuIq7)NmJ5QLi!nm+r^AzFS3A)TgQu3 zu-9n-QpQb;uENC`*SXXKkY@8nsc5ej0i+FCk-D9h2qEM2uG6prz9%b^;}W5I##w4s zAWF-bk<n$y#0{`)8Fn9oWH)q<4+Fhz8*n^CGzjSLH==5w6CJoa|QCbScE!9E?uJx{(q6C!C? z3i9=t7$qz^^7WYzB|`~>ug`=i8J=;zJ`-xW}L6j#3*6L`T9(Z5@wvQ&%`KU#`*e8j1p#?ug^3TKQ>E7bF6eMltx-cLsj-T XSQceDCHk)mrBMCFNFn3DCMo_0`kQ2~ literal 37629 zcmeHQU5FM{7(VCwboW~oS7w*C{9QCsGBhkIOfs}TOx)0@P_fXpBqhV5!q&blD4{^G zJ1;8guA+;&t8h&UilCtGD%cbRF>=M|N0*&xe!iV==6%k3=A6z8UYxnuotbav-RF6q z_dVy#ob%4tDSAY&2t*)j4cQPv^vmw(a5N>}6J5!VzfYfktJa9(Ps@jAdg3eo=n=up zpgX7q^lB>@=urYaHa&s6M5YY<3gc00q@Fw*6Oh*=zR_-7qW)!c`7P|$T8aOl zN2Fd|JgZCAE|v|Bk2LcW!^vLQtYR^@_lnFfPj?FTM$;4FkcmC^v}e>liwj!5X7Tc;TfTCimhU{H_}fSMo_@XTLbG@gn{<578pX5RsO4*> z$B&e6nXPgD{-on;*dHCy^4)2ouRNmVd%(zEkCv~Iz9P`_HPTni*77xLujaVrD~~$n zd(MMTF_5CNMI(CjQHspKeV${AD zk4=rGH@yX$X5%ZlJJUA-_SOWDoHf=_~I~ z^=&4m(hcny@s;1@`X=T^6!^^eep9j+HUFo+;*E*?ZKiY;@nXjJP^|A|H#2?Zw6?x# zvu5!urkC?~9Q|j+S9F*4K#YcbXK3x2#q;3_eGyr9#;ko7Z@Sf2eE-#Cz*^_c^p!u9 z^+n@meB}nmeAm0xSL}7GuiQiVQoNzj_)4DB=C9HCN{qVYD?XxpX~Y=v{n#yEx!i3$ zi)C*4id8f|z<);i%GGZ9%3&=&qj(lyXzdyC6_I1Ukrtm3Upb_;XU4bbIDfbPRt~sJ zg{g}46T|%7<~V;x9P|CvasIyTnD0Ao`O3MD`ObICSM-&`PjzJUywk0{_FTU0?0!5e z-kKOc*PAX&=#+XqPfypX7Hisbj;#17>;_1)cp*{Y5E5qG)y$BHa0qD#yz~e!Br2R@!3IEjffo`LPO;_# zAl=3cNhe&?>L3dp$`W2kR5*;K0r1i;UPx3pgoNRJA2TE(oMQb8c&Wh)i3+D!LIaRy z@Is=(DOTYCr1i{@h;SH72LaL^UPx3pgoJ(E4ZM)3a0m(exK-64h4Fm{)u77QyGAdf zm_lp>hIk>_2)C6Nl3uuZ5Z-gELR#=I)xb(PTv`Q?;@h_>_i>?E@Ujggt#D_tk9)8x zB+Kw7_i;43BSm;W%M6LSmSPIAsl1sNl2$my?ZCCwAW?G3ai#Fq3bzx&dypBDR=5KI z=`LPKdf_nRrtm`2Hl%#bXEyM-5$jd0KLLb4I= zA!bMx!d=A+$ws*OypU{!+r|vZLb#WBA?by~`?x!JA?by~k-#!$NLu0Wk=IkakZgq8 zzzfMnxS7n5EQFiJ3#qQ3)rEoXI$lUZbsteY7vc^0le~~@o}66I3&|$qRx(4%@8hy{ zz_`K|h1<^yN$3|%LwIlIh1ANpe5o{g3H!L&ypY66?b2=VQoswT)?UpqlH@*m32!Yo z@HTE-5L7V<*M`?zL?OtCT?AZ_P` zlw{mxH$@+}h8I#HQtC>}B|;)P_BaW_?iWIZ3JuaJQ7euftk$vBixA>1ZjNHvS5vf?5}Tj6XnZVs=P zY%*?3RY;vyQ-qLlwCN1-$;pdVAz4llwnvp1+R2#^pPbyz3&}>frPUy*C{~$|1L3G4 zg>buhA?XJvDBS(LkZhXD>AaBiO(kYrH!mc8Q;EV2@ItZ?ZZ9(=+B8fCNm@p;U49MWFy=HUPv~5Tpuqap|383vG>EgkZk(6=XoL72zM(lB%8s>VqQo# z!aczY$ws()c_G;d*U1aXM!2byK&ns+SZVC7w*&3c-B${voY559M0kS`b=M+X_aw`q9b3Q z37%B+alSqiy@YF?e0^r*>oXxxs*EbJkMs4J;7G*^3}2s#Uc#A9U!RFy!i@9vndqef zc;xEqGto;2!ArhA6TO5P=j$`kOPF!KJ`=r!8RzRW(MvcI@b#JKCA^RG^_l1;T&(8n zGto=)U?kw{Gtog#)YoUKoD}I7t6?AK z>oc+S#y-y1XF|X!3Tu6RCVB}o&evz6moVdeeI|MdN0q)l6TV Date: Sun, 17 Nov 2013 22:23:08 -0800 Subject: [PATCH 141/200] Another little fix for the two's complement change -- initialize SGPIO data registers to DAC zero values. --- firmware/common/sgpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 5e49c85c..b73b922d 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -215,8 +215,8 @@ void sgpio_configure( SGPIO_POS_POS_RESET(pos) | SGPIO_POS_POS(pos) ; - SGPIO_REG(slice_index) = 0x80808080; // Primary output data register - SGPIO_REG_SS(slice_index) = 0x80808080; // Shadow output data register + SGPIO_REG(slice_index) = 0x00000000; // Primary output data register + SGPIO_REG_SS(slice_index) = 0x00000000; // Shadow output data register slice_enable_mask |= (1 << slice_index); } From 24a8e2bdb53f17ac71a155231f57e3425a1d8681 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Nov 2013 19:45:36 -0800 Subject: [PATCH 142/200] Remove CPLD SVF file, as it's not used by anybody (as far as I know). --- firmware/cpld/sgpio_if/default.svf | 2079 ---------------------------- 1 file changed, 2079 deletions(-) delete mode 100755 firmware/cpld/sgpio_if/default.svf diff --git a/firmware/cpld/sgpio_if/default.svf b/firmware/cpld/sgpio_if/default.svf deleted file mode 100755 index ed629766..00000000 --- a/firmware/cpld/sgpio_if/default.svf +++ /dev/null @@ -1,2079 +0,0 @@ -// Created using Xilinx Cse Software [ISE - 14.1] -// Date: Thu Apr 04 19:24:32 2013 - -TRST OFF; -ENDIR IDLE; -ENDDR IDLE; -STATE RESET; -STATE IDLE; -FREQUENCY 1E6 HZ; -//Operation: Erase -p 0 -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) SMASK (ff) ; -SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6e5f093) MASK (0fff8fff) ; -//Check for Read/Write Protect. -SIR 8 TDI (ff) TDO (01) MASK (03) ; -//Boundary Scan Chain Contents -//Position 1: xc2c64a -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) ; -SDR 32 TDI (00000000) TDO (f6e5f093) ; -//Check for Read/Write Protect. -SIR 8 TDI (ff) TDO (01) MASK (03) ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -// Loading devices with 'enable' or 'bypass' instruction. -SIR 8 TDI (e8) ; -// Loading devices with 'erase' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (ed) SMASK (ff) ; -ENDIR IDLE; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRPAUSE; -RUNTEST DRPAUSE 20 TCK; -STATE IDLE; -RUNTEST IDLE 100000 TCK; -STATE DRPAUSE; -RUNTEST DRPAUSE 5000 TCK; -RUNTEST IDLE 1 TCK; -// Loading devices with 'init' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IDLE; -RUNTEST IDLE 20 TCK; -// Loading devices with 'init' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; -RUNTEST 800 TCK; -ENDIR IDLE; -// Loading devices with 'conld' or 'bypass' instruction. -SIR 8 TDI (c0) ; -RUNTEST 100 TCK; -// Loading devices with 'conld' or 'bypass' instruction. -SIR 8 TDI (c0) ; -RUNTEST 100 TCK; -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -SIR 8 TDI (ff) ; -SDR 1 TDI (00) SMASK (01) ; -//Operation: Program -p 0 -e -v -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) ; -SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6e5f093) MASK (0fff8fff) ; -//Check for Read/Write Protect. -SIR 8 TDI (ff) TDO (01) MASK (03) ; -//Boundary Scan Chain Contents -//Position 1: xc2c64a -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) ; -SDR 32 TDI (00000000) TDO (f6e5f093) ; -//Check for Read/Write Protect. -SIR 8 TDI (ff) TDO (01) MASK (03) ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -// Loading devices with 'enable' or 'bypass' instruction. -SIR 8 TDI (e8) ; -// Loading devices with 'erase' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (ed) SMASK (ff) ; -ENDIR IDLE; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRPAUSE; -RUNTEST DRPAUSE 20 TCK; -STATE IDLE; -RUNTEST IDLE 100000 TCK; -STATE DRPAUSE; -RUNTEST DRPAUSE 5000 TCK; -RUNTEST IDLE 1 TCK; -// Loading devices with 'init' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IDLE; -RUNTEST IDLE 20 TCK; -// Loading devices with 'init' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; -RUNTEST 800 TCK; -ENDIR IDLE; -// Loading devices with 'conld' or 'bypass' instruction. -SIR 8 TDI (c0) ; -RUNTEST 100 TCK; -// Loading devices with 'conld' or 'bypass' instruction. -SIR 8 TDI (c0) ; -RUNTEST 100 TCK; -// Loading devices with 'enable' or 'bypass' instruction. -SIR 8 TDI (e8) ; -// Programming. -// Loading devices with 'program' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (ea) ; -SDR 281 TDI (0003c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) SMASK (01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -ENDIR IDLE; -RUNTEST 10000 TCK; -SDR 281 TDI (0102f9fffffffffffffffffffffffffffffddf7fffffffffffffffffffbffffffffffe7f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (018201fffffffffffffffffffffffffffffddf7fffffffffffffffffeffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0083c1fffffffffffffffffffffffffffffddf7ffffffffffbfffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00c2f9fffffffffffffffffffffffffffffddf7fffffffffffffbffffffffffffffffe7f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01c201fffffffffffffffffffffffffffffddf7fffffefbefbffbfffefbefffffffff27c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0143c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0042f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (006201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0163c1fffffffffffffffffffffffffffffddf7ffffffffefffffffffffffffffffffe4f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01e2f9fffffffffffffffffffffffffffffd7f7fffffffbffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00e201ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00a3c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01a2f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (012201fffffffffffffffffffffffffffffd7f7fffffffffffffffffffff7ffffffffe81) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0023c1fffffffffffffffffffffffffffff5ff7ffffffffffffffffffffffffffffff24f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0032f9fffffffffffffffffffffffffffffd7f7fffffeffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (013201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01b3c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00b2f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00f201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01f3c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0172f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (007201ffffffffffffffffffffffffffffffe587fffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0053c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea4f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0152f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01d201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00d3c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0092f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe65) ; -RUNTEST 10000 TCK; -SDR 281 TDI (019201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0113c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0012f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (001a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) ; -RUNTEST 10000 TCK; -SDR 281 TDI (011bc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (019af9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (009a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00dbc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01daf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (015a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) ; -RUNTEST 10000 TCK; -SDR 281 TDI (005bc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (007af9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (017a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01fbc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00faf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00ba01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01bbc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (013af9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (003a01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (002bc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0128fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01aa01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00abc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00ebf9fffffffffffffffff7fffffffffffbeefffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01e8f9fffbfffffffffffffffffffffffffbbefffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (016bc9fffffffffff7fffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0068e1fffff7fffffffffffffffffffffffffefafffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (004ac5ffffffffffffffffffdffffffffffbeefffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (014bc1ffffffff7ffffffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01cbf9ffffffffffffffffffffffffdffffbeefffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00c8f9ffffffffffffffffffffffffff7ffbbefffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (008bc9ffffffffffffff7ffffffffffffffbbefffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0188e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (010ac5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (000bc1fffffffffffffffffffffffffffdfbbefffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (000ff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (010cf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (018fc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (008ce1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00cec4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01cfc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (014ee1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (004cf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) ; -RUNTEST 10000 TCK; -SDR 281 TDI (006fc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (016ce1fffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01eec5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00efc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00ace1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01aec5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (012fc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (002ee1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (003cf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (013fc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01bff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00bcf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00ffc1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01fff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (017cf9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (007fc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (005ce0fffffffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (015ec5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (01dfc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (00dce1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (009ec5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (019fc9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) ; -RUNTEST 10000 TCK; -SDR 281 TDI (011ce1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) ; -RUNTEST 10000 TCK; -SDR 281 TDI (001ec5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 10000 TCK; -SDR 281 TDI (0117ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 10000 TCK; -// Loading devices with 'init' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IDLE; -RUNTEST IDLE 20 TCK; -// Loading devices with 'init' or 'bypass' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; -RUNTEST 800 TCK; -ENDIR IDLE; -// Loading devices with 'conld' or 'bypass' instruction. -SIR 8 TDI (c0) ; -RUNTEST 100 TCK; -// Loading devices with 'conld' or 'bypass' instruction. -SIR 8 TDI (c0) ; -RUNTEST 100 TCK; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -//Loading device with 'enable' instruction. -SIR 8 TDI (e8) ; -//Loading device with 'enable' instruction. -SIR 8 TDI (e8) ; -// Verification. -// Loading device with a 'verify' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (ee) ; -ENDDR DRPAUSE; -SDR 7 TDI (00) SMASK (7f) ; -ENDIR IDLE; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (40) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffddf7fffffffffffffffffffbffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (60) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffddf7fffffffffffffffffeffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (20) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffddf7ffffffffffbfffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (30) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffddf7fffffffffffffbffffffffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (70) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffddf7fffffefbefbffbfffefbefffffffff27c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (50) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (10) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (18) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (58) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffddf7ffffffffefffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (78) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffd7f7fffffffbffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (38) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (28) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (68) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (48) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffd7f7fffffffffffffffffffff7ffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (08) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffff5ff7ffffffffffffffffffffffffffffff24f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffd7f7fffffeffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201ffffffffffffffffffffffffffffffe587fffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe001ff801ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (14) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea4f) MASK ( -03fffffffffffffffffffffffffffffe001f8001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (54) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (74) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (34) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (24) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe65) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (64) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (44) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (04) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (06) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (46) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (66) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (26) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (36) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (76) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (56) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (16) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffff7fffffffffffbeefffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffbfffffffffffffffffffffffffbbefffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffff7fffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffff7fffffffffffffffffffffffffefafffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (12) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5ffffffffffffffffffdffffffffffbeefffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (52) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ffffffff7ffffffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (72) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9ffffffffffffffffffffffffdffffbeefffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (32) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffffffffffffffffffffff7ffbbefffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (22) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9ffffffffffffff7ffffffffffffffbbefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (62) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (42) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (02) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffdfbbefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (03) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (43) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (63) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (23) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (33) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (73) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (53) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (13) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffe7d) MASK ( -03fffffffffffffffffffffffffffffe00078001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (17) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e0fffffffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (57) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (77) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (37) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (27) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (67) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (47) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (07) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (05) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) MASK ( -0000000000000000000000000000000000000000000000000000000000000000000000) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (45) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -// masking lower UES bits. -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) MASK ( -0000000000000000000000000000000000000000000000000000000000000000000000) ; -RUNTEST 100 TCK; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IDLE; -RUNTEST IDLE 20 TCK; -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; -RUNTEST 800 TCK; -ENDIR IDLE; -//Loading device with 'conld' instruction. -SIR 8 TDI (c0) ; -RUNTEST IDLE 100 TCK; -//Loading device with 'enable' instruction. -SIR 8 TDI (e8) ; -// Setting Done bit ... -// Loading device with a 'program' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (ea) ; -SDR 281 TDI (0017fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -ENDIR IDLE; -RUNTEST 10000 TCK; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IDLE; -RUNTEST IDLE 20 TCK; -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; -RUNTEST 800 TCK; -ENDIR IDLE; -//Loading device with 'conld' instruction. -SIR 8 TDI (c0) ; -RUNTEST IDLE 100 TCK; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) ; -SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6e5f093) MASK (0fff8fff) ; -//Check for Done bit. -SIR 8 TDI (ff) TDO (05) MASK (07) ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -SIR 8 TDI (ff) ; -SDR 1 TDI (00) SMASK (01) ; -//Operation: Verify -p 0 -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) ; -SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6e5f093) MASK (0fff8fff) ; -//Check for Read/Write Protect. -SIR 8 TDI (ff) TDO (01) MASK (03) ; -//Boundary Scan Chain Contents -//Position 1: xc2c64a -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) ; -SDR 32 TDI (00000000) TDO (f6e5f093) ; -//Check for Read/Write Protect. -SIR 8 TDI (ff) TDO (01) MASK (03) ; -//Loading device with 'bypass' instruction. -SIR 8 TDI (ff) ; -//Loading device with 'enable' instruction. -SIR 8 TDI (e8) ; -//Loading device with 'enable' instruction. -SIR 8 TDI (e8) ; -//Loading device with 'enable' instruction. -SIR 8 TDI (e8) ; -// Verification. -// Loading device with a 'verify' instruction. -ENDIR IRPAUSE; -SIR 8 TDI (ee) ; -ENDDR DRPAUSE; -SDR 7 TDI (00) SMASK (7f) ; -ENDIR IDLE; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (40) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffddf7fffffffffffffffffffbffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (60) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffddf7fffffffffffffffffeffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (20) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffddf7ffffffffffbfffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (30) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffddf7fffffffffffffbffffffffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (70) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffddf7fffffefbefbffbfffefbefffffffff27c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (50) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (10) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (18) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (58) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffddf7ffffffffefffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (78) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffd7f7fffffffbffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (38) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (28) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (68) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (48) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffd7f7fffffffffffffffffffff7ffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (08) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffff5ff7ffffffffffffffffffffffffffffff24f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffd7f7fffffeffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1c) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201ffffffffffffffffffffffffffffffe587fffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe001ff801ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (14) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea4f) MASK ( -03fffffffffffffffffffffffffffffe001f8001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (54) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (74) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (34) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (24) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe65) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (64) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (44) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (04) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (06) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (46) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (66) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (26) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (36) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (76) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (56) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (16) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe81) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0e) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (0201fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffff7fffffffffffbeefffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffbfffffffffffffffffffffffffbbefffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffff7fffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1a) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffff7fffffffffffffffffffffffffefafffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (12) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5ffffffffffffffffffdffffffffffbeefffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (52) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1ffffffff7ffffffffffffffffffffbeefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (72) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9ffffffffffffffffffffffffdffffbeefffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (32) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9ffffffffffffffffffffffffff7ffbbefffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (22) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9ffffffffffffff7ffffffffffffffbbefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (62) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (42) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (02) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffdfbbefffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (03) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (43) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (63) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (23) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (33) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (73) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (53) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1d) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (13) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7c) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffe7d) MASK ( -03fffffffffffffffffffffffffffffe00078001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03fffffffffffffffffffffffffffffe00000001ffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0b) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (0f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (4f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (6f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (2f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (3f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (7f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (5f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00f9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (1f) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (17) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e0fffffffffffffffffffffffffffffafefffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (57) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (77) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (37) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (27) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (67) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0f) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (47) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (00e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7d) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (07) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (02c5fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01) MASK ( -03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (05) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) MASK ( -0000000000000000000000000000000000000000000000000000000000000000000000) ; -RUNTEST 100 TCK; -ENDDR DRPAUSE; -SDR 7 TDI (45) SMASK (7f) ; -RUNTEST DRPAUSE 20 TCK; -ENDDR IDLE; -RUNTEST IDLE 100 TCK; -// masking lower UES bits. -SDR 274 TDI (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) SMASK (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) TDO (03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) MASK ( -0000000000000000000000000000000000000000000000000000000000000000000000) ; -RUNTEST 100 TCK; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IDLE; -RUNTEST IDLE 20 TCK; -ENDIR IRPAUSE; -SIR 8 TDI (f0) SMASK (ff) ; -STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE; -RUNTEST 800 TCK; -ENDIR IDLE; -//Loading device with 'conld' instruction. -SIR 8 TDI (c0) ; -RUNTEST IDLE 100 TCK; -//Loading device with 'idcode' instruction. -SIR 8 TDI (01) ; -SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6e5f093) MASK (0fff8fff) ; -//Check for Done bit. -SIR 8 TDI (ff) TDO (05) MASK (07) ; -//Loading device with 'conld' instruction. -SIR 8 TDI (c0) ; -RUNTEST IDLE 100 TCK; -//Loading device with 'bypass' instruction. -SIR 8 TDI (ff) ; -TIR 0 ; -HIR 0 ; -HDR 0 ; -TDR 0 ; -TIR 0 ; -HIR 0 ; -TDR 0 ; -HDR 0 ; -SIR 8 TDI (ff) ; -SDR 1 TDI (00) SMASK (01) ; From 3bf6573dc6da154eaea7a528aad750ca51c96151 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Nov 2013 19:52:06 -0800 Subject: [PATCH 143/200] Add skip-every-N function to CPLD, where N is controlled by three input pins from the microcontroller. Updated SGPIO CPLD testbench, as it had fallen a bit out of date. Add SGPIO API initialization and control of CPLD decimation feature. --- firmware/common/sgpio.c | 23 ++++- firmware/common/sgpio.h | 2 + firmware/cpld/sgpio_if/default.xsvf | Bin 37629 -> 37629 bytes firmware/cpld/sgpio_if/top.jed | 148 ++++++++++++++-------------- firmware/cpld/sgpio_if/top.ucf | 6 +- firmware/cpld/sgpio_if/top.vhd | 33 ++++++- firmware/cpld/sgpio_if/top_tb.vhd | 61 ++++++------ 7 files changed, 158 insertions(+), 115 deletions(-) mode change 100755 => 100644 firmware/cpld/sgpio_if/default.xsvf diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index b73b922d..42dfb902 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -20,6 +20,7 @@ * Boston, MA 02110-1301, USA. */ +#include #include #include @@ -41,9 +42,13 @@ void sgpio_configure_pin_functions() { scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[12] */ + scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[13] */ + scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[14] */ + + sgpio_cpld_stream_rx_set_decimation(0); + + GPIO_DIR(GPIO5) |= GPIOPIN14 | GPIOPIN13 | GPIOPIN12; } @@ -238,3 +243,15 @@ void sgpio_cpld_stream_disable() { bool sgpio_cpld_stream_is_enabled() { return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; /* SGPIO10 */ } + +bool sgpio_cpld_stream_rx_set_decimation(const uint_fast8_t skip_n) { + /* CPLD interface is three bits, SGPIO[15:13]: + * 111: decimate by 1 (skip_n=0, skip no samples) + * 110: decimate by 2 (skip_n=1, skip every other sample) + * 101: decimate by 3 (skip_n=2, skip two of three samples) + * ... + * 000: decimate by 8 (skip_n=7, skip seven of eight samples) + */ + GPIO_SET(GPIO5) = GPIOPIN14 | GPIOPIN13 | GPIOPIN12; + GPIO_CLR(GPIO5) = (skip_n & 7) << 12; +} diff --git a/firmware/common/sgpio.h b/firmware/common/sgpio.h index d37ae4de..3f92c1bb 100644 --- a/firmware/common/sgpio.h +++ b/firmware/common/sgpio.h @@ -39,4 +39,6 @@ void sgpio_cpld_stream_enable(); void sgpio_cpld_stream_disable(); bool sgpio_cpld_stream_is_enabled(); +bool sgpio_cpld_stream_rx_set_decimation(const uint_fast8_t skip_n); + #endif//__SGPIO_H__ diff --git a/firmware/cpld/sgpio_if/default.xsvf b/firmware/cpld/sgpio_if/default.xsvf old mode 100755 new mode 100644 index 7bcbb905b77db10166a445d5083fb6ac9752c25c..330198987793e1dd94d8e657330a908ef9d03cfb GIT binary patch delta 1777 zcmeH_O-vI}5XarOZ9$`jZo$@;))q@*BG4^0kqX#WY*G+JQ4{N>-H1Uv7-NDS7h;St z(P$VCaxq-+LP#JlDxMHM!G)L@kr)v?81(>x@=g1EZ`<9J;Mo)Jva>V)nR)Z(m+VE! zUNrEM(=QWxpuE5iqo@QnxILzJnYq-HoVo@!6g1Yzs)v4)(2Bn1uV;A(S($Yu9PIHSzND^IlWSewv6JvhPOOQ$}sP7!sLN5;3J`J#Cujk%#a&zp&T&r|g)IxklVXJT%+moMukzbMyg$l)r+{eHg;anlq1 z&ly6-A#vOZHo?o4fgE(fRl&=rwR8kQ6c#tlNK&a`SQn0Il9*ZKNs!PY4rt3QH;mDe zw5CLV*US~%281F-P*=b#Ch0EdL`!LPpwN$~GEC!Rs05>%t3~8T zXuo-n1Fl$nh|DVHkmWEUYt*zsuGOa_q+f=Sa}Ky@?L=gPnnkc`t>DSp1k>Q?zIKjw z4@c~H(iTUC>0vezTR4t6UhrA_9}ooyyCwUU{j&t+3`6L&1>UOy!2Wy5sf3_k5?*eW-S<;U*Op3tOWWqxSBRMK65B&moMJbI7^mxqp zjW}q4r`2v~3<&V-NFoExqh>P%Dt~7pH?q77fdqXXH)K)IBsC&6~ekQbmiB!XXs**=e3Ja8TP@a6D?`H?!(nn#dt1q2&r7LM`?^E zG`8sb!E{to`AXE?Qu$&^L%pOjRu0|uODbdRe#0j(shlZWXl@upY1V*-v9IZ}E{iv~ XeqO+%XTKS?ncHUWe=^th;IaNM&;XBB delta 1543 zcmeH{-Ahw(7{~jaz4(G{ZcChVbDpIX;$ECmzOpTKs3~S4r59}{EwP)zx^87eM6dYm zB7^G6AR-zZ#O!8?SC$k-1SX|+5u_K3R+^$a{m$8$FZ3_?yE)Ix_j!IV&xf-%#HyMtIg(3QH&KD`5xO<^8Z}pyDv+f`GVgF zQc`9s^!!xeGlp)X!C8L+|6*@_3e8w?tJDCei<4&@c8#lHv9oBY(Btv`Ai~t9#i%Hc z$?-lp)`!`BEQ+i3xKbHhuQ65y<(c0(Y{1j10Aa+r^TpLFk{o;BoGERAPBqksP%H2K#11s@yW~KNu3+LK5l~pQM&32hz%1g3?w)( zOIz7$yA%l&>=>^7g9k@TFkRQ3K;Z_S+sk<3&tW!0Al|5@A(#X~>_6MU$uNk=IM>*n z1VYrRo49o-MDbwLq6~)kqLG7LNjSXC;|y*WJNS~;lS;IHq)$ diff --git a/firmware/cpld/sgpio_if/top.jed b/firmware/cpld/sgpio_if/top.jed index 52f04961..44aa1403 100755 --- a/firmware/cpld/sgpio_if/top.jed +++ b/firmware/cpld/sgpio_if/top.jed @@ -1,5 +1,5 @@ Programmer Jedec Bit Map -Date Extracted: Sat Sep 21 23:00:53 2013 +Date Extracted: Tue Nov 19 16:33:01 2013 QF25812* QP100* @@ -12,20 +12,20 @@ N DEVICE XC2C64A-7-VQ100* Note Block 0 * Note Block 0 ZIA * -L000000 1111111111111111* -L000016 1111111111111111* +L000000 1111111011100111* +L000016 1110101011111111* L000032 1111111011110011* L000048 1111111111111111* L000064 1111111111111111* -L000080 1111111011010111* -L000096 1111111111111111* +L000080 1111111011100111* +L000096 1110101011111111* L000112 1111111111111111* -L000128 1111111111111111* +L000128 1110101011111111* L000144 1111111111111111* L000160 1111111111111111* L000176 1111111111111111* L000192 1111111111111111* -L000208 1111111111111111* +L000208 1111111011100111* L000224 1111111111111111* L000240 1111111111111111* L000256 1111111111111111* @@ -54,11 +54,11 @@ L000608 1111111111111111* L000624 1111111111111111* Note Block 0 PLA AND array * -L000640 11110111110111111111111111111111111111111111111111111111111111111111111111111111* -L000720 11111011111011111111111111111111111111111111111111111111111111111111111111111111* -L000800 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L000880 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L000960 11111111111111111111111111111111111111111111111111111111111111111111111111111111* +L000640 11010111111101110111111111011111111111111111111111111111111111111111111111111111* +L000720 11111011111111111111111111111111111111111111111111111111111111111111111111111111* +L000800 01011111111101110111111111111111111111111111111111111111111111111111111111111111* +L000880 11010111111011110111111111111111111111111111111111111111111111111111111111111111* +L000960 11010111111110110111111111111111111111111111111111111111111111111111111111111111* L001040 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L001120 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L001200 11111111111111111111111111111111111111111111111111111111111111111111111111111111* @@ -109,14 +109,14 @@ L004720 111111111111111111111111111111111111111111111111111111111111111111111111 L004800 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L004880 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L004960 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L005040 11111111111111111111111111111111111111111111111111111111111111111111111111111111* +L005040 11110111111111110111111111111111111111111111111111111111111111111111111111111111* Note Block 0 PLA OR array * L005120 1111111111111110* -L005136 1111111111111110* -L005152 1111111111111111* -L005168 1111111111111111* -L005184 1111111111111111* +L005136 1111111111111101* +L005152 1111111111111101* +L005168 1111111111111011* +L005184 1111111111111011* L005200 1111111111111111* L005216 1111111111111111* L005232 1111111111111111* @@ -184,9 +184,9 @@ L006259 000001111001111110011111100* L006286 000001111001111110011111100* L006313 000001111001111110011111100* L006340 000001111001111110011111100* -L006367 000001111001111110011111100* -L006394 000001111001111110011111100* -L006421 000001111001100110011111101* +L006367 000101111101110110011111100* +L006394 000101111101110111111111100* +L006421 000101111101110111011111100* Note Block 1 * Note Block 1 ZIA * @@ -374,15 +374,15 @@ L012928 1111111011110011* L012944 1111111111111111* L012960 1111111010110111* L012976 1111111011010111* -L012992 1111111010110111* -L013008 1111111011010111* -L013024 1111111010110111* +L012992 1110101011111111* +L013008 1100111011111111* +L013024 1110101011111111* L013040 1111111010110111* L013056 1111111010110111* -L013072 1111111011100111* -L013088 1111111011010111* +L013072 1111111011010111* +L013088 1111111010110111* L013104 1111111111111111* -L013120 1111111111111111* +L013120 1111111010110111* L013136 1111111011010111* L013152 1111111111111111* L013168 1111111111111111* @@ -392,7 +392,7 @@ L013216 1111111111111111* L013232 1111111111111111* L013248 1111111111111111* L013264 1111111111111111* -L013280 1111111111111111* +L013280 1111111011010111* L013296 1111111111111111* L013312 1111111111111111* L013328 1111111111111111* @@ -400,7 +400,7 @@ L013344 1111111111111111* L013360 1111111111111111* L013376 1111111111111111* L013392 1111111111111111* -L013408 1111111111111111* +L013408 1111111011100111* L013424 1111111111111111* L013440 1111111111111111* L013456 1111111111111111* @@ -410,27 +410,27 @@ L013504 1111111111111111* L013520 1111111111111111* Note Block 2 PLA AND array * -L013536 11111011111111111101111111111111111111111111111111111111111111111111111111111111* -L013616 11110111111111111110111111111111111111111111111111111111111111111111111111111111* -L013696 11111011111101111111111111111111111111111111111111111111111111111111111111111111* -L013776 11110111111110111111111111111111111111111111111111111111111111111111111111111111* -L013856 11111011011111111111111111111111111111111111111111111111111111111111111111111111* -L013936 11110111101111111111111111111111111111111111111111111111111111111111111111111111* -L014016 11111011111111110111111111111111111111111111111111111111111111111111111111111111* +L013536 11110111110111111111111111111111111111111111111111111111111111111011111111111111* +L013616 11011011111001110111111111111111111111111111111111111111111111111011111111111111* +L013696 11110111111011011111111111111111111111111111111111111111111111111111111111111111* +L013776 11111011110111011111111111111111111111111111111111111111111111111111111111111111* +L013856 11111011111111111101111111111111111111111111111111111111111111111111111111111111* +L013936 11110111111111111110111111111111111111111111111111111111111111111111111111111111* +L014016 11111011111111111111111111110111111111111111111111111111111111111111111111111111* L014096 11111111111011111111111111111111111111111111111111111111111111111111111111111111* -L014176 11110111111111111011111111111111111111111111111111111111111111111111111111111111* -L014256 11111011111111111111011111111111111111111111111111111111111111111111111111111111* -L014336 11011111111111111111111111111111111111111111111111111111111111111111111111111111* -L014416 11110111111111111111101111111111111111111111111111111111111111111111111111111111* -L014496 11111011111111011111111111111111111111111111111111111111111111111111111111111111* -L014576 11110111111111101111111111111111111111111111111111111111111111111111111111111111* -L014656 11111011111111111111111111111101111111111111111111111111111111111111111111111111* -L014736 11110111111111111111111111111110111111111111111111111111111111111111111111111111* -L014816 11111011111111111111111101111111111111111111111111111111111111111111111111111111* -L014896 11110111111111111111111110111111111111111111111111111111111111111111111111111111* -L014976 11111111111111111111111011111111111111111111111111111111111111111111111111111111* -L015056 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L015136 11111111111111111111111111111111111111111111111111111111111111111111111111111111* +L014176 11110111111111111111111111111011111111111111111111111111111111111111111111111111* +L014256 11111011011111111111111111111111111111111111111111111111111111111111111111111111* +L014336 11110111101111111111111111111111111111111111111111111111111111111111111111111111* +L014416 11111011111111111111111101111111111111111111111111111111111111111111111111111111* +L014496 11110111111111111111111110111111111111111111111111111111111111111111111111111111* +L014576 11111011111111111111011111111111111111111111111111111111111111111111111111111111* +L014656 11110111111111111111101111111111111111111111111111111111111111111111111111111111* +L014736 11111011111111111111110111111111111111111111111111111111111111111111111111111111* +L014816 11110111111111111111111011111111111111111111111111111111111111111111111111111111* +L014896 11111011111111111111111111111101111111111111111111111111111111111111111111111111* +L014976 11110111111111111111111111111110111111111111111111111111111111111111111111111111* +L015056 11111011111111111111111111111111111111111111111101111111111111111111111111111111* +L015136 11110111111111111111111111111111111111111111111110111111111111111111111111111111* L015216 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L015296 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L015376 11111111111111111111111111111111111111111111111111111111111111111111111111111111* @@ -468,27 +468,27 @@ L017856 111111111111111111111111111111111111111111111111111111111111111111111111 L017936 11111111111111111111111111111111111111111111111111111111111111111111111111111111* Note Block 2 PLA OR array * -L018016 1101111111111111* -L018032 1101111111111111* -L018048 1111011111111111* -L018064 1111011111111111* -L018080 1111111101111111* -L018096 1111111101111111* -L018112 1111111110111111* +L018016 0111111111111111* +L018032 0111111111111111* +L018048 0111111111111111* +L018064 0111111111111111* +L018080 1101111111111111* +L018096 1101111111111111* +L018112 1111011111111111* L018128 1111111111111111* -L018144 1111111110111111* -L018160 1111111111111011* -L018176 1111111111111111* -L018192 1111111111111011* -L018208 1111111111111101* -L018224 1111111111111101* -L018240 1111111111111110* -L018256 1111111111111110* -L018272 1111110111111111* -L018288 1111110111111111* -L018304 0111111111111111* -L018320 1111111111111111* -L018336 1111111111111111* +L018144 1111011111111111* +L018160 1111111101111111* +L018176 1111111101111111* +L018192 1111111110111111* +L018208 1111111110111111* +L018224 1111111111111011* +L018240 1111111111111011* +L018256 1111111111111101* +L018272 1111111111111101* +L018288 1111111111111110* +L018304 1111111111111110* +L018320 1111110111111111* +L018336 1111110111111111* L018352 1111111111111111* L018368 1111111111111111* L018384 1111111111111111* @@ -527,12 +527,12 @@ L018896 1111111111111111* Note Block 2 I/O Macrocell Configuration 27 bits * N Aclk ClkOp Clk:2 ClkFreq R:2 P:2 RegMod:2 INz:2 FB:2 InReg St XorIn:2 RegCom Oe:4 Tm Slw Pu* -L018912 000101111111111100000000011* -L018939 000001111001111110011111100* +L018912 000101111001110100000000011* +L018939 000001111000011100011111100* L018966 000101111000011101101000111* -L018993 000001111001111110011111100* +L018993 000001111000011100011111100* L019020 000101111000011101101000111* -L019047 000001111001111110011111100* +L019047 000001111000011100011111100* L019074 000101111000011100001000111* L019101 000001111000011100011111100* L019128 000101111000011101101000111* @@ -753,5 +753,5 @@ L025810 0* Note I/O Bank 1 Vcco * L025811 0* -C1565* -AA4D +C0D64* +AA1A diff --git a/firmware/cpld/sgpio_if/top.ucf b/firmware/cpld/sgpio_if/top.ucf index e03f0385..7fb009ba 100755 --- a/firmware/cpld/sgpio_if/top.ucf +++ b/firmware/cpld/sgpio_if/top.ucf @@ -54,7 +54,11 @@ NET "HOST_DATA<4>" LOC="67" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; NET "HOST_DATA<3>" LOC="72" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; NET "HOST_DATA<2>" LOC="74" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; NET "HOST_DATA<1>" LOC="79" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; -NET "HOST_DATA<0>" LOC="89" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; +NET "HOST_DATA<0>" LOC="89" |IOSTANDARD=LVCMOS33 | SLEW=SLOW | TNM=to_host; + +NET "HOST_DECIM_SEL<2>" LOC="78" |IOSTANDARD=LVCMOS33; +NET "HOST_DECIM_SEL<1>" LOC="81" |IOSTANDARD=LVCMOS33; +NET "HOST_DECIM_SEL<0>" LOC="90" |IOSTANDARD=LVCMOS33; TIMEGRP "adc_data" OFFSET = IN 16 ns BEFORE "CODEC_X2_CLK"; diff --git a/firmware/cpld/sgpio_if/top.vhd b/firmware/cpld/sgpio_if/top.vhd index f431b246..90d6bb84 100755 --- a/firmware/cpld/sgpio_if/top.vhd +++ b/firmware/cpld/sgpio_if/top.vhd @@ -21,6 +21,7 @@ library IEEE; use IEEE.STD_LOGIC_1164.ALL; +use ieee.std_logic_unsigned.all; library UNISIM; use UNISIM.vcomponents.all; @@ -30,7 +31,8 @@ entity top is HOST_DATA : inout std_logic_vector(7 downto 0); HOST_CAPTURE : out std_logic; HOST_DISABLE : in std_logic; - HOST_DIRECTION : in std_logic; + HOST_DIRECTION : in std_logic; + HOST_DECIM_SEL : in std_logic_vector(2 downto 0); DA : in std_logic_vector(7 downto 0); DD : out std_logic_vector(9 downto 0); @@ -57,6 +59,10 @@ architecture Behavioral of top is signal data_from_host_i : std_logic_vector(7 downto 0); signal data_to_host_o : std_logic_vector(7 downto 0); + signal decimate_count : std_logic_vector(2 downto 0) := "111"; + signal decimate_sel_i : std_logic_vector(2 downto 0); + signal decimate_en : std_logic; + begin ------------------------------------------------ @@ -87,9 +93,26 @@ begin host_data_enable_i <= not HOST_DISABLE; transfer_direction_i <= to_dac when HOST_DIRECTION = '1' else from_adc; - - ------------------------------------------------ - + + decimate_sel_i <= HOST_DECIM_SEL; + + ------------------------------------------------ + + decimate_en <= '1' when decimate_count = "111" else '0'; + + process(host_clk_i) + begin + if rising_edge(host_clk_i) then + if codec_clk_i = '1' then + if decimate_count = "111" then + decimate_count <= decimate_sel_i; + else + decimate_count <= decimate_count + 1; + end if; + end if; + end if; + end process; + process(host_clk_i) begin if rising_edge(host_clk_i) then @@ -123,7 +146,7 @@ begin end if; else if codec_clk_i = '0' then - host_data_capture_o <= host_data_enable_i; + host_data_capture_o <= host_data_enable_i and decimate_en; end if; end if; end if; diff --git a/firmware/cpld/sgpio_if/top_tb.vhd b/firmware/cpld/sgpio_if/top_tb.vhd index 3c15e9b2..6c38531b 100755 --- a/firmware/cpld/sgpio_if/top_tb.vhd +++ b/firmware/cpld/sgpio_if/top_tb.vhd @@ -1,22 +1,22 @@ -- --- Copyright 2012 Jared Boone --- --- This file is part of HackRF. --- --- 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, or (at your option) --- any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program; see the file COPYING. If not, write to --- the Free Software Foundation, Inc., 51 Franklin Street, --- Boston, MA 02110-1301, USA. +-- Copyright 2012 Jared Boone +-- +-- This file is part of HackRF. +-- +-- 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, or (at your option) +-- any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; see the file COPYING. If not, write to +-- the Free Software Foundation, Inc., 51 Franklin Street, +-- Boston, MA 02110-1301, USA. LIBRARY ieee; USE ieee.std_logic_1164.ALL; @@ -31,13 +31,12 @@ ARCHITECTURE behavior OF top_tb IS HOST_DATA : INOUT std_logic_vector(7 downto 0); HOST_CAPTURE : OUT std_logic; HOST_DISABLE : IN std_logic; - HOST_DIRECTION : IN std_logic; + HOST_DIRECTION : IN std_logic; + HOST_DECIM_SEL : IN std_logic_vector(2 downto 0); DA : IN std_logic_vector(7 downto 0); DD : OUT std_logic_vector(9 downto 0); CODEC_CLK : IN std_logic; - CODEC_X2_CLK : IN std_logic; - B1AUX : INOUT std_logic_vector(16 downto 9); - B2AUX : INOUT std_logic_vector(16 downto 1) + CODEC_X2_CLK : IN std_logic ); END COMPONENT; @@ -46,12 +45,11 @@ ARCHITECTURE behavior OF top_tb IS signal CODEC_CLK : std_logic := '0'; signal CODEC_X2_CLK : std_logic := '0'; signal HOST_DISABLE : std_logic := '1'; - signal HOST_DIRECTION : std_logic := '0'; + signal HOST_DIRECTION : std_logic := '0'; + signal HOST_DECIM_SEL : std_logic_vector(2 downto 0) := "010"; --BiDirs signal HOST_DATA : std_logic_vector(7 downto 0); - signal B1AUX : std_logic_vector(16 downto 9); - signal B2AUX : std_logic_vector(16 downto 1); --Outputs signal DD : std_logic_vector(9 downto 0); @@ -63,13 +61,12 @@ begin HOST_DATA => HOST_DATA, HOST_CAPTURE => HOST_CAPTURE, HOST_DISABLE => HOST_DISABLE, - HOST_DIRECTION => HOST_DIRECTION, + HOST_DIRECTION => HOST_DIRECTION, + HOST_DECIM_SEL => HOST_DECIM_SEL, DA => DA, DD => DD, CODEC_CLK => CODEC_CLK, - CODEC_X2_CLK => CODEC_X2_CLK, - B1AUX => B1AUX, - B2AUX => B2AUX + CODEC_X2_CLK => CODEC_X2_CLK ); clk_process :process @@ -90,11 +87,11 @@ begin begin wait until rising_edge(CODEC_CLK); wait for 9 ns; - DA <= (others => '0'); + DA <= "00000000"; wait until falling_edge(CODEC_CLK); wait for 9 ns; - DA <= (others => '1'); + DA <= "00000001"; end process; @@ -132,4 +129,4 @@ begin wait; end process; -end; +end; \ No newline at end of file From 39276f162c8ab1a573258052ef7a66b90f6bf512 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 19 Nov 2013 19:52:50 -0800 Subject: [PATCH 144/200] Add M0 linker script. --- firmware/common/LPC4330_M0.ld | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 firmware/common/LPC4330_M0.ld diff --git a/firmware/common/LPC4330_M0.ld b/firmware/common/LPC4330_M0.ld new file mode 100644 index 00000000..787f3f9a --- /dev/null +++ b/firmware/common/LPC4330_M0.ld @@ -0,0 +1,29 @@ +/* + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone + * + * This file is part of HackRF + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x00000000, LENGTH = 4K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx_m0_ram_only.ld From e3f9e204c13e0e8c95c310765e407f9baaea6d6f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 13:22:19 -0800 Subject: [PATCH 145/200] Relocate SGPIO pin configuration -- it only needs to be done once. --- firmware/common/hackrf_core.c | 3 +++ firmware/common/sgpio.c | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index dc2f2013..d301731f 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -25,6 +25,7 @@ #include "si5351c.h" #include "max2837.h" #include "rffc5071.h" +#include "sgpio.h" #include #include #include @@ -588,6 +589,8 @@ void pin_setup(void) { /* Configure external clock in */ //scu_pinmux(P4_7, SCU_CLK_IN | SCU_CONF_FUNCTION1); + + sgpio_configure_pin_functions(); } void enable_1v8_power(void) { diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 42dfb902..0449e8d2 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -63,8 +63,6 @@ void sgpio_test_interface() { // Disable all counters during configuration SGPIO_CTRL_ENABLE = 0; - sgpio_configure_pin_functions(); - // Make all SGPIO controlled by SGPIO's "GPIO" registers for (uint_fast8_t i = 0; i < 16; i++) { SGPIO_OUT_MUX_CFG(i) = @@ -117,8 +115,6 @@ void sgpio_configure( // Disable all counters during configuration SGPIO_CTRL_ENABLE = 0; - sgpio_configure_pin_functions(); - // Set SGPIO output values. const uint_fast8_t cpld_direction = (direction == SGPIO_DIRECTION_TX) ? 1 : 0; From 91a7ca498394a873bf3df990505f6a566043410d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:08:59 -0800 Subject: [PATCH 146/200] Fix return value on SGPIO decimation function. --- firmware/common/sgpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 0449e8d2..ca982966 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -250,4 +250,6 @@ bool sgpio_cpld_stream_rx_set_decimation(const uint_fast8_t skip_n) { */ GPIO_SET(GPIO5) = GPIOPIN14 | GPIOPIN13 | GPIOPIN12; GPIO_CLR(GPIO5) = (skip_n & 7) << 12; + + return (skip_n < 8); } From e29ec6b0849cb9e9510cbd03a7683e88d5da9061 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:09:52 -0800 Subject: [PATCH 147/200] Add default M0 code that just loops forever, if a project doesn't specify any SRC_M0_[CS] files. --- firmware/common/m0_sleep.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 firmware/common/m0_sleep.c diff --git a/firmware/common/m0_sleep.c b/firmware/common/m0_sleep.c new file mode 100644 index 00000000..e540dd59 --- /dev/null +++ b/firmware/common/m0_sleep.c @@ -0,0 +1,26 @@ +/* + * Copyright 2013 Jared Boone + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +int main() { + while(1) { + + } +} \ No newline at end of file From 31a55d0e9b0db756448991a153ba7e9ebdec032e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:13:18 -0800 Subject: [PATCH 148/200] Assembly file that includes M0 binary into a .o to be linked into the M4 binary. There's certainly a more elegant way, but for now... --- firmware/common/m0_bin.s | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 firmware/common/m0_bin.s diff --git a/firmware/common/m0_bin.s b/firmware/common/m0_bin.s new file mode 100644 index 00000000..f01f3e09 --- /dev/null +++ b/firmware/common/m0_bin.s @@ -0,0 +1,23 @@ +# Copyright 2013 Jared Boone +# +# This file is part of HackRF. +# +# 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, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + + .data + .section .m0_bin, "ax" + + .incbin "build/m0/m0.bin" From c365d0a37e39b4435ad86b86abf06425ab410cdd Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:14:13 -0800 Subject: [PATCH 149/200] Add memory regions for M0 code to live. In the "rom_to_ram" (SPIFI) version, put M0 binary in ROM. In the RAM version, put M0 code in the destination RAM region. --- firmware/common/LPC4330_M4.ld | 10 ++++++++++ firmware/common/LPC4330_M4_rom_to_ram.ld | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index f2663957..d449566e 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -40,3 +40,13 @@ MEMORY /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx.ld + +SECTIONS +{ + .m0 0x10090000 : { + PROVIDE(__m0_start__ = .); + KEEP(*(.m0_bin*)); + . = ALIGN(4); + PROVIDE(__m0_end__ = .); + } >ram_m0 +} diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld index a50ba638..febce4e9 100644 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ b/firmware/common/LPC4330_M4_rom_to_ram.ld @@ -42,3 +42,13 @@ MEMORY /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx_rom_to_ram.ld + +SECTIONS +{ + .text : { + PROVIDE(__m0_start__ = .); + KEEP(*(.m0_bin*)); + . = ALIGN(4); + PROVIDE(__m0_end__ = .); + } >rom +} From 6a03f157ffc76d5a3e8626f244bae3ef8cf0ce8e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:20:32 -0800 Subject: [PATCH 150/200] With Makefile RAM/SPIFI option, remove/rework redundant "rom_to_ram" projects. --- firmware/Makefile | 8 +--- firmware/blinky_rom_to_ram/Makefile | 38 ---------------- firmware/blinky_rom_to_ram/README | 3 -- firmware/cpldjtagprog_rom_to_ram/Makefile | 42 ------------------ firmware/cpldjtagprog_rom_to_ram/README | 1 - .../Makefile | 2 +- .../README | 0 .../Test_SGPIO0_to15.ods | Bin .../Test_SGPIO0_to15.pdf | Bin ...t_SGPIO_GPIO_mode_test_sgpio_interface.txt | 0 .../sgpio_passthrough.c | 2 +- firmware/startup_systick_perfo/README | 3 ++ .../result_exec_from_SRAM.txt | 0 .../startup_systick_perfo_rom_to_ram/Makefile | 38 ---------------- .../startup_systick_perfo_rom_to_ram/README | 17 ------- 15 files changed, 6 insertions(+), 148 deletions(-) delete mode 100644 firmware/blinky_rom_to_ram/Makefile delete mode 100644 firmware/blinky_rom_to_ram/README delete mode 100644 firmware/cpldjtagprog_rom_to_ram/Makefile delete mode 100644 firmware/cpldjtagprog_rom_to_ram/README rename firmware/{sgpio_passthrough_rom_to_ram => sgpio_passthrough}/Makefile (95%) rename firmware/{sgpio_passthrough_rom_to_ram => sgpio_passthrough}/README (100%) rename firmware/{sgpio_passthrough_rom_to_ram => sgpio_passthrough}/Test_SGPIO0_to15.ods (100%) rename firmware/{sgpio_passthrough_rom_to_ram => sgpio_passthrough}/Test_SGPIO0_to15.pdf (100%) rename firmware/{sgpio_passthrough_rom_to_ram => sgpio_passthrough}/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt (100%) rename firmware/{sgpio_passthrough_rom_to_ram => sgpio_passthrough}/sgpio_passthrough.c (99%) rename firmware/{startup_systick_perfo_rom_to_ram => startup_systick_perfo}/result_exec_from_SRAM.txt (100%) delete mode 100644 firmware/startup_systick_perfo_rom_to_ram/Makefile delete mode 100644 firmware/startup_systick_perfo_rom_to_ram/README diff --git a/firmware/Makefile b/firmware/Makefile index 0aafc166..cbd920f0 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -21,7 +21,6 @@ # TARGETS = blinky \ - blinky_rom_to_ram \ mixertx \ sgpio \ sgpio-rx \ @@ -29,12 +28,7 @@ TARGETS = blinky \ startup \ startup_systick \ startup_systick_perfo \ - hackrf_usb \ - hackrf_usb_rom_to_ram - -# blinky_rom_to_ram -# sgpio_passthrough_rom_to_ram -# startup_systick_perfo_rom_to_ram + hackrf_usb all: build diff --git a/firmware/blinky_rom_to_ram/Makefile b/firmware/blinky_rom_to_ram/Makefile deleted file mode 100644 index aa7b04d8..00000000 --- a/firmware/blinky_rom_to_ram/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# Hey Emacs, this is a -*- makefile -*- -# -# Copyright 2013 Benjamin Vernoux -# -# This file is part of HackRF. -# -# 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, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -BINARY = blinky_rom_to_ram - -SRC_DIR = blinky - -SRC = blinky.c \ - ../common/hackrf_core.c \ - ../common/si5351c.c \ - ../common/max2837.c - -LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld - -%.o: ../$(SRC_DIR)/%.c Makefile - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -include ../common/Makefile_inc.mk diff --git a/firmware/blinky_rom_to_ram/README b/firmware/blinky_rom_to_ram/README deleted file mode 100644 index 79251aaf..00000000 --- a/firmware/blinky_rom_to_ram/README +++ /dev/null @@ -1,3 +0,0 @@ -This is the simplest example firmware for HackRF. It flashes three LEDs. -This Example Start execution in SPIFI(ROM) and at startup, code from ROM is copied to RAM and shadow pointer is modified to RAM. -So at end all the code and vector table is executed from RAM. diff --git a/firmware/cpldjtagprog_rom_to_ram/Makefile b/firmware/cpldjtagprog_rom_to_ram/Makefile deleted file mode 100644 index 085abb71..00000000 --- a/firmware/cpldjtagprog_rom_to_ram/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# Hey Emacs, this is a -*- makefile -*- -# -# Copyright 2013 Benjamin Vernoux -# -# This file is part of HackRF. -# -# 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, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -BINARY = cpldjtagprog_rom_to_ram - -SRC_DIR = cpldjtagprog - -SRC = cpldjtagprog.c \ - ../common/hackrf_core.c \ - ../common/si5351c.c \ - ../common/max2837.c \ - ../common/cpld_jtag.c \ - ../common/xapp058/lenval.c \ - ../common/xapp058/micro.c \ - ../common/xapp058/ports.c - -LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld - -%.o: ../$(SRC_DIR)/%.c Makefile - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -include ../common/Makefile_inc.mk diff --git a/firmware/cpldjtagprog_rom_to_ram/README b/firmware/cpldjtagprog_rom_to_ram/README deleted file mode 100644 index 82388a2c..00000000 --- a/firmware/cpldjtagprog_rom_to_ram/README +++ /dev/null @@ -1 +0,0 @@ -This is a test program for CPLD JTAG programming. diff --git a/firmware/sgpio_passthrough_rom_to_ram/Makefile b/firmware/sgpio_passthrough/Makefile similarity index 95% rename from firmware/sgpio_passthrough_rom_to_ram/Makefile rename to firmware/sgpio_passthrough/Makefile index 004c19a8..efaf31b9 100644 --- a/firmware/sgpio_passthrough_rom_to_ram/Makefile +++ b/firmware/sgpio_passthrough/Makefile @@ -25,8 +25,8 @@ BINARY = sgpio_passthrough SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c -LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld include ../common/Makefile_inc.mk diff --git a/firmware/sgpio_passthrough_rom_to_ram/README b/firmware/sgpio_passthrough/README similarity index 100% rename from firmware/sgpio_passthrough_rom_to_ram/README rename to firmware/sgpio_passthrough/README diff --git a/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.ods b/firmware/sgpio_passthrough/Test_SGPIO0_to15.ods similarity index 100% rename from firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.ods rename to firmware/sgpio_passthrough/Test_SGPIO0_to15.ods diff --git a/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.pdf b/firmware/sgpio_passthrough/Test_SGPIO0_to15.pdf similarity index 100% rename from firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO0_to15.pdf rename to firmware/sgpio_passthrough/Test_SGPIO0_to15.pdf diff --git a/firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt b/firmware/sgpio_passthrough/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt similarity index 100% rename from firmware/sgpio_passthrough_rom_to_ram/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt rename to firmware/sgpio_passthrough/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt diff --git a/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c b/firmware/sgpio_passthrough/sgpio_passthrough.c similarity index 99% rename from firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c rename to firmware/sgpio_passthrough/sgpio_passthrough.c index 561aaa9d..8e4d38d5 100644 --- a/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c +++ b/firmware/sgpio_passthrough/sgpio_passthrough.c @@ -169,7 +169,7 @@ void test_sgpio_sliceA_D(void) /* SGPIO pin 14 outputs slice H bit 0. */ /* SGPIO pin 15 outputs slice P bit 0. */ /*******************************************************************************/ -const u8 slice_preset_tab[16] = +const uint8_t slice_preset_tab[16] = { 0, /* Idx00 = Slice A => SGPIO0 Freq Div by 1=0 */ 8, /* Idx01 = Slice B => SGPIO8 Freq Div by 9=8 */ diff --git a/firmware/startup_systick_perfo/README b/firmware/startup_systick_perfo/README index 1014d873..525ca664 100644 --- a/firmware/startup_systick_perfo/README +++ b/firmware/startup_systick_perfo/README @@ -4,6 +4,9 @@ Test number of instruction per second (MIPS) slow blink ON 1s, OFF 1s Then after 16s (the 16tests) it blink LED1/2/3 ON/OFF each 250ms. This example compute the number of instructions per second executed called also MIPS (Millions of Instructions Per Second) +This example code run from SRAM so maximum performance expected is 204MIPS. +See result details in result_exec_from_SRAM.txt + This example code run from SPIFI (SPI Quad mode) and the tests check different loop size to compute the cache size used with SPIFI and estimated to less than 256Bytes (about 128 instructions in best case and in Thumb2). See result_exec_from_SPIFI.txt for more details. diff --git a/firmware/startup_systick_perfo_rom_to_ram/result_exec_from_SRAM.txt b/firmware/startup_systick_perfo/result_exec_from_SRAM.txt similarity index 100% rename from firmware/startup_systick_perfo_rom_to_ram/result_exec_from_SRAM.txt rename to firmware/startup_systick_perfo/result_exec_from_SRAM.txt diff --git a/firmware/startup_systick_perfo_rom_to_ram/Makefile b/firmware/startup_systick_perfo_rom_to_ram/Makefile deleted file mode 100644 index 489f608c..00000000 --- a/firmware/startup_systick_perfo_rom_to_ram/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# Hey Emacs, this is a -*- makefile -*- -# -# Copyright 2013 Benjamin Vernoux -# -# This file is part of HackRF. -# -# 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, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -BINARY = startup_systick_perfo_rom_to_ram - -SRC_DIR = startup_systick_perfo - -SRC = startup_systick.c \ - perf_mips.c \ - ../common/hackrf_core.c \ - ../common/si5351c.c \ - ../common/max2837.c -LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld - -%.o: ../$(SRC_DIR)/%.c Makefile - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -include ../common/Makefile_inc.mk diff --git a/firmware/startup_systick_perfo_rom_to_ram/README b/firmware/startup_systick_perfo_rom_to_ram/README deleted file mode 100644 index 4d9af838..00000000 --- a/firmware/startup_systick_perfo_rom_to_ram/README +++ /dev/null @@ -1,17 +0,0 @@ -This program is an example of the startup sequence for HackRF (Jellybean with -Lemondrop attached). -Test number of instruction per second (MIPS) slow blink ON 1s, OFF 1s -Then after 16s (the 16tests) it blink LED1/2/3 ON/OFF each 250ms. -This example compute the number of instructions per second executed called also MIPS (Millions of Instructions Per Second) - -This example code run from SRAM so maximum performance expected is 204MIPS. -See result details in result_exec_from_SRAM.txt - -Required Lemondrop -> Jellybean connections: - -SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 -SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 -SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 -VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 -1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 -GND: Lemondrop P5 -> Jellybean P13 From 552dbe4a6d24e8e777877dd56f9d558f0c314a6d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:23:26 -0800 Subject: [PATCH 151/200] Add sgpio.c to C files, now required for pin initialization. --- firmware/blinky/Makefile | 1 + firmware/mixertx/Makefile | 1 + firmware/simpletx/Makefile | 1 + firmware/spiflash/Makefile | 1 + firmware/startup/Makefile | 1 + firmware/startup_systick/Makefile | 1 + firmware/startup_systick_perfo/Makefile | 1 + 7 files changed, 7 insertions(+) diff --git a/firmware/blinky/Makefile b/firmware/blinky/Makefile index 6ad30dde..01ca290b 100644 --- a/firmware/blinky/Makefile +++ b/firmware/blinky/Makefile @@ -25,6 +25,7 @@ BINARY = blinky SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c diff --git a/firmware/mixertx/Makefile b/firmware/mixertx/Makefile index 0954b89b..3c2ffc00 100644 --- a/firmware/mixertx/Makefile +++ b/firmware/mixertx/Makefile @@ -4,6 +4,7 @@ BINARY = mixertx SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ ../common/rffc5071.c diff --git a/firmware/simpletx/Makefile b/firmware/simpletx/Makefile index abe150b6..ad3e171b 100644 --- a/firmware/simpletx/Makefile +++ b/firmware/simpletx/Makefile @@ -4,6 +4,7 @@ BINARY = simpletx SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c diff --git a/firmware/spiflash/Makefile b/firmware/spiflash/Makefile index 3c219c62..a3a6763c 100644 --- a/firmware/spiflash/Makefile +++ b/firmware/spiflash/Makefile @@ -25,6 +25,7 @@ BINARY = spiflash SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ ../common/w25q80bv.c diff --git a/firmware/startup/Makefile b/firmware/startup/Makefile index eb1502a9..ab4b43cc 100644 --- a/firmware/startup/Makefile +++ b/firmware/startup/Makefile @@ -4,6 +4,7 @@ BINARY = startup SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c diff --git a/firmware/startup_systick/Makefile b/firmware/startup_systick/Makefile index 22dbecac..9a8cd55a 100644 --- a/firmware/startup_systick/Makefile +++ b/firmware/startup_systick/Makefile @@ -4,6 +4,7 @@ BINARY = startup_systick SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c diff --git a/firmware/startup_systick_perfo/Makefile b/firmware/startup_systick_perfo/Makefile index 2a35de93..a1d0b116 100644 --- a/firmware/startup_systick_perfo/Makefile +++ b/firmware/startup_systick_perfo/Makefile @@ -5,6 +5,7 @@ BINARY = startup_systick_perfo_SPIFI SRC = startup_systick.c \ perf_mips.c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c From 893c20e41f5542ad73fa0667d67c5a39bd31bb31 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:24:14 -0800 Subject: [PATCH 152/200] Fix naming problem with SGPIO test project. This is due to my use of VPATH in Makefile_inc.mk, which I'm starting to regret a little bit... --- firmware/sgpio/Makefile | 2 +- firmware/sgpio/{sgpio.c => sgpio_test.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename firmware/sgpio/{sgpio.c => sgpio_test.c} (100%) diff --git a/firmware/sgpio/Makefile b/firmware/sgpio/Makefile index 5429c192..9f0303b7 100644 --- a/firmware/sgpio/Makefile +++ b/firmware/sgpio/Makefile @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -BINARY = sgpio +BINARY = sgpio_test SRC = $(BINARY).c \ ../common/hackrf_core.c \ diff --git a/firmware/sgpio/sgpio.c b/firmware/sgpio/sgpio_test.c similarity index 100% rename from firmware/sgpio/sgpio.c rename to firmware/sgpio/sgpio_test.c From 02ba23bf680a771a5b497cc5ebd92e4b4aea7d64 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:24:50 -0800 Subject: [PATCH 153/200] Fix broken sgpio-rx project, broken due to massive changes to how RF path and tuning is done. --- firmware/sgpio-rx/Makefile | 2 ++ firmware/sgpio-rx/sgpio-rx.c | 25 +++++-------------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/firmware/sgpio-rx/Makefile b/firmware/sgpio-rx/Makefile index db89574e..79ed6509 100644 --- a/firmware/sgpio-rx/Makefile +++ b/firmware/sgpio-rx/Makefile @@ -24,6 +24,8 @@ BINARY = sgpio-rx SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/tuning.c \ + ../common/rf_path.c \ ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c index 61c33604..823204b4 100644 --- a/firmware/sgpio-rx/sgpio-rx.c +++ b/firmware/sgpio-rx/sgpio-rx.c @@ -21,16 +21,12 @@ */ #include -#include #include -#include -#include #include -#include -#include -#include +#include #include +#include void tx_test() { sgpio_configure(TRANSCEIVER_MODE_TX, false); @@ -91,27 +87,16 @@ void rx_test() { int main(void) { const uint32_t freq = 2700000000U; - uint8_t switchctrl = 0; pin_setup(); enable_1v8_power(); cpu_clock_init(); ssp1_init(); - ssp1_set_mode_max2837(); - max2837_setup(); - rffc5071_setup(); -#ifdef JAWBREAKER - switchctrl = (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP); -#endif - rffc5071_rx(switchctrl); - rffc5071_set_frequency(500); // 500 MHz + rf_path_init(); + rf_path_set_direction(RF_PATH_DIRECTION_RX); - max2837_set_frequency(freq); - max2837_start(); - max2837_rx(); + set_freq(freq / 1000000, freq % 1000000); - ssp1_set_mode_max5864(); - max5864_xcvr(); rx_test(); gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ From 986e4dec93d15f5d0236ce61d24510df188d3eba Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:28:28 -0800 Subject: [PATCH 154/200] Massive rework of Makefile_inc.mk, to support building of heterogeneous (M4+M0) binaries, and easy switching between RAM and SPIFI-bootable builds. Constructive criticism welcome -- I'm sure there's better ways to do this. --- firmware/common/Makefile_inc.mk | 161 +++++++++++++++++++++++--------- firmware/hackrf_usb/Makefile | 3 +- 2 files changed, 116 insertions(+), 48 deletions(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 48a7ced3..75c50a95 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -26,12 +26,10 @@ # derived primarily from Makefiles in libopencm3 -#BOARD ?= JELLYBEAN BOARD ?= JAWBREAKER +RUN_FROM ?= SPIFI -LPC43XX_TARGET ?= M4 - -HACKRF_OPTS = -D$(BOARD) -DLPC43XX -DLPC43XX_$(LPC43XX_TARGET) +HACKRF_OPTS = -D$(BOARD) -DLPC43XX # comment to disable RF transmission HACKRF_OPTS += -DTX_ENABLE @@ -42,6 +40,28 @@ HACKRF_OPTS += $(VERSION_STRING) LIBOPENCM3 ?= ../libopencm3 +VPATH += ../common/xapp058 +VPATH += ../common + +SRC_M4_C ?= $(SRC) +SRC_M0_C ?= ../common/m0_sleep.c + +BUILD_DIR = build +OBJDIR_M4 = $(BUILD_DIR)/m4 +OBJDIR_M0 = $(BUILD_DIR)/m0 + +OBJ_M4_C = $(patsubst %.c, $(OBJDIR_M4)/%.o, $(notdir $(SRC_M4_C))) +OBJ_M4_S = $(patsubst %.s, $(OBJDIR_M4)/%.o, $(notdir $(SRC_M4_S))) + +OBJ_M0_C = $(patsubst %.c, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_C))) +OBJ_M0_S = $(patsubst %.s, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_S))) + +ifeq ($(RUN_FROM),RAM) + LDSCRIPT_M4 = ../common/LPC4330_M4.ld +else + LDSCRIPT_M4 = ../common/LPC4330_M4_rom_to_ram.ld +endif + PREFIX ?= arm-none-eabi CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc @@ -50,34 +70,34 @@ OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -CFLAGS += -std=gnu99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \ +CFLAGS_COMMON += -std=gnu99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \ $(HACKRF_OPTS) -fno-common -mthumb -MD -LDFLAGS += -mthumb \ +LDFLAGS_COMMON += -mthumb \ -L../common \ -L$(LIBOPENCM3)/lib -L$(LIBOPENCM3)/lib/lpc43xx \ - -T$(LDSCRIPT) -nostartfiles \ - -Wl,--gc-sections -Xlinker -Map=$(BINARY).map \ + -nostartfiles \ + -Wl,--gc-sections \ -lc -lnosys -ifeq ($(LPC43XX_TARGET),M0) - CFLAGS += -mcpu=cortex-m0 - LDFLAGS += -mcpu=cortex-m0 - LDFLAGS += -lopencm3_lpc43xx_m0 - LDSCRIPT ?= ../common/LPC4330_M0.ld -else - CFLAGS += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 - LDFLAGS += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 - LDFLAGS += -L$(TOOLCHAIN_DIR)/lib/armv7e-m/fpu - LDFLAGS += -lopencm3_lpc43xx -lm - LDSCRIPT ?= ../common/LPC4330_M4.ld -endif -OBJ = $(SRC:.c=.o) +CFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 +LDSCRIPT_M0 ?= ../common/LPC4330_M0.ld +LDFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 +LDFLAGS_M0 += -T$(LDSCRIPT_M0) +LDFLAGS_M0 += -Xlinker -Map=$(OBJDIR_M0)/m0.map +LDFLAGS_M0 += -lopencm3_lpc43xx_m0 + +CFLAGS_M4 += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX_M4 +LDFLAGS_M4 += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX_M4 +LDFLAGS_M4 += -L$(TOOLCHAIN_DIR)/lib/armv7e-m/fpu +LDFLAGS_M4 += -T$(LDSCRIPT_M4) +LDFLAGS_M4 += -Xlinker -Map=$(OBJDIR_M4)/m4.map +LDFLAGS_M4 += -lopencm3_lpc43xx -lm # Be silent per default, but 'make V=1' will show all compiler calls. ifneq ($(V),1) Q := @ NULL := 2>/dev/null else -LDFLAGS += -Wl,--print-gc-sections +LDFLAGS_COMMON += -Wl,--print-gc-sections endif .SUFFIXES: .elf .bin .hex .srec .list .images @@ -92,44 +112,77 @@ flash: $(BINARY).flash program: $(BINARY).dfu $(Q)dfu-util --device 1fc9:000c --alt 0 --download $(BINARY).dfu -%.images: %.bin %.hex %.srec %.list +$(BINARY).images: $(BINARY).bin $(BINARY).hex $(BINARY).srec $(BINARY).list @#echo "*** $* images generated ***" -%.dfu: %.bin +$(BINARY).dfu: $(BINARY).bin $(Q)rm -f _tmp.dfu _header.bin - $(Q)cp $(*).bin _tmp.dfu + $(Q)cp $(BINARY).bin _tmp.dfu $(Q)dfu-suffix --vid=0x1fc9 --pid=0x000c --did=0x0 -s 0 -a _tmp.dfu $(Q)python -c "import os.path; import struct; print('0000000: da ff ' + ' '.join(map(lambda s: '%02x' % ord(s), struct.pack(' _header.bin - $(Q)cat _header.bin _tmp.dfu >$(*).dfu + $(Q)cat _header.bin _tmp.dfu >$(BINARY).dfu $(Q)rm -f _tmp.dfu _header.bin -%.bin: %.elf +$(BINARY).bin: $(BINARY).elf @#printf " OBJCOPY $(*).bin\n" - $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + $(Q)$(OBJCOPY) -Obinary $(BINARY).elf $(BINARY).bin -%.hex: %.elf - @#printf " OBJCOPY $(*).hex\n" - $(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex +$(OBJDIR_M0)/m0.bin: $(OBJDIR_M0)/m0.elf + @#printf " OBJCOPY $(*).bin\n" + $(Q)$(OBJCOPY) -Obinary $(OBJDIR_M0)/m0.elf $(OBJDIR_M0)/m0.bin -%.srec: %.elf - @#printf " OBJCOPY $(*).srec\n" - $(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec +#$(OBJDIR_M0)/m0.o: $(OBJDIR_M0)/m0.bin +# $(Q)$(OBJCOPY) -I binary -B arm -O elf32-littlearm $(OBJDIR_M0)/m0.bin $(OBJDIR_M0)/m0.o -%.list: %.elf - @#printf " OBJDUMP $(*).list\n" - $(Q)$(OBJDUMP) -S $(*).elf > $(*).list +$(BINARY).hex: $(BINARY).elf + @#printf " OBJCOPY $(BINARY).hex\n" + $(Q)$(OBJCOPY) -Oihex $(BINARY).elf $(BINARY).hex -%.elf: $(OBJ) $(LDSCRIPT) +$(BINARY).srec: $(BINARY).elf + @#printf " OBJCOPY $(BINARY).srec\n" + $(Q)$(OBJCOPY) -Osrec $(BINARY).elf $(BINARY).srec + +$(BINARY).list: $(BINARY).elf + @#printf " OBJDUMP $(BINARY).list\n" + $(Q)$(OBJDUMP) -S $(BINARY).elf > $(BINARY).list + +$(BINARY).elf: obj_m4 @#printf " LD $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(LD) -o $(*).elf $(OBJ) $(LDFLAGS) + $(Q)$(LD) -o $(BINARY).elf $(OBJ_M4_C) $(OBJDIR_M4)/m0_bin.o $(LDFLAGS_COMMON) $(LDFLAGS_M4) -%.o: %.c Makefile - @#printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< +$(OBJDIR_M0)/m0.elf: obj_m0 + @#printf " LD $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(LD) -o $(OBJDIR_M0)/m0.elf $(OBJ_M0_C) $(LDFLAGS_COMMON) $(LDFLAGS_M0) -%.o: %.s Makefile - @#printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< +obj_m4: $(OBJ_M4_C) $(OBJDIR_M4)/m0_bin.o + +obj_m0: $(OBJ_M0_C) + +$(OBJDIR_M4)/%.o: %.c | $(OBJDIR_M4) + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS_COMMON) $(CFLAGS_M4) -o $@ -c $< + +$(OBJDIR_M4)/%.o: %.s | $(OBJDIR_M4) + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS_COMMON) $(CFLAGS_M4) -o $@ -c $< + +$(OBJDIR_M4)/m0_bin.o: m0_bin.s $(OBJDIR_M0)/m0.bin | $(OBJDIR_M4) + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS_COMMON) $(CFLAGS_M4) -o $@ -c $< + +$(OBJDIR_M0)/%.o: %.c | $(OBJDIR_M0) + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS_COMMON) $(CFLAGS_M0) -o $@ -c $< + +$(OBJDIR_M0)/%.o: %.s | $(OBJDIR_M0) + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS_COMMON) $(CFLAGS_M0) -o $@ -c $< + +$(OBJDIR_M4): + $(Q)mkdir -p $@ + +$(OBJDIR_M0): + $(Q)mkdir -p $@ clean: $(Q)rm -f *.o @@ -143,12 +196,28 @@ clean: $(Q)rm -f *.list $(Q)rm -f *.map $(Q)rm -f *.lst + $(Q)rm -f ../hackrf_usb/*.o + $(Q)rm -f ../hackrf_usb/*.d + $(Q)rm -f ../hackrf_usb/*.lst $(Q)rm -f ../common/*.o $(Q)rm -f ../common/*.d $(Q)rm -f ../common/*.lst $(Q)rm -f ../common/xapp058/*.o $(Q)rm -f ../common/xapp058/*.d + $(Q)rm -f $(OBJDIR_M4)/*.o + $(Q)rm -f $(OBJDIR_M4)/*.d + $(Q)rm -f $(OBJDIR_M4)/*.elf + $(Q)rm -f $(OBJDIR_M4)/*.bin + $(Q)rm -f $(OBJDIR_M4)/*.map + $(Q)rm -f $(OBJDIR_M0)/*.o + $(Q)rm -f $(OBJDIR_M0)/*.d + $(Q)rm -f $(OBJDIR_M0)/*.elf + $(Q)rm -f $(OBJDIR_M0)/*.bin + $(Q)rm -f $(OBJDIR_M0)/*.map + $(Q)rm -f $(OBJDIR_M0)/*.map + $(Q)rm -rf $(BUILD_DIR) .PHONY: images clean --include $(OBJ:.o=.d) +-include $(OBJ_M4_C:.o=.d) +-include $(OBJ_M0_C:.o=.d) diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index a22b90bc..8e302bb2 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -24,10 +24,9 @@ ifeq ($(RUN_FROM),RAM) BINARY = hackrf_usb_ram else BINARY = hackrf_usb_rom_to_ram - LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld endif -SRC = hackrf_usb.c \ +SRC_M4_C = hackrf_usb.c \ ../common/rf_path.c \ ../common/tuning.c \ ../common/streaming.c \ From f453e4c3774ad17ca5d01a52bec767e8665a449b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:44:15 -0800 Subject: [PATCH 155/200] Bump libopencm3. --- firmware/libopencm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index 0f435b51..28e93221 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 0f435b51f60cc8539641789b670f6f003412d744 +Subproject commit 28e93221cab64bb4fa6e818f29d96107d2c8a6b9 From 9db166427f1d270b6199974c6953e1edb06e2d8a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:46:53 -0800 Subject: [PATCH 156/200] Remove I2S pin definitions, since they're too specific for generic/shared HackRF code. --- firmware/common/hackrf_core.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 9df84472..1e23e40d 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -170,11 +170,6 @@ extern "C" #define SCU_PINMUX_ISP (P2_7) /* GPIO0[7] */ -#define SCU_PINMUX_I2S0_TX_SDA (P3_2) -#define SCU_PINMUX_I2S0_TX_WS (P3_1) -#define SCU_PINMUX_I2S0_TX_SCK (P3_0) -#define SCU_PINMUX_I2S0_TX_MCLK (CLK2) - /* * GPIO Pins */ From 62ab69c3d2355cdec999bc34acead27e257f5e2a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 20 Nov 2013 15:51:59 -0800 Subject: [PATCH 157/200] Giant .gitignore to knock out build files, Xilinx spew, and editor/OS turds. --- .gitignore | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..6f2674aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,66 @@ +# Compiled output +*.bin +*.d +*.elf +*.hex +*.srec +host/build/ + +# Operating system spew +.DS_Store +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Editor junk +*.swp +*.sublime-project +*.sublime-workspace + +# Xilinx tools create an enormous amount of poop: +firmware/cpld/**/isim/ +firmware/cpld/**/_ngo/ +firmware/cpld/**/_xmsgs/ +firmware/cpld/**/iseconfig/ +firmware/cpld/**/*_html/ +firmware/cpld/**/xlnx_auto_0_xdb/ +firmware/cpld/**/xst/ +firmware/cpld/**/_*.cmd +firmware/cpld/**/_*.log +firmware/cpld/**/*.bld +firmware/cpld/**/*.chk +firmware/cpld/**/*.cmd +firmware/cpld/**/*.cmd_log +firmware/cpld/**/*.csv +firmware/cpld/**/*.cxt +firmware/cpld/**/*.dat +firmware/cpld/**/*.err +firmware/cpld/**/*.exe +firmware/cpld/**/*.gise +firmware/cpld/**/*.gyd +firmware/cpld/**/*.html +firmware/cpld/**/*.ini +firmware/cpld/**/*.ipf +firmware/cpld/**/*.log +firmware/cpld/**/*.lso +firmware/cpld/**/*.mfd +firmware/cpld/**/*.ng[acdr] +firmware/cpld/**/*.pad +firmware/cpld/**/*.phd +firmware/cpld/**/*.pnx +firmware/cpld/**/*.prj +firmware/cpld/**/*.rpt +firmware/cpld/**/*.stx +firmware/cpld/**/*.syr +firmware/cpld/**/*.tim +firmware/cpld/**/*.tspec +firmware/cpld/**/*.vm6 +firmware/cpld/**/*.wcfg +firmware/cpld/**/*.wdb +firmware/cpld/**/*.xml +firmware/cpld/**/*.xmsgs +firmware/cpld/**/*.xrpt +firmware/cpld/**/*.xsl +firmware/cpld/**/*.xst +firmware/cpld/**/*.xwbt From 5468a01a9b547e7ef2b9f26d0afa3eb054e8bc69 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 21 Nov 2013 10:23:53 -0800 Subject: [PATCH 158/200] Forgot to include rf_path.h now that its pin setup is called from hackrf_core. --- firmware/common/hackrf_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index cb2be704..629aa065 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -26,6 +26,7 @@ #include "max2837.h" #include "rffc5071.h" #include "sgpio.h" +#include "rf_path.h" #include #include #include From 3e7ff530d7d60e3856a93a7fea89fe24a1bc78d5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Dec 2013 15:28:59 -0800 Subject: [PATCH 159/200] Add GPDMA API. Should go in libopencm3 when it's more fleshed-out. --- firmware/common/gpdma.c | 46 +++++++++++++++++++++++++++++++++++++++++ firmware/common/gpdma.h | 35 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 firmware/common/gpdma.c create mode 100644 firmware/common/gpdma.h diff --git a/firmware/common/gpdma.c b/firmware/common/gpdma.c new file mode 100644 index 00000000..14fc6406 --- /dev/null +++ b/firmware/common/gpdma.c @@ -0,0 +1,46 @@ +/* + * Copyright 2013 Jared Boone + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include + +void gpdma_controller_enable() { + GPDMA_CONFIG |= GPDMA_CONFIG_E(1); + while( (GPDMA_CONFIG & GPDMA_CONFIG_E_MASK) == 0 ); +} + +void gpdma_channel_enable(const uint_fast8_t channel) { + GPDMA_CCONFIG(channel) |= GPDMA_CCONFIG_E(1); +} + +void gpdma_channel_disable(const uint_fast8_t channel) { + GPDMA_CCONFIG(channel) &= ~GPDMA_CCONFIG_E_MASK; + while( (GPDMA_ENBLDCHNS & GPDMA_ENBLDCHNS_ENABLEDCHANNELS(1 << channel)) ); +} + +void gpdma_channel_interrupt_tc_clear(const uint_fast8_t channel) { + GPDMA_INTTCCLEAR = GPDMA_INTTCCLEAR_INTTCCLEAR(1 << channel); +} + +void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel) { + GPDMA_INTERRCLR = GPDMA_INTERRCLR_INTERRCLR(1 << channel); +} diff --git a/firmware/common/gpdma.h b/firmware/common/gpdma.h new file mode 100644 index 00000000..53310456 --- /dev/null +++ b/firmware/common/gpdma.h @@ -0,0 +1,35 @@ +/* + * Copyright 2013 Jared Boone + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GPDMA_H__ +#define __GPDMA_H__ + +#include + +void gpdma_controller_enable(); + +void gpdma_channel_enable(const uint_fast8_t channel); +void gpdma_channel_disable(const uint_fast8_t channel); + +void gpdma_channel_interrupt_tc_clear(const uint_fast8_t channel); +void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel); + +#endif/*__GPDMA_H__*/ From 34b01d89af4515e0bfbc54758c8a0190ef17473e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Dec 2013 15:29:14 -0800 Subject: [PATCH 160/200] Add SGPIO DMA configuration code. --- firmware/common/sgpio_dma.c | 142 ++++++++++++++++++++++++++++++++++++ firmware/common/sgpio_dma.h | 35 +++++++++ 2 files changed, 177 insertions(+) create mode 100644 firmware/common/sgpio_dma.c create mode 100644 firmware/common/sgpio_dma.h diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c new file mode 100644 index 00000000..b0383250 --- /dev/null +++ b/firmware/common/sgpio_dma.c @@ -0,0 +1,142 @@ +/* + * Copyright 2013 Jared Boone + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#define LLI_COUNT 4 + +static void configure_dma_lli(gpdma_lli_t* const lli, const bool direction_transmit, void* const buffer, const size_t byte_count) { + const size_t transfer_count = LLI_COUNT; + const size_t transfer_bytes = 4; + const size_t transfer_size = byte_count / transfer_count / transfer_bytes; + const size_t transfer_size_bytes = transfer_size * transfer_bytes; + + for(size_t i=0; i Peripheral + * 2: Peripheral -> Memory */ + const uint_fast8_t flowcntrl = direction_transmit ? 1 : 2; + + GPDMA_CCONFIG(channel) = + GPDMA_CCONFIG_E(0) | + GPDMA_CCONFIG_SRCPERIPHERAL(0) | + GPDMA_CCONFIG_DESTPERIPHERAL(0) | + GPDMA_CCONFIG_FLOWCNTRL(flowcntrl) | + GPDMA_CCONFIG_IE(1) | + GPDMA_CCONFIG_ITC(1) | + GPDMA_CCONFIG_L(0) | + GPDMA_CCONFIG_H(0) + ; + + gpdma_channel_enable(channel); +} + +static gpdma_lli_t lli_rx[LLI_COUNT]; +static gpdma_lli_t lli_tx[LLI_COUNT]; + +void sgpio_dma_init(void* const buffer, const size_t byte_count) { + configure_dma_lli(lli_rx, false, buffer, byte_count); + configure_dma_lli(lli_tx, true, buffer, byte_count); + + /* DMA peripheral/source 0, option 2 (SGPIO14) -- BREQ */ + CREG_DMAMUX &= ~(CREG_DMAMUX_DMAMUXPER0_MASK); + CREG_DMAMUX |= CREG_DMAMUX_DMAMUXPER0(0x2); + + // Disable sync, maybe it is causing max speed (10MT/sec) glitches? + //GPDMA_DMACSYNC = (1 << 0); + //GPDMA_SYNC = GPDMA_SYNC_DMACSYNC(0xFFFF); // TODO: Don't do this, I'm just going nuts here. + + gpdma_controller_enable(); +} + +static const uint_fast8_t dma_channel_sgpio = 0; + +void sgpio_dma_rx_start() { + sgpio_dma_enable(dma_channel_sgpio, lli_rx, false); +} + +void sgpio_dma_tx_start() { + sgpio_dma_enable(dma_channel_sgpio, lli_tx, true); +} + +void sgpio_dma_irq_tc_acknowledge() { + gpdma_channel_interrupt_tc_clear(dma_channel_sgpio); +} + +void sgpio_dma_stop() { + gpdma_channel_disable(dma_channel_sgpio); +} + +size_t sgpio_dma_current_transfer_index() { + const gpdma_lli_t* const next_lli = (gpdma_lli_t*)GPDMA_CLLI(dma_channel_sgpio); + for(size_t i=0; i + * + * This file is part of HackRF. + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SGPIO_DMA_H__ +#define __SGPIO_DMA_H__ + +#include + +void sgpio_dma_init(void* const buffer, const size_t byte_count); +void sgpio_dma_rx_start(); +void sgpio_dma_tx_start(); +void sgpio_dma_irq_tc_acknowledge(); +void sgpio_dma_stop(); + +size_t sgpio_dma_current_transfer_index(); + +#endif/*__SGPIO_DMA_H__*/ From f51ee2dc61a4836a30d4d8304f91b68e7911d6fd Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 7 Dec 2013 15:29:50 -0800 Subject: [PATCH 161/200] Modified ldscripts to more accurately represent LPC4330 hardware. Moved M0 RAM from local to AHB. Created separate region for sleep RAM. --- firmware/common/LPC4330_M4.ld | 14 +++++++------- firmware/common/LPC4330_M4_rom_to_ram.ld | 9 ++++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index d449566e..199ba807 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -20,22 +20,22 @@ * Boston, MA 02110-1301, USA. */ -/* Linker script for HackRF Jellybean (LPC4330, 1M SPI flash, 264K SRAM). */ +/* Linker script for HackRF Jellybean/Jawbreaker (LPC4330, 1M SPI flash, 264K SRAM). */ MEMORY { + /* Physical address in Flash used to copy Code from Flash to RAM */ + rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M /* rom is really the shadow region that points to SPI flash or elsewhere */ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M + rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K - ram_m0 (rwx) : ORIGIN = 0x10090000, LENGTH = 8K - /* there are some additional RAM regions */ - ram_ahb1 (rwx) : ORIGIN = 0x20000000, LENGTH = 16K + ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_ahb2 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K + ram_m0 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K } /* Include the common ld script. */ @@ -43,7 +43,7 @@ INCLUDE libopencm3_lpc43xx.ld SECTIONS { - .m0 0x10090000 : { + .m0 0x2000C000 : { PROVIDE(__m0_start__ = .); KEEP(*(.m0_bin*)); . = ALIGN(4); diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld index febce4e9..0f8114f4 100644 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ b/firmware/common/LPC4330_M4_rom_to_ram.ld @@ -21,23 +21,22 @@ * Boston, MA 02110-1301, USA. */ -/* Linker script for HackRF Jellybean (LPC4330, 1M SPI flash, 264K SRAM). */ +/* Linker script for HackRF Jellybean/Jawbreaker (LPC4330, 1M SPI flash, 264K SRAM). */ MEMORY { /* Physical address in Flash used to copy Code from Flash to RAM */ rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M /* rom is really the shadow region that points to SPI flash or elsewhere */ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M + rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K - ram_m0 (rwx) : ORIGIN = 0x10090000, LENGTH = 8K - ram_ahb1 (rwx) : ORIGIN = 0x20000000, LENGTH = 16K + ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_ahb2 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K + ram_m0 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K } /* Include the common ld script. */ From 45c0a6c31a9d24a7f9415e4743ef225c109b1799 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 11:33:47 -0800 Subject: [PATCH 162/200] Extract/isolate path details in Makefile_inc.mk. --- firmware/common/Makefile_inc.mk | 38 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 75c50a95..6822fd07 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -38,13 +38,18 @@ HACKRF_OPTS += -DTX_ENABLE VERSION_STRING ?= -D'VERSION_STRING="git-$(shell git log -n 1 --format=%h)"' HACKRF_OPTS += $(VERSION_STRING) -LIBOPENCM3 ?= ../libopencm3 +PATH_HACKRF ?= ../.. -VPATH += ../common/xapp058 -VPATH += ../common +PATH_HACKRF_FIRMWARE = $(PATH_HACKRF)/firmware +PATH_HACKRF_FIRMWARE_COMMON = $(PATH_HACKRF_FIRMWARE)/common + +LIBOPENCM3 ?= $(PATH_HACKRF_FIRMWARE)/libopencm3 + +VPATH += $(PATH_HACKRF_FIRMWARE_COMMON)/xapp058 +VPATH += $(PATH_HACKRF_FIRMWARE_COMMON) SRC_M4_C ?= $(SRC) -SRC_M0_C ?= ../common/m0_sleep.c +SRC_M0_C ?= $(PATH_HACKRF_FIRMWARE_COMMON)/m0_sleep.c BUILD_DIR = build OBJDIR_M4 = $(BUILD_DIR)/m4 @@ -57,9 +62,9 @@ OBJ_M0_C = $(patsubst %.c, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_C))) OBJ_M0_S = $(patsubst %.s, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_S))) ifeq ($(RUN_FROM),RAM) - LDSCRIPT_M4 = ../common/LPC4330_M4.ld + LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/LPC4330_M4.ld else - LDSCRIPT_M4 = ../common/LPC4330_M4_rom_to_ram.ld + LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/LPC4330_M4_rom_to_ram.ld endif PREFIX ?= arm-none-eabi @@ -70,7 +75,7 @@ OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -CFLAGS_COMMON += -std=gnu99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \ +CFLAGS_COMMON += -std=gnu99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I$(PATH_HACKRF_FIRMWARE_COMMON) \ $(HACKRF_OPTS) -fno-common -mthumb -MD LDFLAGS_COMMON += -mthumb \ -L../common \ @@ -79,7 +84,7 @@ LDFLAGS_COMMON += -mthumb \ -Wl,--gc-sections \ -lc -lnosys CFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 -LDSCRIPT_M0 ?= ../common/LPC4330_M0.ld +LDSCRIPT_M0 ?= $(PATH_HACKRF_FIRMWARE_COMMON)/LPC4330_M0.ld LDFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 LDFLAGS_M0 += -T$(LDSCRIPT_M0) LDFLAGS_M0 += -Xlinker -Map=$(OBJDIR_M0)/m0.map @@ -196,14 +201,14 @@ clean: $(Q)rm -f *.list $(Q)rm -f *.map $(Q)rm -f *.lst - $(Q)rm -f ../hackrf_usb/*.o - $(Q)rm -f ../hackrf_usb/*.d - $(Q)rm -f ../hackrf_usb/*.lst - $(Q)rm -f ../common/*.o - $(Q)rm -f ../common/*.d - $(Q)rm -f ../common/*.lst - $(Q)rm -f ../common/xapp058/*.o - $(Q)rm -f ../common/xapp058/*.d + $(Q)rm -f $(PATH_HACKRF_FIRMWARE)/hackrf_usb/*.o + $(Q)rm -f $(PATH_HACKRF_FIRMWARE)/hackrf_usb/*.d + $(Q)rm -f $(PATH_HACKRF_FIRMWARE)/hackrf_usb/*.lst + $(Q)rm -f $(PATH_HACKRF_FIRMWARE_COMMON)/*.o + $(Q)rm -f $(PATH_HACKRF_FIRMWARE_COMMON)/*.d + $(Q)rm -f $(PATH_HACKRF_FIRMWARE_COMMON)/*.lst + $(Q)rm -f $(PATH_HACKRF_FIRMWARE_COMMON)/xapp058/*.o + $(Q)rm -f $(PATH_HACKRF_FIRMWARE_COMMON)/xapp058/*.d $(Q)rm -f $(OBJDIR_M4)/*.o $(Q)rm -f $(OBJDIR_M4)/*.d $(Q)rm -f $(OBJDIR_M4)/*.elf @@ -214,7 +219,6 @@ clean: $(Q)rm -f $(OBJDIR_M0)/*.elf $(Q)rm -f $(OBJDIR_M0)/*.bin $(Q)rm -f $(OBJDIR_M0)/*.map - $(Q)rm -f $(OBJDIR_M0)/*.map $(Q)rm -rf $(BUILD_DIR) .PHONY: images clean From 809df425c1d3b39177897db3e9a5b54ba9b274d3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 11:54:50 -0800 Subject: [PATCH 163/200] Add SGPIO configuration to support GPDMA interrupts. --- firmware/common/sgpio.c | 42 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index ca982966..09860c2e 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -129,7 +129,8 @@ void sgpio_configure( ? (0xFF << 0) : (0x00 << 0); SGPIO_GPIO_OENREG = - (1L << 11) // direction output SGPIO11 active + (1L << 14) // GPDMA burst request SGPIO14 active + | (1L << 11) // direction output SGPIO11 active | (1L << 10) // disable output SGPIO10 active | (0L << 9) // capture input SGPIO9 (output i is tri-stated) | (0L << 8) // clock input SGPIO8 (output i is tri-stated) @@ -152,6 +153,10 @@ void sgpio_configure( SGPIO_OUT_MUX_CFG_P_OE_CFG(0) /* 0x0 gpio_oe (state set by GPIO_OEREG) */ | SGPIO_OUT_MUX_CFG_P_OUT_CFG(4) /* 0x4=gpio_out (level set by GPIO_OUTREG) */ ; + SGPIO_OUT_MUX_CFG(14) = // SGPIO14: Output: internal GPDMA burst request + SGPIO_OUT_MUX_CFG_P_OE_CFG(0) /* 0x4 dout_oem1 (1-bit mode) */ + | SGPIO_OUT_MUX_CFG_P_OUT_CFG(0) /* 0x0 dout_doutm1 (1-bit mode) */ + ; const uint_fast8_t output_multiplexing_mode = multi_slice ? 11 : 9; @@ -174,10 +179,12 @@ void sgpio_configure( SGPIO_SLICE_F, SGPIO_SLICE_L, }; + const uint_fast8_t slice_gpdma = SGPIO_SLICE_H; const uint_fast8_t pos = multi_slice ? 0x1f : 0x03; const bool single_slice = !multi_slice; const uint_fast8_t slice_count = multi_slice ? 8 : 1; + const uint_fast8_t clk_capture_mode = (direction == SGPIO_DIRECTION_TX) ? 0 : 1; uint32_t slice_enable_mask = 0; /* Configure Slice A, I, E, J, C, K, F, L (multi_slice mode) */ @@ -187,7 +194,6 @@ void sgpio_configure( const bool input_slice = (i == 0) && (direction != SGPIO_DIRECTION_TX); /* Only for slice0/A and RX mode set input_slice to 1 */ const uint_fast8_t concat_order = (input_slice || single_slice) ? 0 : 3; /* 0x0=Self-loop(slice0/A RX mode), 0x3=8 slices */ const uint_fast8_t concat_enable = (input_slice || single_slice) ? 0 : 1; /* 0x0=External data pin(slice0/A RX mode), 0x1=Concatenate data */ - const uint_fast8_t clk_capture_mode = (direction == SGPIO_DIRECTION_TX) ? 0 : 1; SGPIO_MUX_CFG(slice_index) = SGPIO_MUX_CFG_CONCAT_ORDER(concat_order) @@ -221,6 +227,38 @@ void sgpio_configure( slice_enable_mask |= (1 << slice_index); } + + SGPIO_MUX_CFG(slice_gpdma) = + SGPIO_MUX_CFG_CONCAT_ORDER(0) /* Self-loop */ + | SGPIO_MUX_CFG_CONCAT_ENABLE(1) + | SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE(0) /* Select qualifier slice A(0x0) */ + | SGPIO_MUX_CFG_QUALIFIER_PIN_MODE(1) /* Select qualifier pin SGPIO9(0x1) */ + | SGPIO_MUX_CFG_QUALIFIER_MODE(3) /* External SGPIO */ + | SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE(0) /* Select clock source slice D(0x0) */ + | SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE(0) /* Source Clock Pin 0x0 = SGPIO8 */ + | SGPIO_MUX_CFG_EXT_CLK_ENABLE(1) /* External clock signal(pin) selected */ + ; + + SGPIO_SLICE_MUX_CFG(slice_gpdma) = + SGPIO_SLICE_MUX_CFG_INV_QUALIFIER(0) /* 0x0=Use normal qualifier. */ + | SGPIO_SLICE_MUX_CFG_PARALLEL_MODE(0) /* 0x0=Shift 1 bit per clock. */ + | SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE(0) /* 0x0=Detect rising edge. (Condition for input bit match interrupt) */ + | SGPIO_SLICE_MUX_CFG_INV_OUT_CLK(0) /* 0x0=Normal clock. */ + | SGPIO_SLICE_MUX_CFG_CLKGEN_MODE(1) /* 0x1=Use external clock from a pin or other slice */ + | SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE(clk_capture_mode) /* 0x0=Use rising clock edge, 0x1=Use falling clock edge */ + | SGPIO_SLICE_MUX_CFG_MATCH_MODE(0) /* 0x0=Do not match data */ + ; + + SGPIO_PRESET(slice_gpdma) = 0; // External clock, don't care + SGPIO_COUNT(slice_gpdma) = 0; // External clock, don't care + SGPIO_POS(slice_gpdma) = + SGPIO_POS_POS_RESET(0x1f) + | SGPIO_POS_POS(0x1f) + ; + SGPIO_REG(slice_gpdma) = 0x77777777; // Primary output data register, LSB -> out + SGPIO_REG_SS(slice_gpdma) = 0x77777777; // Shadow output data register, LSB -> out1 + + slice_enable_mask |= (1 << slice_gpdma); // Start SGPIO operation by enabling slice clocks. SGPIO_CTRL_ENABLE = slice_enable_mask; From 50ec2687942bac0b95f5e58ab7cec552d3c9d2e3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 12:14:00 -0800 Subject: [PATCH 164/200] Bracket SGPIO GPDMA slice configuration with multislice==false test. It only makes sense in single slice mode (until I have a clever idea for doing GPDMA with multiple slices). --- firmware/common/sgpio.c | 62 +++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 09860c2e..0e196e80 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -228,38 +228,40 @@ void sgpio_configure( slice_enable_mask |= (1 << slice_index); } - SGPIO_MUX_CFG(slice_gpdma) = - SGPIO_MUX_CFG_CONCAT_ORDER(0) /* Self-loop */ - | SGPIO_MUX_CFG_CONCAT_ENABLE(1) - | SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE(0) /* Select qualifier slice A(0x0) */ - | SGPIO_MUX_CFG_QUALIFIER_PIN_MODE(1) /* Select qualifier pin SGPIO9(0x1) */ - | SGPIO_MUX_CFG_QUALIFIER_MODE(3) /* External SGPIO */ - | SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE(0) /* Select clock source slice D(0x0) */ - | SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE(0) /* Source Clock Pin 0x0 = SGPIO8 */ - | SGPIO_MUX_CFG_EXT_CLK_ENABLE(1) /* External clock signal(pin) selected */ - ; + if( multi_slice == false ) { + SGPIO_MUX_CFG(slice_gpdma) = + SGPIO_MUX_CFG_CONCAT_ORDER(0) /* Self-loop */ + | SGPIO_MUX_CFG_CONCAT_ENABLE(1) + | SGPIO_MUX_CFG_QUALIFIER_SLICE_MODE(0) /* Select qualifier slice A(0x0) */ + | SGPIO_MUX_CFG_QUALIFIER_PIN_MODE(1) /* Select qualifier pin SGPIO9(0x1) */ + | SGPIO_MUX_CFG_QUALIFIER_MODE(3) /* External SGPIO */ + | SGPIO_MUX_CFG_CLK_SOURCE_SLICE_MODE(0) /* Select clock source slice D(0x0) */ + | SGPIO_MUX_CFG_CLK_SOURCE_PIN_MODE(0) /* Source Clock Pin 0x0 = SGPIO8 */ + | SGPIO_MUX_CFG_EXT_CLK_ENABLE(1) /* External clock signal(pin) selected */ + ; - SGPIO_SLICE_MUX_CFG(slice_gpdma) = - SGPIO_SLICE_MUX_CFG_INV_QUALIFIER(0) /* 0x0=Use normal qualifier. */ - | SGPIO_SLICE_MUX_CFG_PARALLEL_MODE(0) /* 0x0=Shift 1 bit per clock. */ - | SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE(0) /* 0x0=Detect rising edge. (Condition for input bit match interrupt) */ - | SGPIO_SLICE_MUX_CFG_INV_OUT_CLK(0) /* 0x0=Normal clock. */ - | SGPIO_SLICE_MUX_CFG_CLKGEN_MODE(1) /* 0x1=Use external clock from a pin or other slice */ - | SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE(clk_capture_mode) /* 0x0=Use rising clock edge, 0x1=Use falling clock edge */ - | SGPIO_SLICE_MUX_CFG_MATCH_MODE(0) /* 0x0=Do not match data */ - ; + SGPIO_SLICE_MUX_CFG(slice_gpdma) = + SGPIO_SLICE_MUX_CFG_INV_QUALIFIER(0) /* 0x0=Use normal qualifier. */ + | SGPIO_SLICE_MUX_CFG_PARALLEL_MODE(0) /* 0x0=Shift 1 bit per clock. */ + | SGPIO_SLICE_MUX_CFG_DATA_CAPTURE_MODE(0) /* 0x0=Detect rising edge. (Condition for input bit match interrupt) */ + | SGPIO_SLICE_MUX_CFG_INV_OUT_CLK(0) /* 0x0=Normal clock. */ + | SGPIO_SLICE_MUX_CFG_CLKGEN_MODE(1) /* 0x1=Use external clock from a pin or other slice */ + | SGPIO_SLICE_MUX_CFG_CLK_CAPTURE_MODE(clk_capture_mode) /* 0x0=Use rising clock edge, 0x1=Use falling clock edge */ + | SGPIO_SLICE_MUX_CFG_MATCH_MODE(0) /* 0x0=Do not match data */ + ; - SGPIO_PRESET(slice_gpdma) = 0; // External clock, don't care - SGPIO_COUNT(slice_gpdma) = 0; // External clock, don't care - SGPIO_POS(slice_gpdma) = - SGPIO_POS_POS_RESET(0x1f) - | SGPIO_POS_POS(0x1f) - ; - SGPIO_REG(slice_gpdma) = 0x77777777; // Primary output data register, LSB -> out - SGPIO_REG_SS(slice_gpdma) = 0x77777777; // Shadow output data register, LSB -> out1 - - slice_enable_mask |= (1 << slice_gpdma); - + SGPIO_PRESET(slice_gpdma) = 0; // External clock, don't care + SGPIO_COUNT(slice_gpdma) = 0; // External clock, don't care + SGPIO_POS(slice_gpdma) = + SGPIO_POS_POS_RESET(0x1f) + | SGPIO_POS_POS(0x1f) + ; + SGPIO_REG(slice_gpdma) = 0x77777777; // Primary output data register, LSB -> out + SGPIO_REG_SS(slice_gpdma) = 0x77777777; // Shadow output data register, LSB -> out1 + + slice_enable_mask |= (1 << slice_gpdma); + } + // Start SGPIO operation by enabling slice clocks. SGPIO_CTRL_ENABLE = slice_enable_mask; } From 2fab6c40cd3f326aaa27a3d9f087095b5c09b9d5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 12:21:41 -0800 Subject: [PATCH 165/200] Extract SGPIO multi_slice configuration argument into an init-time function, so it doesn't need to be passed each time the SGPIO interface direction is changed. --- firmware/common/rf_path.c | 6 +++--- firmware/common/sgpio.c | 24 +++++++++++++++--------- firmware/common/sgpio.h | 6 ++++-- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index 4a52af8c..d462f217 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -225,7 +225,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { max5864_tx(); ssp1_set_mode_max2837(); max2837_tx(); - sgpio_configure(SGPIO_DIRECTION_TX, true); + sgpio_configure(SGPIO_DIRECTION_TX); break; case RF_PATH_DIRECTION_RX: @@ -244,7 +244,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { max5864_rx(); ssp1_set_mode_max2837(); max2837_rx(); - sgpio_configure(SGPIO_DIRECTION_RX, true); + sgpio_configure(SGPIO_DIRECTION_RX); break; case RF_PATH_DIRECTION_OFF: @@ -256,7 +256,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { max5864_standby(); ssp1_set_mode_max2837(); max2837_set_mode(MAX2837_MODE_STANDBY); - sgpio_configure(SGPIO_DIRECTION_RX, true); + sgpio_configure(SGPIO_DIRECTION_RX); break; } diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 0e196e80..d0d634e6 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -28,6 +28,8 @@ #include +static bool sgpio_slice_mode_multislice = true; + void sgpio_configure_pin_functions() { scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); @@ -95,6 +97,11 @@ void sgpio_test_interface() { } } +void sgpio_set_slice_mode( + const bool multi_slice +) { + sgpio_slice_mode_multislice = multi_slice; +} /* SGPIO0 to 7 = DAC/ADC data bits 0 to 7 (Nota: DAC is 10bits but only bit9 to bit2 are used bit1 & 0 are forced to 0 by CPLD) @@ -109,8 +116,7 @@ void sgpio_test_interface() { SGPIO11 Direction Output (1/High=TX mode LPC43xx=>CPLD=>DAC, 0/Low=RX mode LPC43xx<=CPLD<=ADC) */ void sgpio_configure( - const sgpio_direction_t direction, - const bool multi_slice + const sgpio_direction_t direction ) { // Disable all counters during configuration SGPIO_CTRL_ENABLE = 0; @@ -159,7 +165,7 @@ void sgpio_configure( ; const uint_fast8_t output_multiplexing_mode = - multi_slice ? 11 : 9; + sgpio_slice_mode_multislice ? 11 : 9; /* SGPIO0 to SGPIO7 */ for(uint_fast8_t i=0; i<8; i++) { // SGPIO pin 0 outputs slice A bit "i". @@ -181,13 +187,13 @@ void sgpio_configure( }; const uint_fast8_t slice_gpdma = SGPIO_SLICE_H; - const uint_fast8_t pos = multi_slice ? 0x1f : 0x03; - const bool single_slice = !multi_slice; - const uint_fast8_t slice_count = multi_slice ? 8 : 1; + const uint_fast8_t pos = sgpio_slice_mode_multislice ? 0x1f : 0x03; + const bool single_slice = !sgpio_slice_mode_multislice; + const uint_fast8_t slice_count = sgpio_slice_mode_multislice ? 8 : 1; const uint_fast8_t clk_capture_mode = (direction == SGPIO_DIRECTION_TX) ? 0 : 1; uint32_t slice_enable_mask = 0; - /* Configure Slice A, I, E, J, C, K, F, L (multi_slice mode) */ + /* Configure Slice A, I, E, J, C, K, F, L (sgpio_slice_mode_multislice mode) */ for(uint_fast8_t i=0; i Date: Sun, 8 Dec 2013 12:50:20 -0800 Subject: [PATCH 166/200] Move LLI_COUNT constant out of SGPIO DMA utility functions. --- firmware/common/sgpio_dma.c | 37 +++++++++++++++++++++++-------------- firmware/common/sgpio_dma.h | 7 ++++++- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index b0383250..18366beb 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -29,15 +29,18 @@ #include #include -#define LLI_COUNT 4 - -static void configure_dma_lli(gpdma_lli_t* const lli, const bool direction_transmit, void* const buffer, const size_t byte_count) { - const size_t transfer_count = LLI_COUNT; +static void configure_dma_lli( + gpdma_lli_t* const lli, + const size_t lli_count, + const bool direction_transmit, + void* const buffer, + const size_t byte_count +) { const size_t transfer_bytes = 4; - const size_t transfer_size = byte_count / transfer_count / transfer_bytes; + const size_t transfer_size = byte_count / lli_count / transfer_bytes; const size_t transfer_size_bytes = transfer_size * transfer_bytes; - for(size_t i=0; i +#include + void sgpio_dma_init(void* const buffer, const size_t byte_count); void sgpio_dma_rx_start(); void sgpio_dma_tx_start(); void sgpio_dma_irq_tc_acknowledge(); void sgpio_dma_stop(); -size_t sgpio_dma_current_transfer_index(); +size_t sgpio_dma_current_transfer_index( + const gpdma_lli_t* const lli, + const size_t lli_count +); #endif/*__SGPIO_DMA_H__*/ From d2fd5e74c5b104dc49f3ded01bc3a4b33742ee17 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 13:05:30 -0800 Subject: [PATCH 167/200] Change SGPIO DMA configuration API from dividing up a buffer's length into M parts to creating a chain of M transfers of size N. --- firmware/common/sgpio_dma.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index 18366beb..a47ecd8c 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -34,15 +34,14 @@ static void configure_dma_lli( const size_t lli_count, const bool direction_transmit, void* const buffer, - const size_t byte_count + const size_t transfer_bytes ) { - const size_t transfer_bytes = 4; - const size_t transfer_size = byte_count / lli_count / transfer_bytes; - const size_t transfer_size_bytes = transfer_size * transfer_bytes; + const size_t bytes_per_word = 4; + const size_t transfer_words = (transfer_bytes + bytes_per_word - 1) / bytes_per_word; for(size_t i=0; i Date: Sun, 8 Dec 2013 13:06:14 -0800 Subject: [PATCH 168/200] Remove irrelevant assumption that LLI argument is a pointer to an array. --- firmware/common/sgpio_dma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index a47ecd8c..e1e04688 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -74,10 +74,10 @@ static void sgpio_dma_enable(const uint_fast8_t channel, const gpdma_lli_t* cons gpdma_channel_interrupt_tc_clear(channel); gpdma_channel_interrupt_error_clear(channel); - GPDMA_CSRCADDR(channel) = (uint32_t)lli[0].csrcaddr; - GPDMA_CDESTADDR(channel) = (uint32_t)lli[0].cdestaddr; - GPDMA_CLLI(channel) = (uint32_t)lli[0].clli; - GPDMA_CCONTROL(channel) = lli[0].ccontrol; + GPDMA_CSRCADDR(channel) = (uint32_t)lli->csrcaddr; + GPDMA_CDESTADDR(channel) = (uint32_t)lli->cdestaddr; + GPDMA_CLLI(channel) = (uint32_t)lli->clli; + GPDMA_CCONTROL(channel) = lli->ccontrol; /* 1: Memory -> Peripheral * 2: Peripheral -> Memory */ From ea2ca52301c667c4a486fc84326821d99947884d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 13:07:32 -0800 Subject: [PATCH 169/200] Rename SGPIO DMA internal function to match style of public functions. --- firmware/common/sgpio_dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index e1e04688..2c90f4ed 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -29,7 +29,7 @@ #include #include -static void configure_dma_lli( +static void sgpio_dma_configure_lli( gpdma_lli_t* const lli, const size_t lli_count, const bool direction_transmit, @@ -104,8 +104,8 @@ static gpdma_lli_t lli_rx[RX_LLI_COUNT]; static gpdma_lli_t lli_tx[TX_LLI_COUNT]; void sgpio_dma_init(void* const buffer, const size_t transfer_bytes) { - configure_dma_lli(lli_rx, RX_LLI_COUNT, false, buffer, transfer_bytes); - configure_dma_lli(lli_tx, TX_LLI_COUNT, true, buffer, transfer_bytes); + sgpio_dma_configure_lli(lli_rx, RX_LLI_COUNT, false, buffer, transfer_bytes); + sgpio_dma_configure_lli(lli_tx, TX_LLI_COUNT, true, buffer, transfer_bytes); /* DMA peripheral/source 0, option 2 (SGPIO14) -- BREQ */ CREG_DMAMUX &= ~(CREG_DMAMUX_DMAMUXPER0_MASK); From ca070acad069d8f1042152b8563f306a75b98971 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 13:14:26 -0800 Subject: [PATCH 170/200] Expose SGPIO DMA LLI configuration function. Remove LLI declarations internal to SGPIO DMA module. Require a start LLI for SGPIO DMA start functions. --- firmware/common/sgpio_dma.c | 21 ++++++--------------- firmware/common/sgpio_dma.h | 14 +++++++++++--- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index 2c90f4ed..a2ab003c 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -29,7 +29,7 @@ #include #include -static void sgpio_dma_configure_lli( +void sgpio_dma_configure_lli( gpdma_lli_t* const lli, const size_t lli_count, const bool direction_transmit, @@ -97,16 +97,7 @@ static void sgpio_dma_enable(const uint_fast8_t channel, const gpdma_lli_t* cons gpdma_channel_enable(channel); } -#define RX_LLI_COUNT 4 -#define TX_LLI_COUNT 4 - -static gpdma_lli_t lli_rx[RX_LLI_COUNT]; -static gpdma_lli_t lli_tx[TX_LLI_COUNT]; - -void sgpio_dma_init(void* const buffer, const size_t transfer_bytes) { - sgpio_dma_configure_lli(lli_rx, RX_LLI_COUNT, false, buffer, transfer_bytes); - sgpio_dma_configure_lli(lli_tx, TX_LLI_COUNT, true, buffer, transfer_bytes); - +void sgpio_dma_init() { /* DMA peripheral/source 0, option 2 (SGPIO14) -- BREQ */ CREG_DMAMUX &= ~(CREG_DMAMUX_DMAMUXPER0_MASK); CREG_DMAMUX |= CREG_DMAMUX_DMAMUXPER0(0x2); @@ -120,12 +111,12 @@ void sgpio_dma_init(void* const buffer, const size_t transfer_bytes) { static const uint_fast8_t dma_channel_sgpio = 0; -void sgpio_dma_rx_start() { - sgpio_dma_enable(dma_channel_sgpio, lli_rx, false); +void sgpio_dma_rx_start(const gpdma_lli_t* const start_lli) { + sgpio_dma_enable(dma_channel_sgpio, start_lli, false); } -void sgpio_dma_tx_start() { - sgpio_dma_enable(dma_channel_sgpio, lli_tx, true); +void sgpio_dma_tx_start(const gpdma_lli_t* const start_lli) { + sgpio_dma_enable(dma_channel_sgpio, start_lli, true); } void sgpio_dma_irq_tc_acknowledge() { diff --git a/firmware/common/sgpio_dma.h b/firmware/common/sgpio_dma.h index 28c6df37..f4f07bd5 100644 --- a/firmware/common/sgpio_dma.h +++ b/firmware/common/sgpio_dma.h @@ -26,9 +26,17 @@ #include -void sgpio_dma_init(void* const buffer, const size_t byte_count); -void sgpio_dma_rx_start(); -void sgpio_dma_tx_start(); +void sgpio_dma_configure_lli( + gpdma_lli_t* const lli, + const size_t lli_count, + const bool direction_transmit, + void* const buffer, + const size_t transfer_bytes +); + +void sgpio_dma_init(); +void sgpio_dma_rx_start(const gpdma_lli_t* const start_lli); +void sgpio_dma_tx_start(const gpdma_lli_t* const start_lli); void sgpio_dma_irq_tc_acknowledge(); void sgpio_dma_stop(); From 6185b67008dc9361c27c60703fe300c0948ab199 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 17:49:50 -0800 Subject: [PATCH 171/200] Add GPDMA LLI function to enable interrupt after LLI operation is complete. --- firmware/common/gpdma.c | 4 ++++ firmware/common/gpdma.h | 4 ++++ firmware/common/sgpio_dma.c | 3 +-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/firmware/common/gpdma.c b/firmware/common/gpdma.c index 14fc6406..dbccbd7f 100644 --- a/firmware/common/gpdma.c +++ b/firmware/common/gpdma.c @@ -44,3 +44,7 @@ void gpdma_channel_interrupt_tc_clear(const uint_fast8_t channel) { void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel) { GPDMA_INTERRCLR = GPDMA_INTERRCLR_INTERRCLR(1 << channel); } + +void gpdma_lli_enable_interrupt(gpdma_lli_t* const lli) { + lli->ccontrol |= GPDMA_CCONTROL_I(1); +} diff --git a/firmware/common/gpdma.h b/firmware/common/gpdma.h index 53310456..e9cc66d4 100644 --- a/firmware/common/gpdma.h +++ b/firmware/common/gpdma.h @@ -24,6 +24,8 @@ #include +#include + void gpdma_controller_enable(); void gpdma_channel_enable(const uint_fast8_t channel); @@ -32,4 +34,6 @@ void gpdma_channel_disable(const uint_fast8_t channel); void gpdma_channel_interrupt_tc_clear(const uint_fast8_t channel); void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel); +void gpdma_lli_enable_interrupt(gpdma_lli_t* const lli); + #endif/*__GPDMA_H__*/ diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index a2ab003c..ec7c02ed 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -46,7 +46,6 @@ void sgpio_dma_configure_lli( const uint_fast8_t source_master = direction_transmit ? 1 : 0; const uint_fast8_t destination_master = direction_transmit ? 0 : 1; const uint_fast8_t lli_fetch_master = direction_transmit ? 0 : 1; - const uint_fast8_t interrupt_after_this_lli = i & 1; lli[i].csrcaddr = direction_transmit ? memory_address : peripheral_address; lli[i].cdestaddr = direction_transmit ? peripheral_address : memory_address; @@ -64,7 +63,7 @@ void sgpio_dma_configure_lli( GPDMA_CCONTROL_PROT1(0) | GPDMA_CCONTROL_PROT2(0) | GPDMA_CCONTROL_PROT3(0) | - GPDMA_CCONTROL_I(interrupt_after_this_lli) + GPDMA_CCONTROL_I(0) ; } } From 5b59f9cb0a620476632df2853de88b2b9a572dd1 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 8 Dec 2013 18:16:58 -0800 Subject: [PATCH 172/200] Change GPDMA channel clli member to uint32_t, casting to/from gpdma_lli_t and dealing with the multiple fields was driving me crazy. --- firmware/common/sgpio_dma.c | 4 ++-- firmware/libopencm3 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index ec7c02ed..10c655db 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -49,7 +49,7 @@ void sgpio_dma_configure_lli( lli[i].csrcaddr = direction_transmit ? memory_address : peripheral_address; lli[i].cdestaddr = direction_transmit ? peripheral_address : memory_address; - lli[i].clli = (gpdma_lli_t*)((uint32_t)&lli[(i + 1) % lli_count] | lli_fetch_master); + lli[i].clli = (lli[i].clli & ~GPDMA_CLLI_LM_MASK) | GPDMA_CLLI_LM(lli_fetch_master); lli[i].ccontrol = GPDMA_CCONTROL_TRANSFERSIZE(transfer_words) | GPDMA_CCONTROL_SBSIZE(0) | @@ -130,7 +130,7 @@ size_t sgpio_dma_current_transfer_index( const gpdma_lli_t* const lli, const size_t lli_count ) { - const gpdma_lli_t* const next_lli = (gpdma_lli_t*)GPDMA_CLLI(dma_channel_sgpio); + const uint32_t next_lli = GPDMA_CLLI(dma_channel_sgpio); for(size_t i=0; i Date: Sun, 8 Dec 2013 18:18:22 -0800 Subject: [PATCH 173/200] Add GPDMA LLI functions to create a loop or one-shot chain of LLIs. --- firmware/common/gpdma.c | 12 ++++++++++++ firmware/common/gpdma.h | 4 ++++ firmware/common/sgpio_dma.c | 2 ++ 3 files changed, 18 insertions(+) diff --git a/firmware/common/gpdma.c b/firmware/common/gpdma.c index dbccbd7f..315b3180 100644 --- a/firmware/common/gpdma.c +++ b/firmware/common/gpdma.c @@ -48,3 +48,15 @@ void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel) { void gpdma_lli_enable_interrupt(gpdma_lli_t* const lli) { lli->ccontrol |= GPDMA_CCONTROL_I(1); } + +void gpdma_lli_create_loop(gpdma_lli_t* const lli, const size_t lli_count) { + for(size_t i=0; i> 2); + } +} + +void gpdma_lli_create_oneshot(gpdma_lli_t* const lli, const size_t lli_count) { + gpdma_lli_create_loop(lli, lli_count); + lli[lli_count - 1].clli &= ~GPDMA_CLLI_LLI_MASK; +} diff --git a/firmware/common/gpdma.h b/firmware/common/gpdma.h index e9cc66d4..11c4e74f 100644 --- a/firmware/common/gpdma.h +++ b/firmware/common/gpdma.h @@ -22,6 +22,7 @@ #ifndef __GPDMA_H__ #define __GPDMA_H__ +#include #include #include @@ -36,4 +37,7 @@ void gpdma_channel_interrupt_error_clear(const uint_fast8_t channel); void gpdma_lli_enable_interrupt(gpdma_lli_t* const lli); +void gpdma_lli_create_loop(gpdma_lli_t* const lli, const size_t lli_count); +void gpdma_lli_create_oneshot(gpdma_lli_t* const lli, const size_t lli_count); + #endif/*__GPDMA_H__*/ diff --git a/firmware/common/sgpio_dma.c b/firmware/common/sgpio_dma.c index 10c655db..dc78ddf1 100644 --- a/firmware/common/sgpio_dma.c +++ b/firmware/common/sgpio_dma.c @@ -39,6 +39,8 @@ void sgpio_dma_configure_lli( const size_t bytes_per_word = 4; const size_t transfer_words = (transfer_bytes + bytes_per_word - 1) / bytes_per_word; + gpdma_lli_create_loop(lli, lli_count); + for(size_t i=0; i Date: Tue, 31 Dec 2013 20:05:26 -0800 Subject: [PATCH 174/200] Add baseband sampling frequencies useful for 48kHz audio output. --- firmware/common/hackrf_core.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 629aa065..de6001a4 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -190,16 +190,32 @@ bool sample_rate_set(const uint32_t sample_rate_hz) { #if (defined JAWBREAKER || defined HACKRF_ONE) uint32_t p1 = 4608; + uint32_t p2 = 0; + uint32_t p3 = 0; switch(sample_rate_hz) { case 8000000: p1 = SI_INTDIV(50); // 800MHz / 50 = 16 MHz (SGPIO), 8 MHz (codec) break; + case 9216000: + // 43.40277777777778: a = 43; b = 29; c = 72 + p1 = 5043; + p2 = 40; + p3 = 72; + break; + case 10000000: p1 = SI_INTDIV(40); // 800MHz / 40 = 20 MHz (SGPIO), 10 MHz (codec) break; + case 12288000: + // 32.552083333333336: a = 32; b = 159; c = 288 + p1 = 3654; + p2 = 192; + p3 = 288; + break; + case 12500000: p1 = SI_INTDIV(32); // 800MHz / 32 = 25 MHz (SGPIO), 12.5 MHz (codec) break; @@ -208,6 +224,13 @@ bool sample_rate_set(const uint32_t sample_rate_hz) { p1 = SI_INTDIV(25); // 800MHz / 25 = 32 MHz (SGPIO), 16 MHz (codec) break; + case 18432000: + // 21.70138888889: a = 21; b = 101; c = 144 + p1 = 2265; + p2 = 112; + p3 = 144; + break; + case 20000000: p1 = SI_INTDIV(20); // 800MHz / 20 = 40 MHz (SGPIO), 20 MHz (codec) break; @@ -217,7 +240,7 @@ bool sample_rate_set(const uint32_t sample_rate_hz) { } /* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */ - si5351c_configure_multisynth(0, p1, 0, 1, 1); + si5351c_configure_multisynth(0, p1, p2, p3, 1); /* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */ si5351c_configure_multisynth(1, p1, 0, 1, 0);//p1 doesn't matter From 0ddb4cb7f2c78c49bcf0f8b7b3e3ca56583ddadc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Dec 2013 20:07:11 -0800 Subject: [PATCH 175/200] Configure LPC43xx for GP_CLKIN input. --- firmware/common/hackrf_core.c | 2 +- firmware/common/hackrf_core.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index de6001a4..1441394f 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -614,7 +614,7 @@ void pin_setup(void) { scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); /* Configure external clock in */ - //scu_pinmux(P4_7, SCU_CLK_IN | SCU_CONF_FUNCTION1); + scu_pinmux(SCU_PINMUX_GP_CLKIN, SCU_CLK_IN | SCU_CONF_FUNCTION1); sgpio_configure_pin_functions(); } diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index fff0fb14..b010cecf 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -198,6 +198,8 @@ extern "C" #define SCU_PINMUX_ISP (P2_7) /* GPIO0[7] */ +#define SCU_PINMUX_GP_CLKIN (P4_7) + /* * GPIO Pins */ From 7f35ceaff251b768e9c542e83f4291af3fc491bc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Dec 2013 20:09:44 -0800 Subject: [PATCH 176/200] Set Si5351C CLK7 output to drive LPC GP_CLKIN at 40MHz, so that activity (e.g. audio) on the LPC can be synchronized with the baseband sample rate. --- firmware/common/hackrf_core.c | 5 +++-- firmware/common/si5351c.c | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 1441394f..3de6dc15 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -319,9 +319,10 @@ void cpu_clock_init(void) /* MS5/CLK5 is the source for the MAX2837 clock input. */ si5351c_configure_multisynth(5, 20*128-512, 0, 1, 0); /* 800/20 = 40MHz */ + /* MS6/CLK6 is unused. */ /* MS7/CLK7 is the source for the LPC43xx microcontroller. */ - //uint8_t ms7data[] = { 91, 40, 0x0 }; - //si5351c_write(ms7data, sizeof(ms7data)); + uint8_t ms7data[] = { 90, 255, 20, 0 }; + si5351c_write(ms7data, sizeof(ms7data)); #endif /* Set to 10 MHz, the common rate between Jellybean and Jawbreaker. */ diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index d90559cb..6ddac500 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -237,16 +237,16 @@ void si5351c_configure_clock_control() ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_2MA) ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/ - ,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /* pllb int mode*/| SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_B) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) + ,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA) }; si5351c_write(data, sizeof(data)); } #endif -/* Enable CLK outputs 0, 1, 2, 4, 5, ~7 only. */ +/* Enable CLK outputs 0, 1, 2, 4, 5, 7 only. */ void si5351c_enable_clock_outputs() { - uint8_t data[] = { 3, 0xC8 }; + uint8_t data[] = { 3, 0x48 }; si5351c_write(data, sizeof(data)); } From fc5ec03353566c08463dcdd5155832e37fbb6a0a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Dec 2013 20:12:47 -0800 Subject: [PATCH 177/200] Adjust tuning API to use a single 64-bit integer for frequency in Hz, since the Cortex-M4F has good support for uint64_t. --- firmware/common/tuning.c | 12 +++++++----- firmware/common/tuning.h | 2 +- firmware/hackrf_usb/usb_api_transceiver.c | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/firmware/common/tuning.c b/firmware/common/tuning.c index bab3b7f1..aefeafc4 100644 --- a/firmware/common/tuning.c +++ b/firmware/common/tuning.c @@ -40,13 +40,13 @@ static uint32_t max2837_freq_nominal_hz=2560000000; -uint32_t freq_mhz_cache=100, freq_hz_cache=0; +uint64_t freq_cache = 100000000; /* * Set freq/tuning between 5MHz to 6800 MHz (less than 16bits really used) * hz between 0 to 999999 Hz (not checked) * return false on error or true if success. */ -bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) +bool set_freq(const uint64_t freq) { bool success; uint32_t RFFC5071_freq_mhz; @@ -54,6 +54,9 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) uint32_t real_RFFC5071_freq_hz; uint32_t tmp_hz; + const uint32_t freq_mhz = freq / 1000000; + const uint32_t freq_hz = freq % 1000000; + success = true; const max2837_mode_t prior_max2837_mode = max2837_mode(); @@ -107,8 +110,7 @@ bool set_freq(uint32_t freq_mhz, uint32_t freq_hz) success = false; } max2837_set_mode(prior_max2837_mode); - freq_mhz_cache = freq_mhz; - freq_hz_cache = freq_hz; + freq_cache = freq; return success; } @@ -116,7 +118,7 @@ bool set_freq_if(const uint32_t freq_if_hz) { bool success = false; if( (freq_if_hz >= MIN_BYPASS_FREQ_MHZ) && (freq_if_hz <= MAX_BYPASS_FREQ_MHZ) ) { max2837_freq_nominal_hz = freq_if_hz; - success = set_freq(freq_mhz_cache, freq_hz_cache); + success = set_freq(freq_cache); } return success; } diff --git a/firmware/common/tuning.h b/firmware/common/tuning.h index 0c1a99d9..16887c9e 100644 --- a/firmware/common/tuning.h +++ b/firmware/common/tuning.h @@ -26,7 +26,7 @@ #include #include -bool set_freq(uint32_t freq_mhz, uint32_t freq_hz); +bool set_freq(const uint64_t freq); bool set_freq_if(const uint32_t freq_if_hz); #endif/*__TUNING_H__*/ diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index 6566c9e2..1dd071c5 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -75,7 +75,8 @@ usb_request_status_t usb_vendor_request_set_freq( return USB_REQUEST_STATUS_OK; } else if (stage == USB_TRANSFER_STAGE_DATA) { - if( set_freq(set_freq_params.freq_mhz, set_freq_params.freq_hz) ) + const uint64_t freq = set_freq_params.freq_mhz * 1000000 + set_freq_params.freq_hz; + if( set_freq(freq) ) { usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; From c6b1ec2979e813c0302034e6f4cdf01ba7b7c0b7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Dec 2013 20:27:14 -0800 Subject: [PATCH 178/200] Adjust SGPIO GPDMA trigger slice data to a single clock width pulse. Previously, it was 3 clocks long with a 4 clock period, which *seemed* to address GPDMA data drop-outs at maximum baseband speed (20Msps complex). --- firmware/common/sgpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index d0d634e6..c0da0fe6 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -262,8 +262,8 @@ void sgpio_configure( SGPIO_POS_POS_RESET(0x1f) | SGPIO_POS_POS(0x1f) ; - SGPIO_REG(slice_gpdma) = 0x77777777; // Primary output data register, LSB -> out - SGPIO_REG_SS(slice_gpdma) = 0x77777777; // Shadow output data register, LSB -> out1 + SGPIO_REG(slice_gpdma) = 0x11111111; // Primary output data register, LSB -> out + SGPIO_REG_SS(slice_gpdma) = 0x11111111; // Shadow output data register, LSB -> out1 slice_enable_mask |= (1 << slice_gpdma); } From 7920490f1e0051c009637ec43d6dc9ecd071b217 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Dec 2013 20:34:01 -0800 Subject: [PATCH 179/200] Change USB bulk endpoint for baseband data to have only one queue item. Since there are only two baseband buffers, and one is transferring with the codec and the other with USB, enqueueing more than one buffer at a time would result in transferring an incomplete buffer. --- firmware/hackrf_usb/usb_endpoint.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/hackrf_usb/usb_endpoint.c b/firmware/hackrf_usb/usb_endpoint.c index c965287f..623f9d1f 100644 --- a/firmware/hackrf_usb/usb_endpoint.c +++ b/firmware/hackrf_usb/usb_endpoint.c @@ -58,7 +58,7 @@ usb_endpoint_t usb_endpoint_bulk_in = { .setup_complete = 0, .transfer_complete = usb_queue_transfer_complete }; -static USB_DEFINE_QUEUE(usb_endpoint_bulk_in, 4); +static USB_DEFINE_QUEUE(usb_endpoint_bulk_in, 1); usb_endpoint_t usb_endpoint_bulk_out = { .address = 0x02, @@ -68,6 +68,6 @@ usb_endpoint_t usb_endpoint_bulk_out = { .setup_complete = 0, .transfer_complete = usb_queue_transfer_complete }; -static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 4); +static USB_DEFINE_QUEUE(usb_endpoint_bulk_out, 1); From 63292419c8b7eb931620c1cedf0486c803f3716a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 2 Jan 2014 15:10:09 -0800 Subject: [PATCH 180/200] Moved M0 memory region to larger first AHB region (32K), moved USB bulk buffers to smaller AHB RAM area. --- firmware/common/LPC4330_M0.ld | 2 +- firmware/common/LPC4330_M4.ld | 4 ++-- firmware/common/LPC4330_M4_rom_to_ram.ld | 2 +- firmware/hackrf_usb/usb_bulk_buffer.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/common/LPC4330_M0.ld b/firmware/common/LPC4330_M0.ld index 787f3f9a..3ec9ad54 100644 --- a/firmware/common/LPC4330_M0.ld +++ b/firmware/common/LPC4330_M0.ld @@ -22,7 +22,7 @@ MEMORY { - ram (rwx) : ORIGIN = 0x00000000, LENGTH = 4K + ram (rwx) : ORIGIN = 0x00000000, LENGTH = 32K } /* Include the common ld script. */ diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index 199ba807..013c9ddf 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -35,7 +35,7 @@ MEMORY * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_m0 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 32K } /* Include the common ld script. */ @@ -43,7 +43,7 @@ INCLUDE libopencm3_lpc43xx.ld SECTIONS { - .m0 0x2000C000 : { + .m0 0x20000000 : { PROVIDE(__m0_start__ = .); KEEP(*(.m0_bin*)); . = ALIGN(4); diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld index 0f8114f4..588eb6f8 100644 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ b/firmware/common/LPC4330_M4_rom_to_ram.ld @@ -36,7 +36,7 @@ MEMORY * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_m0 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 32K } /* Include the common ld script. */ diff --git a/firmware/hackrf_usb/usb_bulk_buffer.c b/firmware/hackrf_usb/usb_bulk_buffer.c index 3e6d0320..b4da7e6d 100644 --- a/firmware/hackrf_usb/usb_bulk_buffer.c +++ b/firmware/hackrf_usb/usb_bulk_buffer.c @@ -22,6 +22,6 @@ #include "usb_bulk_buffer.h" -uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; +uint8_t* const usb_bulk_buffer = (uint8_t*)0x20008000; const uint32_t usb_bulk_buffer_mask = 32768 - 1; volatile uint32_t usb_bulk_buffer_offset = 0; From dbba407069e21148ea6c6eed1e818d0f4a73baf8 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 2 Jan 2014 15:11:15 -0800 Subject: [PATCH 181/200] Change M0 linking to use newlib-nano. snprintf() is a pig when the floating point junk gets pulled in on an M0... --- firmware/common/Makefile_inc.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 6822fd07..2689260b 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -87,6 +87,7 @@ CFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 LDSCRIPT_M0 ?= $(PATH_HACKRF_FIRMWARE_COMMON)/LPC4330_M0.ld LDFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 LDFLAGS_M0 += -T$(LDSCRIPT_M0) +LDFLAGS_M0 += --specs=nano.specs LDFLAGS_M0 += -Xlinker -Map=$(OBJDIR_M0)/m0.map LDFLAGS_M0 += -lopencm3_lpc43xx_m0 From 7c2f252d3700cd753948b63e99aa85f6a97c5338 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 2 Jan 2014 17:56:34 -0800 Subject: [PATCH 182/200] Bump libopencm3 submodule commit hash. --- firmware/libopencm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index 645f50ed..05bbde3f 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 645f50eddca3e06533a52d30bea244071c6992f1 +Subproject commit 05bbde3fece0aff3a4c3e91dbb9af1cbf3d3af00 From 574056c495a1b6ee9f8b3210e58baa55e52a394c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 2 Jan 2014 18:24:55 -0800 Subject: [PATCH 183/200] Fix long-standing example projects breakage due to tuning and SGPIO API and dependency changes. --- firmware/blinky/Makefile | 5 ++++- firmware/mixertx/Makefile | 2 ++ firmware/sgpio-rx/sgpio-rx.c | 10 ++++++---- firmware/sgpio/Makefile | 4 +++- firmware/sgpio/sgpio_test.c | 6 ++++-- firmware/simpletx/Makefile | 5 ++++- firmware/startup/Makefile | 5 ++++- firmware/startup_systick/Makefile | 5 ++++- firmware/startup_systick_perfo/Makefile | 5 ++++- 9 files changed, 35 insertions(+), 12 deletions(-) diff --git a/firmware/blinky/Makefile b/firmware/blinky/Makefile index 01ca290b..57f3e7a2 100644 --- a/firmware/blinky/Makefile +++ b/firmware/blinky/Makefile @@ -26,7 +26,10 @@ BINARY = blinky SRC = $(BINARY).c \ ../common/hackrf_core.c \ ../common/sgpio.c \ + ../common/rf_path.c \ ../common/si5351c.c \ - ../common/max2837.c + ../common/max2837.c \ + ../common/max5864.c \ + ../common/rffc5071.c include ../common/Makefile_inc.mk diff --git a/firmware/mixertx/Makefile b/firmware/mixertx/Makefile index 3c2ffc00..0f0ab0f0 100644 --- a/firmware/mixertx/Makefile +++ b/firmware/mixertx/Makefile @@ -4,9 +4,11 @@ BINARY = mixertx SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/rf_path.c \ ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ + ../common/max5864.c \ ../common/rffc5071.c include ../common/Makefile_inc.mk diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c index 823204b4..a5fb1e86 100644 --- a/firmware/sgpio-rx/sgpio-rx.c +++ b/firmware/sgpio-rx/sgpio-rx.c @@ -29,7 +29,8 @@ #include void tx_test() { - sgpio_configure(TRANSCEIVER_MODE_TX, false); + sgpio_set_slice_mode(false); + sgpio_configure(TRANSCEIVER_MODE_TX); // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { @@ -50,7 +51,8 @@ void tx_test() { } void rx_test() { - sgpio_configure(TRANSCEIVER_MODE_RX, false); + sgpio_set_slice_mode(false); + sgpio_configure(TRANSCEIVER_MODE_RX); volatile uint32_t buffer[4096]; uint32_t i = 0; @@ -86,7 +88,7 @@ void rx_test() { int main(void) { - const uint32_t freq = 2700000000U; + const uint64_t freq = 2700000000U; pin_setup(); enable_1v8_power(); @@ -95,7 +97,7 @@ int main(void) { rf_path_init(); rf_path_set_direction(RF_PATH_DIRECTION_RX); - set_freq(freq / 1000000, freq % 1000000); + set_freq(freq); rx_test(); gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ diff --git a/firmware/sgpio/Makefile b/firmware/sgpio/Makefile index 9f0303b7..d9651279 100644 --- a/firmware/sgpio/Makefile +++ b/firmware/sgpio/Makefile @@ -24,9 +24,11 @@ BINARY = sgpio_test SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/rf_path.c \ ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ - ../common/max5864.c + ../common/max5864.c \ + ../common/rffc5071.c include ../common/Makefile_inc.mk diff --git a/firmware/sgpio/sgpio_test.c b/firmware/sgpio/sgpio_test.c index e298c93e..802129db 100644 --- a/firmware/sgpio/sgpio_test.c +++ b/firmware/sgpio/sgpio_test.c @@ -31,7 +31,8 @@ #include void tx_test() { - sgpio_configure(TRANSCEIVER_MODE_TX, false); + sgpio_set_slice_mode(false); + sgpio_configure(TRANSCEIVER_MODE_TX); // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { @@ -52,7 +53,8 @@ void tx_test() { } void rx_test() { - sgpio_configure(TRANSCEIVER_MODE_RX, false); + sgpio_set_slice_mode(false); + sgpio_configure(TRANSCEIVER_MODE_RX); volatile uint32_t buffer[4096]; uint32_t i = 0; diff --git a/firmware/simpletx/Makefile b/firmware/simpletx/Makefile index ad3e171b..2cfc070d 100644 --- a/firmware/simpletx/Makefile +++ b/firmware/simpletx/Makefile @@ -4,8 +4,11 @@ BINARY = simpletx SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/rf_path.c \ ../common/sgpio.c \ ../common/si5351c.c \ - ../common/max2837.c + ../common/max2837.c \ + ../common/max5864.c \ + ../common/rffc5071.c include ../common/Makefile_inc.mk diff --git a/firmware/startup/Makefile b/firmware/startup/Makefile index ab4b43cc..0895e670 100644 --- a/firmware/startup/Makefile +++ b/firmware/startup/Makefile @@ -4,8 +4,11 @@ BINARY = startup SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/rf_path.c \ ../common/sgpio.c \ ../common/si5351c.c \ - ../common/max2837.c + ../common/max2837.c \ + ../common/max5864.c \ + ../common/rffc5071.c include ../common/Makefile_inc.mk diff --git a/firmware/startup_systick/Makefile b/firmware/startup_systick/Makefile index 9a8cd55a..e98f315c 100644 --- a/firmware/startup_systick/Makefile +++ b/firmware/startup_systick/Makefile @@ -4,8 +4,11 @@ BINARY = startup_systick SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/rf_path.c \ ../common/sgpio.c \ ../common/si5351c.c \ - ../common/max2837.c + ../common/max2837.c \ + ../common/max5864.c \ + ../common/rffc5071.c include ../common/Makefile_inc.mk diff --git a/firmware/startup_systick_perfo/Makefile b/firmware/startup_systick_perfo/Makefile index a1d0b116..9874184e 100644 --- a/firmware/startup_systick_perfo/Makefile +++ b/firmware/startup_systick_perfo/Makefile @@ -5,8 +5,11 @@ BINARY = startup_systick_perfo_SPIFI SRC = startup_systick.c \ perf_mips.c \ ../common/hackrf_core.c \ + ../common/rf_path.c \ ../common/sgpio.c \ ../common/si5351c.c \ - ../common/max2837.c + ../common/max2837.c \ + ../common/max5864.c \ + ../common/rffc5071.c include ../common/Makefile_inc.mk From de10aa8b0e44f17cbad69a76e5bc123935850458 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 2 Jan 2014 22:05:42 -0800 Subject: [PATCH 184/200] Bump libopencm3 submodule hash. --- firmware/libopencm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/libopencm3 b/firmware/libopencm3 index 05bbde3f..1cf02283 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 05bbde3fece0aff3a4c3e91dbb9af1cbf3d3af00 +Subproject commit 1cf022831031d16b337d9f0d3f7006158132330f From 75e1dcd9cfa2448172373b7908ce446a2bfae0c2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 4 Jan 2014 10:15:01 -0800 Subject: [PATCH 185/200] Don't update MAX2837 freq_cache unless set_freq() is successful. --- firmware/common/tuning.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/common/tuning.c b/firmware/common/tuning.c index aefeafc4..66a01d76 100644 --- a/firmware/common/tuning.c +++ b/firmware/common/tuning.c @@ -110,7 +110,9 @@ bool set_freq(const uint64_t freq) success = false; } max2837_set_mode(prior_max2837_mode); - freq_cache = freq; + if( success ) { + freq_cache = freq; + } return success; } From 19f285288c4745a49f4ffe1cde4365aa5374737c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 15:17:39 -0800 Subject: [PATCH 186/200] Reset decimator sample count when host_data_enable is 0, so that sample stream starts with a consistent phase. May not be particularly important, but feels cleaner this way... --- firmware/cpld/sgpio_if/default.xsvf | Bin 37629 -> 37629 bytes firmware/cpld/sgpio_if/top.jed | 62 ++++++++++++++-------------- firmware/cpld/sgpio_if/top.vhd | 2 +- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/firmware/cpld/sgpio_if/default.xsvf b/firmware/cpld/sgpio_if/default.xsvf index 330198987793e1dd94d8e657330a908ef9d03cfb..720733d4b74e33aec56a4ebf7a72cf2d3f2fe67f 100644 GIT binary patch delta 536 zcmeynlk+FXA#wfYXFIhh@ zv;6;mwSID=jqK!Kocc_mT9X?UWjA|pU0`Lr31rGowh%Cwd{IkrbEiO?0Ngnn41^{- zDkj35BRknGKydOE#Ux1-XT7`!cjNoX2UR6Drz^Dsy##jW1gIP3CL1UUPTs8Y1?E=S z$qN30n{TQDRYD!Sxj~(s5#r*>4=jZ?@6d2%N4R=|vEXEVgG89i*BhMVg1US{knrTy Z)(Mjzm?>`7v1yhY%C7$;GkM=6djM!f{Zaq` delta 523 zcmeynlW^&hlt-lAFS0Pu51p|C>*<^06@et)HBzB0u>Tr#_?p z7qM)QJJG_ipkhe!AllM)s2LO|34`BcR diff --git a/firmware/cpld/sgpio_if/top.jed b/firmware/cpld/sgpio_if/top.jed index 44aa1403..9d609adf 100755 --- a/firmware/cpld/sgpio_if/top.jed +++ b/firmware/cpld/sgpio_if/top.jed @@ -1,5 +1,5 @@ Programmer Jedec Bit Map -Date Extracted: Tue Nov 19 16:33:01 2013 +Date Extracted: Fri Nov 29 16:09:27 2013 QF25812* QP100* @@ -23,7 +23,7 @@ L000112 1111111111111111* L000128 1110101011111111* L000144 1111111111111111* L000160 1111111111111111* -L000176 1111111111111111* +L000176 1111111011100111* L000192 1111111111111111* L000208 1111111011100111* L000224 1111111111111111* @@ -54,19 +54,19 @@ L000608 1111111111111111* L000624 1111111111111111* Note Block 0 PLA AND array * -L000640 11010111111101110111111111011111111111111111111111111111111111111111111111111111* -L000720 11111011111111111111111111111111111111111111111111111111111111111111111111111111* -L000800 01011111111101110111111111111111111111111111111111111111111111111111111111111111* -L000880 11010111111011110111111111111111111111111111111111111111111111111111111111111111* -L000960 11010111111110110111111111111111111111111111111111111111111111111111111111111111* -L001040 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L001120 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L001200 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L001280 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L001360 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L001440 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L001520 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L001600 11111111111111111111111111111111111111111111111111111111111111111111111111111111* +L000640 11110111111111111111110111011111111111111111111111111111111111111111111111111111* +L000720 11011011111111111111111111111111111111111111111111111111111111111111111111111111* +L000800 11011111111111111011111011111111111111111111111111111111111111111111111111111111* +L000880 11100111111111110111111011111111111111111111111111111111111111111111111111111111* +L000960 11011111111101111111111111011111111111111111111111111111111111111111111111111111* +L001040 11111011111111111111111111111111111111111111111111111111111111111111111111111111* +L001120 01111111111111110111110111111111111111111111111111111111111111111111111111111111* +L001200 10111111111111111011110111111111111111111111111111111111111111111111111111111111* +L001280 01011111111101110111111111111111111111111111111111111111111111111111111111111111* +L001360 11110111111001111111110111111111111111111111111111111111111111111111111111111111* +L001440 11010111111001110111111111111111111111111111111111111111111111111111111111111111* +L001520 11110111110110111111110111111111111111111111111111111111111111111111111111111111* +L001600 11010111111110110111111011111111111111111111111111111111111111111111111111111111* L001680 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L001760 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L001840 11111111111111111111111111111111111111111111111111111111111111111111111111111111* @@ -109,22 +109,22 @@ L004720 111111111111111111111111111111111111111111111111111111111111111111111111 L004800 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L004880 11111111111111111111111111111111111111111111111111111111111111111111111111111111* L004960 11111111111111111111111111111111111111111111111111111111111111111111111111111111* -L005040 11110111111111110111111111111111111111111111111111111111111111111111111111111111* +L005040 11111111111111111111111111111111111111111111111111111111111111111111111111111111* Note Block 0 PLA OR array * L005120 1111111111111110* -L005136 1111111111111101* -L005152 1111111111111101* -L005168 1111111111111011* -L005184 1111111111111011* -L005200 1111111111111111* -L005216 1111111111111111* -L005232 1111111111111111* -L005248 1111111111111111* -L005264 1111111111111111* -L005280 1111111111111111* -L005296 1111111111111111* -L005312 1111111111111111* +L005136 1111111111111110* +L005152 1111111111111110* +L005168 1111111111111110* +L005184 1111111111111110* +L005200 1111111111111101* +L005216 1111111111111101* +L005232 1111111111111101* +L005248 1111111111111101* +L005264 1111111111111011* +L005280 1111111111111011* +L005296 1111111111111011* +L005312 1111111111111011* L005328 1111111111111111* L005344 1111111111111111* L005360 1111111111111111* @@ -186,7 +186,7 @@ L006313 000001111001111110011111100* L006340 000001111001111110011111100* L006367 000101111101110110011111100* L006394 000101111101110111111111100* -L006421 000101111101110111011111100* +L006421 000101111001110110011111100* Note Block 1 * Note Block 1 ZIA * @@ -753,5 +753,5 @@ L025810 0* Note I/O Bank 1 Vcco * L025811 0* -C0D64* -AA1A +C0625* +A9E4 diff --git a/firmware/cpld/sgpio_if/top.vhd b/firmware/cpld/sgpio_if/top.vhd index 90d6bb84..c8fab177 100755 --- a/firmware/cpld/sgpio_if/top.vhd +++ b/firmware/cpld/sgpio_if/top.vhd @@ -104,7 +104,7 @@ begin begin if rising_edge(host_clk_i) then if codec_clk_i = '1' then - if decimate_count = "111" then + if decimate_count = "111" or host_data_enable_i = '0' then decimate_count <= decimate_sel_i; else decimate_count <= decimate_count + 1; From 572f2285f210804d0b60f4aa0cab0978cb7f1ee3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 15:17:47 -0800 Subject: [PATCH 187/200] Let Xilinx ISE update some unimportant project file header stuff. --- firmware/cpld/sgpio_if/sgpio_if.xise | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/cpld/sgpio_if/sgpio_if.xise b/firmware/cpld/sgpio_if/sgpio_if.xise index 82c5ad11..500e07da 100755 --- a/firmware/cpld/sgpio_if/sgpio_if.xise +++ b/firmware/cpld/sgpio_if/sgpio_if.xise @@ -9,10 +9,10 @@ - + - + From 80047c9a0c9ddb937f79348d83651d920585f390 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 15:20:10 -0800 Subject: [PATCH 188/200] Makefile: Add separate OBJ_M4_S and OBJ_M0_S variables for .S files. (Unused, but worked earlier and may be useful later.) --- firmware/common/Makefile_inc.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 2689260b..ac1874af 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -154,15 +154,15 @@ $(BINARY).list: $(BINARY).elf $(BINARY).elf: obj_m4 @#printf " LD $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(LD) -o $(BINARY).elf $(OBJ_M4_C) $(OBJDIR_M4)/m0_bin.o $(LDFLAGS_COMMON) $(LDFLAGS_M4) + $(Q)$(LD) -o $(BINARY).elf $(OBJ_M4_C) $(OBJ_M4_S) $(OBJDIR_M4)/m0_bin.o $(LDFLAGS_COMMON) $(LDFLAGS_M4) $(OBJDIR_M0)/m0.elf: obj_m0 @#printf " LD $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(LD) -o $(OBJDIR_M0)/m0.elf $(OBJ_M0_C) $(LDFLAGS_COMMON) $(LDFLAGS_M0) + $(Q)$(LD) -o $(OBJDIR_M0)/m0.elf $(OBJ_M0_C) $(OBJ_M0_S) $(LDFLAGS_COMMON) $(LDFLAGS_M0) -obj_m4: $(OBJ_M4_C) $(OBJDIR_M4)/m0_bin.o +obj_m4: $(OBJ_M4_C) $(OBJ_M4_S) $(OBJDIR_M4)/m0_bin.o -obj_m0: $(OBJ_M0_C) +obj_m0: $(OBJ_M0_C) $(OBJ_M0_S) $(OBJDIR_M4)/%.o: %.c | $(OBJDIR_M4) @printf " CC $(subst $(shell pwd)/,,$(@))\n" From 095f55abce865e0200e072af879c0df77914ef05 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 15:21:20 -0800 Subject: [PATCH 189/200] Make a bit of room in the M0 AHB RAM region for fixed-location shared (M4, M0 cores) data structures. --- firmware/common/LPC4330_M0.ld | 2 +- firmware/common/LPC4330_M4.ld | 2 +- firmware/common/LPC4330_M4_rom_to_ram.ld | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/common/LPC4330_M0.ld b/firmware/common/LPC4330_M0.ld index 3ec9ad54..04dc7428 100644 --- a/firmware/common/LPC4330_M0.ld +++ b/firmware/common/LPC4330_M0.ld @@ -22,7 +22,7 @@ MEMORY { - ram (rwx) : ORIGIN = 0x00000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x00000000, LENGTH = 28K } /* Include the common ld script. */ diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index 013c9ddf..75f4c65e 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -35,7 +35,7 @@ MEMORY * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 32K + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K } /* Include the common ld script. */ diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld index 588eb6f8..5c42df73 100644 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ b/firmware/common/LPC4330_M4_rom_to_ram.ld @@ -36,7 +36,7 @@ MEMORY * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 32K + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K } /* Include the common ld script. */ From 936e35604077e1736568b672f2317d04d6e44541 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 15:49:46 -0800 Subject: [PATCH 190/200] ldscript memory region clean-up for LPC4330 targets. --- firmware/common/LPC4330_M4.ld | 7 +++++-- firmware/common/LPC4330_M4_rom_to_ram.ld | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index 75f4c65e..db336a52 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -31,11 +31,14 @@ MEMORY ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K - /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K + ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K + ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K + ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K + /* ram_usb[01]: USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K } /* Include the common ld script. */ diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld index 5c42df73..e7701a5a 100644 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ b/firmware/common/LPC4330_M4_rom_to_ram.ld @@ -32,11 +32,14 @@ MEMORY ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K - /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K + ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K + ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K + ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K + /* ram_usb[01]: USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ - ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K } /* Include the common ld script. */ From 10e379f492a00c12dadcd1969cf8328635ed18d0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 15:52:38 -0800 Subject: [PATCH 191/200] Add ldscripts for LPC4320 targets (e.g. HackRF One). Qualify Makefile ldscripts based on BOARD. --- firmware/common/LPC4320_M0.ld | 29 ++++++++++++ firmware/common/LPC4320_M4.ld | 55 +++++++++++++++++++++++ firmware/common/LPC4320_M4_rom_to_ram.ld | 56 ++++++++++++++++++++++++ firmware/common/Makefile_inc.mk | 14 ++++-- 4 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 firmware/common/LPC4320_M0.ld create mode 100644 firmware/common/LPC4320_M4.ld create mode 100644 firmware/common/LPC4320_M4_rom_to_ram.ld diff --git a/firmware/common/LPC4320_M0.ld b/firmware/common/LPC4320_M0.ld new file mode 100644 index 00000000..04dc7428 --- /dev/null +++ b/firmware/common/LPC4320_M0.ld @@ -0,0 +1,29 @@ +/* + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone + * + * This file is part of HackRF + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x00000000, LENGTH = 28K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx_m0_ram_only.ld diff --git a/firmware/common/LPC4320_M4.ld b/firmware/common/LPC4320_M4.ld new file mode 100644 index 00000000..8b1382eb --- /dev/null +++ b/firmware/common/LPC4320_M4.ld @@ -0,0 +1,55 @@ +/* + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone + * + * This file is part of HackRF + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* Linker script for HackRF One (LPC4320, 1M SPI flash, 200K SRAM). */ + +MEMORY +{ + /* Physical address in Flash used to copy Code from Flash to RAM */ + rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M + /* rom is really the shadow region that points to SPI flash or elsewhere */ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 96K + ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 96K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 32K + ram_sleep (rwx) : ORIGIN = 0x10088000, LENGTH = 8K + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K + ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K + ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K + ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K + /* ram_usb[01]: USB buffer. Straddles two blocks of RAM + * to get performance benefit of having two USB buffers addressable + * simultaneously (on two different buses of the AHB multilayer matrix) + */ +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx.ld + +SECTIONS +{ + .m0 0x20000000 : { + PROVIDE(__m0_start__ = .); + KEEP(*(.m0_bin*)); + . = ALIGN(4); + PROVIDE(__m0_end__ = .); + } >ram_m0 +} diff --git a/firmware/common/LPC4320_M4_rom_to_ram.ld b/firmware/common/LPC4320_M4_rom_to_ram.ld new file mode 100644 index 00000000..23a309ae --- /dev/null +++ b/firmware/common/LPC4320_M4_rom_to_ram.ld @@ -0,0 +1,56 @@ +/* + * Copyright 2012 Michael Ossmann + * Copyright (C) 2012 Benjamin Vernoux + * Copyright 2012 Jared Boone + * + * This file is part of HackRF + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* Linker script for HackRF One (LPC4320, 1M SPI flash, 200K SRAM). */ + +MEMORY +{ + /* Physical address in Flash used to copy Code from Flash to RAM */ + rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M + /* rom is really the shadow region that points to SPI flash or elsewhere */ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 96K + ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 96K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 32K + ram_sleep (rwx) : ORIGIN = 0x10088000, LENGTH = 8K + ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K + ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K + ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K + ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K + /* ram_usb[01]: USB buffer. Straddles two blocks of RAM + * to get performance benefit of having two USB buffers addressable + * simultaneously (on two different buses of the AHB multilayer matrix) + */ +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx_rom_to_ram.ld + +SECTIONS +{ + .text : { + PROVIDE(__m0_start__ = .); + KEEP(*(.m0_bin*)); + . = ALIGN(4); + PROVIDE(__m0_end__ = .); + } >rom +} diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index ac1874af..5cb449e3 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -29,7 +29,13 @@ BOARD ?= JAWBREAKER RUN_FROM ?= SPIFI -HACKRF_OPTS = -D$(BOARD) -DLPC43XX +ifeq ($(BOARD),HACKRF_ONE) + MCU_PARTNO=LPC4320 +else + MCU_PARTNO=LPC4330 +endif + +HACKRF_OPTS = -D$(BOARD) -DLPC43XX -D$(MCU_PARTNO) # comment to disable RF transmission HACKRF_OPTS += -DTX_ENABLE @@ -62,9 +68,9 @@ OBJ_M0_C = $(patsubst %.c, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_C))) OBJ_M0_S = $(patsubst %.s, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_S))) ifeq ($(RUN_FROM),RAM) - LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/LPC4330_M4.ld + LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M4.ld else - LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/LPC4330_M4_rom_to_ram.ld + LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M4_rom_to_ram.ld endif PREFIX ?= arm-none-eabi @@ -84,7 +90,7 @@ LDFLAGS_COMMON += -mthumb \ -Wl,--gc-sections \ -lc -lnosys CFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 -LDSCRIPT_M0 ?= $(PATH_HACKRF_FIRMWARE_COMMON)/LPC4330_M0.ld +LDSCRIPT_M0 ?= $(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M0.ld LDFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 LDFLAGS_M0 += -T$(LDSCRIPT_M0) LDFLAGS_M0 += --specs=nano.specs From ba2cc32ac696faa730cb2f81862ec6ae3e62c520 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 17:07:49 -0800 Subject: [PATCH 192/200] Combine ram_usb[01] into a single region. Assign usb_bulk_buffer symbol to ram_usb origin, instead of hard-coding a pointer in C. Change declaration of usb_bulk_buffer from a pointer to an array. --- firmware/common/LPC4320_M4.ld | 7 ++++--- firmware/common/LPC4320_M4_rom_to_ram.ld | 7 ++++--- firmware/common/LPC4330_M4.ld | 7 ++++--- firmware/common/LPC4330_M4_rom_to_ram.ld | 7 ++++--- firmware/hackrf_usb/usb_bulk_buffer.c | 7 ++++++- firmware/hackrf_usb/usb_bulk_buffer.h | 2 +- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/firmware/common/LPC4320_M4.ld b/firmware/common/LPC4320_M4.ld index 8b1382eb..f72ef9ee 100644 --- a/firmware/common/LPC4320_M4.ld +++ b/firmware/common/LPC4320_M4.ld @@ -33,14 +33,15 @@ MEMORY ram_sleep (rwx) : ORIGIN = 0x10088000, LENGTH = 8K ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K - ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K - ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K - /* ram_usb[01]: USB buffer. Straddles two blocks of RAM + ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K + /* ram_usb: USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ } +usb_bulk_buffer = ORIGIN(ram_usb); + /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx.ld diff --git a/firmware/common/LPC4320_M4_rom_to_ram.ld b/firmware/common/LPC4320_M4_rom_to_ram.ld index 23a309ae..13436e79 100644 --- a/firmware/common/LPC4320_M4_rom_to_ram.ld +++ b/firmware/common/LPC4320_M4_rom_to_ram.ld @@ -34,14 +34,15 @@ MEMORY ram_sleep (rwx) : ORIGIN = 0x10088000, LENGTH = 8K ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K - ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K - ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K - /* ram_usb[01]: USB buffer. Straddles two blocks of RAM + ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K + /* ram_usb: USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ } +usb_bulk_buffer = ORIGIN(ram_usb); + /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx_rom_to_ram.ld diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index db336a52..c87fbf68 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -33,14 +33,15 @@ MEMORY ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K - ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K - ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K - /* ram_usb[01]: USB buffer. Straddles two blocks of RAM + ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K + /* ram_usb: USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ } +usb_bulk_buffer = ORIGIN(ram_usb); + /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx.ld diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld index e7701a5a..7833245d 100644 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ b/firmware/common/LPC4330_M4_rom_to_ram.ld @@ -34,14 +34,15 @@ MEMORY ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K - ram_usb0 (rwx) : ORIGIN = 0x20008000, LENGTH = 16K - ram_usb1 (rwx) : ORIGIN = 0x2000c000, LENGTH = 16K - /* ram_usb[01]: USB buffer. Straddles two blocks of RAM + ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K + /* ram_usb: USB buffer. Straddles two blocks of RAM * to get performance benefit of having two USB buffers addressable * simultaneously (on two different buses of the AHB multilayer matrix) */ } +usb_bulk_buffer = ORIGIN(ram_usb); + /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx_rom_to_ram.ld diff --git a/firmware/hackrf_usb/usb_bulk_buffer.c b/firmware/hackrf_usb/usb_bulk_buffer.c index b4da7e6d..9048f49a 100644 --- a/firmware/hackrf_usb/usb_bulk_buffer.c +++ b/firmware/hackrf_usb/usb_bulk_buffer.c @@ -22,6 +22,11 @@ #include "usb_bulk_buffer.h" -uint8_t* const usb_bulk_buffer = (uint8_t*)0x20008000; +/* Address of usb_bulk_buffer is set in ldscripts. If you change the name of this + * variable, it won't be where it needs to be in the processor's address space, + * unless you also adjust the ldscripts. + */ +uint8_t usb_bulk_buffer[32768]; + const uint32_t usb_bulk_buffer_mask = 32768 - 1; volatile uint32_t usb_bulk_buffer_offset = 0; diff --git a/firmware/hackrf_usb/usb_bulk_buffer.h b/firmware/hackrf_usb/usb_bulk_buffer.h index fe298e69..967bd16c 100644 --- a/firmware/hackrf_usb/usb_bulk_buffer.h +++ b/firmware/hackrf_usb/usb_bulk_buffer.h @@ -25,7 +25,7 @@ #include -extern uint8_t* const usb_bulk_buffer; +extern uint8_t usb_bulk_buffer[32768]; extern const uint32_t usb_bulk_buffer_mask; extern volatile uint32_t usb_bulk_buffer_offset; From bb8943ce5b984222d33a195c4d8c1a7bc4d71394 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 17:38:27 -0800 Subject: [PATCH 193/200] Break ldscripts into smaller pieces that can be shared. --- ..._M4_rom_to_ram.ld => LPC4320_M4_memory.ld} | 25 +------- .../{LPC4330_M4.ld => LPC4330_M4_memory.ld} | 24 +------- firmware/common/LPC4330_M4_rom_to_ram.ld | 57 ------------------- .../{LPC4320_M0.ld => LPC43xx_M0_memory.ld} | 3 - ...0.ld => LPC43xx_M4_M0_image_from_spifi.ld} | 12 ++-- firmware/common/LPC43xx_M4_M0_image_in_ram.ld | 31 ++++++++++ .../{LPC4320_M4.ld => LPC43xx_M4_memory.ld} | 20 ------- firmware/common/Makefile_inc.mk | 15 +++-- 8 files changed, 50 insertions(+), 137 deletions(-) rename firmware/common/{LPC4320_M4_rom_to_ram.ld => LPC4320_M4_memory.ld} (61%) rename firmware/common/{LPC4330_M4.ld => LPC4330_M4_memory.ld} (63%) delete mode 100644 firmware/common/LPC4330_M4_rom_to_ram.ld rename firmware/common/{LPC4320_M0.ld => LPC43xx_M0_memory.ld} (92%) rename firmware/common/{LPC4330_M0.ld => LPC43xx_M4_M0_image_from_spifi.ld} (86%) create mode 100644 firmware/common/LPC43xx_M4_M0_image_in_ram.ld rename firmware/common/{LPC4320_M4.ld => LPC43xx_M4_memory.ld} (71%) diff --git a/firmware/common/LPC4320_M4_rom_to_ram.ld b/firmware/common/LPC4320_M4_memory.ld similarity index 61% rename from firmware/common/LPC4320_M4_rom_to_ram.ld rename to firmware/common/LPC4320_M4_memory.ld index 13436e79..536db5eb 100644 --- a/firmware/common/LPC4320_M4_rom_to_ram.ld +++ b/firmware/common/LPC4320_M4_memory.ld @@ -1,6 +1,5 @@ /* * Copyright 2012 Michael Ossmann - * Copyright (C) 2012 Benjamin Vernoux * Copyright 2012 Jared Boone * * This file is part of HackRF @@ -25,33 +24,11 @@ MEMORY { - /* Physical address in Flash used to copy Code from Flash to RAM */ - rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M /* rom is really the shadow region that points to SPI flash or elsewhere */ rom (rx) : ORIGIN = 0x00000000, LENGTH = 96K ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 96K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 32K ram_sleep (rwx) : ORIGIN = 0x10088000, LENGTH = 8K - ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K - ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K - ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K - /* ram_usb: USB buffer. Straddles two blocks of RAM - * to get performance benefit of having two USB buffers addressable - * simultaneously (on two different buses of the AHB multilayer matrix) - */ } -usb_bulk_buffer = ORIGIN(ram_usb); - -/* Include the common ld script. */ -INCLUDE libopencm3_lpc43xx_rom_to_ram.ld - -SECTIONS -{ - .text : { - PROVIDE(__m0_start__ = .); - KEEP(*(.m0_bin*)); - . = ALIGN(4); - PROVIDE(__m0_end__ = .); - } >rom -} +INCLUDE LPC43xx_M4_memory.ld diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4_memory.ld similarity index 63% rename from firmware/common/LPC4330_M4.ld rename to firmware/common/LPC4330_M4_memory.ld index c87fbf68..42e217cf 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4_memory.ld @@ -24,33 +24,11 @@ MEMORY { - /* Physical address in Flash used to copy Code from Flash to RAM */ - rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M /* rom is really the shadow region that points to SPI flash or elsewhere */ rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K - ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K - ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K - ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K - /* ram_usb: USB buffer. Straddles two blocks of RAM - * to get performance benefit of having two USB buffers addressable - * simultaneously (on two different buses of the AHB multilayer matrix) - */ } -usb_bulk_buffer = ORIGIN(ram_usb); - -/* Include the common ld script. */ -INCLUDE libopencm3_lpc43xx.ld - -SECTIONS -{ - .m0 0x20000000 : { - PROVIDE(__m0_start__ = .); - KEEP(*(.m0_bin*)); - . = ALIGN(4); - PROVIDE(__m0_end__ = .); - } >ram_m0 -} +INCLUDE LPC43xx_M4_memory.ld diff --git a/firmware/common/LPC4330_M4_rom_to_ram.ld b/firmware/common/LPC4330_M4_rom_to_ram.ld deleted file mode 100644 index 7833245d..00000000 --- a/firmware/common/LPC4330_M4_rom_to_ram.ld +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012 Michael Ossmann - * Copyright (C) 2012 Benjamin Vernoux - * Copyright 2012 Jared Boone - * - * This file is part of HackRF - * - * 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, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* Linker script for HackRF Jellybean/Jawbreaker (LPC4330, 1M SPI flash, 264K SRAM). */ - -MEMORY -{ - /* Physical address in Flash used to copy Code from Flash to RAM */ - rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M - /* rom is really the shadow region that points to SPI flash or elsewhere */ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K - ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K - ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 64K - ram_sleep (rwx) : ORIGIN = 0x10090000, LENGTH = 8K - ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K - ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K - ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K - /* ram_usb: USB buffer. Straddles two blocks of RAM - * to get performance benefit of having two USB buffers addressable - * simultaneously (on two different buses of the AHB multilayer matrix) - */ -} - -usb_bulk_buffer = ORIGIN(ram_usb); - -/* Include the common ld script. */ -INCLUDE libopencm3_lpc43xx_rom_to_ram.ld - -SECTIONS -{ - .text : { - PROVIDE(__m0_start__ = .); - KEEP(*(.m0_bin*)); - . = ALIGN(4); - PROVIDE(__m0_end__ = .); - } >rom -} diff --git a/firmware/common/LPC4320_M0.ld b/firmware/common/LPC43xx_M0_memory.ld similarity index 92% rename from firmware/common/LPC4320_M0.ld rename to firmware/common/LPC43xx_M0_memory.ld index 04dc7428..ec2f646a 100644 --- a/firmware/common/LPC4320_M0.ld +++ b/firmware/common/LPC43xx_M0_memory.ld @@ -24,6 +24,3 @@ MEMORY { ram (rwx) : ORIGIN = 0x00000000, LENGTH = 28K } - -/* Include the common ld script. */ -INCLUDE libopencm3_lpc43xx_m0_ram_only.ld diff --git a/firmware/common/LPC4330_M0.ld b/firmware/common/LPC43xx_M4_M0_image_from_spifi.ld similarity index 86% rename from firmware/common/LPC4330_M0.ld rename to firmware/common/LPC43xx_M4_M0_image_from_spifi.ld index 04dc7428..3c61f69e 100644 --- a/firmware/common/LPC4330_M0.ld +++ b/firmware/common/LPC43xx_M4_M0_image_from_spifi.ld @@ -20,10 +20,12 @@ * Boston, MA 02110-1301, USA. */ -MEMORY +SECTIONS { - ram (rwx) : ORIGIN = 0x00000000, LENGTH = 28K + .text : { + PROVIDE(__m0_start__ = .); + KEEP(*(.m0_bin*)); + . = ALIGN(4); + PROVIDE(__m0_end__ = .); + } >rom } - -/* Include the common ld script. */ -INCLUDE libopencm3_lpc43xx_m0_ram_only.ld diff --git a/firmware/common/LPC43xx_M4_M0_image_in_ram.ld b/firmware/common/LPC43xx_M4_M0_image_in_ram.ld new file mode 100644 index 00000000..e07bd79d --- /dev/null +++ b/firmware/common/LPC43xx_M4_M0_image_in_ram.ld @@ -0,0 +1,31 @@ +/* + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone + * + * This file is part of HackRF + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +SECTIONS +{ + .m0 0x20000000 : { + PROVIDE(__m0_start__ = .); + KEEP(*(.m0_bin*)); + . = ALIGN(4); + PROVIDE(__m0_end__ = .); + } >ram_m0 +} diff --git a/firmware/common/LPC4320_M4.ld b/firmware/common/LPC43xx_M4_memory.ld similarity index 71% rename from firmware/common/LPC4320_M4.ld rename to firmware/common/LPC43xx_M4_memory.ld index f72ef9ee..71e78216 100644 --- a/firmware/common/LPC4320_M4.ld +++ b/firmware/common/LPC43xx_M4_memory.ld @@ -20,17 +20,10 @@ * Boston, MA 02110-1301, USA. */ -/* Linker script for HackRF One (LPC4320, 1M SPI flash, 200K SRAM). */ - MEMORY { /* Physical address in Flash used to copy Code from Flash to RAM */ rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M - /* rom is really the shadow region that points to SPI flash or elsewhere */ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 96K - ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 96K - ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 32K - ram_sleep (rwx) : ORIGIN = 0x10088000, LENGTH = 8K ram_m0 (rwx) : ORIGIN = 0x20000000, LENGTH = 28K ram_shared (rwx) : ORIGIN = 0x20007000, LENGTH = 4K ram_usb (rwx) : ORIGIN = 0x20008000, LENGTH = 32K @@ -41,16 +34,3 @@ MEMORY } usb_bulk_buffer = ORIGIN(ram_usb); - -/* Include the common ld script. */ -INCLUDE libopencm3_lpc43xx.ld - -SECTIONS -{ - .m0 0x20000000 : { - PROVIDE(__m0_start__ = .); - KEEP(*(.m0_bin*)); - . = ALIGN(4); - PROVIDE(__m0_end__ = .); - } >ram_m0 -} diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 5cb449e3..288b7fc5 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -67,12 +67,18 @@ OBJ_M4_S = $(patsubst %.s, $(OBJDIR_M4)/%.o, $(notdir $(SRC_M4_S))) OBJ_M0_C = $(patsubst %.c, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_C))) OBJ_M0_S = $(patsubst %.s, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_S))) +LDSCRIPT_M4 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M4_memory.ld ifeq ($(RUN_FROM),RAM) - LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M4.ld + LDSCRIPT_M4 += -Tlibopencm3_lpc43xx.ld + LDSCRIPT_M4 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M4_M0_image_in_ram.ld else - LDSCRIPT_M4 = $(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M4_rom_to_ram.ld + LDSCRIPT_M4 += -Tlibopencm3_lpc43xx_rom_to_ram.ld + LDSCRIPT_M4 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M4_M0_image_from_spifi.ld endif +LDSCRIPT_M0 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M0_memory.ld +LDSCRIPT_M0 += -Tlibopencm3_lpc43xx_m0_ram_only.ld + PREFIX ?= arm-none-eabi CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc @@ -90,9 +96,8 @@ LDFLAGS_COMMON += -mthumb \ -Wl,--gc-sections \ -lc -lnosys CFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 -LDSCRIPT_M0 ?= $(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M0.ld LDFLAGS_M0 += -mcpu=cortex-m0 -DLPC43XX_M0 -LDFLAGS_M0 += -T$(LDSCRIPT_M0) +LDFLAGS_M0 += $(LDSCRIPT_M0) LDFLAGS_M0 += --specs=nano.specs LDFLAGS_M0 += -Xlinker -Map=$(OBJDIR_M0)/m0.map LDFLAGS_M0 += -lopencm3_lpc43xx_m0 @@ -100,7 +105,7 @@ LDFLAGS_M0 += -lopencm3_lpc43xx_m0 CFLAGS_M4 += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX_M4 LDFLAGS_M4 += -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DLPC43XX_M4 LDFLAGS_M4 += -L$(TOOLCHAIN_DIR)/lib/armv7e-m/fpu -LDFLAGS_M4 += -T$(LDSCRIPT_M4) +LDFLAGS_M4 += $(LDSCRIPT_M4) LDFLAGS_M4 += -Xlinker -Map=$(OBJDIR_M4)/m4.map LDFLAGS_M4 += -lopencm3_lpc43xx -lm From a097879528507b677f2b1f1735c00780f026aa93 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 11 Jan 2014 17:49:26 -0800 Subject: [PATCH 194/200] Un-hardcode base address of M0 memory region. --- firmware/common/LPC43xx_M4_M0_image_in_ram.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/LPC43xx_M4_M0_image_in_ram.ld b/firmware/common/LPC43xx_M4_M0_image_in_ram.ld index e07bd79d..53eca09b 100644 --- a/firmware/common/LPC43xx_M4_M0_image_in_ram.ld +++ b/firmware/common/LPC43xx_M4_M0_image_in_ram.ld @@ -22,7 +22,7 @@ SECTIONS { - .m0 0x20000000 : { + .m0 ORIGIN(ram_m0) : { PROVIDE(__m0_start__ = .); KEEP(*(.m0_bin*)); . = ALIGN(4); From ec508cadcd649c83284779668cad6d1671fa6816 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 12 Jan 2014 14:51:54 -0800 Subject: [PATCH 195/200] Fix relative path for libs and ldscripts in linking. --- firmware/common/Makefile_inc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 288b7fc5..cac1af28 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -90,7 +90,7 @@ TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) CFLAGS_COMMON += -std=gnu99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I$(PATH_HACKRF_FIRMWARE_COMMON) \ $(HACKRF_OPTS) -fno-common -mthumb -MD LDFLAGS_COMMON += -mthumb \ - -L../common \ + -L$(PATH_HACKRF_FIRMWARE_COMMON) \ -L$(LIBOPENCM3)/lib -L$(LIBOPENCM3)/lib/lpc43xx \ -nostartfiles \ -Wl,--gc-sections \ From 4aa3a3b5539553e1bc60ecb96a35fdabeec5ebd7 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 14 Feb 2014 10:47:05 -0800 Subject: [PATCH 196/200] Fix M0 ldscript breakage. --- firmware/common/Makefile_inc.mk | 2 +- firmware/libopencm3 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index cac1af28..8bd4b081 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -77,7 +77,7 @@ else endif LDSCRIPT_M0 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M0_memory.ld -LDSCRIPT_M0 += -Tlibopencm3_lpc43xx_m0_ram_only.ld +LDSCRIPT_M0 += -Tlibopencm3_lpc43xx_m0.ld PREFIX ?= arm-none-eabi CC = $(PREFIX)-gcc diff --git a/firmware/libopencm3 b/firmware/libopencm3 index 1cf02283..854c112a 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit 1cf022831031d16b337d9f0d3f7006158132330f +Subproject commit 854c112a0ea7b27e85a15345507c8a2e13e76607 From a51eb9dd60760ad7402dd25c4e812f9abf9203d4 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 14 Feb 2014 10:48:38 -0800 Subject: [PATCH 197/200] Remove usb_bulk_buffer declaration, it was causing duplicate buffers to exist in RAM. Allow ldscript to determine symbol's address by making buffer "extern" only. --- firmware/hackrf_usb/usb_bulk_buffer.c | 6 ------ firmware/hackrf_usb/usb_bulk_buffer.h | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/firmware/hackrf_usb/usb_bulk_buffer.c b/firmware/hackrf_usb/usb_bulk_buffer.c index 9048f49a..9b671e05 100644 --- a/firmware/hackrf_usb/usb_bulk_buffer.c +++ b/firmware/hackrf_usb/usb_bulk_buffer.c @@ -22,11 +22,5 @@ #include "usb_bulk_buffer.h" -/* Address of usb_bulk_buffer is set in ldscripts. If you change the name of this - * variable, it won't be where it needs to be in the processor's address space, - * unless you also adjust the ldscripts. - */ -uint8_t usb_bulk_buffer[32768]; - const uint32_t usb_bulk_buffer_mask = 32768 - 1; volatile uint32_t usb_bulk_buffer_offset = 0; diff --git a/firmware/hackrf_usb/usb_bulk_buffer.h b/firmware/hackrf_usb/usb_bulk_buffer.h index 967bd16c..2acce718 100644 --- a/firmware/hackrf_usb/usb_bulk_buffer.h +++ b/firmware/hackrf_usb/usb_bulk_buffer.h @@ -25,7 +25,12 @@ #include +/* Address of usb_bulk_buffer is set in ldscripts. If you change the name of this + * variable, it won't be where it needs to be in the processor's address space, + * unless you also adjust the ldscripts. + */ extern uint8_t usb_bulk_buffer[32768]; + extern const uint32_t usb_bulk_buffer_mask; extern volatile uint32_t usb_bulk_buffer_offset; From dfd04e3c89a0157a8ed86ac122e39eff85b8016d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Fri, 14 Feb 2014 10:49:11 -0800 Subject: [PATCH 198/200] Change default Makefile target board to HACKRF_ONE. --- firmware/common/Makefile_inc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 8bd4b081..b6d52f66 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -26,7 +26,7 @@ # derived primarily from Makefiles in libopencm3 -BOARD ?= JAWBREAKER +BOARD ?= HACKRF_ONE RUN_FROM ?= SPIFI ifeq ($(BOARD),HACKRF_ONE) From 9797512186dd199a04b8f6a6a24607a26423b74f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 18 Feb 2014 16:48:21 -0800 Subject: [PATCH 199/200] Rename ldscript to be the one and only M0 embedding .ld, reading from .text. --- ...fi.ld => LPC43xx_M4_M0_image_from_text.ld} | 0 firmware/common/LPC43xx_M4_M0_image_in_ram.ld | 31 ------------------- firmware/common/Makefile_inc.mk | 3 +- 3 files changed, 1 insertion(+), 33 deletions(-) rename firmware/common/{LPC43xx_M4_M0_image_from_spifi.ld => LPC43xx_M4_M0_image_from_text.ld} (100%) delete mode 100644 firmware/common/LPC43xx_M4_M0_image_in_ram.ld diff --git a/firmware/common/LPC43xx_M4_M0_image_from_spifi.ld b/firmware/common/LPC43xx_M4_M0_image_from_text.ld similarity index 100% rename from firmware/common/LPC43xx_M4_M0_image_from_spifi.ld rename to firmware/common/LPC43xx_M4_M0_image_from_text.ld diff --git a/firmware/common/LPC43xx_M4_M0_image_in_ram.ld b/firmware/common/LPC43xx_M4_M0_image_in_ram.ld deleted file mode 100644 index 53eca09b..00000000 --- a/firmware/common/LPC43xx_M4_M0_image_in_ram.ld +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012 Michael Ossmann - * Copyright 2012 Jared Boone - * - * This file is part of HackRF - * - * 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, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -SECTIONS -{ - .m0 ORIGIN(ram_m0) : { - PROVIDE(__m0_start__ = .); - KEEP(*(.m0_bin*)); - . = ALIGN(4); - PROVIDE(__m0_end__ = .); - } >ram_m0 -} diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index b6d52f66..e92d8112 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -70,11 +70,10 @@ OBJ_M0_S = $(patsubst %.s, $(OBJDIR_M0)/%.o, $(notdir $(SRC_M0_S))) LDSCRIPT_M4 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/$(MCU_PARTNO)_M4_memory.ld ifeq ($(RUN_FROM),RAM) LDSCRIPT_M4 += -Tlibopencm3_lpc43xx.ld - LDSCRIPT_M4 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M4_M0_image_in_ram.ld else LDSCRIPT_M4 += -Tlibopencm3_lpc43xx_rom_to_ram.ld - LDSCRIPT_M4 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M4_M0_image_from_spifi.ld endif +LDSCRIPT_M4 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M4_M0_image_from_text.ld LDSCRIPT_M0 += -T$(PATH_HACKRF_FIRMWARE_COMMON)/LPC43xx_M0_memory.ld LDSCRIPT_M0 += -Tlibopencm3_lpc43xx_m0.ld From e3025e94ff696ebd969d0d38e03761a86619cfba Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 18 Feb 2014 17:05:53 -0800 Subject: [PATCH 200/200] Apparent fix for .dfu not being generated. TODO: Does not address the fact that make continues despite the .dfu creation failure... --- firmware/common/Makefile_inc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index e92d8112..5e351158 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -135,7 +135,7 @@ $(BINARY).dfu: $(BINARY).bin $(Q)rm -f _tmp.dfu _header.bin $(Q)cp $(BINARY).bin _tmp.dfu $(Q)dfu-suffix --vid=0x1fc9 --pid=0x000c --did=0x0 -s 0 -a _tmp.dfu - $(Q)python -c "import os.path; import struct; print('0000000: da ff ' + ' '.join(map(lambda s: '%02x' % ord(s), struct.pack(' _header.bin + $(Q)python -c "import os.path; import struct; print('0000000: da ff ' + ' '.join(map(lambda s: '%02x' % ord(s), struct.pack(' _header.bin $(Q)cat _header.bin _tmp.dfu >$(BINARY).dfu $(Q)rm -f _tmp.dfu _header.bin