diff --git a/firmware/hackrf_usb/sgpio_m0.s b/firmware/hackrf_usb/sgpio_m0.s index ba5abce7c..1fa0bf6e2 100644 --- a/firmware/hackrf_usb/sgpio_m0.s +++ b/firmware/hackrf_usb/sgpio_m0.s @@ -45,6 +45,8 @@ .equ TARGET_DATA_BUFFER, 0x20000000 .equ BUF_SIZE, 0x10000 .equ BUF_SIZE_MASK, 0xffff +.equ CHUNK_SIZE, 0x4000 +.equ CHUNK_SIZE_MASK, 0x3fff // Base address of the buffer statistics. .ifdef RAD10 @@ -68,6 +70,13 @@ .equ MODE_TX_START, 2 .equ MODE_TX_RUN, 3 +.text +chunk_addresses: + .word TARGET_DATA_BUFFER + (0 * CHUNK_SIZE) + .word TARGET_DATA_BUFFER + (2 * CHUNK_SIZE) + .word TARGET_DATA_BUFFER + (1 * CHUNK_SIZE) + .word TARGET_DATA_BUFFER + (3 * CHUNK_SIZE) + .global main .thumb_func @@ -108,7 +117,7 @@ main: // Cycle counts: // Initialise high registers used for constant values. ldr r0, =BUF_SIZE // 2 mov r11, r0 // 1 - ldr r0, =TARGET_DATA_BUFFER // 2 + ldr r0, =chunk_addresses // 2 mov r10, r0 // 1 // Initialise buffer stats. @@ -142,12 +151,18 @@ loop: str r0, [r7, #INT_CLEAR] // 2 14 // ... and grab the address of the buffer segment we want to write to / read from. - ldr r4, =BUF_SIZE_MASK // r4 = mask // 2 16 - ldr r2, [r5, #M0_COUNT] // r2 = m0_count // 2 18 - and r4, r2, r4 // r4 = position_in_buffer = m0_count & mask // 1 19 - add r4, r10, r4 // r4 = buffer_target = &buffer + position_in_buffer // 1 20 - - mov r8, r2 // r8 = m0_count // 1 21 + ldr r4, =BUF_SIZE_MASK // r4 = buf_size_mask // 2 16 + lsr r3, r4, #2 // r3 = chunk_size_mask = buf_size_mask >> 2 // 1 17 + ldr r2, [r5, #M0_COUNT] // r2 = m0_count // 2 19 + and r4, r2, r4 // r4 = pos_in_buffer = m0_count & buf_size_mask // 1 20 + lsr r0, r4, #14 // r0 = chunk_index = pos_in_buffer >> 14 // 1 21 + lsl r0, #2 // r0 = chunk_index * sizeof(ptr) = chunk_index << 2 // 1 22 + mov r1, r10 // r1 = &chunk_addresses // 1 23 + ldr r0, [r1, r0] // r0 = chunk_address = chunk_addresses[chunk_index] // 2 25 + and r4, r4, r3 // r4 = pos_in_chunk = pos_in_buffer & chunk_size_mask // 1 26 + add r4, r0, r4 // r4 = buffer_target = chunk_address + pos_in_chunk // 1 27 + + mov r8, r2 // r8 = m0_count // 1 28 // Load mode ldr r3, [r5, #MODE] // r3 = mode // 2 23 diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index 7e3d82c29..97ca53dce 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -380,6 +380,13 @@ void transceiver_bulk_transfer_complete(void *user_data, unsigned int bytes_tran usb_bulk_buffer_stats.m4_count += bytes_transferred; } +static uint32_t chunk_offsets[] = { + 0 * USB_BULK_BUFFER_CHUNK_SIZE, + 2 * USB_BULK_BUFFER_CHUNK_SIZE, + 1 * USB_BULK_BUFFER_CHUNK_SIZE, + 3 * USB_BULK_BUFFER_CHUNK_SIZE, +}; + void rx_mode(void) { // Which chunk the M4 last set up to transfer. uint8_t m4_chunk = USB_BULK_BUFFER_NUM_CHUNKS - 1; @@ -397,7 +404,7 @@ void rx_mode(void) { if (m4_next_chunk != m0_chunk) { usb_transfer_schedule_block( &usb_endpoint_bulk_in, - &usb_bulk_buffer[m4_next_chunk * USB_BULK_BUFFER_CHUNK_SIZE], + &usb_bulk_buffer[chunk_offsets[m4_next_chunk]], USB_BULK_BUFFER_CHUNK_SIZE, transceiver_bulk_transfer_complete, NULL @@ -414,7 +421,7 @@ void tx_mode(void) { // Set up OUT transfer of first buffer chunk. usb_transfer_schedule_block( &usb_endpoint_bulk_out, - &usb_bulk_buffer[0], + &usb_bulk_buffer[chunk_offsets[m4_chunk]], USB_BULK_BUFFER_CHUNK_SIZE, transceiver_bulk_transfer_complete, NULL @@ -434,7 +441,7 @@ void tx_mode(void) { if (m4_next_chunk != m0_chunk) { usb_transfer_schedule_block( &usb_endpoint_bulk_out, - &usb_bulk_buffer[m4_next_chunk * USB_BULK_BUFFER_CHUNK_SIZE], + &usb_bulk_buffer[chunk_offsets[m4_next_chunk]], USB_BULK_BUFFER_CHUNK_SIZE, transceiver_bulk_transfer_complete, NULL