Reworked USB code to pump SGPIO with an interrupt.
Relocated USB buffers to be split across two AHB memory regions, so that USB endpoint priming doesn't choke SGPIO transfers. Added code to configure 2.4GHz front-end. Changed USB and SGPIO priority levels (probably unnecessary because sample corruption was due to USB priming bursts).
This commit is contained in:
@ -29,8 +29,11 @@ SRC = $(BINARY).c \
|
|||||||
usb_descriptor.c \
|
usb_descriptor.c \
|
||||||
../common/fault_handler.c \
|
../common/fault_handler.c \
|
||||||
../common/hackrf_core.c \
|
../common/hackrf_core.c \
|
||||||
|
../common/sgpio.c \
|
||||||
../common/si5351c.c \
|
../common/si5351c.c \
|
||||||
../common/bitband.c
|
../common/max2837.c \
|
||||||
|
../common/max5864.c \
|
||||||
|
../common/rffc5071.c
|
||||||
|
|
||||||
LDSCRIPT = ../common/LPC4330_M4_ram_only.ld
|
LDSCRIPT = ../common/LPC4330_M4_ram_only.ld
|
||||||
include ../common/Makefile_inc.mk
|
include ../common/Makefile_inc.mk
|
||||||
|
@ -21,10 +21,15 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <hackrf_core.h>
|
|
||||||
|
|
||||||
#include <libopencm3/lpc43xx/cgu.h>
|
#include <libopencm3/lpc43xx/cgu.h>
|
||||||
#include <libopencm3/lpc43xx/gpio.h>
|
#include <libopencm3/lpc43xx/gpio.h>
|
||||||
|
#include <libopencm3/lpc43xx/nvic.h>
|
||||||
|
#include <libopencm3/lpc43xx/sgpio.h>
|
||||||
|
|
||||||
|
#include <hackrf_core.h>
|
||||||
|
#include <max5864.h>
|
||||||
|
#include <max2837.h>
|
||||||
|
#include <sgpio.h>
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "usb_type.h"
|
#include "usb_type.h"
|
||||||
@ -32,14 +37,55 @@
|
|||||||
#include "usb_descriptor.h"
|
#include "usb_descriptor.h"
|
||||||
#include "usb_standard_request.h"
|
#include "usb_standard_request.h"
|
||||||
|
|
||||||
volatile uint_fast8_t usb_bulk_buffer_index = 0;
|
uint8_t* const usb_bulk_buffer = 0x20004000;
|
||||||
uint8_t usb_bulk_buffer[2][16384] ATTR_SECTION(".usb_data");
|
static volatile uint32_t usb_bulk_buffer_offset = 0;
|
||||||
const uint_fast8_t usb_bulk_buffer_count =
|
static const uint32_t usb_bulk_buffer_mask = 32768 - 1;
|
||||||
sizeof(usb_bulk_buffer) / sizeof(usb_bulk_buffer[0]);
|
|
||||||
|
|
||||||
static void usb_endpoint_bulk_transfer(usb_endpoint_t* const endpoint) {
|
usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64);
|
||||||
usb_endpoint_schedule(endpoint, usb_bulk_buffer[usb_bulk_buffer_index], sizeof(usb_bulk_buffer[usb_bulk_buffer_index]));
|
const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]);
|
||||||
usb_bulk_buffer_index = (usb_bulk_buffer_index + 1) % usb_bulk_buffer_count;
|
|
||||||
|
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 = {
|
usb_configuration_t usb_configuration_high_speed = {
|
||||||
@ -97,7 +143,7 @@ usb_endpoint_t usb_endpoint_bulk_in = {
|
|||||||
.in = &usb_endpoint_bulk_in,
|
.in = &usb_endpoint_bulk_in,
|
||||||
.out = 0,
|
.out = 0,
|
||||||
.setup_complete = 0,
|
.setup_complete = 0,
|
||||||
.transfer_complete = usb_endpoint_bulk_transfer,
|
.transfer_complete = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
usb_endpoint_t usb_endpoint_bulk_out = {
|
usb_endpoint_t usb_endpoint_bulk_out = {
|
||||||
@ -106,7 +152,7 @@ usb_endpoint_t usb_endpoint_bulk_out = {
|
|||||||
.in = 0,
|
.in = 0,
|
||||||
.out = &usb_endpoint_bulk_out,
|
.out = &usb_endpoint_bulk_out,
|
||||||
.setup_complete = 0,
|
.setup_complete = 0,
|
||||||
.transfer_complete = usb_endpoint_bulk_transfer,
|
.transfer_complete = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const usb_request_handlers_t usb_request_handlers = {
|
const usb_request_handlers_t usb_request_handlers = {
|
||||||
@ -157,10 +203,21 @@ bool usb_set_configuration(
|
|||||||
if( device->configuration && (device->configuration->number == 1) ) {
|
if( device->configuration && (device->configuration->number == 1) ) {
|
||||||
usb_endpoint_init(&usb_endpoint_bulk_in);
|
usb_endpoint_init(&usb_endpoint_bulk_in);
|
||||||
usb_endpoint_init(&usb_endpoint_bulk_out);
|
usb_endpoint_init(&usb_endpoint_bulk_out);
|
||||||
|
|
||||||
|
usb_init_buffers_bulk();
|
||||||
|
|
||||||
usb_endpoint_bulk_transfer(&usb_endpoint_bulk_out);
|
sgpio_configure_for_rx_deep();
|
||||||
//usb_endpoint_bulk_transfer(&usb_endpoint_bulk_in);
|
|
||||||
|
nvic_set_priority(NVIC_M4_SGPIO_IRQ, 0);
|
||||||
|
nvic_enable_irq(NVIC_M4_SGPIO_IRQ);
|
||||||
|
SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A);
|
||||||
|
|
||||||
|
sgpio_cpld_stream_enable();
|
||||||
} else {
|
} else {
|
||||||
|
sgpio_cpld_stream_disable();
|
||||||
|
|
||||||
|
nvic_disable_irq(NVIC_M4_SGPIO_IRQ);
|
||||||
|
|
||||||
usb_endpoint_disable(&usb_endpoint_bulk_in);
|
usb_endpoint_disable(&usb_endpoint_bulk_in);
|
||||||
usb_endpoint_disable(&usb_endpoint_bulk_out);
|
usb_endpoint_disable(&usb_endpoint_bulk_out);
|
||||||
}
|
}
|
||||||
@ -175,7 +232,45 @@ bool usb_set_configuration(
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void sgpio_irqhandler() {
|
||||||
|
SGPIO_CLR_STATUS_1 = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
uint32_t* const p32 = &usb_bulk_buffer[usb_bulk_buffer_offset];
|
||||||
|
volatile const uint32_t* const sgpio_reg_ss_base = SGPIO_PORT_BASE + 0x100;
|
||||||
|
|
||||||
|
__asm__(
|
||||||
|
"ldr r0, [%[sgpio_reg_ss_base], #0]\n\t" // Slice A -> p_local[7]
|
||||||
|
"ldr r1, [%[sgpio_reg_ss_base], #32]\n\t" // Slice I -> p_local[6]
|
||||||
|
"ldr r2, [%[sgpio_reg_ss_base], #16]\n\t" // Slice E -> p_local[5]
|
||||||
|
"ldr r3, [%[sgpio_reg_ss_base], #36]\n\t" // Slice J -> p_local[4]
|
||||||
|
|
||||||
|
"str r0, [%[p], #28]\n\t"
|
||||||
|
"str r1, [%[p], #24]\n\t"
|
||||||
|
"str r2, [%[p], #20]\n\t"
|
||||||
|
"str r3, [%[p], #16]\n\t"
|
||||||
|
|
||||||
|
"ldr r0, [%[sgpio_reg_ss_base], #8]\n\t" // Slice C -> p_local[3]
|
||||||
|
"ldr r1, [%[sgpio_reg_ss_base], #40]\n\t" // Slice K -> p_local[2]
|
||||||
|
"ldr r2, [%[sgpio_reg_ss_base], #20]\n\t" // Slice F -> p_local[1]
|
||||||
|
"ldr r3, [%[sgpio_reg_ss_base], #44]\n\t" // Slice L -> p_local[0]
|
||||||
|
|
||||||
|
"str r0, [%[p], #12]\n\t"
|
||||||
|
"str r1, [%[p], #8]\n\t"
|
||||||
|
"str r2, [%[p], #4]\n\t"
|
||||||
|
"str r3, [%[p], #0]\n\t"
|
||||||
|
:
|
||||||
|
: [sgpio_reg_ss_base] "l" (sgpio_reg_ss_base),
|
||||||
|
[p] "l" (p32)
|
||||||
|
: "r0", "r1", "r2", "r3"
|
||||||
|
);
|
||||||
|
|
||||||
|
usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
const uint32_t freq = 2441000000U;
|
||||||
|
uint8_t switchctrl = 0;
|
||||||
|
|
||||||
pin_setup();
|
pin_setup();
|
||||||
enable_1v8_power();
|
enable_1v8_power();
|
||||||
cpu_clock_init();
|
cpu_clock_init();
|
||||||
@ -193,9 +288,33 @@ int main(void) {
|
|||||||
usb_endpoint_init(&usb_endpoint_control_out);
|
usb_endpoint_init(&usb_endpoint_control_out);
|
||||||
usb_endpoint_init(&usb_endpoint_control_in);
|
usb_endpoint_init(&usb_endpoint_control_in);
|
||||||
|
|
||||||
|
nvic_set_priority(NVIC_M4_USB0_IRQ, 255);
|
||||||
|
|
||||||
usb_run(&usb_device);
|
usb_run(&usb_device);
|
||||||
|
|
||||||
while (1) {
|
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, 0); // 500 MHz, 0 Hz (Hz ignored)
|
||||||
|
*/
|
||||||
|
max2837_set_frequency(freq);
|
||||||
|
max2837_start();
|
||||||
|
max2837_rx();
|
||||||
|
ssp1_set_mode_max5864();
|
||||||
|
max5864_xcvr();
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
while( usb_bulk_buffer_offset < 16384 );
|
||||||
|
usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]);
|
||||||
|
|
||||||
|
while( usb_bulk_buffer_offset >= 16384 );
|
||||||
|
usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user