Merge 'upstream/master' - At least it builds...

This commit is contained in:
furrtek
2017-01-16 03:45:44 +00:00
298 changed files with 8122 additions and 4685 deletions
+31 -34
View File
@@ -52,84 +52,81 @@ struct Config {
uint32_t cr;
};
template<uint32_t BaseAddress>
class ADC {
public:
constexpr ADC(
LPC_ADCx_Type* adcp
) : adcp(adcp)
{
static void power_up(const Config config) {
adcp().CR = config.cr;
}
void power_up(const Config config) const {
adcp->CR = config.cr;
}
void clock_enable() const {
if( adcp == LPC_ADC0 ) {
static void clock_enable() {
if( &adcp() == LPC_ADC0 ) {
LPC_CCU1->CLK_APB3_ADC0_CFG.AUTO = 1;
LPC_CCU1->CLK_APB3_ADC0_CFG.RUN = 1;
}
if( adcp == LPC_ADC1 ) {
if( &adcp() == LPC_ADC1 ) {
LPC_CCU1->CLK_APB3_ADC1_CFG.AUTO = 1;
LPC_CCU1->CLK_APB3_ADC1_CFG.RUN = 1;
}
}
void clock_disable() const {
if( adcp == LPC_ADC0 ) {
static void clock_disable() {
if( &adcp() == LPC_ADC0 ) {
LPC_CCU1->CLK_APB3_ADC0_CFG.RUN = 0;
}
if( adcp == LPC_ADC1 ) {
if( &adcp() == LPC_ADC1 ) {
LPC_CCU1->CLK_APB3_ADC1_CFG.RUN = 0;
}
}
void disable() const {
adcp->INTEN = 0;
adcp->CR = 0;
static void disable() {
adcp().INTEN = 0;
adcp().CR = 0;
clock_disable();
}
void interrupts_disable() const {
adcp->INTEN = 0;
static void interrupts_disable() {
adcp().INTEN = 0;
}
void interrupts_enable(const uint32_t mask) const {
adcp->INTEN = mask;
static void interrupts_enable(const uint32_t mask) {
adcp().INTEN = mask;
}
void start_burst() const {
adcp->CR |= (1U << 16);
static void start_burst() {
adcp().CR |= (1U << 16);
}
void start_once() const {
adcp->CR |= (1U << 24);
static void start_once() {
adcp().CR |= (1U << 24);
}
void start_once(size_t n) const {
uint32_t cr = adcp->CR;
static void start_once(size_t n) {
uint32_t cr = adcp().CR;
cr &= ~(0xffU);
cr |= (1 << 24) | (1 << n);
adcp->CR = cr;
adcp().CR = cr;
}
void stop_burst() const {
adcp->CR &= ~(1U << 16);
static void stop_burst() {
adcp().CR &= ~(1U << 16);
}
uint32_t convert(size_t n) const {
static uint32_t convert(size_t n) {
start_once(n);
while(true) {
const uint32_t data = adcp->DR[n];
const uint32_t data = adcp().DR[n];
if( (data >> 31) & 1 ) {
return (data >> 6) & 0x3ff;
}
}
}
private:
LPC_ADCx_Type* const adcp;
static LPC_ADCx_Type& adcp() {
return *reinterpret_cast<LPC_ADCx_Type*>(BaseAddress);
}
};
} /* namespace adc */
+7 -15
View File
@@ -32,21 +32,13 @@
namespace baseband {
namespace ais {
// RRC length should be about 4 x the symbol length (4T) to do a good job of
// cleaning up ISI.
// Translate+RRC filter
// sample=38.4k, deviation=2400, b=0.5, symbol=9600
// Length: 16 taps, 4 symbols, 1 cycles of sinusoid
constexpr std::array<std::complex<float>, 16> rrc_taps_38k4_4t_p { {
{ 1.0619794019e-02f, 0.0000000000e+00f }, { 3.5758705854e-03f, 1.4811740938e-03f },
{ -1.3274742629e-02f, -1.3274742629e-02f }, { -1.5018657262e-02f, -3.6258246051e-02f },
{ 0.0000000000e+00f, -2.6549484581e-02f }, { -1.5018657262e-02f, 3.6258246051e-02f },
{ -1.0237997393e-01f, 1.0237997393e-01f }, { -2.2527985355e-01f, 9.3313970669e-02f },
{ -2.8440842032e-01f, 0.0000000000e+00f }, { -2.2527985355e-01f, -9.3313970669e-02f },
{ -1.0237997393e-01f, -1.0237997393e-01f }, { -1.5018657262e-02f, -3.6258246051e-02f },
{ 0.0000000000e+00f, 2.6549484581e-02f }, { -1.5018657262e-02f, 3.6258246051e-02f },
{ -1.3274742629e-02f, 1.3274742629e-02f }, { 3.5758705854e-03f, -1.4811740938e-03f },
// Translate+Rectangular window filter
// sample=38.4k, deviation=2400, symbol=9600
// Length: 4 taps, 1 symbol, 1/4 cycle of sinusoid
// Gain: 1.0 (sinusoid / len(taps))
constexpr std::array<std::complex<float>, 4> square_taps_38k4_1t_p { {
{ 0.25000000f, 0.00000000f }, { 0.23096988f, 0.09567086f },
{ 0.17677670f, 0.17677670f }, { 0.09567086f, 0.23096988f },
} };
} /* namespace ais */
+1 -1
View File
@@ -62,7 +62,7 @@ public:
}
private:
std::bitset<1408> data;
std::bitset<1408> data { };
Timestamp timestamp_ { };
size_t count { 0 };
};
+11 -4
View File
@@ -184,13 +184,13 @@ constexpr Slice slice_order[] {
};
constexpr uint32_t gpio_outreg(const Direction direction) {
return ((direction == Direction::Transmit) ? (1U << 11) : 0U) | (1U << 10);
return ((direction == Direction::Transmit) ? (1U << PIN_DIRECTION) : 0U) | (1U << PIN_DISABLE);
}
constexpr uint32_t gpio_oenreg(const Direction direction) {
return
(0U << PIN_DECIM2)
| (1U << PIN_DECIM1)
| (0U << PIN_DECIM1)
| (0U << PIN_DECIM0)
| (0U << PIN_INVERT)
| (1U << PIN_DIRECTION)
@@ -282,7 +282,7 @@ constexpr CLK_CAPTURE_MODE data_clk_capture_mode(
) {
return (direction == Direction::Transmit)
? CLK_CAPTURE_MODE::RISING_CLOCK_EDGE
: CLK_CAPTURE_MODE::FALLING_CLOCK_EDGE
: CLK_CAPTURE_MODE::RISING_CLOCK_EDGE
;
}
@@ -298,8 +298,12 @@ constexpr P_OUT_CFG data_p_out_cfg(
void SGPIO::configure(const Direction direction) {
disable_all_slice_counters();
// Set data pins as input, temporarily.
LPC_SGPIO->GPIO_OENREG = gpio_oenreg(Direction::Receive);
// Now that data pins are inputs, safe to change CPLD direction.
LPC_SGPIO->GPIO_OUTREG = gpio_outreg(direction);
LPC_SGPIO->GPIO_OENREG = gpio_oenreg(direction);
LPC_SGPIO->OUT_MUX_CFG[ 8] = out_mux_cfg(P_OUT_CFG::DOUT_DOUTM1, P_OE_CFG::GPIO_OE);
LPC_SGPIO->OUT_MUX_CFG[ 9] = out_mux_cfg(P_OUT_CFG::DOUT_DOUTM1, P_OE_CFG::GPIO_OE);
LPC_SGPIO->OUT_MUX_CFG[10] = out_mux_cfg(P_OUT_CFG::GPIO_OUT, P_OE_CFG::GPIO_OE);
@@ -314,6 +318,9 @@ void SGPIO::configure(const Direction direction) {
LPC_SGPIO->OUT_MUX_CFG[i] = data_out_mux_cfg;
}
// Now that output enable sources are set, enable data bus in correct direction.
LPC_SGPIO->GPIO_OENREG = gpio_oenreg(direction);
const auto slice_gpdma = Slice::H;
const size_t slice_count = slice_mode_multislice ? 8 : 1;
+36
View File
@@ -0,0 +1,36 @@
/*
* 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 "buffer.hpp"
#if defined(LPC43XX_M4)
#include "lpc43xx_m4.h"
Timestamp Timestamp::now() {
// Code stolen from LPC43xx rtc_lld.c
Timestamp timestamp;
do {
timestamp.tv_time = LPC_RTC->CTIME0;
timestamp.tv_date = LPC_RTC->CTIME1;
} while( (timestamp.tv_time != LPC_RTC->CTIME0) || (timestamp.tv_date != LPC_RTC->CTIME1) );
return timestamp;
}
#endif
+1 -11
View File
@@ -33,21 +33,11 @@
* a knot to tackle at the moment, though...
*/
#if defined(LPC43XX_M4)
#include "lpc43xx_m4.h"
struct Timestamp {
uint32_t tv_date { 0 };
uint32_t tv_time { 0 };
static Timestamp now() {
// Code stolen from LPC43xx rtc_lld.c
Timestamp timestamp;
do {
timestamp.tv_time = LPC_RTC->CTIME0;
timestamp.tv_date = LPC_RTC->CTIME1;
} while( (timestamp.tv_time != LPC_RTC->CTIME0) || (timestamp.tv_date != LPC_RTC->CTIME1) );
return timestamp;
}
static Timestamp now();
};
#endif
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2016 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 "buffer_exchange.hpp"
BufferExchange* BufferExchange::obj { nullptr };
BufferExchange::BufferExchange(
CaptureConfig* const config
) : config { config }
{
obj = this;
fifo_buffers_for_baseband = config->fifo_buffers_empty;
fifo_buffers_for_application = config->fifo_buffers_full;
}
BufferExchange::~BufferExchange() {
obj = nullptr;
fifo_buffers_for_baseband = nullptr;
fifo_buffers_for_application = nullptr;
}
StreamBuffer* BufferExchange::get(FIFO<StreamBuffer*>* fifo) {
while(true) {
StreamBuffer* p { nullptr };
fifo->out(p);
if( p ) {
return p;
}
chSysLock();
thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
chSysUnlock();
}
}
+96
View File
@@ -0,0 +1,96 @@
/*
* Copyright (C) 2016 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.
*/
#pragma once
#include "ch.h"
#include "message.hpp"
#include "fifo.hpp"
#include "io.hpp"
class BufferExchange {
public:
BufferExchange(CaptureConfig* const config);
~BufferExchange();
BufferExchange(const BufferExchange&) = delete;
BufferExchange(BufferExchange&&) = delete;
BufferExchange& operator=(const BufferExchange&) = delete;
BufferExchange& operator=(BufferExchange&&) = delete;
#if defined(LPC43XX_M0)
bool empty() const {
return fifo_buffers_for_application->is_empty();
}
StreamBuffer* get() {
return get(fifo_buffers_for_application);
}
bool put(StreamBuffer* const p) {
return fifo_buffers_for_baseband->in(p);
}
#endif
#if defined(LPC43XX_M4)
bool empty() const {
return fifo_buffers_for_baseband->is_empty();
}
StreamBuffer* get() {
return get(fifo_buffers_for_baseband);
}
bool put(StreamBuffer* const p) {
return fifo_buffers_for_application->in(p);
}
#endif
static void handle_isr() {
if( obj ) {
obj->check_fifo_isr();
}
}
private:
CaptureConfig* const config;
FIFO<StreamBuffer*>* fifo_buffers_for_baseband { nullptr };
FIFO<StreamBuffer*>* fifo_buffers_for_application { nullptr };
Thread* thread { nullptr };
static BufferExchange* obj;
void check_fifo_isr() {
if( !empty() ) {
wakeup_isr();
}
}
void wakeup_isr() {
auto thread_tmp = thread;
if( thread_tmp ) {
thread = nullptr;
chSchReadyI(thread_tmp);
}
}
StreamBuffer* get(FIFO<StreamBuffer*>* fifo);
};
+8
View File
@@ -41,6 +41,14 @@ void operator delete[](void* p) noexcept {
chHeapFree(p);
}
void operator delete(void* ptr, std::size_t) noexcept {
::operator delete(ptr);
}
void operator delete[](void* ptr, std::size_t) noexcept {
::operator delete(ptr);
}
extern uint8_t __heap_base__[];
extern uint8_t __heap_end__[];
+2
View File
@@ -30,6 +30,8 @@ void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void* p);
void operator delete[](void* p);
void operator delete(void* ptr, std::size_t);
void operator delete[](void* ptr, std::size_t);
namespace chibios {
+7 -7
View File
@@ -35,14 +35,14 @@ struct PinConfig {
const uint32_t input;
const uint32_t ifilt;
constexpr operator uint16_t() {
constexpr operator uint16_t() const {
return
((~ifilt) << 7)
| (input << 6)
| (fast << 5)
| ((~pu) << 4)
| (pd << 3)
| (mode << 0);
(((~ifilt) & 1) << 7)
| ((input & 1) << 6)
| ((fast & 1) << 5)
| (((~pu) & 1) << 4)
| ((pd & 1) << 3)
| ((mode & 7) << 0);
}
/*
constexpr operator uint32_t() {
+1 -6
View File
@@ -71,12 +71,7 @@ constexpr GPIO gpio_max2837_txenable = gpio[GPIO2_4];
constexpr GPIO gpio_max5864_select = gpio[GPIO2_7];
constexpr std::array<GPIO, 3> gpios_baseband_decimation {
gpio[GPIO5_12],
gpio[GPIO5_13],
gpio[GPIO5_14]
};
constexpr GPIO gpio_baseband_q_invert = gpio[GPIO0_13];
constexpr GPIO gpio_baseband_invert = gpio[GPIO0_13];
constexpr GPIO gpio_cpld_tdo = gpio[GPIO5_18];
constexpr GPIO gpio_cpld_tck = gpio[GPIO3_0];
+2 -2
View File
@@ -67,11 +67,11 @@ constexpr size_t clock_generator_output_mcu_clkin = 7;
/* ADC0 */
constexpr adc::ADC adc0 { LPC_ADC0 };
using adc0 = adc::ADC<LPC_ADC0_BASE>;
/* ADC1 */
constexpr adc::ADC adc1 { LPC_ADC1 };
using adc1 = adc::ADC<LPC_ADC1_BASE>;
void reset();
+3 -3
View File
@@ -46,15 +46,15 @@ struct I2CClockConfig {
return 1e9 / f;
}
constexpr uint32_t i2c_period_count() {
constexpr uint32_t i2c_period_count() const {
return period_ns(bus_f) / period_ns(clock_source_f) + 0.5f;
}
constexpr uint32_t i2c_high_count() {
constexpr uint32_t i2c_high_count() const {
return high_period_ns / period_ns(clock_source_f) + 0.5f;
}
constexpr uint32_t i2c_low_count() {
constexpr uint32_t i2c_low_count() const {
return i2c_period_count() - i2c_high_count();
}
};
+24 -22
View File
@@ -155,8 +155,6 @@ struct ConfigDMA {
template<uint32_t BaseAddress>
class I2S {
public:
static constexpr LPC_I2S_Type* Peripheral = reinterpret_cast<LPC_I2S_Type*>(BaseAddress);
static void configure(
const ConfigTX& config_tx,
const ConfigRX& config_rx
@@ -167,28 +165,28 @@ public:
/* NOTE: Documentation of CREG6 is quite confusing. Refer to "I2S clocking and
* pin connections" and other I2S diagrams for more clarity.
*/
if( Peripheral == LPC_I2S0 ) {
if( &p() == LPC_I2S0 ) {
LPC_CREG->CREG6 |=
(1U << 12)
| (1U << 13)
;
}
if( Peripheral == LPC_I2S1 ) {
if( &p() == LPC_I2S1 ) {
LPC_CREG->CREG6 |=
(1U << 14)
| (1U << 15)
;
}
Peripheral->DAO = config_tx.dao;
Peripheral->TXRATE = config_tx.txrate;
Peripheral->TXBITRATE = config_tx.txbitrate;
Peripheral->TXMODE = config_tx.txmode;
p().DAO = config_tx.dao;
p().TXRATE = config_tx.txrate;
p().TXBITRATE = config_tx.txbitrate;
p().TXMODE = config_tx.txmode;
Peripheral->DAI = config_rx.dai;
Peripheral->RXRATE = config_rx.rxrate;
Peripheral->RXBITRATE = config_rx.rxbitrate;
Peripheral->RXMODE = config_rx.rxmode;
p().DAI = config_rx.dai;
p().RXRATE = config_rx.rxrate;
p().RXBITRATE = config_rx.rxbitrate;
p().RXMODE = config_rx.rxmode;
}
static void configure(
@@ -198,38 +196,42 @@ public:
) {
configure(config_tx, config_rx);
Peripheral->DMA1 = config_dma.dma1;
Peripheral->DMA2 = config_dma.dma2;
p().DMA1 = config_dma.dma1;
p().DMA2 = config_dma.dma2;
}
static void rx_start() {
Peripheral->DAI &= ~(1U << 3);
p().DAI &= ~(1U << 3);
}
static void rx_stop() {
Peripheral->DAI |= (1U << 3);
p().DAI |= (1U << 3);
}
static void tx_start() {
Peripheral->DAO &= ~(1U << 3);
p().DAO &= ~(1U << 3);
}
static void tx_stop() {
Peripheral->DAO |= (1U << 3);
p().DAO |= (1U << 3);
}
static void tx_mute() {
Peripheral->DAO |= (1U << 15);
p().DAO |= (1U << 15);
}
static void tx_unmute() {
Peripheral->DAO &= ~(1U << 15);
p().DAO &= ~(1U << 15);
}
private:
static void reset() {
Peripheral->DAO |= (1U << 4);
Peripheral->DAI |= (1U << 4);
p().DAO |= (1U << 4);
p().DAI |= (1U << 4);
}
static LPC_I2S_Type& p() {
return *reinterpret_cast<LPC_I2S_Type*>(BaseAddress);
}
};
+20 -23
View File
@@ -198,8 +198,8 @@ void lcd_start_ram_write(
const ui::Point p,
const ui::Size s
) {
lcd_caset(p.x, p.x + s.w - 1);
lcd_paset(p.y, p.y + s.h - 1);
lcd_caset(p.x(), p.x() + s.width() - 1);
lcd_paset(p.y(), p.y() + s.height() - 1);
lcd_ramwr_start();
}
@@ -207,21 +207,21 @@ void lcd_start_ram_read(
const ui::Point p,
const ui::Size s
) {
lcd_caset(p.x, p.x + s.w - 1);
lcd_paset(p.y, p.y + s.h - 1);
lcd_caset(p.x(), p.x() + s.width() - 1);
lcd_paset(p.y(), p.y() + s.height() - 1);
lcd_ramrd_start();
}
void lcd_start_ram_write(
const ui::Rect& r
) {
lcd_start_ram_write(r.pos, r.size);
lcd_start_ram_write(r.location(), r.size());
}
void lcd_start_ram_read(
const ui::Rect& r
) {
lcd_start_ram_read(r.pos, r.size);
lcd_start_ram_read(r.location(), r.size());
}
void lcd_vertical_scrolling_definition(
@@ -274,7 +274,7 @@ void ILI9341::fill_rectangle(ui::Rect r, const ui::Color c) {
const auto r_clipped = r.intersect(screen_rect());
if( !r_clipped.is_empty() ) {
lcd_start_ram_write(r_clipped);
size_t count = r_clipped.size.w * r_clipped.size.h;
size_t count = r_clipped.width() * r_clipped.height();
io.lcd_write_pixels(c, count);
}
}
@@ -286,7 +286,7 @@ void ILI9341::render_line(const ui::Point p, const uint8_t count, const ui::Colo
void ILI9341::render_box(const ui::Point p, const ui::Size s, const ui::Color* line_buffer) {
lcd_start_ram_write(p, s);
io.lcd_write_pixels(line_buffer, s.w * s.h);
io.lcd_write_pixels(line_buffer, s.width() * s.height());
}
// RLE_4 BMP loader (delta not implemented)
@@ -328,7 +328,7 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
} else {
by = bitmap[data_idx++];
if (by == 0) {
render_line({p.x, p.y + py}, bmp_header->width, line_buffer);
render_line({p.x(), p.y() + py}, bmp_header->width, line_buffer);
py--;
px = 0;
} else if (by == 1) {
@@ -354,10 +354,10 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
count = by >> 1;
by = bitmap[data_idx++];
for (c = 0; c < count; c++) {
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by >> 4]);
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by >> 4]);
px++;
if (px < bmp_header->width) {
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by & 15]);
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by & 15]);
}
px++;
}
@@ -375,10 +375,10 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
count = by >> 1;
for (c = 0; c < count; c++) {
by = bitmap[data_idx++];
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by >> 4]);
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by >> 4]);
px++;
if (px < bmp_header->width) {
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by & 15]);
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by & 15]);
}
px++;
}
@@ -390,10 +390,10 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
}
void ILI9341::draw_line(const ui::Point start, const ui::Point end, const ui::Color color) {
int x0 = start.x;
int y0 = start.y;
int x1 = end.x;
int y1 = end.y;
int x0 = start.x();
int y0 = start.y();
int x1 = end.x();
int y1 = end.y();
int dx = std::abs(x1-x0), sx = x0<x1 ? 1 : -1;
int dy = std::abs(y1-y0), sy = y0<y1 ? 1 : -1;
@@ -422,10 +422,7 @@ void ILI9341::fill_circle(
const uint32_t d2 = x2 + y2;
const bool inside = d2 < radius2;
const auto color = inside ? foreground : background;
draw_pixel({
static_cast<ui::Coord>(x + center.x),
static_cast<ui::Coord>(y + center.y)
}, color);
draw_pixel({ x + center.x(), y + center.y() }, color);
}
}
}
@@ -446,7 +443,7 @@ void ILI9341::draw_pixels(
const size_t count
) {
/* TODO: Assert that rectangle width x height < count */
lcd_start_ram_write(r.pos, r.size);
lcd_start_ram_write(r);
io.lcd_write_pixels(colors, count);
}
@@ -472,7 +469,7 @@ void ILI9341::draw_bitmap(
) {
lcd_start_ram_write(p, size);
const size_t count = size.w * size.h;
const size_t count = size.width() * size.height();
for(size_t i=0; i<count; i++) {
const auto pixel = pixels[i >> 3] & (1U << (i & 0x7));
io.lcd_write_pixel(pixel ? foreground : background);
+3 -3
View File
@@ -43,15 +43,15 @@ public:
}
constexpr uint32_t base() {
constexpr uint32_t base() const {
return base_;
}
constexpr uint32_t end() {
constexpr uint32_t end() const {
return base_ + size_;
}
constexpr size_t size() {
constexpr size_t size() const {
return size_;
}
+5 -1
View File
@@ -439,7 +439,7 @@ public:
return used_ >= capacity_;
}
const void* data() const {
void* data() const {
return data_;
}
@@ -447,6 +447,10 @@ public:
return used_;
}
void set_size(const size_t value) {
used_ = value;
}
void empty() {
used_ = 0;
}
+1 -1
View File
@@ -80,7 +80,7 @@ public:
private:
FIFO<uint8_t> fifo;
Mutex mutex_write;
Mutex mutex_write { };
Message* peek(std::array<uint8_t, Message::MAX_SIZE>& buf) {
Message* const p = reinterpret_cast<Message*>(buf.data());
+1 -1
View File
@@ -61,7 +61,7 @@ constexpr Pin pins[] = {
[P1_15] = { 1, 15, PinConfig::sgpio_inout_fast(2) }, /* SGPIO2/BANK2F3M9: CPLD.74/HOST_DATA2(IO) */
[P1_16] = { 1, 16, PinConfig::sgpio_inout_fast(2) }, /* SGPIO3/BANK2F3M10: CPLD.72/HOST_DATA3(IO) */
[P1_17] = { 1, 17, PinConfig::sgpio_out_fast_with_pullup(6) }, /* SGPIO11/P79/BANK2F3M11: CPLD.71/HOST_DIRECTION(I) */
[P1_18] = { 1, 18, PinConfig::gpio_out_with_pulldown(0) }, /* SGPIO12/BANK2F3M12: CPLD.70/HOST_Q_INVERT(I) */
[P1_18] = { 1, 18, PinConfig::gpio_out_with_pulldown(0) }, /* SGPIO12/BANK2F3M12: CPLD.70/HOST_INVERT(I) */
[P1_19] = { 1, 19, { .mode=1, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* SSP1_SCK/P39: MAX2837.SCLK(I), MAX5864.SCLK(I) */
[P1_20] = { 1, 20, { .mode=0, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* CS_XCVR/P53: MAX2837.CS(I) */
[P2_0] = { 2, 0, { .mode=4, .pd=0, .pu=1, .fast=0, .input=1, .ifilt=1 } }, /* U0_TXD: PortaPack P2_0/IO_STBX */
+1 -1
View File
@@ -50,7 +50,7 @@ static constexpr std::array<uint8_t, 12> png_iend { {
} };
Optional<File::Error> PNGWriter::create(
const std::string& filename
const std::filesystem::path& filename
) {
const auto create_error = file.create(filename);
if( create_error.is_valid() ) {
+3 -3
View File
@@ -35,7 +35,7 @@ class PNGWriter {
public:
~PNGWriter();
Optional<File::Error> create(const std::string& filename);
Optional<File::Error> create(const std::filesystem::path& filename);
void write_scanline(const std::array<ui::ColorRGB888, 240>& scanline);
@@ -44,10 +44,10 @@ private:
static constexpr int width { 240 };
static constexpr int height { 320 };
File file;
File file { };
int scanline_count { 0 };
CRC<32, true, true> crc { 0x04c11db7, 0xffffffff, 0xffffffff };
Adler32 adler_32;
Adler32 adler_32 { };
void write_chunk_header(const size_t length, const std::array<uint8_t, 4>& type);
void write_chunk_content(const void* const p, const size_t count);
+1 -1
View File
@@ -64,7 +64,7 @@ struct SharedMemory {
ToneData tones_data;
JammerRange jammer_ranges[9];
uint8_t data[512];
} bb_data;
} bb_data { { { { 0, 0 } }, 0, { 0 } } };
};
extern SharedMemory& shared_memory;
+30
View File
@@ -28,6 +28,30 @@
#include <cstdint>
template<typename T>
struct simd32_t {
union {
uint32_t raw;
T vec;
};
operator uint32_t() const {
return raw;
}
simd32_t& operator=(uint32_t v) {
raw = v;
return *this;
}
static_assert(sizeof(raw) == sizeof(vec), "simd32_t types are not the same size.");
};
template<typename T>
simd32_t<T>* simd32_ptr(T* const p) {
return reinterpret_cast<simd32_t<T>*>(p);
}
struct vec4_s8 {
union {
int8_t v[4];
@@ -41,6 +65,12 @@ struct vec2_s16 {
{
}
constexpr vec2_s16(
const int16_t v
) : v { v, v }
{
}
constexpr vec2_s16(
const int16_t v0,
const int16_t v1
+1 -1
View File
@@ -100,7 +100,7 @@ struct region_t {
const size_t offset;
const size_t size;
constexpr const void* base() {
constexpr const void* base() const {
return reinterpret_cast<void*>(portapack::memory::map::spifi_cached.base() + offset);
}
};
+1 -1
View File
@@ -88,7 +88,7 @@ Optional<Reading> Packet::reading_ook_8k192_schrader() const {
reader_.read(3, 24),
Pressure { static_cast<int>(reader_.read(27, 8)) * 4 / 3 },
{ },
Flags { (flags << 4) | checksum }
Flags { static_cast<Flags>((flags << 4) | checksum) }
};
} else {
return { };
+16 -4
View File
@@ -26,8 +26,8 @@
namespace ui {
bool Rect::contains(const Point p) const {
return (p.x >= left()) && (p.y >= top()) &&
(p.x < right()) && (p.y < bottom());
return (p.x() >= left()) && (p.y() >= top()) &&
(p.x() < right()) && (p.y() < bottom());
}
Rect Rect::intersect(const Rect& o) const {
@@ -42,6 +42,8 @@ Rect Rect::intersect(const Rect& o) const {
}
}
// TODO: This violates the principle of least surprise!
// This does a union, but that might not be obvious from "+=" syntax.
Rect& Rect::operator+=(const Rect& p) {
if( is_empty() ) {
*this = p;
@@ -49,12 +51,22 @@ Rect& Rect::operator+=(const Rect& p) {
if( !p.is_empty() ) {
const auto x1 = std::min(left(), p.left());
const auto y1 = std::min(top(), p.top());
pos = { x1, y1 };
_pos = { x1, y1 };
const auto x2 = std::max(right(), p.right());
const auto y2 = std::max(bottom(), p.bottom());
size = { x2 - x1, y2 - y1 };
_size = { x2 - x1, y2 - y1 };
}
return *this;
}
Rect& Rect::operator+=(const Point& p) {
_pos += p;
return *this;
}
Rect& Rect::operator-=(const Point& p) {
_pos -= p;
return *this;
}
} /* namespace ui */
+77 -39
View File
@@ -116,121 +116,157 @@ struct ColorRGB888 {
};
struct Point {
Coord x;
Coord y;
private:
Coord _x;
Coord _y;
public:
constexpr Point(
) : x { 0 },
y { 0 }
) : _x { 0 },
_y { 0 }
{
}
constexpr Point(
int x,
int y
) : x { static_cast<Coord>(x) },
y { static_cast<Coord>(y) }
) : _x { static_cast<Coord>(x) },
_y { static_cast<Coord>(y) }
{
}
Point operator-() const {
return { -x, -y };
constexpr int x() const {
return _x;
}
Point operator+(const Point& p) const {
return { x + p.x, y + p.y };
constexpr int y() const {
return _y;
}
Point operator-(const Point& p) const {
return { x - p.x, y - p.y };
constexpr Point operator-() const {
return { -_x, -_y };
}
constexpr Point operator+(const Point& p) const {
return { _x + p._x, _y + p._y };
}
constexpr Point operator-(const Point& p) const {
return { _x - p._x, _y - p._y };
}
Point& operator+=(const Point& p) {
x += p.x;
y += p.y;
_x += p._x;
_y += p._y;
return *this;
}
Point& operator-=(const Point& p) {
_x -= p._x;
_y -= p._y;
return *this;
}
};
struct Size {
Dim w;
Dim h;
private:
Dim _w;
Dim _h;
public:
constexpr Size(
) : w { 0 },
h { 0 }
) : _w { 0 },
_h { 0 }
{
}
constexpr Size(
int w,
int h
) : w { static_cast<Dim>(w) },
h { static_cast<Dim>(h) }
) : _w { static_cast<Dim>(w) },
_h { static_cast<Dim>(h) }
{
}
int width() const {
return _w;
}
int height() const {
return _h;
}
bool is_empty() const {
return (w < 1) || (h < 1);
return (_w < 1) || (_h < 1);
}
};
struct Rect {
Point pos;
Size size;
private:
Point _pos;
Size _size;
public:
constexpr Rect(
) : pos { },
size { }
) : _pos { },
_size { }
{
}
constexpr Rect(
int x, int y,
int w, int h
) : pos { x, y },
size { w, h }
) : _pos { x, y },
_size { w, h }
{
}
constexpr Rect(
Point pos,
Size size
) : pos(pos),
size(size)
) : _pos(pos),
_size(size)
{
}
Point location() const {
return _pos;
}
Size size() const {
return _size;
}
int top() const {
return pos.y;
return _pos.y();
}
int bottom() const {
return pos.y + size.h;
return _pos.y() + _size.height();
}
int left() const {
return pos.x;
return _pos.x();
}
int right() const {
return pos.x + size.w;
return _pos.x() + _size.width();
}
int width() const {
return size.w;
return _size.width();
}
int height() const {
return size.h;
return _size.height();
}
Point center() const {
return { pos.x + size.w / 2, pos.y + size.h / 2 };
return { _pos.x() + _size.width() / 2, _pos.y() + _size.height() / 2 };
}
bool is_empty() const {
return size.is_empty();
return _size.is_empty();
}
bool contains(const Point p) const;
@@ -238,13 +274,15 @@ struct Rect {
Rect intersect(const Rect& o) const;
Rect operator+(const Point& p) const {
return { pos + p, size };
return { _pos + p, _size };
}
Rect& operator+=(const Rect& p);
Rect& operator+=(const Point& p);
Rect& operator-=(const Point& p);
operator bool() const {
return !size.is_empty();
return !_size.is_empty();
}
};
+4 -4
View File
@@ -127,14 +127,14 @@ static int32_t rect_distances(
switch(direction) {
case KeyEvent::Right:
case KeyEvent::Left:
perpendicular_axis_start = rect_start.center().y;
perpendicular_axis_end = rect_end.center().y;
perpendicular_axis_start = rect_start.center().y();
perpendicular_axis_end = rect_end.center().y();
break;
case KeyEvent::Up:
case KeyEvent::Down:
perpendicular_axis_start = rect_start.center().x;
perpendicular_axis_end = rect_end.center().x;
perpendicular_axis_start = rect_start.center().x();
perpendicular_axis_end = rect_end.center().x();
break;
default:
+6 -6
View File
@@ -39,7 +39,7 @@ Style Style::invert() const {
int Painter::draw_char(const Point p, const Style& style, const char c) {
const auto glyph = style.font.glyph(c);
display.draw_glyph(p, glyph, style.foreground, style.background);
return glyph.advance().x;
return glyph.advance().x();
}
int Painter::draw_string(Point p, const Style& style, const std::string text) {
@@ -49,7 +49,7 @@ int Painter::draw_string(Point p, const Style& style, const std::string text) {
display.draw_glyph(p, glyph, style.foreground, style.background);
const auto advance = glyph.advance();
p += advance;
width += advance.x;
width += advance.x();
}
return width;
}
@@ -67,10 +67,10 @@ void Painter::draw_vline(Point p, int height, const Color c) {
}
void Painter::draw_rectangle(const Rect r, const Color c) {
draw_hline(r.pos, r.size.w, c);
draw_vline({ r.pos.x, r.pos.y + 1 }, r.size.h - 2, c);
draw_vline({ r.pos.x + r.size.w - 1, r.pos.y + 1 }, r.size.h - 2, c);
draw_hline({ r.pos.x, r.pos.y + r.size.h - 1 }, r.size.w, c);
draw_hline(r.location(), r.width(), c);
draw_vline({ r.left(), r.top() + 1 }, r.height() - 2, c);
draw_vline({ r.left() + r.width() - 1, r.top() + 1 }, r.height() - 2, c);
draw_hline({ r.left(), r.top() + r.height() - 1 }, r.width(), c);
}
void Painter::fill_rectangle(const Rect r, const Color c) {
+4 -2
View File
@@ -44,8 +44,10 @@ Size Font::size_of(const std::string s) const {
for(const auto c : s) {
const auto glyph_data = glyph(c);
size.w += glyph_data.w();
size.h = std::max(size.h, glyph_data.h());
size = {
size.width() + glyph_data.w(),
std::max(size.height(), glyph_data.h())
};
}
return size;
+2 -2
View File
@@ -42,11 +42,11 @@ public:
{
}
Dim w() const {
int w() const {
return w_;
}
Dim h() const {
int h() const {
return h_;
}
+69 -65
View File
@@ -53,19 +53,23 @@ bool is_dirty() {
const std::vector<Widget*> Widget::no_children { };
Point Widget::screen_pos() {
return screen_rect().pos;
return screen_rect().location();
}
Size Widget::size() const {
return parent_rect.size;
return _parent_rect.size();
}
Rect Widget::screen_rect() const {
return parent() ? (parent_rect + parent()->screen_pos()) : parent_rect;
return parent() ? (parent_rect() + parent()->screen_pos()) : parent_rect();
}
Rect Widget::parent_rect() const {
return _parent_rect;
}
void Widget::set_parent_rect(const Rect new_parent_rect) {
parent_rect = new_parent_rect;
_parent_rect = new_parent_rect;
set_dirty();
}
@@ -74,12 +78,19 @@ Widget* Widget::parent() const {
}
void Widget::set_parent(Widget* const widget) {
if( widget == parent_ ) {
return;
}
if( parent_ && !widget ) {
// We have a parent, but are losing it. Update visible status.
dirty_overlapping_children_in_rect(screen_rect());
visible(false);
}
parent_ = widget;
set_dirty();
}
void Widget::set_dirty() {
@@ -103,7 +114,7 @@ void Widget::hidden(bool hide) {
if( hide ) {
// TODO: Instead of dirtying parent entirely, dirty only children
// that overlap with this widget.
dirty_overlapping_children_in_rect(parent_rect);
parent()->dirty_overlapping_children_in_rect(parent_rect());
/* TODO: Notify self and all non-hidden children that they're
* now effectively hidden?
*/
@@ -211,7 +222,7 @@ void Widget::set_highlighted(const bool value) {
void Widget::dirty_overlapping_children_in_rect(const Rect& child_rect) {
for(auto child : children()) {
if( !child_rect.intersect(child->parent_rect).is_empty() ) {
if( !child_rect.intersect(child->parent_rect()).is_empty() ) {
child->set_dirty();
}
}
@@ -231,21 +242,20 @@ void View::add_child(Widget* const widget) {
if( widget->parent() == nullptr ) {
widget->set_parent(this);
children_.push_back(widget);
widget->set_dirty();
}
}
}
void View::add_children(const std::vector<Widget*>& children) {
void View::add_children(const std::initializer_list<Widget*> children) {
children_.insert(std::end(children_), children);
for(auto child : children) {
add_child(child);
child->set_parent(this);
}
}
void View::remove_child(Widget* const widget) {
if( widget ) {
children_.erase(std::remove(children_.begin(), children_.end(), widget), children_.end());
dirty_overlapping_children_in_rect(widget->screen_rect());
widget->set_parent(nullptr);
}
}
@@ -281,11 +291,6 @@ Rectangle::Rectangle(
{
}
Rectangle::Rectangle(
) : Widget { }
{
}
void Rectangle::set_color(const Color c) {
color = c;
set_dirty();
@@ -316,7 +321,7 @@ Text::Text(
Rect parent_rect,
std::string text
) : Widget { parent_rect },
text_ { text }
text { text }
{
}
@@ -327,14 +332,10 @@ Text::Text(
}
void Text::set(const std::string value) {
text_ = value;
text = value;
set_dirty();
}
std::string Text::text() const {
return text_;
}
void Text::paint(Painter& painter) {
const auto rect = screen_rect();
const auto s = style();
@@ -342,9 +343,9 @@ void Text::paint(Painter& painter) {
painter.fill_rectangle(rect, s.background);
painter.draw_string(
rect.pos,
rect.location(),
s,
text_
text
);
}
@@ -387,7 +388,7 @@ void BigFrequency::paint(Painter& painter) {
const auto rect = screen_rect();
// Erase
painter.fill_rectangle({{0, rect.pos.y}, {240, 52}}, ui::Color::black());
painter.fill_rectangle({{0, rect.location().y()}, {240, 52}}, ui::Color::black());
if (!_frequency) {
for (i = 0; i < 7; i++) // ----.------
@@ -412,10 +413,10 @@ void BigFrequency::paint(Painter& painter) {
segment_color = style().foreground;
// Draw
digit_x = rect.pos.x; // 7 * 32 + 8 = 232 (4 px margins)
digit_x = rect.location().x(); // 7 * 32 + 8 = 232 (4 px margins)
for (i = 0; i < 7; i++) {
digit = digits[i];
digit_y = rect.pos.y;
digit_y = rect.location().y();
if (digit < 16) {
digit_def = big_segment_font[(uint8_t)digit];
if (digit_def & 0x01) painter.fill_rectangle({{digit_x + 4, digit_y}, {20, 4}}, segment_color);
@@ -464,10 +465,10 @@ void ProgressBar::paint(Painter& painter) {
const auto rect = screen_rect();
const auto s = style();
v_sized = (rect.size.w * _value) / _max;
v_sized = (rect.size().width() * _value) / _max;
painter.fill_rectangle({rect.pos, {v_sized, rect.size.h}}, style().foreground);
painter.fill_rectangle({{rect.pos.x + v_sized, rect.pos.y}, {rect.size.w - v_sized, rect.size.h}}, s.background);
painter.fill_rectangle({rect.location(), {v_sized, rect.size().height()}}, style().foreground);
painter.fill_rectangle({{rect.location().x() + v_sized, rect.location().y()}, {rect.size().width() - v_sized, rect.size().height()}}, s.background);
painter.draw_rectangle(rect, s.foreground);
}
@@ -500,15 +501,15 @@ void Console::write(std::string message) {
} else {
const auto glyph = font.glyph(c);
const auto advance = glyph.advance();
if( (pos.x + advance.x) > rect.width() ) {
if( (pos.x() + advance.x()) > rect.width() ) {
crlf();
}
const Point pos_glyph {
rect.pos.x + pos.x,
display.scroll_area_y(pos.y)
rect.left() + pos.x(),
display.scroll_area_y(pos.y())
};
display.draw_glyph(pos_glyph, glyph, s.foreground, s.background);
pos.x += advance.x;
pos += { advance.x(), 0 };
}
}
buffer = message;
@@ -545,14 +546,13 @@ void Console::crlf() {
const Style& s = style();
const auto sr = screen_rect();
const auto line_height = s.font.line_height();
pos.x = 0;
pos.y += line_height;
const int32_t y_excess = pos.y + line_height - sr.height();
pos = { 0, pos.y() + line_height };
const int32_t y_excess = pos.y() + line_height - sr.height();
if( y_excess > 0 ) {
display.scroll(-y_excess);
pos.y -= y_excess;
pos = { pos.x(), pos.y() - y_excess };
const Rect dirty { sr.left(), display.scroll_area_y(pos.y), sr.width(), line_height };
const Rect dirty { sr.left(), display.scroll_area_y(pos.y()), sr.width(), line_height };
display.fill_rectangle(dirty, s.background);
}
}
@@ -596,33 +596,33 @@ void Checkbox::paint(Painter& painter) {
const auto paint_style = (has_focus() || highlighted()) ? style().invert() : style();
painter.draw_rectangle({ r.pos.x, r.pos.y, 24, 24 }, style().foreground);
painter.draw_rectangle({ r.location().x(), r.location().y(), 24, 24 }, style().foreground);
painter.fill_rectangle(
{
static_cast<Coord>(r.pos.x + 1), static_cast<Coord>(r.pos.y + 1),
static_cast<Coord>(r.location().x() + 1), static_cast<Coord>(r.location().y() + 1),
static_cast<Dim>(24 - 2), static_cast<Dim>(24 - 2)
},
style().background
);
painter.draw_rectangle({ r.pos.x+2, r.pos.y+2, 24-4, 24-4 }, paint_style.background);
painter.draw_rectangle({ r.location().x() + 2, r.location().y() + 2, 24-4, 24-4 }, paint_style.background);
if (value_ == true) {
// Check
portapack::display.draw_line( {r.pos.x+2, r.pos.y+14}, {r.pos.x+6, r.pos.y+18}, ui::Color::green());
portapack::display.draw_line( {r.pos.x+6, r.pos.y+18}, {r.pos.x+20, r.pos.y+4}, ui::Color::green());
portapack::display.draw_line( {r.location().x()+2, r.location().y()+14}, {r.location().x()+6, r.location().y()+18}, ui::Color::green());
portapack::display.draw_line( {r.location().x()+6, r.location().y()+18}, {r.location().x()+20, r.location().y()+4}, ui::Color::green());
} else {
// Cross
portapack::display.draw_line( {r.pos.x+1, r.pos.y+1}, {r.pos.x+24-2, r.pos.y+24-2}, ui::Color::red());
portapack::display.draw_line( {r.pos.x+24-2, r.pos.y+1}, {r.pos.x+1, r.pos.y+24-2}, ui::Color::red());
portapack::display.draw_line( {r.location().x()+1, r.location().y()+1}, {r.location().x()+24-2, r.location().y()+24-2}, ui::Color::red());
portapack::display.draw_line( {r.location().x()+24-2, r.location().y()+1}, {r.location().x()+1, r.location().y()+24-2}, ui::Color::red());
}
const auto label_r = paint_style.font.size_of(text_);
painter.draw_string(
{
static_cast<Coord>(r.pos.x + 24 + 4),
static_cast<Coord>(r.pos.y + (24 - label_r.h) / 2)
static_cast<Coord>(r.location().x() + 24 + 4),
static_cast<Coord>(r.location().y() + (24 - label_r.height()) / 2)
},
paint_style,
text_
@@ -691,18 +691,18 @@ void Button::paint(Painter& painter) {
const Style paint_style = { style().font, bg, fg };
painter.draw_rectangle({r.pos, {r.size.w, 1}}, Color::light_grey());
painter.draw_rectangle({r.pos.x, r.pos.y + r.size.h - 1, r.size.w, 1}, Color::dark_grey());
painter.draw_rectangle({r.pos.x + r.size.w - 1, r.pos.y, 1, r.size.h}, Color::dark_grey());
painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Color::light_grey());
painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Color::dark_grey());
painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Color::dark_grey());
painter.fill_rectangle(
{ r.pos.x, r.pos.y + 1, r.size.w - 1, r.size.h - 2 },
{ r.location().x(), r.location().y() + 1, r.size().width() - 1, r.size().height() - 2 },
paint_style.background
);
const auto label_r = paint_style.font.size_of(text_);
painter.draw_string(
{ r.pos.x + (r.size.w - label_r.w) / 2, r.pos.y + (r.size.h - label_r.h) / 2 },
{ r.location().x() + (r.size().width() - label_r.width()) / 2, r.location().y() + (r.size().height() - label_r.height()) / 2 },
paint_style,
text_
);
@@ -753,6 +753,7 @@ bool Button::on_touch(const TouchEvent event) {
flags.highlighted = true;
set_dirty();
return true;
case TouchEvent::Type::Move:
{
const bool new_highlighted = screen_rect().contains(event.point);
@@ -762,6 +763,7 @@ bool Button::on_touch(const TouchEvent event) {
}
}
return true;
case TouchEvent::Type::End:
if( flags.highlighted ) {
flags.highlighted = false;
@@ -771,6 +773,7 @@ bool Button::on_touch(const TouchEvent event) {
}
}
return true;
default:
return false;
}
@@ -865,6 +868,7 @@ bool ImageButton::on_touch(const TouchEvent event) {
set_dirty();
return true;
case TouchEvent::Type::End:
set_highlighted(false);
set_dirty();
@@ -931,9 +935,9 @@ void ImageOptionsField::paint(Painter& painter) {
if( selected_index() < options.size() ) {
const auto bmp_ptr = options[selected_index()].first;
painter.fill_rectangle({screen_rect().pos, {screen_rect().size.w + 4, screen_rect().size.h + 4}}, ui::Color::black());
painter.draw_rectangle({screen_rect().pos, {screen_rect().size.w + 4, screen_rect().size.h + 4}}, paint_style.background);
portapack::display.drawBMP({screen_pos().x + 2, screen_pos().y + 1}, bmp_ptr, true);
painter.fill_rectangle({screen_rect().location(), {screen_rect().size().width() + 4, screen_rect().size().height() + 4}}, ui::Color::black());
painter.draw_rectangle({screen_rect().location(), {screen_rect().size().width() + 4, screen_rect().size().height() + 4}}, paint_style.background);
portapack::display.drawBMP({screen_pos().x() + 2, screen_pos().y() + 1}, bmp_ptr, true);
}
}
@@ -959,9 +963,9 @@ bool ImageOptionsField::on_touch(const TouchEvent event) {
OptionsField::OptionsField(
Point parent_pos,
size_t length,
int length,
options_t options
) : Widget { { parent_pos, { static_cast<ui::Dim>(8 * length), 16 } } },
) : Widget { { parent_pos, { 8 * length, 16 } } },
length_ { length },
options { options }
{
@@ -1008,7 +1012,7 @@ void OptionsField::set_options(options_t new_options) {
void OptionsField::paint(Painter& painter) {
const auto paint_style = has_focus() ? style().invert() : style();
painter.fill_rectangle({screen_rect().pos, {(int)length_ * 8, 16}}, ui::Color::black());
painter.fill_rectangle({screen_rect().location(), {(int)length_ * 8, 16}}, ui::Color::black());
if( selected_index() < options.size() ) {
const auto text = options[selected_index()].first;
@@ -1042,11 +1046,11 @@ bool OptionsField::on_touch(const TouchEvent event) {
NumberField::NumberField(
Point parent_pos,
size_t length,
int length,
range_t range,
int32_t step,
char fill_char
) : Widget { { parent_pos, { static_cast<ui::Dim>(8 * length), 16 } } },
) : Widget { { parent_pos, { 8 * length, 16 } } },
range { range },
step { step },
length_ { length },
@@ -1224,7 +1228,7 @@ void SymField::paint(Painter& painter) {
text
);
pt_draw.x += 8;
pt_draw += { 8, 0 };
}
}
@@ -1319,15 +1323,15 @@ void Waveform::set_length(const uint32_t new_length) {
void Waveform::paint(Painter& painter) {
uint32_t n, point_count;
Coord y, y_offset = screen_rect().pos.y;
Coord prev_x = screen_rect().pos.x, prev_y;
Coord y, y_offset = screen_rect().location().y();
Coord prev_x = screen_rect().location().x(), prev_y;
float x, x_inc;
Dim h = screen_rect().size.h;
Dim h = screen_rect().size().height();
// Clear
painter.fill_rectangle(screen_rect(), Color::black());
x_inc = (float)screen_rect().size.w / length_;
x_inc = (float)screen_rect().size().width() / length_;
point_count = length_;
const float y_scale = (float)(h - 1) / 256; // TODO: Make variable
+47 -30
View File
@@ -49,30 +49,33 @@ public:
}
private:
FocusManager focus_manager_;
FocusManager focus_manager_ { };
};
class Widget {
public:
Widget(
) : parent_rect { }
) : _parent_rect { }
{
}
Widget(
Rect parent_rect
) : parent_rect { parent_rect }
) : _parent_rect { parent_rect }
{
}
Widget(const Widget&) = delete;
Widget(Widget&&) = delete;
Widget& operator=(const Widget&) = delete;
Widget& operator=(Widget&&) = delete;
virtual ~Widget() = default;
Point screen_pos();
Size size() const;
Rect screen_rect() const;
Rect parent_rect() const;
virtual void set_parent_rect(const Rect new_parent_rect);
Widget* parent() const;
@@ -122,7 +125,7 @@ protected:
private:
/* Widget rectangle relative to parent pos(). */
Rect parent_rect;
Rect _parent_rect;
const Style* style_ { nullptr };
Widget* parent_ { nullptr };
@@ -159,7 +162,7 @@ public:
void paint(Painter& painter) override;
void add_child(Widget* const widget);
void add_children(const std::vector<Widget*>& children);
void add_children(const std::initializer_list<Widget*> children);
void remove_child(Widget* const widget);
void remove_children(const std::vector<Widget*>& children);
const std::vector<Widget*>& children() const override;
@@ -167,7 +170,7 @@ public:
virtual std::string title() const;
protected:
std::vector<Widget*> children_;
std::vector<Widget*> children_ { };
void invalidate_child(Widget* const widget);
};
@@ -176,7 +179,10 @@ class Rectangle : public Widget {
public:
Rectangle(Color c);
Rectangle(Rect parent_rect, Color c);
Rectangle();
Rectangle(
) : Rectangle { { }, { } }
{
}
void paint(Painter& painter) override;
@@ -191,19 +197,18 @@ private:
class Text : public Widget {
public:
Text(
) : text_ { "" } {
) : text { "" } {
}
Text(Rect parent_rect, std::string text);
Text(Rect parent_rect);
void set(const std::string value);
std::string text() const;
void paint(Painter& painter) override;
private:
std::string text_;
std::string text;
};
class BigFrequency : public Widget {
@@ -248,14 +253,14 @@ public:
private:
bool visible = false;
Point pos { 0, 0 };
std::string buffer;
std::string buffer { };
void crlf();
};
class Checkbox : public Widget {
public:
std::function<void(Checkbox&)> on_select;
std::function<void(Checkbox&)> on_select { };
Checkbox(Point parent_pos, size_t length, std::string text);
@@ -264,6 +269,11 @@ public:
{
}
Checkbox(const Checkbox&) = delete;
Checkbox(Checkbox&&) = delete;
Checkbox& operator=(const Checkbox&) = delete;
Checkbox& operator=(Checkbox&&) = delete;
void set_text(const std::string value);
bool set_value(const bool value);
bool value() const;
@@ -281,9 +291,9 @@ private:
class Button : public Widget {
public:
std::function<void(Button&)> on_select;
std::function<bool(Button&,KeyEvent)> on_dir;
std::function<void(Button&)> on_highlight;
std::function<void(Button&)> on_select { };
std::function<bool(Button&, KeyEvent)> on_dir { };
std::function<void(Button&)> on_highlight { };
Button(Rect parent_rect, std::string text);
@@ -315,6 +325,11 @@ public:
const Color background
);
Image(const Image&) = delete;
Image(Image&&) = delete;
Image& operator=(const Image&) = delete;
Image& operator=(Image&&) = delete;
void set_bitmap(const Bitmap* bitmap);
void set_foreground(const Color color);
void set_background(const Color color);
@@ -330,7 +345,7 @@ private:
class ImageButton : public Image {
public:
std::function<void(ImageButton&)> on_select;
std::function<void(ImageButton&)> on_select { };
ImageButton(
const Rect parent_rect,
@@ -350,8 +365,8 @@ public:
using option_t = std::pair<image_t, value_t>;
using options_t = std::vector<option_t>;
std::function<void(size_t, value_t)> on_change;
std::function<void(void)> on_show_options;
std::function<void(size_t, value_t)> on_change { };
std::function<void(void)> on_show_options { };
ImageOptionsField(Rect parent_rect, options_t options);
@@ -386,10 +401,10 @@ public:
using option_t = std::pair<name_t, value_t>;
using options_t = std::vector<option_t>;
std::function<void(size_t, value_t)> on_change;
std::function<void(void)> on_show_options;
std::function<void(size_t, value_t)> on_change { };
std::function<void(void)> on_show_options { };
OptionsField(Point parent_pos, size_t length, options_t options);
OptionsField(Point parent_pos, int length, options_t options);
void set_options(options_t new_options);
@@ -406,19 +421,19 @@ public:
bool on_touch(const TouchEvent event) override;
private:
const size_t length_;
const int length_;
options_t options;
size_t selected_index_ { 0 };
};
class NumberField : public Widget {
public:
std::function<void(NumberField&)> on_select;
std::function<void(int32_t)> on_change;
std::function<void(NumberField&)> on_select { };
std::function<void(int32_t)> on_change { };
using range_t = std::pair<int32_t, int32_t>;
NumberField(Point parent_pos, size_t length, range_t range, int32_t step, char fill_char);
NumberField(Point parent_pos, int length, range_t range, int32_t step, char fill_char);
NumberField(
) : NumberField { { 0, 0 }, 1, { 0, 1 }, 1, ' ' }
{
@@ -440,17 +455,17 @@ public:
private:
range_t range;
const int32_t step;
const size_t length_;
const int length_;
const char fill_char;
int32_t value_;
int32_t value_ { 0 };
int32_t clip_value(int32_t value);
};
class SymField : public Widget {
public:
std::function<void(SymField&)> on_select;
std::function<void()> on_change;
std::function<void(SymField&)> on_select { };
std::function<void()> on_change { };
SymField(Point parent_pos, size_t length);
SymField(Point parent_pos, size_t length, bool hex);
@@ -474,7 +489,7 @@ private:
std::string symbol_list_[32] = { "01" }; // Failsafe init
uint32_t values_[32] = { 0 };
uint32_t selected_ = 0;
size_t length_, prev_length_;
size_t length_, prev_length_ = 0;
bool erase_prev_ = false;
bool hex_ = false;
@@ -488,6 +503,8 @@ public:
Waveform(const Waveform&) = delete;
Waveform(Waveform&&) = delete;
Waveform& operator=(const Waveform&) = delete;
Waveform& operator=(Waveform&&) = delete;
void set_offset(const uint32_t new_offset);
void set_length(const uint32_t new_length);
-42
View File
@@ -121,46 +121,4 @@ struct range_t {
}
};
namespace std {
/*! Stephan T Lavavej (STL!) implementation of make_unique, which has been accepted into the C++14 standard.
* It includes handling for arrays.
* Paper here: http://isocpp.org/files/papers/N3656.txt
*/
template<class T> struct _Unique_if {
typedef unique_ptr<T> _Single_object;
};
//! Specialization for unbound array
template<class T> struct _Unique_if<T[]> {
typedef unique_ptr<T[]> _Unknown_bound;
};
//! Specialization for array of known size
template<class T, size_t N> struct _Unique_if<T[N]> {
typedef void _Known_bound;
};
//! Specialization for normal object type
template<class T, class... Args>
typename _Unique_if<T>::_Single_object
make_unique(Args&& ... args) {
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
//! Specialization for unknown bound
template<class T>
typename _Unique_if<T>::_Unknown_bound
make_unique(size_t n) {
typedef typename remove_extent<T>::type U;
return unique_ptr<T>(new U[n]());
}
//! Deleted specialization
template<class T, class... Args>
typename _Unique_if<T>::_Known_bound
make_unique(Args&& ...) = delete;
} /* namespace std */
#endif/*__UTILITY_H__*/