Cleaned up Xylos TX, J/N works again

This commit is contained in:
furrtek 2016-07-27 05:54:55 +02:00
parent 2177456b7e
commit 79f2134d91
11 changed files with 166 additions and 223 deletions

View File

@ -24,10 +24,8 @@
//BUG: No audio in about when shown second time //BUG: No audio in about when shown second time
//BUG: Description doesn't show up first time going to system>module info (UI drawn on top) //BUG: Description doesn't show up first time going to system>module info (UI drawn on top)
//BUG: Crash after TX stop (unregister message !)
//TODO: Show MD5 mismatches for modules not found, etc... //TODO: Frequency manager
//TODO: Frequency manager !
//TODO: Weird LCR AFSK scrambling ? //TODO: Weird LCR AFSK scrambling ?
//TODO: SD card wiper //TODO: SD card wiper
//TODO: Draw on touchscreen and transmit as spectrum paint //TODO: Draw on touchscreen and transmit as spectrum paint
@ -41,6 +39,7 @@
//TODO: GSM channel detector //TODO: GSM channel detector
//TODO: AFSK receiver //TODO: AFSK receiver
//TODO: SIGFOX RX/TX //TODO: SIGFOX RX/TX
//TODO: Show MD5 mismatches for modules not found, etc...
//TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule //TODO: Module name/filename in modules.hpp to indicate requirement in case it's not found ui_loadmodule
//TODO: Check bw setting in LCR TX //TODO: Check bw setting in LCR TX
//TODO: Bodet :) //TODO: Bodet :)
@ -48,7 +47,6 @@
//TODO: Setup: Play dead by default ? Enable/disable ? //TODO: Setup: Play dead by default ? Enable/disable ?
//TODO: Hide statusview when playing dead //TODO: Hide statusview when playing dead
//TODO: Persistent playdead ! //TODO: Persistent playdead !
//TODO: LCR EC=A,J,N
//TODO: LCR full message former (see norm) //TODO: LCR full message former (see norm)
//TODO: AFSK NRZI //TODO: AFSK NRZI
//TODO: TX power setting //TODO: TX power setting

View File

@ -138,17 +138,17 @@ private:
}; };
Text text_firmware { Text text_firmware {
{ 0, 128, 240, 16 }, { 0, 236, 240, 16 },
"Git Commit Hash " GIT_REVISION, "Git Commit Hash " GIT_REVISION,
}; };
Text text_cpld_hackrf { Text text_cpld_hackrf {
{ 0, 144, 11*8, 16 }, { 0, 252, 11*8, 16 },
"HackRF CPLD", "HackRF CPLD",
}; };
Text text_cpld_hackrf_status { Text text_cpld_hackrf_status {
{ 240 - 3*8, 144, 3*8, 16 }, { 240 - 3*8, 252, 3*8, 16 },
"???" "???"
}; };

View File

@ -122,152 +122,139 @@ XylosView::~XylosView() {
baseband::shutdown(); baseband::shutdown();
} }
void XylosView::upd_message() { void XylosView::generate_message() {
uint8_t c; uint8_t c;
ccirmessage[0] = (header_code_a.value() / 10) + 0x30;
ccirmessage[1] = (header_code_a.value() % 10) + 0x30;
ccirmessage[2] = (header_code_b.value() / 10) + 0x30;
ccirmessage[3] = (header_code_b.value() % 10) + 0x30;
ccirmessage[4] = (city_code.value() / 10) + 0x30; // Init CCIR message
ccirmessage[5] = (city_code.value() % 10) + 0x30; memcpy(ccir_message, ccir_base, 21);
ccirmessage[6] = family_code.value() + 0x30;
// Header
ccir_message[0] = (header_code_a.value() / 10) + 0x30;
ccir_message[1] = (header_code_a.value() % 10) + 0x30;
ccir_message[2] = (header_code_b.value() / 10) + 0x30;
ccir_message[3] = (header_code_b.value() % 10) + 0x30;
// Addresses
ccir_message[4] = (city_code.value() / 10) + 0x30;
ccir_message[5] = (city_code.value() % 10) + 0x30;
ccir_message[6] = family_code.value() + 0x30;
if (checkbox_wcsubfamily.value() == false) if (checkbox_wcsubfamily.value() == false)
ccirmessage[7] = subfamily_code.value() + 0x30; ccir_message[7] = subfamily_code.value() + 0x30;
else else
ccirmessage[7] = 'A'; ccir_message[7] = 'A';
if (checkbox_wcid.value() == false) { if (checkbox_wcid.value() == false) {
ccirmessage[8] = (receiver_code.value() / 10) + 0x30; ccir_message[8] = (receiver_code.value() / 10) + 0x30;
ccirmessage[9] = (receiver_code.value() % 10) + 0x30; ccir_message[9] = (receiver_code.value() % 10) + 0x30;
} else { } else {
ccirmessage[8] = 'A'; ccir_message[8] = 'A';
ccirmessage[9] = 'A'; ccir_message[9] = 'A';
} }
ccirmessage[10] = 'B'; // Commands
ccir_message[11] = options_ra.selected_index() + 0x30;
ccir_message[12] = options_rb.selected_index() + 0x30;
ccir_message[13] = options_rc.selected_index() + 0x30;
ccir_message[14] = options_rd.selected_index() + 0x30;
ccirmessage[11] = options_ra.selected_index() + 0x30; // Get rid of repeats with E code
ccirmessage[12] = options_rb.selected_index() + 0x30; for (c = 1; c < 20; c++)
ccirmessage[13] = options_rc.selected_index() + 0x30; if (ccir_message[c] == ccir_message[c - 1]) ccir_message[c] = 'E';
ccirmessage[14] = options_rd.selected_index() + 0x30;
ccirmessage[15] = 'B';
ccirmessage[16] = '0';
ccirmessage[17] = '0';
ccirmessage[18] = '0';
ccirmessage[19] = '0';
// Repeats elimination
for (c = 1; c < 20; c++) {
if (ccirmessage[c] == ccirmessage[c - 1]) ccirmessage[c] = 'E';
}
ccirmessage[20] = 0;
// Display as text // Display as text
text_message.set(ccirmessage); text_message.set(ccir_message);
// ASCII to frequency LUT index ascii_to_ccir(ccir_message);
for (c=0; c<20; c++) {
if (ccirmessage[c] > '9')
ccirmessage[c] -= 0x37;
else
ccirmessage[c] -= 0x30;
}
ccirmessage[20] = 0xFF;
} }
void XylosView::start_tx() { void XylosView::start_tx() {
upd_message();
//audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max); //audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max);
transmitter_model.set_tuning_frequency(xylos_freqs[options_freq.selected_index()]);
transmitter_model.set_baseband_configuration({ transmitter_model.set_baseband_configuration({
.mode = 0, .mode = 0,
.sampling_rate = 1536000U, .sampling_rate = 1536000U,
.decimation_factor = 1, .decimation_factor = 1,
}); });
transmitter_model.set_rf_amp(true); transmitter_model.set_rf_amp(true);
transmitter_model.set_lna(40);
transmitter_model.set_vga(40);
transmitter_model.set_baseband_bandwidth(1750000); transmitter_model.set_baseband_bandwidth(1750000);
transmitter_model.enable(); transmitter_model.enable();
baseband::set_xylos_data(ccirmessage); baseband::set_xylos_data(ccir_message);
}
// ASCII to frequency LUT index
void XylosView::ascii_to_ccir(char *ascii) {
uint8_t c;
for (c = 0; c < 20; c++) {
if (ascii[c] > '9')
ascii[c] -= 0x37;
else
ascii[c] -= 0x30;
}
// EOM code for baseband
ascii[20] = 0xFF;
} }
void XylosView::on_txdone(const int n) { void XylosView::on_txdone(const int n) {
int c, sr; size_t sr;
if (testing == true) { if (tx_mode == TESTING) {
if (n == 25) { if (n == 25) {
transmitter_model.disable(); transmitter_model.disable();
if (sequence_idx != 9) { /*if (sequence_idx != 9) {
chThdSleepMilliseconds(15000); chThdSleepMilliseconds(15000);
memcpy(ccirmessage, &xylos_sequence[sequence_idx][0], 21); memcpy(ccir_message, &xylos_sequence[sequence_idx][0], 21);
// ASCII to frequency LUT index // ASCII to frequency LUT index
for (c=0; c<20; c++) { for (c=0; c<20; c++) {
if (ccirmessage[c] > '9') if (ccir_message[c] > '9')
ccirmessage[c] -= 0x37; ccir_message[c] -= 0x37;
else else
ccirmessage[c] -= 0x30; ccir_message[c] -= 0x30;
} }
ccirmessage[20] = 0xFF; ccir_message[20] = 0xFF;
//memcpy(shared_memory.xylosdata, ccirmessage, 21); TODO !!! //memcpy(shared_memory.xylosdata, ccirmessage, 21); TODO !!!
sequence_idx++; sequence_idx++;
txing = true; tx_mode = TESTING;
transmitter_model.enable(); transmitter_model.enable();
} else { } else {*/
button_txtest.set_style(&style()); button_txtest.set_style(&style());
button_txtest.set_text("TEST"); button_txtest.set_text("TEST");
testing = false; tx_mode = IDLE;
} //}
} }
} else { } else {
if (n == 25) { if (n == 25) {
audio::headphone::set_volume(volume_t::decibel(0 - 99) + audio::headphone::volume_range().max); //audio::headphone::set_volume(volume_t::decibel(0 - 99) + audio::headphone::volume_range().max);
transmitter_model.disable(); transmitter_model.disable();
progress.set_value(0); progress.set_value(0);
if (inc_cnt) { if (checkbox_cligno.value() == false) {
chThdSleepMilliseconds(1000); tx_mode = IDLE;
header_code_b.set_value(header_code_b.value() + 1); button_transmit.set_style(&style_val);
button_transmit.set_text("START");
upd_message();
start_tx();
inc_cnt--;
} else { } else {
header_code_b.set_value(header_init); chThdSleepMilliseconds(tempo_cligno.value() * 1000);
if (checkbox_cligno.value() == false) {
txing = false; // Invert relay states
button_transmit.set_style(&style_val); sr = options_ra.selected_index();
button_transmit.set_text("START"); if (sr > 0) options_ra.set_selected_index(sr ^ 3);
} else { sr = options_rb.selected_index();
if (checkbox_hinc.value()) if (sr > 0) options_rb.set_selected_index(sr ^ 3);
inc_cnt = 3; sr = options_rc.selected_index();
else if (sr > 0) options_rc.set_selected_index(sr ^ 3);
inc_cnt = 0; sr = options_rd.selected_index();
if (sr > 0) options_rd.set_selected_index(sr ^ 3);
chThdSleepMilliseconds(tempo_cligno.value() * 1000);
generate_message();
// Invert relay states start_tx();
sr = options_ra.selected_index();
if (sr > 0) options_ra.set_selected_index(sr ^ 3);
sr = options_rb.selected_index();
if (sr > 0) options_rb.set_selected_index(sr ^ 3);
sr = options_rc.selected_index();
if (sr > 0) options_rc.set_selected_index(sr ^ 3);
sr = options_rd.selected_index();
if (sr > 0) options_rd.set_selected_index(sr ^ 3);
upd_message();
start_tx();
}
} }
} else { } else {
progress.set_value((n + 1) * 5); progress.set_value((n + 1) * 5);
@ -276,10 +263,11 @@ void XylosView::on_txdone(const int n) {
} }
XylosView::XylosView(NavigationView& nav) { XylosView::XylosView(NavigationView& nav) {
(void)nav;
baseband::run_image(portapack::spi_flash::image_tag_xylos); baseband::run_image(portapack::spi_flash::image_tag_xylos);
add_children({ { add_children({ {
&checkbox_hinc,
&button_txtest, &button_txtest,
&text_header, &text_header,
&header_code_a, &header_code_a,
@ -325,27 +313,27 @@ XylosView::XylosView(NavigationView& nav) {
header_code_a.on_change = [this](int32_t v) { header_code_a.on_change = [this](int32_t v) {
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
header_code_b.on_change = [this](int32_t v) { header_code_b.on_change = [this](int32_t v) {
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
city_code.on_change = [this](int32_t v) { city_code.on_change = [this](int32_t v) {
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
family_code.on_change = [this](int32_t v) { family_code.on_change = [this](int32_t v) {
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
subfamily_code.on_change = [this](int32_t v) { subfamily_code.on_change = [this](int32_t v) {
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
receiver_code.on_change = [this](int32_t v) { receiver_code.on_change = [this](int32_t v) {
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
subfamily_code.hidden(true); subfamily_code.hidden(true);
@ -358,7 +346,7 @@ XylosView::XylosView(NavigationView& nav) {
subfamily_code.hidden(false); subfamily_code.hidden(false);
text_subfamily.set_style(&style()); text_subfamily.set_style(&style());
} }
XylosView::upd_message(); XylosView::generate_message();
}; };
receiver_code.hidden(true); receiver_code.hidden(true);
@ -372,119 +360,75 @@ XylosView::XylosView(NavigationView& nav) {
text_receiver.set_style(&style()); text_receiver.set_style(&style());
} }
receiver_code.set_dirty(); receiver_code.set_dirty();
XylosView::upd_message(); XylosView::generate_message();
}; };
options_ra.on_change = [this](size_t n, OptionsField::value_t v) { options_ra.on_change = [this](size_t n, OptionsField::value_t v) {
(void)n; (void)n;
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
options_rb.on_change = [this](size_t n, OptionsField::value_t v) { options_rb.on_change = [this](size_t n, OptionsField::value_t v) {
(void)n; (void)n;
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
options_rc.on_change = [this](size_t n, OptionsField::value_t v) { options_rc.on_change = [this](size_t n, OptionsField::value_t v) {
(void)n; (void)n;
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
options_rd.on_change = [this](size_t n, OptionsField::value_t v) { options_rd.on_change = [this](size_t n, OptionsField::value_t v) {
(void)n; (void)n;
(void)v; (void)v;
XylosView::upd_message(); XylosView::generate_message();
}; };
button_transmit.set_style(&style_val); button_transmit.set_style(&style_val);
XylosView::upd_message(); XylosView::generate_message();
/*button_txtest.on_select = [this](Button&) { // Transmission and tones testing
const uint8_t ccirtest[21] = { 11, 13, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 14, 12, 10, 12, 14, 0, 9, 0xFF };
if (txing == false) {
EventDispatcher::message_map().unregister_handler(Message::ID::TXDone);
EventDispatcher::message_map().register_handler(Message::ID::TXDone,
[this](Message* const p) {
const auto message = static_cast<const TXDoneMessage*>(p);
if (message->n == 25) {
audio::headphone::set_volume(volume_t::decibel(0 - 99) + audio::headphone::volume_range().max);
transmitter_model.disable();
txing = false;
button_txtest.set_style(&style());
button_txtest.set_text("TEST");
}
}
);
memcpy(ccirmessage, ccirtest, 21);
shared_memory.transmit_done = false;
memcpy(shared_memory.xylosdata, ccirmessage, 21);
transmitter_model.set_tuning_frequency(xylos_freqs[options_freq.selected_index()]);
audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max);
txing = true;
button_txtest.set_style(&style_cancel);
button_txtest.set_text("Wait");
transmitter_model.enable();
}
};*/
// Sequence testing:
button_txtest.on_select = [this](Button&) { button_txtest.on_select = [this](Button&) {
int c; // Tones going up in pitch
const uint8_t ccir_test[21] = { 11, 13, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 14, 12, 10, 12, 14, 0, 9, 0xFF };
if (txing == false) { if (tx_mode == IDLE) {
sequence_idx = 0; tx_mode = TESTING;
memcpy(ccir_message, ccir_test, 21);
memcpy(ccirmessage, &xylos_sequence[sequence_idx][0], 21); //audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max);
// ASCII to frequency LUT index
for (c=0; c<20; c++) {
if (ccirmessage[c] > '9')
ccirmessage[c] -= 0x37;
else
ccirmessage[c] -= 0x30;
}
ccirmessage[20] = 0xFF;
//memcpy(shared_memory.xylosdata, ccirmessage, 21); TODO !!!
sequence_idx++;
transmitter_model.set_tuning_frequency(xylos_freqs[options_freq.selected_index()]);
txing = true;
testing = true;
button_txtest.set_style(&style_cancel); button_txtest.set_style(&style_cancel);
button_txtest.set_text("Wait"); button_txtest.set_text("Wait");
transmitter_model.enable(); start_tx();
} }
}; };
// Sequence playback
/*button_txtest.on_select = [this](Button&) {
if (tx_mode == IDLE) {
tx_mode = TESTING;
sequence_idx = 0;
memcpy(ccir_message, &xylos_sequence[sequence_idx][0], 21);
ascii_to_ccir(ccir_message);
sequence_idx++;
button_txtest.set_style(&style_cancel);
button_txtest.set_text("Wait");
start_tx();
}
};*/
// Single transmit
button_transmit.on_select = [this](Button&) { button_transmit.on_select = [this](Button&) {
if (tx_mode == IDLE) {
if (txing == false) { // audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max);
upd_message(); tx_mode = SINGLE;
if (checkbox_hinc.value())
inc_cnt = 3;
else
inc_cnt = 0;
header_init = header_code_b.value();
//shared_memory.transmit_done = false;
//memcpy(shared_memory.xylosdata, ccirmessage, 21);
transmitter_model.set_tuning_frequency(xylos_freqs[options_freq.selected_index()]);
audio::headphone::set_volume(volume_t::decibel(90 - 99) + audio::headphone::volume_range().max);
txing = true;
testing = false;
button_transmit.set_style(&style_cancel); button_transmit.set_style(&style_cancel);
button_transmit.set_text("Wait"); button_transmit.set_text("Wait");
generate_message();
start_tx(); start_tx();
} }
}; };

View File

@ -150,12 +150,18 @@ public:
void focus() override; void focus() override;
private: private:
int inc_cnt; enum tx_modes {
int header_init; IDLE = 0,
bool txing = false; SINGLE,
bool testing = false; SEQUENCE,
TESTING
};
tx_modes tx_mode = IDLE;
const rf::Frequency xylos_freqs[7] = { 31325000, 31387500, 31437500, 31475000, 31687500, 31975000, 88000000 }; const rf::Frequency xylos_freqs[7] = { 31325000, 31387500, 31437500, 31475000, 31687500, 31975000, 88000000 };
char ccirmessage[21]; char ccir_message[21];
const char ccir_base[21] = "0000000000B0000B0000";
const char xylos_sequence[9][21] = { const char xylos_sequence[9][21] = {
"0E0E18920EB1E10B0E0E", "0E0E18920EB1E10B0E0E",
@ -171,8 +177,9 @@ private:
int sequence_idx; int sequence_idx;
void ascii_to_ccir(char *ascii);
void start_tx(); void start_tx();
void upd_message(); void generate_message();
void on_txdone(const int n); void on_txdone(const int n);
const Style style_val { const Style style_val {
@ -191,12 +198,6 @@ private:
.foreground = Color::grey(), .foreground = Color::grey(),
}; };
Checkbox checkbox_hinc {
{ 21 * 8, 12},
2,
"+3"
};
Text text_header { Text text_header {
{ 8 * 8, 1 * 16, 7 * 8, 16 }, { 8 * 8, 1 * 16, 7 * 8, 16 },
"Header:" "Header:"

Binary file not shown.

Binary file not shown.

View File

@ -42,7 +42,7 @@ void XylosProcessor::execute(const buffer_c8_t& buffer) {
for (size_t i = 0; i<buffer.count; i++) { for (size_t i = 0; i<buffer.count; i++) {
// Sample generation rate: 1536000/10 = 153kHz // Sample generation rate: 1536000/10 = 153kHz
if (s >= (5-1)) { if (s >= (2-1)) {
s = 0; s = 0;
if (silence) { if (silence) {
@ -55,15 +55,15 @@ void XylosProcessor::execute(const buffer_c8_t& buffer) {
} else { } else {
if (sample_count >= CCIR_TONELENGTH) { if (sample_count >= CCIR_TONELENGTH) {
if (transmit_done == false) { if (transmit_done == false) {
message.n = byte_pos; // Inform UI about progress (just as eye candy)
shared_memory.application_queue.push(message);
digit = xylosdata[byte_pos++]; digit = xylosdata[byte_pos++];
} if ((digit == 0xFF) || (byte_pos >= 21)) {
message.n = 25; // End of message code
if ((digit == 0xFF) || (byte_pos >= 21)) { transmit_done = true;
message.n = 25; // End of message code shared_memory.application_queue.push(message);
transmit_done = true; } else {
shared_memory.application_queue.push(message); message.n = byte_pos; // Inform UI about progress (just as eye candy)
shared_memory.application_queue.push(message);
}
} }
sample_count = 0; sample_count = 0;
@ -81,7 +81,7 @@ void XylosProcessor::execute(const buffer_c8_t& buffer) {
re = 0; re = 0;
im = 0; im = 0;
} else { } else {
sample = (sine_table_f32[(aphase & 0x03FF0000)>>18]*127); // 255 here before sample = (sine_table_f32[(aphase & 0x03FC0000)>>18]*127); // 255 here before
// Audio preview sample generation: 1536000/48000 = 32 // Audio preview sample generation: 1536000/48000 = 32
/*if (as >= 31) { /*if (as >= 31) {
@ -92,13 +92,13 @@ void XylosProcessor::execute(const buffer_c8_t& buffer) {
}*/ }*/
//FM //FM
frq = sample * 1000; // 500 was here frq = sample * 800; // ?
phase = (phase + frq); phase = (phase + frq);
sphase = phase + (256<<16); sphase = phase + (256<<16);
re = (sine_table_f32[(sphase & 0x03FF0000)>>18]*15); re = (sine_table_f32[(sphase & 0x03FC0000)>>18]*127);
im = (sine_table_f32[(phase & 0x03FF0000)>>18]*15); im = (sine_table_f32[(phase & 0x03FC0000)>>18]*127);
} }
buffer.p[i] = {(int8_t)re,(int8_t)im}; buffer.p[i] = {(int8_t)re,(int8_t)im};

View File

@ -31,9 +31,9 @@
#include "audio_output.hpp" #include "audio_output.hpp"
#include "baseband_thread.hpp" #include "baseband_thread.hpp"
#define CCIR_TONELENGTH (15360*2)-1 // 1536000/10/10 #define CCIR_TONELENGTH (15360*5)-1 // 1536000/10/10
#define PHASEV (436.91/2) // (65536*1024)/1536000*10 #define PHASEV (436.91/5) // (65536*1024)/1536000*10
#define SILENCE (46080*2)-1 // 400ms #define SILENCE (46080*5)-1 // 400ms
class XylosProcessor : public BasebandProcessor { class XylosProcessor : public BasebandProcessor {
public: public:

View File

@ -102,12 +102,12 @@ struct region_t {
constexpr region_t bootstrap { constexpr region_t bootstrap {
.offset = 0x00000, .offset = 0x00000,
.size = 0x10000, .size = 0x8000,
}; };
constexpr region_t images { constexpr region_t images {
.offset = 0x10000, .offset = 0x8000,
.size = 0x30000, .size = 0x38000,
}; };
constexpr region_t application { constexpr region_t application {

Binary file not shown.

View File

@ -56,12 +56,12 @@ images = (
{ {
'name': 'bootstrap', 'name': 'bootstrap',
'data': bootstrap_image, 'data': bootstrap_image,
'size': 0x10000, 'size': 0x8000,
}, },
{ {
'name': 'baseband', 'name': 'baseband',
'data': baseband_image, 'data': baseband_image,
'size': 0x30000, 'size': 0x38000,
}, },
{ {
'name': 'application', 'name': 'application',