来看看ui_debug.cpp代码
这一段是跟几个芯片有关的界面代码。
DebugPeripheralsMenuView::DebugPeripheralsMenuView(NavigationView& nav) {
add_items({
{ "RFFC5072", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
"RFFC5072", RegistersWidgetConfig { 31, 16 },
[](const size_t register_number) { return radio::debug::first_if::register_read(register_number); }
); } },
{ "MAX2837", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
"MAX2837", RegistersWidgetConfig { 32, 10 },
[](const size_t register_number) { return radio::debug::second_if::register_read(register_number); }
); } },
{ "Si5351C", ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
"Si5351C", RegistersWidgetConfig { 96, 8 },
[](const size_t register_number) { return portapack::clock_generator.read_register(register_number); }
); } },
{ audio::debug::codec_name(), ui::Color::dark_cyan(), &bitmap_icon_peripherals_details, [&nav](){ nav.push<RegistersView>(
audio::debug::codec_name(), RegistersWidgetConfig { audio::debug::reg_count(), audio::debug::reg_bits() },
[](const size_t register_number) { return audio::debug::reg_read(register_number); }
); } },
});
set_max_rows(2); // allow wider buttons
}
我们关心的RFFC5072和MAX2837都是会调用RegistersView。
所以就看一下同样在ui_debug里实现的RegistersView。
对比draw_legend和draw_values。它们代码差不多,只不过一个的text来自于循环变量i,另一个text来自于value。
所以可以明确draw_legend是用来显示序号的,draw_values是用来显示寄存器的值。
void RegistersWidget::draw_legend(const Coord left, Painter& painter) {
const auto pos = screen_pos();
for(size_t i=0; i<config.registers_count; i+=config.registers_per_row()) {
const Point offset {
left, static_cast<int>((i / config.registers_per_row()) * row_height)
};
const auto text = to_string_hex(i, config.legend_length());
painter.draw_string(
pos + offset,
style().invert(),
text
);
}
}
void RegistersWidget::draw_values(
const Coord left,
Painter& painter
) {
const auto pos = screen_pos();
for(size_t i=0; i<config.registers_count; i++) {
const Point offset = {
static_cast<int>(left + config.legend_width() + 8 + (i % config.registers_per_row()) * (config.value_width() + 8)),
static_cast<int>((i / config.registers_per_row()) * row_height)
};
const auto value = reader(i);
const auto text = to_string_hex(value, config.value_length());
painter.draw_string(
pos + offset,
style(),
text
);
}
}
/* RegistersView *********************************************************/
RegistersView::RegistersView(
NavigationView& nav,
const std::string& title,
RegistersWidgetConfig&& config,
std::function<uint32_t(const size_t register_number)>&& reader
) : registers_widget { std::move(config), std::move(reader) }
{
add_children({
&text_title,
®isters_widget,
&button_update,
&button_done,
});
button_update.on_select = [this](Button&){
this->registers_widget.update();
};
button_done.on_select = [&nav](Button&){ nav.pop(); };
registers_widget.set_parent_rect({ 0, 48, 240, 192 });
text_title.set_parent_rect({
(240 - static_cast<int>(title.size()) * 8) / 2, 16,
static_cast<int>(title.size()) * 8, 16
});
text_title.set(title);
}
寄存器的值是用reader(i)得到的。reader函数是RegistersView这个类初始化的时候传入的。是在第一段界面有关的代码里动态传入的。
它是动态的,根据芯片不同,传入的具体函数也不同,比如如果选择MAX2837芯片,就传入如下函数。
radio::debug::second_if::register_read(register_number)
这个函数的具体实现要看application/radio.cpp
max2837::MAX2837 second_if { ssp1_target_max2837 };
namespace debug {
namespace first_if {
uint32_t register_read(const size_t register_number) {
return radio::first_if.read(register_number);
}
} /* namespace first_if */
namespace second_if {
uint32_t register_read(const size_t register_number) {
return radio::second_if.read(register_number);
}
uint8_t temp_sense() {
return radio::second_if.temp_sense() & 0x1f;
}
} /* namespace second_if */
} /* namespace debug */
可以看到radio::debug::second_if::register_read函数实际是在调用radio::second_if.read函数
而开头second_if就是max2837,所以调用的就是max2837的read函数。
max2837.cpp
reg_t MAX2837::read(const address_t reg_num) {
uint16_t t = (1U << 15) | (reg_num << 10);
_target.transfer(&t, 1U);
return t & 0x3ffU;
}
reg_t MAX2837::read(const Register reg) {
return read(toUType(reg));
}
这篇博客介绍了UI界面中针对不同嵌入式芯片如RFFC5072和MAX2837的调试菜单实现,通过`DebugPeripheralsMenuView`和`RegistersView`类来展示和操作芯片寄存器。`RegistersView`使用传递的函数指针动态获取寄存器值,例如MAX2837调用的是`radio::debug::second_if::register_read`函数,该函数最终会调用`MAX2837`的`read`方法来读取寄存器数据。

被折叠的 条评论
为什么被折叠?



