mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2024-12-13 03:34:35 +00:00
commit
ecbb232d9c
@ -235,6 +235,7 @@ set(CPPSRC
|
||||
apps/ui_encoders.cpp
|
||||
apps/ui_fileman.cpp
|
||||
apps/ui_flash_utility.cpp
|
||||
apps/ui_sd_over_usb.cpp
|
||||
apps/ui_freqman.cpp
|
||||
apps/ui_jammer.cpp
|
||||
apps/ui_keyfob.cpp
|
||||
|
62
firmware/application/apps/ui_sd_over_usb.cpp
Normal file
62
firmware/application/apps/ui_sd_over_usb.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 "ui_sd_over_usb.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
SdOverUsbView::SdOverUsbView(NavigationView& nav) : nav_ (nav) {
|
||||
add_children({
|
||||
&labels,
|
||||
&button_run
|
||||
});
|
||||
|
||||
button_run.on_select = [this](Button&) {
|
||||
ui::Painter painter;
|
||||
painter.fill_rectangle(
|
||||
{ 0, 0, portapack::display.width(), portapack::display.height() },
|
||||
ui::Color::black()
|
||||
);
|
||||
|
||||
painter.draw_bitmap(
|
||||
{ portapack::display.width()/2-8, portapack::display.height()/2-8 },
|
||||
bitmap_icon_hackrf,
|
||||
ui::Color::yellow(),
|
||||
ui::Color::black()
|
||||
);
|
||||
|
||||
sdcDisconnect(&SDCD1);
|
||||
sdcStop(&SDCD1);
|
||||
|
||||
portapack::shutdown(true);
|
||||
m4_init(portapack::spi_flash::image_tag_usb_sd, portapack::memory::map::m4_code, false);
|
||||
m0_halt();
|
||||
/* will not return*/
|
||||
};
|
||||
}
|
||||
|
||||
void SdOverUsbView::focus() {
|
||||
button_run.focus();
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
64
firmware/application/apps/ui_sd_over_usb.hpp
Normal file
64
firmware/application/apps/ui_sd_over_usb.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 __UI_SD_OVER_USB_H__
|
||||
#define __UI_SD_OVER_USB_H__
|
||||
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "string_format.hpp"
|
||||
#include "ff.h"
|
||||
#include "baseband_api.hpp"
|
||||
#include "core_control.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ui {
|
||||
|
||||
class SdOverUsbView : public View {
|
||||
public:
|
||||
SdOverUsbView(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Flash Utility"; };
|
||||
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
|
||||
Labels labels {
|
||||
{ { 3 * 8, 2 * 16 }, "Click Run to start the", Color::white() },
|
||||
{ { 3 * 8, 3 * 16 }, "USB Mass Storage Mode.", Color::white() },
|
||||
{ { 3 * 8, 5 * 16 }, "It can take up to 20s", Color::white() },
|
||||
{ { 3 * 8, 6 * 16 }, "for the drive to be", Color::white() },
|
||||
{ { 3 * 8, 7 * 16 }, "available.", Color::white() },
|
||||
};
|
||||
|
||||
Button button_run {
|
||||
{ 9 * 8, 15 * 16, 12 * 8, 3 * 16 },
|
||||
"Run"
|
||||
};
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
#endif /*__UI_SD_OVER_USB_H__*/
|
@ -515,11 +515,13 @@ bool init() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
void shutdown(const bool leave_screen_on) {
|
||||
gpdma::controller.disable();
|
||||
|
||||
backlight()->off();
|
||||
display.shutdown();
|
||||
if (!leave_screen_on) {
|
||||
backlight()->off();
|
||||
display.shutdown();
|
||||
}
|
||||
|
||||
radio::disable();
|
||||
audio::shutdown();
|
||||
|
@ -63,7 +63,7 @@ void set_antenna_bias(const bool v);
|
||||
bool get_antenna_bias();
|
||||
|
||||
bool init();
|
||||
void shutdown();
|
||||
void shutdown(const bool leave_screen_on = false);
|
||||
|
||||
Backlight* backlight();
|
||||
|
||||
|
@ -71,6 +71,7 @@
|
||||
#include "ui_view_wav.hpp"
|
||||
#include "ui_whipcalc.hpp"
|
||||
#include "ui_flash_utility.hpp"
|
||||
#include "ui_sd_over_usb.hpp"
|
||||
|
||||
//#include "acars_app.hpp"
|
||||
#include "ais_app.hpp"
|
||||
@ -614,8 +615,8 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) {
|
||||
{ "Antenna length", ui::Color::green(), &bitmap_icon_tools_antenna, [&nav](){ nav.push<WhipCalcView>(); } },
|
||||
|
||||
{ "Wipe SD card", ui::Color::red(), &bitmap_icon_tools_wipesd, [&nav](){ nav.push<WipeSDView>(); } },
|
||||
{ "Flash Utility", ui::Color::red(), &bitmap_icon_temperature, [&nav](){ nav.push<FlashUtilityView>(); } },
|
||||
|
||||
{ "Flash Utility", ui::Color::red(), &bitmap_icon_temperature, [&nav](){ nav.push<FlashUtilityView>(); } },
|
||||
{ "SD over USB", ui::Color::yellow(), &bitmap_icon_hackrf, [&nav](){ nav.push<SdOverUsbView>(); } },
|
||||
});
|
||||
set_max_rows(2); // allow wider buttons
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ set(AOPT)
|
||||
set(TOPT "-mthumb -DTHUMB")
|
||||
|
||||
# Define C warning options here
|
||||
set(CWARN "-Wall -Wextra -Wstrict-prototypes")
|
||||
set(CWARN "-Wall -Wextra")
|
||||
|
||||
# Define C++ warning options here
|
||||
set(CPPWARN "-Wall -Wextra")
|
||||
@ -515,6 +515,53 @@ set(MODE_CPPSRC
|
||||
)
|
||||
DeclareTargets(PFUT flash_utility)
|
||||
|
||||
### SD over USB
|
||||
|
||||
set(MODE_INCDIR
|
||||
${HACKRF_PATH}/firmware
|
||||
${HACKRF_PATH}/firmware/common
|
||||
${HACKRF_PATH}/firmware/libopencm3/include
|
||||
)
|
||||
set(MODE_CPPSRC
|
||||
sd_over_usb/proc_sd_over_usb.cpp
|
||||
|
||||
sd_over_usb/scsi.c
|
||||
sd_over_usb/diskio.c
|
||||
sd_over_usb/sd_over_usb.c
|
||||
sd_over_usb/usb_descriptor.c
|
||||
sd_over_usb/hackrf_core.c
|
||||
|
||||
${HACKRF_PATH}/firmware/common/usb.c
|
||||
${HACKRF_PATH}/firmware/common/usb_queue.c
|
||||
${HACKRF_PATH}/firmware/hackrf_usb/usb_device.c
|
||||
${HACKRF_PATH}/firmware/hackrf_usb/usb_endpoint.c
|
||||
${HACKRF_PATH}/firmware/common/usb_request.c
|
||||
${HACKRF_PATH}/firmware/common/usb_standard_request.c
|
||||
${HACKRF_PATH}/firmware/common/platform_detect.c
|
||||
${HACKRF_PATH}/firmware/common/gpio_lpc.c
|
||||
${HACKRF_PATH}/firmware/common/firmware_info.c
|
||||
${HACKRF_PATH}/firmware/common/si5351c.c
|
||||
${HACKRF_PATH}/firmware/common/i2c_bus.c
|
||||
${HACKRF_PATH}/firmware/common/mixer.c
|
||||
${HACKRF_PATH}/firmware/common/clkin.c
|
||||
${HACKRF_PATH}/firmware/common/spi_bus.c
|
||||
${HACKRF_PATH}/firmware/common/sgpio.c
|
||||
${HACKRF_PATH}/firmware/common/rf_path.c
|
||||
${HACKRF_PATH}/firmware/common/i2c_lpc.c
|
||||
${HACKRF_PATH}/firmware/common/spi_ssp.c
|
||||
${HACKRF_PATH}/firmware/common/rffc5071_spi.c
|
||||
${HACKRF_PATH}/firmware/common/rffc5071.c
|
||||
${HACKRF_PATH}/firmware/common/clkin.c
|
||||
${HACKRF_PATH}/firmware/common/gpdma.c
|
||||
|
||||
${HACKRF_PATH}/firmware/libopencm3/lib/cm3/nvic.c
|
||||
${HACKRF_PATH}/firmware/libopencm3/lib/cm3/sync.c
|
||||
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/scu.c
|
||||
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/timer.c
|
||||
${HACKRF_PATH}/firmware/libopencm3/lib/lpc43xx/i2c.c
|
||||
)
|
||||
DeclareTargets(PUSB sd_over_usb)
|
||||
|
||||
### HackRF "factory" firmware
|
||||
|
||||
add_custom_command(
|
||||
|
@ -119,7 +119,7 @@
|
||||
* @brief Enables the SDC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
|
||||
#ifdef BASEBAND_flash_utility
|
||||
#if defined(BASEBAND_flash_utility) || defined(BASEBAND_sd_over_usb)
|
||||
#define HAL_USE_SDC TRUE
|
||||
#else
|
||||
#define HAL_USE_SDC FALSE
|
||||
|
38
firmware/baseband/sd_over_usb/diskio.c
Normal file
38
firmware/baseband/sd_over_usb/diskio.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 "diskio.h"
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
uint32_t get_capacity(void) {
|
||||
return mmcsdGetCardCapacity(&SDCD1);
|
||||
}
|
||||
|
||||
bool_t read_block(uint32_t startblk, uint8_t *buf, uint32_t n) {
|
||||
return sdcRead(&SDCD1, startblk, buf, n);
|
||||
}
|
||||
|
||||
bool_t write_block(uint32_t startblk, uint8_t *buf, uint32_t n) {
|
||||
return sdcWrite(&SDCD1, startblk, buf, n);
|
||||
}
|
33
firmware/baseband/sd_over_usb/diskio.h
Normal file
33
firmware/baseband/sd_over_usb/diskio.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 __DISKIO_H__
|
||||
#define __DISKIO_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <chtypes.h>
|
||||
|
||||
uint32_t get_capacity(void);
|
||||
bool_t read_block(uint32_t startblk, uint8_t *buf, uint32_t n);
|
||||
bool_t write_block(uint32_t startblk, uint8_t *buf, uint32_t n);
|
||||
|
||||
#endif /* __DISKIO_H__ */
|
1084
firmware/baseband/sd_over_usb/hackrf_core.c
Normal file
1084
firmware/baseband/sd_over_usb/hackrf_core.c
Normal file
File diff suppressed because it is too large
Load Diff
47
firmware/baseband/sd_over_usb/proc_sd_over_usb.cpp
Normal file
47
firmware/baseband/sd_over_usb/proc_sd_over_usb.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
extern "C" {
|
||||
void start_usb(void);
|
||||
void irq_usb(void);
|
||||
void usb_transfer(void);
|
||||
|
||||
CH_IRQ_HANDLER(Vector60) {
|
||||
irq_usb();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
sdcStart(&SDCD1, nullptr);
|
||||
if (sdcConnect(&SDCD1) == CH_FAILED) chDbgPanic("no sd card #1");
|
||||
|
||||
start_usb();
|
||||
|
||||
while (true) {
|
||||
usb_transfer();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
274
firmware/baseband/sd_over_usb/scsi.c
Normal file
274
firmware/baseband/sd_over_usb/scsi.c
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 "scsi.h"
|
||||
#include "diskio.h"
|
||||
|
||||
volatile bool usb_bulk_block_done = false;
|
||||
|
||||
void usb_bulk_block_cb(void* user_data, unsigned int bytes_transferred) {
|
||||
usb_bulk_block_done = true;
|
||||
|
||||
(void)user_data;
|
||||
(void)bytes_transferred;
|
||||
}
|
||||
|
||||
void usb_send_bulk(void* const data, const uint32_t maximum_length) {
|
||||
usb_bulk_block_done = false;
|
||||
|
||||
usb_transfer_schedule_block(
|
||||
&usb_endpoint_bulk_in,
|
||||
data,
|
||||
maximum_length,
|
||||
usb_bulk_block_cb,
|
||||
NULL);
|
||||
|
||||
while (!usb_bulk_block_done);
|
||||
}
|
||||
|
||||
void usb_receive_bulk(void* const data, const uint32_t maximum_length) {
|
||||
usb_bulk_block_done = false;
|
||||
|
||||
usb_transfer_schedule_block(
|
||||
&usb_endpoint_bulk_out,
|
||||
data,
|
||||
maximum_length,
|
||||
usb_bulk_block_cb,
|
||||
NULL);
|
||||
|
||||
while (!usb_bulk_block_done);
|
||||
}
|
||||
|
||||
void usb_send_csw(msd_cbw_t *msd_cbw_data, uint8_t status) {
|
||||
msd_csw_t csw = {
|
||||
.signature = MSD_CSW_SIGNATURE,
|
||||
.tag = msd_cbw_data->tag,
|
||||
.data_residue = 0,
|
||||
.status = status
|
||||
};
|
||||
|
||||
memcpy(&usb_bulk_buffer[0], &csw, sizeof(msd_csw_t));
|
||||
usb_send_bulk(&usb_bulk_buffer[0], sizeof(msd_csw_t));
|
||||
}
|
||||
|
||||
uint8_t handle_inquiry(msd_cbw_t *msd_cbw_data) {
|
||||
(void)msd_cbw_data;
|
||||
|
||||
scsi_inquiry_response_t ret = {
|
||||
0x00, /* direct access block device */
|
||||
0x80, /* removable */
|
||||
0x00, //0x04, /* SPC-2 */
|
||||
0x00, //0x02, /* response data format */
|
||||
0x20, /* response has 0x20 + 4 bytes */
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
"Mayhem",
|
||||
"Portapack MSD",
|
||||
{'v','1','.','6'}
|
||||
};
|
||||
|
||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_inquiry_response_t));
|
||||
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_inquiry_response_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t handle_inquiry_serial_number(msd_cbw_t *msd_cbw_data) {
|
||||
(void)msd_cbw_data;
|
||||
|
||||
scsi_unit_serial_number_inquiry_response_t ret = {
|
||||
.peripheral = 0x00,
|
||||
.page_code = 0x80,
|
||||
.reserved = 0,
|
||||
.page_length = 0x08,
|
||||
.serialNumber = "Mayhem"
|
||||
};
|
||||
|
||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_unit_serial_number_inquiry_response_t));
|
||||
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_unit_serial_number_inquiry_response_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t read_format_capacities(msd_cbw_t *msd_cbw_data) {
|
||||
uint16_t len = msd_cbw_data->cmd_data[7] << 8 | msd_cbw_data->cmd_data[8];
|
||||
|
||||
if (len != 0) {
|
||||
size_t num_blocks = get_capacity();
|
||||
|
||||
scsi_read_format_capacities_response_t ret = {
|
||||
.header = {0, 0, 0, 1 * 8 /* num_entries * 8 */},
|
||||
.blocknum = {((num_blocks) >> 24)& 0xff, ((num_blocks) >> 16)& 0xff, ((num_blocks) >> 8)& 0xff, num_blocks & 0xff},
|
||||
.blocklen = {0b10 /* formated */, 0, (512) >> 8, 0},
|
||||
};
|
||||
|
||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_read_format_capacities_response_t));
|
||||
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_read_format_capacities_response_t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t read_capacity10(msd_cbw_t *msd_cbw_data) {
|
||||
(void)msd_cbw_data;
|
||||
|
||||
size_t num_blocks = get_capacity();
|
||||
|
||||
scsi_read_capacity10_response_t ret = {
|
||||
.last_block_addr = cpu_to_be32(num_blocks - 1),
|
||||
.block_size = cpu_to_be32(512)
|
||||
};
|
||||
|
||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_read_capacity10_response_t));
|
||||
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_read_capacity10_response_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t request_sense(msd_cbw_t *msd_cbw_data) {
|
||||
(void)msd_cbw_data;
|
||||
|
||||
scsi_sense_response_t ret = {
|
||||
.byte = { 0x70, 0, SCSI_SENSE_KEY_GOOD, 0,
|
||||
0, 0, 0, 8,
|
||||
0, 0 ,0 ,0,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION, SCSI_ASENSEQ_NO_QUALIFIER, 0, 0,
|
||||
0, 0 }
|
||||
};
|
||||
|
||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_sense_response_t));
|
||||
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_sense_response_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t mode_sense6(msd_cbw_t *msd_cbw_data) {
|
||||
(void)msd_cbw_data;
|
||||
|
||||
scsi_mode_sense6_response_t ret = {
|
||||
.byte = {
|
||||
sizeof(scsi_mode_sense6_response_t) - 1,
|
||||
0,
|
||||
0,
|
||||
0 }
|
||||
};
|
||||
|
||||
memcpy(&usb_bulk_buffer[0], &ret, sizeof(scsi_mode_sense6_response_t));
|
||||
usb_send_bulk(&usb_bulk_buffer[0], sizeof(scsi_mode_sense6_response_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static data_request_t decode_data_request(const uint8_t *cmd) {
|
||||
data_request_t req;
|
||||
uint32_t lba;
|
||||
uint16_t blk;
|
||||
|
||||
memcpy(&lba, &cmd[2], sizeof(lba));
|
||||
memcpy(&blk, &cmd[7], sizeof(blk));
|
||||
|
||||
req.first_lba = be32_to_cpu(lba);
|
||||
req.blk_cnt = be16_to_cpu(blk);
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
uint8_t data_read10(msd_cbw_t *msd_cbw_data) {
|
||||
data_request_t req = decode_data_request(msd_cbw_data->cmd_data);
|
||||
|
||||
for (size_t block_index = 0; block_index < req.blk_cnt; block_index++) {
|
||||
read_block(req.first_lba + block_index, &usb_bulk_buffer[0], 1 /* n blocks */);
|
||||
usb_send_bulk(&usb_bulk_buffer[0], 512);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t data_write10(msd_cbw_t *msd_cbw_data) {
|
||||
data_request_t req = decode_data_request(msd_cbw_data->cmd_data);
|
||||
|
||||
for (size_t block_index = 0; block_index < req.blk_cnt; block_index++) {
|
||||
usb_receive_bulk(&usb_bulk_buffer[0], 512);
|
||||
write_block(req.first_lba + block_index, &usb_bulk_buffer[0], 1 /* n blocks */);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scsi_command(msd_cbw_t *msd_cbw_data) {
|
||||
uint8_t status = 1;
|
||||
|
||||
switch (msd_cbw_data->cmd_data[0]) {
|
||||
case SCSI_CMD_INQUIRY:
|
||||
if ((msd_cbw_data->cmd_data[1] & 0b1) && msd_cbw_data->cmd_data[2] == 0x80) {
|
||||
status = handle_inquiry_serial_number(msd_cbw_data);
|
||||
}
|
||||
else if ((msd_cbw_data->cmd_data[1] & 0b11) || msd_cbw_data->cmd_data[2] != 0) {
|
||||
status = 1;
|
||||
}
|
||||
else {
|
||||
status = handle_inquiry(msd_cbw_data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCSI_CMD_REQUEST_SENSE:
|
||||
status = request_sense(msd_cbw_data);
|
||||
break;
|
||||
|
||||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
status = read_capacity10(msd_cbw_data);
|
||||
break;
|
||||
|
||||
case SCSI_CMD_READ_10:
|
||||
status = data_read10(msd_cbw_data);
|
||||
break;
|
||||
|
||||
case SCSI_CMD_WRITE_10:
|
||||
status = data_write10(msd_cbw_data);
|
||||
break;
|
||||
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
case SCSI_CMD_MODE_SENSE_6:
|
||||
status = mode_sense6(msd_cbw_data);
|
||||
break;
|
||||
|
||||
case SCSI_CMD_READ_FORMAT_CAPACITIES:
|
||||
status = read_format_capacities(msd_cbw_data);
|
||||
break;
|
||||
|
||||
case SCSI_CMD_VERIFY_10:
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
usb_send_csw(msd_cbw_data, status);
|
||||
}
|
197
firmware/baseband/sd_over_usb/scsi.h
Normal file
197
firmware/baseband/sd_over_usb/scsi.h
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 __SCSI_H__
|
||||
#define __SCSI_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <common/usb.h>
|
||||
#include <common/usb_request.h>
|
||||
#include <common/usb_standard_request.h>
|
||||
#include <hackrf_usb/usb_device.h>
|
||||
#include <hackrf_usb/usb_endpoint.h>
|
||||
#include <libopencm3/lpc43xx/m4/nvic.h>
|
||||
#include <libopencm3/lpc43xx/cgu.h>
|
||||
#include "platform_detect.h"
|
||||
#include "hackrf_core.h"
|
||||
#include "usb_bulk_buffer.h"
|
||||
|
||||
#define MSD_CBW_SIGNATURE 0x43425355
|
||||
#define MSD_CSW_SIGNATURE 0x53425355
|
||||
|
||||
#define SCSI_CMD_TEST_UNIT_READY 0x00
|
||||
#define SCSI_CMD_REQUEST_SENSE 0x03
|
||||
#define SCSI_CMD_INQUIRY 0x12
|
||||
#define SCSI_CMD_MODE_SENSE_6 0x1A
|
||||
#define SCSI_CMD_START_STOP_UNIT 0x1B
|
||||
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
|
||||
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
|
||||
#define SCSI_CMD_READ_CAPACITY_10 0x25
|
||||
#define SCSI_CMD_READ_FORMAT_CAPACITIES 0x23
|
||||
#define SCSI_CMD_READ_10 0x28
|
||||
#define SCSI_CMD_WRITE_10 0x2A
|
||||
#define SCSI_CMD_VERIFY_10 0x2F
|
||||
|
||||
#define SCSI_SENSE_KEY_GOOD 0x00
|
||||
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
||||
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
||||
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
||||
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
||||
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
||||
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
||||
|
||||
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
|
||||
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
|
||||
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
|
||||
#define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28
|
||||
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
|
||||
#define SCSI_ASENSE_FORMAT_ERROR 0x31
|
||||
#define SCSI_ASENSE_INVALID_COMMAND 0x20
|
||||
#define SCSI_ASENSE_LBA_OUT_OF_RANGE 0x21
|
||||
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
|
||||
|
||||
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
|
||||
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
|
||||
#define SCSI_ASENSEQ_INIT_COMMAND_REQUIRED 0x02
|
||||
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
|
||||
|
||||
#define MSD_CBW_SIGNATURE 0x43425355
|
||||
#define MSD_CSW_SIGNATURE 0x53425355
|
||||
|
||||
#define USB_TRANSFER_SIZE 0x2000
|
||||
|
||||
typedef struct {
|
||||
uint32_t signature;
|
||||
uint32_t tag;
|
||||
uint32_t data_len;
|
||||
uint8_t flags;
|
||||
uint8_t lun;
|
||||
uint8_t cmd_len;
|
||||
uint8_t cmd_data[16];
|
||||
} __attribute__((packed)) msd_cbw_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t peripheral;
|
||||
uint8_t removable;
|
||||
uint8_t version;
|
||||
uint8_t response_data_format;
|
||||
uint8_t additional_length;
|
||||
uint8_t sccstp;
|
||||
uint8_t bqueetc;
|
||||
uint8_t cmdque;
|
||||
uint8_t vendorID[8];
|
||||
uint8_t productID[16];
|
||||
uint8_t productRev[4];
|
||||
} scsi_inquiry_response_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t signature;
|
||||
uint32_t tag;
|
||||
uint32_t data_residue;
|
||||
uint8_t status;
|
||||
} __attribute__((packed)) msd_csw_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t header[4];
|
||||
uint8_t blocknum[4];
|
||||
uint8_t blocklen[4];
|
||||
} scsi_read_format_capacities_response_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t last_block_addr;
|
||||
uint32_t block_size;
|
||||
} scsi_read_capacity10_response_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t byte[18];
|
||||
} scsi_sense_response_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t byte[4];
|
||||
} scsi_mode_sense6_response_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t first_lba;
|
||||
uint16_t blk_cnt;
|
||||
} data_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t peripheral;
|
||||
uint8_t page_code;
|
||||
uint8_t reserved;
|
||||
uint8_t page_length;
|
||||
uint8_t serialNumber[8];
|
||||
} scsi_unit_serial_number_inquiry_response_t;
|
||||
|
||||
static inline uint16_t bswap_16(const uint16_t x)
|
||||
__attribute__ ((warn_unused_result))
|
||||
__attribute__ ((const))
|
||||
__attribute__ ((always_inline));
|
||||
|
||||
static inline uint16_t bswap_16(const uint16_t x) {
|
||||
uint8_t tmp;
|
||||
union { uint16_t x; uint8_t b[2]; } data;
|
||||
|
||||
data.x = x;
|
||||
tmp = data.b[0];
|
||||
data.b[0] = data.b[1];
|
||||
data.b[1] = tmp;
|
||||
|
||||
return data.x;
|
||||
}
|
||||
|
||||
static inline uint32_t bswap_32(const uint32_t x)
|
||||
__attribute__ ((warn_unused_result))
|
||||
__attribute__ ((const))
|
||||
__attribute__ ((always_inline));
|
||||
|
||||
static inline uint32_t bswap_32(const uint32_t x) {
|
||||
uint8_t tmp;
|
||||
union { uint32_t x; uint8_t b[4]; } data;
|
||||
|
||||
data.x = x;
|
||||
tmp = data.b[0];
|
||||
data.b[0] = data.b[3];
|
||||
data.b[3] = tmp;
|
||||
tmp = data.b[1];
|
||||
data.b[1] = data.b[2];
|
||||
data.b[2] = tmp;
|
||||
|
||||
return data.x;
|
||||
}
|
||||
|
||||
#define be16_to_cpu(x) bswap_16(x)
|
||||
#define be32_to_cpu(x) bswap_32(x)
|
||||
|
||||
#define cpu_to_be16(x) bswap_16(x)
|
||||
#define cpu_to_be32(x) bswap_32(x)
|
||||
|
||||
void scsi_command(msd_cbw_t *msd_cbw_data);
|
||||
|
||||
#endif /* __SCSI_H__ */
|
132
firmware/baseband/sd_over_usb/sd_over_usb.c
Normal file
132
firmware/baseband/sd_over_usb/sd_over_usb.c
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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 "sd_over_usb.h"
|
||||
#include "scsi.h"
|
||||
|
||||
bool scsi_running = false;
|
||||
|
||||
usb_request_status_t report_max_lun(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP) {
|
||||
endpoint->buffer[0] = 0;
|
||||
usb_transfer_schedule_block(
|
||||
endpoint->in,
|
||||
&endpoint->buffer,
|
||||
1,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
usb_transfer_schedule_ack(endpoint->out);
|
||||
|
||||
scsi_running = true;
|
||||
}
|
||||
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
|
||||
usb_request_status_t usb_class_request(usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) {
|
||||
usb_request_status_t status = USB_REQUEST_STATUS_STALL;
|
||||
|
||||
volatile uint8_t request = endpoint->setup.request;
|
||||
|
||||
if (request == 0xFE)
|
||||
return report_max_lun(endpoint, stage);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
const usb_request_handlers_t usb_request_handlers = {
|
||||
.standard = usb_standard_request,
|
||||
.class = usb_class_request,
|
||||
.vendor = 0,
|
||||
.reserved = 0
|
||||
};
|
||||
|
||||
void usb_configuration_changed(usb_device_t* const device) {
|
||||
(void)device;
|
||||
|
||||
usb_endpoint_init(&usb_endpoint_bulk_in);
|
||||
usb_endpoint_init(&usb_endpoint_bulk_out);
|
||||
}
|
||||
|
||||
void start_usb(void) {
|
||||
detect_hardware_platform();
|
||||
pin_setup();
|
||||
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);
|
||||
|
||||
nvic_set_priority(NVIC_USB0_IRQ, 255);
|
||||
|
||||
usb_run(&usb_device);
|
||||
}
|
||||
|
||||
void stop_usb(void) {
|
||||
usb_peripheral_reset();
|
||||
}
|
||||
|
||||
void irq_usb(void) {
|
||||
usb0_isr();
|
||||
}
|
||||
|
||||
volatile bool transfer_complete = false;
|
||||
void scsi_bulk_transfer_complete(void* user_data, unsigned int bytes_transferred)
|
||||
{
|
||||
(void)user_data;
|
||||
(void)bytes_transferred;
|
||||
|
||||
transfer_complete = true;
|
||||
}
|
||||
|
||||
void usb_transfer(void) {
|
||||
if (scsi_running) {
|
||||
transfer_complete = false;
|
||||
usb_transfer_schedule_block(
|
||||
&usb_endpoint_bulk_out,
|
||||
&usb_bulk_buffer[0x4000],
|
||||
USB_TRANSFER_SIZE,
|
||||
scsi_bulk_transfer_complete,
|
||||
NULL);
|
||||
|
||||
while (!transfer_complete);
|
||||
|
||||
msd_cbw_t *msd_cbw_data = (msd_cbw_t *) &usb_bulk_buffer[0x4000];
|
||||
|
||||
if (msd_cbw_data->signature == MSD_CBW_SIGNATURE){
|
||||
scsi_command(msd_cbw_data);
|
||||
}
|
||||
}
|
||||
}
|
43
firmware/baseband/sd_over_usb/sd_over_usb.h
Normal file
43
firmware/baseband/sd_over_usb/sd_over_usb.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* 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_SD_OVER_USB_H__
|
||||
#define __USB_SD_OVER_USB_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <common/usb.h>
|
||||
#include <common/usb_request.h>
|
||||
#include <common/usb_standard_request.h>
|
||||
#include <hackrf_usb/usb_device.h>
|
||||
#include <hackrf_usb/usb_endpoint.h>
|
||||
#include <libopencm3/lpc43xx/m4/nvic.h>
|
||||
#include <libopencm3/lpc43xx/cgu.h>
|
||||
#include "platform_detect.h"
|
||||
#include "hackrf_core.h"
|
||||
#include "usb_bulk_buffer.h"
|
||||
|
||||
void start_usb(void);
|
||||
void stop_usb(void);
|
||||
void irq_usb(void);
|
||||
void usb_transfer(void);
|
||||
|
||||
#endif /* __USB_SD_OVER_USB_H__ */
|
39
firmware/baseband/sd_over_usb/usb_bulk_buffer.h
Normal file
39
firmware/baseband/sd_over_usb/usb_bulk_buffer.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012-2022 Great Scott Gadgets <info@greatscottgadgets.com>
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define USB_BULK_BUFFER_SIZE 0x8000
|
||||
#define USB_BULK_BUFFER_MASK 0x7FFF
|
||||
|
||||
/* 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[USB_BULK_BUFFER_SIZE];
|
||||
|
||||
#endif /*__USB_BULK_BUFFER_H__*/
|
322
firmware/baseband/sd_over_usb/usb_descriptor.c
Normal file
322
firmware/baseband/sd_over_usb/usb_descriptor.c
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright 2012-2022 Great Scott Gadgets <info@greatscottgadgets.com>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "usb_type.h"
|
||||
#include "usb_descriptor.h"
|
||||
|
||||
#define USB_VENDOR_ID (0x1D50)
|
||||
|
||||
#ifdef HACKRF_ONE
|
||||
#define USB_PRODUCT_ID (0x6089)
|
||||
#elif JAWBREAKER
|
||||
#define USB_PRODUCT_ID (0x604B)
|
||||
#elif RAD1O
|
||||
#define USB_PRODUCT_ID (0xCC15)
|
||||
#else
|
||||
#define USB_PRODUCT_ID (0xFFFF)
|
||||
#endif
|
||||
|
||||
#define USB_API_VERSION (0x0107)
|
||||
|
||||
#define USB_WORD(x) (x & 0xFF), ((x >> 8) & 0xFF)
|
||||
|
||||
#define USB_MAX_PACKET0 (64)
|
||||
#define USB_MAX_PACKET_BULK_FS (64)
|
||||
#define USB_MAX_PACKET_BULK_HS (512)
|
||||
|
||||
#define USB_BULK_IN_EP_ADDR (0x81)
|
||||
#define USB_BULK_OUT_EP_ADDR (0x02)
|
||||
|
||||
#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(USB_API_VERSION), // bcdDevice
|
||||
0x01, // iManufacturer
|
||||
0x02, // iProduct
|
||||
0x04, // 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
|
||||
};
|
||||
|
||||
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
|
||||
0x08, // bInterfaceClass: vendor-specific
|
||||
0x06, // bInterfaceSubClass
|
||||
0x50, // 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
|
||||
0x08, // bInterfaceClass: vendor-specific
|
||||
0x06, // bInterfaceSubClass
|
||||
0x50, // 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
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
uint8_t usb_descriptor_string_manufacturer[] = {
|
||||
40, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'G', 0x00,
|
||||
'r', 0x00,
|
||||
'e', 0x00,
|
||||
'a', 0x00,
|
||||
't', 0x00,
|
||||
' ', 0x00,
|
||||
'S', 0x00,
|
||||
'c', 0x00,
|
||||
'o', 0x00,
|
||||
't', 0x00,
|
||||
't', 0x00,
|
||||
' ', 0x00,
|
||||
'G', 0x00,
|
||||
'a', 0x00,
|
||||
'd', 0x00,
|
||||
'g', 0x00,
|
||||
'e', 0x00,
|
||||
't', 0x00,
|
||||
's', 0x00,
|
||||
};
|
||||
|
||||
uint8_t usb_descriptor_string_product[] = {
|
||||
#ifdef HACKRF_ONE
|
||||
43, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'P', 0x00,
|
||||
'o', 0x00,
|
||||
'r', 0x00,
|
||||
't', 0x00,
|
||||
'a', 0x00,
|
||||
'P', 0x00,
|
||||
'a', 0x00,
|
||||
'c', 0x00,
|
||||
'k', 0x00,
|
||||
' ', 0x00,
|
||||
|
||||
'M', 0x00,
|
||||
'a', 0x00,
|
||||
'y', 0x00,
|
||||
'h', 0x00,
|
||||
'e', 0x00,
|
||||
'm', 0x00,
|
||||
|
||||
#elif JAWBREAKER
|
||||
36, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'H', 0x00,
|
||||
'a', 0x00,
|
||||
'c', 0x00,
|
||||
'k', 0x00,
|
||||
'R', 0x00,
|
||||
'F', 0x00,
|
||||
' ', 0x00,
|
||||
'J', 0x00,
|
||||
'a', 0x00,
|
||||
'w', 0x00,
|
||||
'b', 0x00,
|
||||
'r', 0x00,
|
||||
'e', 0x00,
|
||||
'a', 0x00,
|
||||
'k', 0x00,
|
||||
'e', 0x00,
|
||||
'r', 0x00,
|
||||
#elif RAD1O
|
||||
12, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'r', 0x00,
|
||||
'a', 0x00,
|
||||
'd', 0x00,
|
||||
'1', 0x00,
|
||||
'o', 0x00,
|
||||
#else
|
||||
14, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'H', 0x00,
|
||||
'a', 0x00,
|
||||
'c', 0x00,
|
||||
'k', 0x00,
|
||||
'R', 0x00,
|
||||
'F', 0x00,
|
||||
#endif
|
||||
};
|
||||
|
||||
uint8_t usb_descriptor_string_config_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,
|
||||
};
|
||||
|
||||
#ifdef DFU_MODE
|
||||
uint8_t usb_descriptor_string_serial_number[] = {
|
||||
30, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'R', 0x00,
|
||||
'u', 0x00,
|
||||
'n', 0x00,
|
||||
'n', 0x00,
|
||||
'i', 0x00,
|
||||
'n', 0x00,
|
||||
'g', 0x00,
|
||||
'F', 0x00,
|
||||
'r', 0x00,
|
||||
'o', 0x00,
|
||||
'm', 0x00,
|
||||
'R', 0x00,
|
||||
'A', 0x00,
|
||||
'M', 0x00,
|
||||
};
|
||||
#else
|
||||
uint8_t usb_descriptor_string_serial_number[USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN];
|
||||
#endif
|
||||
|
||||
uint8_t* usb_descriptor_strings[] = {
|
||||
usb_descriptor_string_languages,
|
||||
usb_descriptor_string_manufacturer,
|
||||
usb_descriptor_string_product,
|
||||
usb_descriptor_string_config_description,
|
||||
usb_descriptor_string_serial_number,
|
||||
0, // TERMINATOR
|
||||
};
|
||||
|
||||
uint8_t wcid_string_descriptor[] = {
|
||||
18, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'M', 0x00,
|
||||
'S', 0x00,
|
||||
'F', 0x00,
|
||||
'T', 0x00,
|
||||
'1', 0x00,
|
||||
'0', 0x00,
|
||||
'0', 0x00,
|
||||
USB_WCID_VENDOR_REQ, // vendor request code for further descriptor
|
||||
0x00
|
||||
};
|
||||
|
||||
uint8_t wcid_feature_descriptor[] = {
|
||||
0x28, 0x00, 0x00, 0x00, // bLength
|
||||
USB_WORD(0x0100), // WCID version
|
||||
USB_WORD(0x0004), // WICD descriptor index
|
||||
0x01, // bNumSections
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Reserved
|
||||
0x00, // bInterfaceNumber
|
||||
0x01, // Reserved
|
||||
'W', 'I', 'N', 'U', 'S', 'B', 0x00,0x00, // Compatible ID, padded with zeros
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Sub-compatible ID
|
||||
0x00,0x00,0x00,0x00,0x00,0x00 // Reserved
|
||||
};
|
42
firmware/baseband/sd_over_usb/usb_descriptor.h
Normal file
42
firmware/baseband/sd_over_usb/usb_descriptor.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012-2022 Great Scott Gadgets <info@greatscottgadgets.com>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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_string_languages[];
|
||||
extern uint8_t usb_descriptor_string_manufacturer[];
|
||||
extern uint8_t usb_descriptor_string_product[];
|
||||
|
||||
#define USB_DESCRIPTOR_STRING_SERIAL_LEN 32
|
||||
#define USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN \
|
||||
(USB_DESCRIPTOR_STRING_SERIAL_LEN * 2 + 2) /* UTF-16LE */
|
||||
extern uint8_t usb_descriptor_string_serial_number[];
|
||||
|
||||
extern uint8_t* usb_descriptor_strings[];
|
||||
|
||||
#define USB_WCID_VENDOR_REQ 0x19
|
||||
extern uint8_t wcid_string_descriptor[];
|
||||
extern uint8_t wcid_feature_descriptor[];
|
@ -25,8 +25,10 @@ MEMORY
|
||||
{
|
||||
flash (rx) : org = 0x00000000, len = 32752 /* Local SRAM @ 0x10080000 */
|
||||
ram (rwx) : org = 0x10000000, len = 96k /* Local SRAM @ 0x10000000 */
|
||||
ram_usb (rwx) : org = 0x20008000, len = 32K
|
||||
}
|
||||
|
||||
usb_bulk_buffer = ORIGIN(ram_usb);
|
||||
__ram_start__ = ORIGIN(ram);
|
||||
__ram_size__ = LENGTH(ram);
|
||||
__ram_end__ = __ram_start__ + __ram_size__;
|
||||
|
@ -107,6 +107,7 @@ constexpr image_tag_t image_tag_siggen { 'P', 'S', 'I', 'G' };
|
||||
constexpr image_tag_t image_tag_sstv_tx { 'P', 'S', 'T', 'X' };
|
||||
constexpr image_tag_t image_tag_tones { 'P', 'T', 'O', 'N' };
|
||||
constexpr image_tag_t image_tag_flash_utility { 'P', 'F', 'U', 'T' };
|
||||
constexpr image_tag_t image_tag_usb_sd { 'P', 'U', 'S', 'B' };
|
||||
|
||||
constexpr image_tag_t image_tag_noop { 'P', 'N', 'O', 'P' };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user