mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-01-08 21:07:40 +00:00
Merge pull request #39 from sharebrained/hackrf_firmware_boot
Hackrf firmware boot
This commit is contained in:
commit
6acce63a26
@ -23,12 +23,15 @@ PATH_BOOTSTRAP=bootstrap
|
|||||||
PATH_APPLICATION=application
|
PATH_APPLICATION=application
|
||||||
PATH_BASEBAND=baseband
|
PATH_BASEBAND=baseband
|
||||||
|
|
||||||
|
# TODO: Pass these (as #defines?) to Makefiles, use values in code.
|
||||||
PAD_BOOTSTRAP=0x10000
|
PAD_BOOTSTRAP=0x10000
|
||||||
PAD_BASEBAND=0x10000
|
PAD_HACKRF_FIRMWARE=0x10000
|
||||||
|
PAD_BASEBAND=0x20000
|
||||||
|
|
||||||
TARGET=portapack-h1-firmware
|
TARGET=portapack-h1-firmware
|
||||||
|
|
||||||
TARGET_BOOTSTRAP=$(PATH_BOOTSTRAP)/bootstrap
|
TARGET_BOOTSTRAP=$(PATH_BOOTSTRAP)/bootstrap
|
||||||
|
TARGET_HACKRF_FIRMWARE=hackrf_one_usb_ram
|
||||||
TARGET_APPLICATION=$(PATH_APPLICATION)/build/application
|
TARGET_APPLICATION=$(PATH_APPLICATION)/build/application
|
||||||
TARGET_BASEBAND=$(PATH_BASEBAND)/build/baseband
|
TARGET_BASEBAND=$(PATH_BASEBAND)/build/baseband
|
||||||
|
|
||||||
@ -53,12 +56,17 @@ program: $(TARGET).bin
|
|||||||
sleep 1s
|
sleep 1s
|
||||||
hackrf_spiflash -w $(TARGET).bin
|
hackrf_spiflash -w $(TARGET).bin
|
||||||
|
|
||||||
$(TARGET).bin: $(TARGET_BOOTSTRAP)_pad.bin $(TARGET_BASEBAND)_pad.bin $(TARGET_APPLICATION).bin
|
$(TARGET).bin: $(TARGET_BOOTSTRAP)_pad.bin $(TARGET_HACKRF_FIRMWARE)_dfu_pad.bin $(TARGET_BASEBAND)_pad.bin $(TARGET_APPLICATION).bin
|
||||||
cat $(TARGET_BOOTSTRAP)_pad.bin $(TARGET_BASEBAND)_pad.bin $(TARGET_APPLICATION).bin >$(TARGET).bin
|
cat $(TARGET_BOOTSTRAP)_pad.bin $(TARGET_HACKRF_FIRMWARE)_dfu_pad.bin $(TARGET_BASEBAND)_pad.bin $(TARGET_APPLICATION).bin >$(TARGET).bin
|
||||||
|
|
||||||
$(TARGET_BOOTSTRAP)_pad.bin: $(TARGET_BOOTSTRAP).elf
|
$(TARGET_BOOTSTRAP)_pad.bin: $(TARGET_BOOTSTRAP).elf
|
||||||
$(CP) -O binary --pad-to $(PAD_BOOTSTRAP) $(TARGET_BOOTSTRAP).elf $(TARGET_BOOTSTRAP)_pad.bin
|
$(CP) -O binary --pad-to $(PAD_BOOTSTRAP) $(TARGET_BOOTSTRAP).elf $(TARGET_BOOTSTRAP)_pad.bin
|
||||||
|
|
||||||
|
$(TARGET_HACKRF_FIRMWARE)_dfu_pad.bin: $(TARGET_HACKRF_FIRMWARE).dfu
|
||||||
|
# TODO: Not confident this is reliable. It certainly won't work on Windows.
|
||||||
|
cp $(TARGET_HACKRF_FIRMWARE).dfu $(TARGET_HACKRF_FIRMWARE)_dfu_pad.bin
|
||||||
|
dd if=/dev/null of=$(TARGET_HACKRF_FIRMWARE)_dfu_pad.bin bs=1 count=1 seek=$(PAD_HACKRF_FIRMWARE)
|
||||||
|
|
||||||
$(TARGET_BASEBAND)_pad.bin: $(TARGET_BASEBAND).elf
|
$(TARGET_BASEBAND)_pad.bin: $(TARGET_BASEBAND).elf
|
||||||
$(CP) -O binary --pad-to $(PAD_BASEBAND) $(TARGET_BASEBAND).elf $(TARGET_BASEBAND)_pad.bin
|
$(CP) -O binary --pad-to $(PAD_BASEBAND) $(TARGET_BASEBAND).elf $(TARGET_BASEBAND)_pad.bin
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ CPPSRC = main.cpp \
|
|||||||
event.cpp \
|
event.cpp \
|
||||||
message_queue.cpp \
|
message_queue.cpp \
|
||||||
hackrf_hal.cpp \
|
hackrf_hal.cpp \
|
||||||
|
portapack.cpp \
|
||||||
portapack_shared_memory.cpp \
|
portapack_shared_memory.cpp \
|
||||||
portapack_io.cpp \
|
portapack_io.cpp \
|
||||||
i2c_pp.cpp \
|
i2c_pp.cpp \
|
||||||
|
@ -296,6 +296,11 @@ void ClockManager::init() {
|
|||||||
clock_generator.reset_plls();
|
clock_generator.reset_plls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClockManager::shutdown() {
|
||||||
|
run_from_irc();
|
||||||
|
clock_generator.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void ClockManager::run_from_irc() {
|
void ClockManager::run_from_irc() {
|
||||||
change_clock_configuration(cgu::CLK_SEL::IRC);
|
change_clock_configuration(cgu::CLK_SEL::IRC);
|
||||||
}
|
}
|
||||||
@ -377,14 +382,14 @@ void ClockManager::change_clock_configuration(const cgu::CLK_SEL clk_sel) {
|
|||||||
|
|
||||||
set_m4_clock_to_irc();
|
set_m4_clock_to_irc();
|
||||||
|
|
||||||
|
update_peripheral_clocks(clk_sel);
|
||||||
|
|
||||||
if( clk_sel == cgu::CLK_SEL::PLL1 ) {
|
if( clk_sel == cgu::CLK_SEL::PLL1 ) {
|
||||||
set_m4_clock_to_pll1();
|
set_m4_clock_to_pll1();
|
||||||
} else {
|
} else {
|
||||||
power_down_pll1();
|
power_down_pll1();
|
||||||
}
|
}
|
||||||
|
|
||||||
update_peripheral_clocks(clk_sel);
|
|
||||||
|
|
||||||
start_peripherals(clk_sel);
|
start_peripherals(clk_sel);
|
||||||
|
|
||||||
if( clk_sel != cgu::CLK_SEL::XTAL ) {
|
if( clk_sel != cgu::CLK_SEL::XTAL ) {
|
||||||
@ -393,6 +398,7 @@ void ClockManager::change_clock_configuration(const cgu::CLK_SEL clk_sel) {
|
|||||||
|
|
||||||
/* If not using PLL1, disable clock feeding GP_CLKIN */
|
/* If not using PLL1, disable clock feeding GP_CLKIN */
|
||||||
if( clk_sel != cgu::CLK_SEL::PLL1 ) {
|
if( clk_sel != cgu::CLK_SEL::PLL1 ) {
|
||||||
|
stop_audio_pll();
|
||||||
disable_gp_clkin_source();
|
disable_gp_clkin_source();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
void run_from_irc();
|
void run_from_irc();
|
||||||
void run_at_full_speed();
|
void run_at_full_speed();
|
||||||
|
@ -23,15 +23,8 @@
|
|||||||
|
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
static constexpr uint32_t m4_text_flash_image_offset = 0x10000;
|
|
||||||
static constexpr size_t m4_text_size = 0x8000;
|
|
||||||
static constexpr uint32_t m4_text_flash_base = LPC_SPIFI_DATA_CACHED_BASE + m4_text_flash_image_offset;
|
|
||||||
static constexpr uint32_t m4_text_ram_base = 0x10080000;
|
|
||||||
|
|
||||||
/* TODO: OK, this is cool, but how do I put the M4 to sleep so I can switch to
|
/* TODO: OK, this is cool, but how do I put the M4 to sleep so I can switch to
|
||||||
* a different image? Other than asking the old image to sleep while the M0
|
* a different image? Other than asking the old image to sleep while the M0
|
||||||
* makes changes?
|
* makes changes?
|
||||||
@ -39,14 +32,14 @@ static constexpr uint32_t m4_text_ram_base = 0x10080000;
|
|||||||
* I suppose I could force M4MEMMAP to an invalid memory reason which would
|
* I suppose I could force M4MEMMAP to an invalid memory reason which would
|
||||||
* cause an exception and effectively halt the M4. But that feels gross.
|
* cause an exception and effectively halt the M4. But that feels gross.
|
||||||
*/
|
*/
|
||||||
void m4_init() {
|
void m4_init(const portapack::spi_flash::region_t from, void* const to) {
|
||||||
/* Initialize M4 code RAM */
|
/* Initialize M4 code RAM */
|
||||||
std::memcpy((void*)m4_text_ram_base, (void*)m4_text_flash_base, m4_text_size);
|
std::memcpy(to, from.base_address(), from.size);
|
||||||
|
|
||||||
/* M4 core is assumed to be sleeping with interrupts off, so we can mess
|
/* M4 core is assumed to be sleeping with interrupts off, so we can mess
|
||||||
* with its address space and RAM without concern.
|
* with its address space and RAM without concern.
|
||||||
*/
|
*/
|
||||||
LPC_CREG->M4MEMMAP = m4_text_ram_base;
|
LPC_CREG->M4MEMMAP = reinterpret_cast<uint32_t>(to);
|
||||||
|
|
||||||
/* Reset M4 core */
|
/* Reset M4 core */
|
||||||
LPC_RGU->RESET_CTRL[0] = (1 << 13);
|
LPC_RGU->RESET_CTRL[0] = (1 << 13);
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
#ifndef __M4_STARTUP_H__
|
#ifndef __M4_STARTUP_H__
|
||||||
#define __M4_STARTUP_H__
|
#define __M4_STARTUP_H__
|
||||||
|
|
||||||
void m4_init();
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "spi_image.hpp"
|
||||||
|
|
||||||
|
void m4_init(const portapack::spi_flash::region_t from, void* const to);
|
||||||
|
|
||||||
#endif/*__M4_STARTUP_H__*/
|
#endif/*__M4_STARTUP_H__*/
|
||||||
|
@ -22,43 +22,29 @@
|
|||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
#include "hackrf_hal.hpp"
|
#include "lpc43xx_cpp.hpp"
|
||||||
#include "hackrf_gpio.hpp"
|
using namespace lpc43xx;
|
||||||
using namespace hackrf::one;
|
|
||||||
|
|
||||||
|
#include "portapack.hpp"
|
||||||
#include "portapack_shared_memory.hpp"
|
#include "portapack_shared_memory.hpp"
|
||||||
#include "portapack_hal.hpp"
|
|
||||||
#include "portapack_io.hpp"
|
|
||||||
|
|
||||||
#include "cpld_update.hpp"
|
#include "cpld_update.hpp"
|
||||||
|
|
||||||
#include "message_queue.hpp"
|
#include "message_queue.hpp"
|
||||||
|
|
||||||
#include "si5351.hpp"
|
|
||||||
#include "clock_manager.hpp"
|
|
||||||
|
|
||||||
#include "wm8731.hpp"
|
|
||||||
#include "radio.hpp"
|
|
||||||
#include "touch.hpp"
|
|
||||||
#include "touch_adc.hpp"
|
|
||||||
|
|
||||||
#include "ui.hpp"
|
#include "ui.hpp"
|
||||||
#include "ui_widget.hpp"
|
#include "ui_widget.hpp"
|
||||||
#include "ui_painter.hpp"
|
#include "ui_painter.hpp"
|
||||||
#include "ui_navigation.hpp"
|
#include "ui_navigation.hpp"
|
||||||
|
|
||||||
#include "receiver_model.hpp"
|
|
||||||
|
|
||||||
#include "irq_ipc.hpp"
|
#include "irq_ipc.hpp"
|
||||||
#include "irq_lcd_frame.hpp"
|
#include "irq_lcd_frame.hpp"
|
||||||
#include "irq_controls.hpp"
|
#include "irq_controls.hpp"
|
||||||
|
|
||||||
#include "event.hpp"
|
#include "event.hpp"
|
||||||
|
|
||||||
#include "i2c_pp.hpp"
|
|
||||||
#include "spi_pp.hpp"
|
|
||||||
|
|
||||||
#include "m4_startup.hpp"
|
#include "m4_startup.hpp"
|
||||||
|
#include "spi_image.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "led.hpp"
|
#include "led.hpp"
|
||||||
@ -67,12 +53,6 @@ using namespace hackrf::one;
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
I2C i2c0(&I2CD0);
|
|
||||||
SPI ssp0(&SPID1);
|
|
||||||
SPI ssp1(&SPID2);
|
|
||||||
|
|
||||||
wolfson::wm8731::WM8731 audio_codec { i2c0, portapack::wm8731_i2c_address };
|
|
||||||
|
|
||||||
/* From ChibiOS crt0.c:
|
/* From ChibiOS crt0.c:
|
||||||
* Two stacks available for Cortex-M, main stack or process stack.
|
* Two stacks available for Cortex-M, main stack or process stack.
|
||||||
*
|
*
|
||||||
@ -146,112 +126,6 @@ static spi_bus_t ssp0 = {
|
|||||||
* _default_exit() (default is infinite loop)
|
* _default_exit() (default is infinite loop)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
si5351::Si5351 clock_generator {
|
|
||||||
i2c0, si5351_i2c_address
|
|
||||||
};
|
|
||||||
|
|
||||||
ClockManager clock_manager {
|
|
||||||
i2c0, clock_generator
|
|
||||||
};
|
|
||||||
|
|
||||||
ReceiverModel receiver_model {
|
|
||||||
clock_manager
|
|
||||||
};
|
|
||||||
|
|
||||||
class Power {
|
|
||||||
public:
|
|
||||||
void init() {
|
|
||||||
/* VAA powers:
|
|
||||||
* MAX5864 analog section.
|
|
||||||
* MAX2837 registers and other functions.
|
|
||||||
* RFFC5072 analog section.
|
|
||||||
*
|
|
||||||
* Beware that power applied to pins of the MAX2837 may
|
|
||||||
* show up on VAA and start powering other components on the
|
|
||||||
* VAA net. So turn on VAA before driving pins from MCU to
|
|
||||||
* MAX2837.
|
|
||||||
*/
|
|
||||||
/* Turn on VAA */
|
|
||||||
gpio_vaa_disable.clear();
|
|
||||||
gpio_vaa_disable.output();
|
|
||||||
|
|
||||||
/* 1V8 powers CPLD internals.
|
|
||||||
*/
|
|
||||||
/* Turn on 1V8 */
|
|
||||||
gpio_1v8_enable.set();
|
|
||||||
gpio_1v8_enable.output();
|
|
||||||
|
|
||||||
/* Set VREGMODE for switching regulator on HackRF One */
|
|
||||||
gpio_vregmode.set();
|
|
||||||
gpio_vregmode.output();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
static Power power;
|
|
||||||
|
|
||||||
static void init() {
|
|
||||||
for(const auto& pin : pins) {
|
|
||||||
pin.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure other pins */
|
|
||||||
LPC_SCU->SFSI2C0 =
|
|
||||||
(1U << 3)
|
|
||||||
| (1U << 11)
|
|
||||||
;
|
|
||||||
|
|
||||||
power.init();
|
|
||||||
|
|
||||||
gpio_max5864_select.set();
|
|
||||||
gpio_max5864_select.output();
|
|
||||||
|
|
||||||
gpio_max2837_select.set();
|
|
||||||
gpio_max2837_select.output();
|
|
||||||
|
|
||||||
led_usb.setup();
|
|
||||||
led_rx.setup();
|
|
||||||
led_tx.setup();
|
|
||||||
|
|
||||||
clock_manager.init();
|
|
||||||
clock_manager.run_at_full_speed();
|
|
||||||
|
|
||||||
clock_manager.start_audio_pll();
|
|
||||||
audio_codec.init();
|
|
||||||
|
|
||||||
clock_manager.enable_first_if_clock();
|
|
||||||
clock_manager.enable_second_if_clock();
|
|
||||||
clock_manager.enable_codec_clocks();
|
|
||||||
radio::init();
|
|
||||||
|
|
||||||
touch::adc::init();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
void __late_init(void) {
|
|
||||||
|
|
||||||
reset();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* System initializations.
|
|
||||||
* - HAL initialization, this also initializes the configured device drivers
|
|
||||||
* and performs the board-specific initializations.
|
|
||||||
* - Kernel initialization, the main() function becomes a thread and the
|
|
||||||
* RTOS is active.
|
|
||||||
*/
|
|
||||||
halInit();
|
|
||||||
|
|
||||||
/* After this call, scheduler, systick, heap, etc. are available. */
|
|
||||||
/* By doing chSysInit() here, it runs before C++ constructors, which may
|
|
||||||
* require the heap.
|
|
||||||
*/
|
|
||||||
chSysInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
CH_IRQ_HANDLER(RTC_IRQHandler) {
|
CH_IRQ_HANDLER(RTC_IRQHandler) {
|
||||||
@ -600,18 +474,8 @@ message_handlers[Message::ID::TestResults] = [&system_view](const Message* const
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
portapack::IO portapack::io {
|
|
||||||
portapack::gpio_dir,
|
|
||||||
portapack::gpio_lcd_rd,
|
|
||||||
portapack::gpio_lcd_wr,
|
|
||||||
portapack::gpio_io_stbx,
|
|
||||||
portapack::gpio_addr,
|
|
||||||
portapack::gpio_lcd_te,
|
|
||||||
portapack::gpio_unused,
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
init();
|
portapack::init();
|
||||||
|
|
||||||
if( !cpld_update_if_necessary() ) {
|
if( !cpld_update_if_necessary() ) {
|
||||||
chSysHalt();
|
chSysHalt();
|
||||||
@ -622,7 +486,7 @@ int main(void) {
|
|||||||
|
|
||||||
portapack::io.init();
|
portapack::io.init();
|
||||||
ui::Context context;
|
ui::Context context;
|
||||||
context.display.init();
|
portapack::display.init();
|
||||||
|
|
||||||
sdcStart(&SDCD1, nullptr);
|
sdcStart(&SDCD1, nullptr);
|
||||||
|
|
||||||
@ -639,17 +503,17 @@ int main(void) {
|
|||||||
context,
|
context,
|
||||||
{ 0, 0, 240, 320 }
|
{ 0, 0, 240, 320 }
|
||||||
};
|
};
|
||||||
ui::Painter painter { context.display };
|
ui::Painter painter;
|
||||||
EventDispatcher event_dispatcher { &system_view, painter, context };
|
EventDispatcher event_dispatcher { &system_view, painter, context };
|
||||||
|
|
||||||
context.message_map[Message::ID::FSKPacket] = [](const Message* const p) {
|
context.message_map[Message::ID::FSKPacket] = [](const Message* const p) {
|
||||||
const auto message = static_cast<const FSKPacketMessage*>(p);
|
const auto message = static_cast<const FSKPacketMessage*>(p);
|
||||||
(void)message;
|
(void)message;
|
||||||
led_usb.toggle();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
m4txevent_interrupt_enable();
|
m4txevent_interrupt_enable();
|
||||||
m4_init();
|
|
||||||
|
m4_init(portapack::spi_flash::baseband, portapack::spi_flash::m4_text_ram_base);
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
const auto events = event_dispatcher.wait();
|
const auto events = event_dispatcher.wait();
|
||||||
|
183
firmware/application/portapack.cpp
Normal file
183
firmware/application/portapack.cpp
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
*
|
||||||
|
* 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 "portapack.hpp"
|
||||||
|
#include "portapack_hal.hpp"
|
||||||
|
|
||||||
|
#include "hackrf_hal.hpp"
|
||||||
|
#include "hackrf_gpio.hpp"
|
||||||
|
using namespace hackrf::one;
|
||||||
|
|
||||||
|
#include "si5351.hpp"
|
||||||
|
#include "clock_manager.hpp"
|
||||||
|
|
||||||
|
#include "i2c_pp.hpp"
|
||||||
|
|
||||||
|
#include "touch_adc.hpp"
|
||||||
|
|
||||||
|
namespace portapack {
|
||||||
|
|
||||||
|
portapack::IO io {
|
||||||
|
portapack::gpio_dir,
|
||||||
|
portapack::gpio_lcd_rd,
|
||||||
|
portapack::gpio_lcd_wr,
|
||||||
|
portapack::gpio_io_stbx,
|
||||||
|
portapack::gpio_addr,
|
||||||
|
portapack::gpio_lcd_te,
|
||||||
|
portapack::gpio_unused,
|
||||||
|
};
|
||||||
|
|
||||||
|
lcd::ILI9341 display;
|
||||||
|
|
||||||
|
I2C i2c0(&I2CD0);
|
||||||
|
SPI ssp0(&SPID1);
|
||||||
|
SPI ssp1(&SPID2);
|
||||||
|
|
||||||
|
wolfson::wm8731::WM8731 audio_codec { i2c0, portapack::wm8731_i2c_address };
|
||||||
|
|
||||||
|
si5351::Si5351 clock_generator {
|
||||||
|
i2c0, hackrf::one::si5351_i2c_address
|
||||||
|
};
|
||||||
|
|
||||||
|
ClockManager clock_manager {
|
||||||
|
i2c0, clock_generator
|
||||||
|
};
|
||||||
|
|
||||||
|
ReceiverModel receiver_model {
|
||||||
|
clock_manager
|
||||||
|
};
|
||||||
|
|
||||||
|
class Power {
|
||||||
|
public:
|
||||||
|
void init() {
|
||||||
|
/* VAA powers:
|
||||||
|
* MAX5864 analog section.
|
||||||
|
* MAX2837 registers and other functions.
|
||||||
|
* RFFC5072 analog section.
|
||||||
|
*
|
||||||
|
* Beware that power applied to pins of the MAX2837 may
|
||||||
|
* show up on VAA and start powering other components on the
|
||||||
|
* VAA net. So turn on VAA before driving pins from MCU to
|
||||||
|
* MAX2837.
|
||||||
|
*/
|
||||||
|
/* Turn on VAA */
|
||||||
|
gpio_vaa_disable.clear();
|
||||||
|
gpio_vaa_disable.output();
|
||||||
|
|
||||||
|
/* 1V8 powers CPLD internals.
|
||||||
|
*/
|
||||||
|
/* Turn on 1V8 */
|
||||||
|
gpio_1v8_enable.set();
|
||||||
|
gpio_1v8_enable.output();
|
||||||
|
|
||||||
|
/* Set VREGMODE for switching regulator on HackRF One */
|
||||||
|
gpio_vregmode.set();
|
||||||
|
gpio_vregmode.output();
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown() {
|
||||||
|
gpio_1v8_enable.clear();
|
||||||
|
gpio_vaa_disable.set();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
static Power power;
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
for(const auto& pin : pins) {
|
||||||
|
pin.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configure other pins */
|
||||||
|
LPC_SCU->SFSI2C0 =
|
||||||
|
(1U << 3)
|
||||||
|
| (1U << 11)
|
||||||
|
;
|
||||||
|
|
||||||
|
power.init();
|
||||||
|
|
||||||
|
gpio_max5864_select.set();
|
||||||
|
gpio_max5864_select.output();
|
||||||
|
|
||||||
|
gpio_max2837_select.set();
|
||||||
|
gpio_max2837_select.output();
|
||||||
|
|
||||||
|
led_usb.setup();
|
||||||
|
led_rx.setup();
|
||||||
|
led_tx.setup();
|
||||||
|
|
||||||
|
clock_manager.init();
|
||||||
|
clock_manager.run_at_full_speed();
|
||||||
|
|
||||||
|
clock_manager.start_audio_pll();
|
||||||
|
audio_codec.init();
|
||||||
|
|
||||||
|
clock_manager.enable_first_if_clock();
|
||||||
|
clock_manager.enable_second_if_clock();
|
||||||
|
clock_manager.enable_codec_clocks();
|
||||||
|
radio::init();
|
||||||
|
|
||||||
|
touch::adc::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown() {
|
||||||
|
sdcStop(&SDCD1);
|
||||||
|
|
||||||
|
display.shutdown();
|
||||||
|
|
||||||
|
radio::disable();
|
||||||
|
audio_codec.reset();
|
||||||
|
clock_manager.shutdown();
|
||||||
|
|
||||||
|
power.shutdown();
|
||||||
|
// TODO: Wait a bit for supplies to discharge?
|
||||||
|
|
||||||
|
chSysDisable();
|
||||||
|
hackrf::one::reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void __late_init(void) {
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System initializations.
|
||||||
|
* - HAL initialization, this also initializes the configured device drivers
|
||||||
|
* and performs the board-specific initializations.
|
||||||
|
* - Kernel initialization, the main() function becomes a thread and the
|
||||||
|
* RTOS is active.
|
||||||
|
*/
|
||||||
|
halInit();
|
||||||
|
|
||||||
|
/* After this call, scheduler, systick, heap, etc. are available. */
|
||||||
|
/* By doing chSysInit() here, it runs before C++ constructors, which may
|
||||||
|
* require the heap.
|
||||||
|
*/
|
||||||
|
chSysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace portapack */
|
48
firmware/application/portapack.hpp
Normal file
48
firmware/application/portapack.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
*
|
||||||
|
* 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 "portapack_io.hpp"
|
||||||
|
|
||||||
|
#include "receiver_model.hpp"
|
||||||
|
|
||||||
|
#include "spi_pp.hpp"
|
||||||
|
#include "wm8731.hpp"
|
||||||
|
#include "lcd_ili9341.hpp"
|
||||||
|
|
||||||
|
#include "radio.hpp"
|
||||||
|
|
||||||
|
namespace portapack {
|
||||||
|
|
||||||
|
extern portapack::IO io;
|
||||||
|
|
||||||
|
extern lcd::ILI9341 display;
|
||||||
|
|
||||||
|
extern SPI ssp0;
|
||||||
|
extern SPI ssp1;
|
||||||
|
|
||||||
|
extern wolfson::wm8731::WM8731 audio_codec;
|
||||||
|
|
||||||
|
extern ReceiverModel receiver_model;
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
} /* namespace portapack */
|
@ -36,8 +36,7 @@
|
|||||||
#include "hackrf_gpio.hpp"
|
#include "hackrf_gpio.hpp"
|
||||||
using namespace hackrf::one;
|
using namespace hackrf::one;
|
||||||
|
|
||||||
#include "spi_pp.hpp"
|
#include "portapack.hpp"
|
||||||
extern SPI ssp1;
|
|
||||||
|
|
||||||
namespace radio {
|
namespace radio {
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ static constexpr SPIConfig ssp_config_max5864 = {
|
|||||||
.cpsr = ssp1_cpsr,
|
.cpsr = ssp1_cpsr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static spi::arbiter::Arbiter ssp1_arbiter(ssp1);
|
static spi::arbiter::Arbiter ssp1_arbiter(portapack::ssp1);
|
||||||
|
|
||||||
static spi::arbiter::Target ssp1_target_max2837 {
|
static spi::arbiter::Target ssp1_target_max2837 {
|
||||||
ssp1_arbiter,
|
ssp1_arbiter,
|
||||||
|
@ -22,13 +22,8 @@
|
|||||||
#include "receiver_model.hpp"
|
#include "receiver_model.hpp"
|
||||||
|
|
||||||
#include "portapack_shared_memory.hpp"
|
#include "portapack_shared_memory.hpp"
|
||||||
#include "radio.hpp"
|
#include "portapack.hpp"
|
||||||
#include "wm8731.hpp"
|
using namespace portapack;
|
||||||
|
|
||||||
// TODO: Nasty. Put this in an #include somewhere, or a shared system state
|
|
||||||
// object?
|
|
||||||
|
|
||||||
extern wolfson::wm8731::WM8731 audio_codec;
|
|
||||||
|
|
||||||
rf::Frequency ReceiverModel::tuning_frequency() const {
|
rf::Frequency ReceiverModel::tuning_frequency() const {
|
||||||
return tuning_frequency_;
|
return tuning_frequency_;
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
#include "ui_console.hpp"
|
#include "ui_console.hpp"
|
||||||
|
|
||||||
|
#include "portapack.hpp"
|
||||||
|
using namespace portapack;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void Console::write(const std::string message) {
|
void Console::write(const std::string message) {
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
#include "ui_painter.hpp"
|
#include "ui_painter.hpp"
|
||||||
#include "ui_widget.hpp"
|
#include "ui_widget.hpp"
|
||||||
|
|
||||||
#include "lcd_ili9341.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
@ -35,10 +33,8 @@ namespace ui {
|
|||||||
class Console : public Widget {
|
class Console : public Widget {
|
||||||
public:
|
public:
|
||||||
constexpr Console(
|
constexpr Console(
|
||||||
const Rect parent_rect,
|
const Rect parent_rect
|
||||||
lcd::ILI9341& display
|
) : Widget { parent_rect }
|
||||||
) : Widget { parent_rect },
|
|
||||||
display(display)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +48,6 @@ private:
|
|||||||
static constexpr Color foreground { Color::white() };
|
static constexpr Color foreground { Color::white() };
|
||||||
|
|
||||||
Point pos { 0, 0 };
|
Point pos { 0, 0 };
|
||||||
lcd::ILI9341& display;
|
|
||||||
|
|
||||||
void crlf();
|
void crlf();
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,10 @@
|
|||||||
#include "ui_debug.hpp"
|
#include "ui_debug.hpp"
|
||||||
#include "ui_receiver.hpp"
|
#include "ui_receiver.hpp"
|
||||||
|
|
||||||
extern ReceiverModel receiver_model;
|
#include "portapack.hpp"
|
||||||
|
#include "m4_startup.hpp"
|
||||||
|
#include "spi_image.hpp"
|
||||||
|
using namespace portapack;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
@ -97,13 +100,14 @@ void NavigationView::focus() {
|
|||||||
/* SystemMenuView ********************************************************/
|
/* SystemMenuView ********************************************************/
|
||||||
|
|
||||||
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||||
add_items<6>({ {
|
add_items<7>({ {
|
||||||
{ "Receiver", [&nav](){ nav.push(new ReceiverView { nav, receiver_model }); } },
|
{ "Receiver", [&nav](){ nav.push(new ReceiverView { nav, receiver_model }); } },
|
||||||
{ "Capture", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
{ "Capture", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||||
{ "Analyze", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
{ "Analyze", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||||
{ "Setup", [&nav](){ nav.push(new SetupMenuView { nav }); } },
|
{ "Setup", [&nav](){ nav.push(new SetupMenuView { nav }); } },
|
||||||
{ "About", [&nav](){ nav.push(new AboutView { nav }); } },
|
{ "About", [&nav](){ nav.push(new AboutView { nav }); } },
|
||||||
{ "Debug", [&nav](){ nav.push(new DebugMenuView { nav }); } },
|
{ "Debug", [&nav](){ nav.push(new DebugMenuView { nav }); } },
|
||||||
|
{ "HackRF", [&nav](){ nav.push(new HackRFFirmwareView { nav }); } },
|
||||||
} });
|
} });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,6 +150,34 @@ Context& SystemView::context() const {
|
|||||||
return context_;
|
return context_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HackRFFirmwareView ****************************************************/
|
||||||
|
|
||||||
|
HackRFFirmwareView::HackRFFirmwareView(NavigationView& nav) {
|
||||||
|
button_yes.on_select = [&nav](Button&){
|
||||||
|
shutdown();
|
||||||
|
|
||||||
|
m4_init(spi_flash::hackrf, reinterpret_cast<void*>(0x10000000));
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
__WFE();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
button_no.on_select = [&nav](Button&){
|
||||||
|
nav.pop();
|
||||||
|
};
|
||||||
|
|
||||||
|
add_children({ {
|
||||||
|
&text_title,
|
||||||
|
&button_yes,
|
||||||
|
&button_no,
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackRFFirmwareView::focus() {
|
||||||
|
button_no.focus();
|
||||||
|
}
|
||||||
|
|
||||||
/* NotImplementedView ****************************************************/
|
/* NotImplementedView ****************************************************/
|
||||||
|
|
||||||
NotImplementedView::NotImplementedView(NavigationView& nav) {
|
NotImplementedView::NotImplementedView(NavigationView& nav) {
|
||||||
|
@ -107,6 +107,29 @@ private:
|
|||||||
Context& context_;
|
Context& context_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HackRFFirmwareView : public View {
|
||||||
|
public:
|
||||||
|
HackRFFirmwareView(NavigationView& nav);
|
||||||
|
|
||||||
|
void focus() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Text text_title {
|
||||||
|
{ 6 * 8, 7 * 16, 19 * 8, 16 },
|
||||||
|
"Enter HackRF Mode?"
|
||||||
|
};
|
||||||
|
|
||||||
|
Button button_yes {
|
||||||
|
{ 4 * 8, 13 * 16, 8 * 8, 24 },
|
||||||
|
"Yes",
|
||||||
|
};
|
||||||
|
|
||||||
|
Button button_no {
|
||||||
|
{ 18 * 8, 13 * 16, 8 * 8, 24 },
|
||||||
|
"No",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class NotImplementedView : public View {
|
class NotImplementedView : public View {
|
||||||
public:
|
public:
|
||||||
NotImplementedView(NavigationView& nav);
|
NotImplementedView(NavigationView& nav);
|
||||||
|
@ -21,11 +21,8 @@
|
|||||||
|
|
||||||
#include "ui_receiver.hpp"
|
#include "ui_receiver.hpp"
|
||||||
|
|
||||||
// TODO: Nasty. Put this in an #include somewhere, or a shared system state
|
#include "portapack.hpp"
|
||||||
// object?
|
using namespace portapack;
|
||||||
|
|
||||||
#include "wm8731.hpp"
|
|
||||||
extern wolfson::wm8731::WM8731 audio_codec;
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
@ -26,7 +26,9 @@
|
|||||||
#include "ui_widget.hpp"
|
#include "ui_widget.hpp"
|
||||||
#include "spectrum_color_lut.hpp"
|
#include "spectrum_color_lut.hpp"
|
||||||
|
|
||||||
#include "lcd_ili9341.hpp"
|
#include "portapack.hpp"
|
||||||
|
using namespace portapack;
|
||||||
|
|
||||||
#include "message.hpp"
|
#include "message.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -180,14 +182,14 @@ class WaterfallView : public Widget {
|
|||||||
public:
|
public:
|
||||||
void on_show() override {
|
void on_show() override {
|
||||||
const auto screen_r = screen_rect();
|
const auto screen_r = screen_rect();
|
||||||
context().display.scroll_set_area(screen_r.top(), screen_r.bottom());
|
display.scroll_set_area(screen_r.top(), screen_r.bottom());
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_hide() override {
|
void on_hide() override {
|
||||||
/* TODO: Clear region to eliminate brief flash of content at un-shifted
|
/* TODO: Clear region to eliminate brief flash of content at un-shifted
|
||||||
* position?
|
* position?
|
||||||
*/
|
*/
|
||||||
context().display.scroll_disable();
|
display.scroll_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter& painter) override {
|
void paint(Painter& painter) override {
|
||||||
@ -212,7 +214,6 @@ public:
|
|||||||
pixel_row[i] = pixel_color;
|
pixel_row[i] = pixel_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& display = context().display;
|
|
||||||
const auto draw_y = display.scroll(1);
|
const auto draw_y = display.scroll(1);
|
||||||
|
|
||||||
display.draw_pixels(
|
display.draw_pixels(
|
||||||
|
@ -99,7 +99,7 @@ int main(void) {
|
|||||||
/* NOTE: MEMMAP registers are ORed with the shadow address to create the
|
/* NOTE: MEMMAP registers are ORed with the shadow address to create the
|
||||||
* actual address.
|
* actual address.
|
||||||
*/
|
*/
|
||||||
LPC_CREG->M0APPMEMMAP = LPC_SPIFI_DATA_CACHED_BASE + 0x20000;
|
LPC_CREG->M0APPMEMMAP = LPC_SPIFI_DATA_CACHED_BASE + 0x40000;
|
||||||
|
|
||||||
/* Change M0APP_RST to 0 */
|
/* Change M0APP_RST to 0 */
|
||||||
LPC_RGU->RESET_CTRL[1] = 0;
|
LPC_RGU->RESET_CTRL[1] = 0;
|
||||||
|
@ -225,6 +225,11 @@ void ILI9341::init() {
|
|||||||
io.lcd_backlight(1);
|
io.lcd_backlight(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ILI9341::shutdown() {
|
||||||
|
io.lcd_backlight(0);
|
||||||
|
lcd_reset();
|
||||||
|
}
|
||||||
|
|
||||||
void ILI9341::fill_rectangle(ui::Rect r, const ui::Color c) {
|
void ILI9341::fill_rectangle(ui::Rect r, const ui::Color c) {
|
||||||
const auto r_clipped = r.intersect(screen_rect());
|
const auto r_clipped = r.intersect(screen_rect());
|
||||||
if( !r_clipped.is_empty() ) {
|
if( !r_clipped.is_empty() ) {
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
void operator=(const ILI9341&) = delete;
|
void operator=(const ILI9341&) = delete;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
void fill_rectangle(ui::Rect r, const ui::Color c);
|
void fill_rectangle(ui::Rect r, const ui::Color c);
|
||||||
void fill_circle(
|
void fill_circle(
|
||||||
|
68
firmware/common/spi_image.hpp
Normal file
68
firmware/common/spi_image.hpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
*
|
||||||
|
* 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 __SPI_IMAGE_H__
|
||||||
|
#define __SPI_IMAGE_H__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
namespace portapack {
|
||||||
|
namespace spi_flash {
|
||||||
|
|
||||||
|
struct region_t {
|
||||||
|
const size_t offset;
|
||||||
|
const size_t size;
|
||||||
|
|
||||||
|
constexpr const void* base_address() {
|
||||||
|
return reinterpret_cast<void*>(LPC_SPIFI_DATA_CACHED_BASE + offset);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr region_t bootstrap {
|
||||||
|
.offset = 0x00000,
|
||||||
|
.size = 0x10000,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr region_t hackrf {
|
||||||
|
.offset = 0x10010, // Image starts at 0x10 into .dfu file.
|
||||||
|
.size = 0x8000,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr region_t baseband {
|
||||||
|
.offset = 0x20000,
|
||||||
|
.size = 0x8000,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr region_t application {
|
||||||
|
.offset = 0x40000,
|
||||||
|
.size = 0x40000,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Refactor into another header that defines memory regions.
|
||||||
|
constexpr void* m4_text_ram_base = reinterpret_cast<void*>(0x10080000);
|
||||||
|
|
||||||
|
} /* namespace spi_flash */
|
||||||
|
} /* namespace portapack */
|
||||||
|
|
||||||
|
#endif/*__SPI_IMAGE_H__*/
|
@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
#include "ui_painter.hpp"
|
#include "ui_painter.hpp"
|
||||||
|
|
||||||
|
#include "portapack.hpp"
|
||||||
|
using namespace portapack;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
Style Style::invert() const {
|
Style Style::invert() const {
|
||||||
@ -33,7 +36,7 @@ Style Style::invert() const {
|
|||||||
|
|
||||||
size_t Painter::draw_char(const Point p, const Style& style, const char c) {
|
size_t Painter::draw_char(const Point p, const Style& style, const char c) {
|
||||||
const auto glyph = style.font.glyph(c);
|
const auto glyph = style.font.glyph(c);
|
||||||
display_.draw_glyph(p, glyph, style.foreground, style.background);
|
display.draw_glyph(p, glyph, style.foreground, style.background);
|
||||||
return glyph.advance().x;
|
return glyph.advance().x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +44,7 @@ size_t Painter::draw_string(Point p, const Style& style, const std::string text)
|
|||||||
size_t width = 0;
|
size_t width = 0;
|
||||||
for(const auto c : text) {
|
for(const auto c : text) {
|
||||||
const auto glyph = style.font.glyph(c);
|
const auto glyph = style.font.glyph(c);
|
||||||
display_.draw_glyph(p, glyph, style.foreground, style.background);
|
display.draw_glyph(p, glyph, style.foreground, style.background);
|
||||||
const auto advance = glyph.advance();
|
const auto advance = glyph.advance();
|
||||||
p += advance;
|
p += advance;
|
||||||
width += advance.x;
|
width += advance.x;
|
||||||
@ -50,11 +53,11 @@ size_t Painter::draw_string(Point p, const Style& style, const std::string text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_hline(Point p, size_t width, const Color c) {
|
void Painter::draw_hline(Point p, size_t width, const Color c) {
|
||||||
display_.fill_rectangle({ p, { static_cast<Dim>(width), 1 } }, c);
|
display.fill_rectangle({ p, { static_cast<Dim>(width), 1 } }, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_vline(Point p, size_t height, const Color c) {
|
void Painter::draw_vline(Point p, size_t height, const Color c) {
|
||||||
display_.fill_rectangle({ p, { 1, static_cast<Dim>(height) } }, c);
|
display.fill_rectangle({ p, { 1, static_cast<Dim>(height) } }, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Painter::draw_rectangle(const Rect r, const Color c) {
|
void Painter::draw_rectangle(const Rect r, const Color c) {
|
||||||
@ -65,7 +68,7 @@ void Painter::draw_rectangle(const Rect r, const Color c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Painter::fill_rectangle(const Rect r, const Color c) {
|
void Painter::fill_rectangle(const Rect r, const Color c) {
|
||||||
display_.fill_rectangle(r, c);
|
display.fill_rectangle(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ui */
|
} /* namespace ui */
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
#include "ui.hpp"
|
#include "ui.hpp"
|
||||||
#include "ui_text.hpp"
|
#include "ui_text.hpp"
|
||||||
|
|
||||||
#include "lcd_ili9341.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
@ -41,11 +39,7 @@ struct Style {
|
|||||||
|
|
||||||
class Painter {
|
class Painter {
|
||||||
public:
|
public:
|
||||||
Painter(
|
Painter() { };
|
||||||
lcd::ILI9341& display
|
|
||||||
) : display_(display)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Painter(const Painter&) = delete;
|
Painter(const Painter&) = delete;
|
||||||
Painter(Painter&&) = delete;
|
Painter(Painter&&) = delete;
|
||||||
@ -58,8 +52,6 @@ public:
|
|||||||
void fill_rectangle(const Rect r, const Color c);
|
void fill_rectangle(const Rect r, const Color c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lcd::ILI9341& display_;
|
|
||||||
|
|
||||||
void draw_hline(Point p, size_t width, const Color c);
|
void draw_hline(Point p, size_t width, const Color c);
|
||||||
void draw_vline(Point p, size_t height, const Color c);
|
void draw_vline(Point p, size_t height, const Color c);
|
||||||
};
|
};
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include "lcd_ili9341.hpp"
|
|
||||||
#include "message.hpp"
|
#include "message.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -48,7 +47,6 @@ std::string to_string_hex(const uint32_t n, const int32_t l = 0);
|
|||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
FocusManager focus_manager;
|
FocusManager focus_manager;
|
||||||
lcd::ILI9341 display;
|
|
||||||
MessageHandlerMap message_map;
|
MessageHandlerMap message_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user