Compare commits

...
Sign in to create a new pull request.

7 commits

Author SHA1 Message Date
Martin Ling
b1dbb4731f Add portapack_io_update().
Some checks failed
Check code style / clang-format-2 (push) Failing after 5s
Check code style / clang-format-3 (push) Failing after 3s
Check includes / includes-check (HACKRF_ONE, 3.12.0) (push) Failing after 3s
Check includes / includes-check (HACKRF_ONE, latest) (push) Failing after 2s
Check includes / includes-check (JAWBREAKER, 3.12.0) (push) Failing after 2s
Check includes / includes-check (JAWBREAKER, latest) (push) Failing after 4s
Check includes / includes-check (PRALINE, 3.12.0) (push) Failing after 3s
Check includes / includes-check (PRALINE, latest) (push) Failing after 3s
Check includes / includes-check (RAD1O, 3.12.0) (push) Failing after 3s
Check includes / includes-check (RAD1O, latest) (push) Failing after 2s
Check includes / includes-check (UNIVERSAL, 3.12.0) (push) Failing after 3s
Check includes / includes-check (UNIVERSAL, latest) (push) Failing after 2s
Build / host (3.10.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (3.16.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (3.21.0, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (3.21.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (4.0.0, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (latest, -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake --install-prefix=$env:GITHUB_WORKSPACE/install, map[os:windows shell:pwsh]) (push) Has been cancelled
Build / host (latest, map[os:macos shell:bash]) (push) Has been cancelled
Build / firmware (HACKRF_ONE, latest, windows) (push) Has been cancelled
Build / firmware (JAWBREAKER, latest, windows) (push) Has been cancelled
Build / firmware (PRALINE, 3.12.0, macos) (push) Has been cancelled
Build / firmware (PRALINE, latest, macos) (push) Has been cancelled
Build / firmware (PRALINE, latest, windows) (push) Has been cancelled
Build / firmware (RAD1O, latest, windows) (push) Has been cancelled
Build / firmware (UNIVERSAL, 3.12.0, macos) (push) Has been cancelled
Build / firmware (UNIVERSAL, latest, macos) (push) Has been cancelled
Build / firmware (UNIVERSAL, latest, windows) (push) Has been cancelled
Build / host (4.0.0, map[os:macos shell:bash]) (push) Has been cancelled
Build / host (latest, --install-prefix=/usr/local, map[os:windows shell:msys2]) (push) Has been cancelled
2026-06-12 18:25:06 +01:00
Martin Ling
202a97b6a8 Add portapack_lcd_display_off(). 2026-06-12 18:25:06 +01:00
Martin Ling
c2ff760ead Add portapack_lcd_sleep_in(). 2026-06-12 18:25:06 +01:00
Martin Ling
fbb6651567 Add portapack_audio_reset_state(). 2026-06-12 18:25:06 +01:00
Martin Ling
0ce3d25ede portapack: Expose more internal functions. 2026-06-12 18:25:06 +01:00
Martin Ling
59b029acca Merge branch 'r9-mcu-clk' into harmony 2026-06-12 18:15:07 +01:00
Martin Ling
42b7f7703d Fix management of CLKOUT/MCU_CLK synth sharing on H1R9. 2026-06-12 16:00:48 +01:00
3 changed files with 157 additions and 30 deletions

View file

@ -50,30 +50,35 @@ static portapack_if_t portapack_if = {
#define GPIO_DATA_SHIFT (8)
static const uint32_t gpio_data_mask = 0xFFU << GPIO_DATA_SHIFT;
static void portapack_data_mask_set(void)
void portapack_data_mask_set(void)
{
portapack_if.gpio_port_data->mask = ~gpio_data_mask;
}
static void portapack_data_write_low(const uint32_t value)
void portapack_data_write_low(const uint32_t value)
{
portapack_if.gpio_port_data->mpin = (value << GPIO_DATA_SHIFT);
}
static void portapack_data_write_high(const uint32_t value)
void portapack_data_write_high(const uint32_t value)
{
/* NOTE: Assumes no other bits in the port are masked. */
/* NOTE: Assumes that bits 15 through 8 are masked. */
portapack_if.gpio_port_data->mpin = value;
}
static void portapack_dir_read(void)
uint8_t portapack_data_read(void)
{
return portapack_if.gpio_port_data->mpin >> GPIO_DATA_SHIFT;
}
void portapack_dir_read(void)
{
portapack_if.gpio_port_data->dir &= ~gpio_data_mask;
gpio_set(portapack_if.gpio_dir);
}
static void portapack_dir_write(void)
void portapack_dir_write(void)
{
gpio_clear(portapack_if.gpio_dir);
portapack_if.gpio_port_data->dir |= gpio_data_mask;
@ -115,12 +120,12 @@ static void portapack_io_stb_deassert(void)
gpio_set(portapack_if.gpio_io_stbx);
}
static void portapack_addr(const bool value)
void portapack_addr(const bool value)
{
gpio_write(portapack_if.gpio_addr, value);
}
static void portapack_lcd_command(const uint32_t value)
void portapack_lcd_command(const uint32_t value)
{
portapack_data_write_high(0); /* Drive high byte (with zero -- don't care) */
portapack_dir_write(); /* Turn around data bus, MCU->CPLD */
@ -139,7 +144,7 @@ static void portapack_lcd_command(const uint32_t value)
portapack_addr(1); /* Set up for data phase (most likely after a command) */
}
static void portapack_lcd_write_data(const uint32_t value)
void portapack_lcd_write_data(const uint32_t value)
{
// NOTE: Assumes and DIR=0 and ADDR=1 from command phase.
portapack_data_write_high(value); /* Drive high byte */
@ -153,7 +158,7 @@ static void portapack_lcd_write_data(const uint32_t value)
portapack_lcd_wr_deassert(); /* Complete write operation */
}
static void portapack_io_write(const bool address, const uint_fast16_t value)
void portapack_io_write(const bool address, const uint_fast16_t value)
{
portapack_data_write_low(value);
portapack_dir_write();
@ -168,7 +173,45 @@ static void portapack_io_write(const bool address, const uint_fast16_t value)
portapack_io_stb_deassert();
}
static void portapack_if_init(void)
uint16_t portapack_io_update(const uint8_t value)
{
/* Very touchy code to save context of PortaPack data bus while the
* resistive touch pin drive is changed. Order of operations is
* important to prevent latching spurious data into the LCD or IO
* registers.
*/
uint8_t save_data = portapack_data_read();
bool addr = gpio_read(portapack_if.gpio_addr);
bool dir = gpio_read(portapack_if.gpio_dir);
portapack_io_stb_assert();
/* Switch to read */
portapack_dir_read();
portapack_addr(0);
__asm__("nop");
__asm__("nop");
__asm__("nop");
uint8_t new_data = portapack_data_read();
/* Switch to write */
portapack_data_write_low(value);
portapack_dir_write();
__asm__("nop");
__asm__("nop");
__asm__("nop");
portapack_io_stb_deassert();
portapack_data_write_low(save_data);
if (dir) { /* 0 (write) -> 1 (read) */
portapack_dir_read();
}
gpio_write(portapack_if.gpio_addr, addr);
return new_data;
}
void portapack_if_init(void)
{
const platform_gpio_t* gpio = platform_gpio();
const platform_scu_t* scu = platform_scu();
@ -214,13 +257,19 @@ static void portapack_if_init(void)
/* scu_pinmux(scu->PINMUX_PP_UNUSED, SCU_CONF_FUNCTION4 | SCU_GPIO_NOPULL); */
}
static void portapack_lcd_reset_state(const bool active)
void portapack_lcd_reset_state(const bool active)
{
portapack_if.io_reg = (portapack_if.io_reg & 0xfe) | (active ? (1 << 0) : 0);
portapack_io_write(1, portapack_if.io_reg);
}
static void portapack_lcd_data_write_command_and_data(
void portapack_audio_reset_state(const bool active)
{
portapack_if.io_reg = (portapack_if.io_reg & 0xfd) | (active ? (1 << 0) : 0);
portapack_io_write(1, portapack_if.io_reg);
}
void portapack_lcd_data_write_command_and_data(
const uint_fast8_t command,
const uint8_t* data,
const size_t data_count)
@ -231,7 +280,17 @@ static void portapack_lcd_data_write_command_and_data(
}
}
static void portapack_lcd_sleep_out(void)
void portapack_lcd_sleep_in(void)
{
const uint8_t cmd_10[] = {};
portapack_lcd_data_write_command_and_data(0x10, cmd_10, ARRAY_SIZEOF(cmd_10));
// "It will be necessary to wait 5msec before sending next command,
// this is to allow time for the supply voltages and clock circuits
// to stabilize."
delay_ms(5);
}
void portapack_lcd_sleep_out(void)
{
const uint8_t cmd_11[] = {};
portapack_lcd_data_write_command_and_data(0x11, cmd_11, ARRAY_SIZEOF(cmd_11));
@ -241,12 +300,18 @@ static void portapack_lcd_sleep_out(void)
delay_ms(120);
}
static void portapack_lcd_display_on(void)
void portapack_lcd_display_on(void)
{
const uint8_t cmd_29[] = {};
portapack_lcd_data_write_command_and_data(0x29, cmd_29, ARRAY_SIZEOF(cmd_29));
}
void portapack_lcd_display_off(void)
{
const uint8_t cmd_28[] = {};
portapack_lcd_data_write_command_and_data(0x28, cmd_28, ARRAY_SIZEOF(cmd_28));
}
static void portapack_lcd_ramwr_start(void)
{
const uint8_t cmd_2c[] = {};
@ -301,7 +366,7 @@ static void portapack_lcd_wake(void)
portapack_lcd_display_on();
}
static void portapack_lcd_reset(void)
void portapack_lcd_reset(void)
{
portapack_lcd_reset_state(false);
delay_ms(1);
@ -311,7 +376,7 @@ static void portapack_lcd_reset(void)
delay_ms(120);
}
static void portapack_lcd_init(void)
void portapack_lcd_init(void)
{
// LCDs are configured for IM[2:0] = 001
// 8080-I system, 16-bit parallel bus

View file

@ -65,6 +65,49 @@ typedef struct {
bool portapack_init(void);
void portapack_if_init(void);
void portapack_audio_reset_state(const bool active);
void portapack_lcd_reset_state(const bool active);
void portapack_lcd_reset(void);
void portapack_lcd_init(void);
void portapack_addr(const bool value);
void portapack_dir_read(void);
void portapack_dir_write(void);
void portapack_data_mask_set(void);
void portapack_data_write_high(const uint32_t value);
void portapack_data_write_low(const uint32_t value);
void portapack_io_write(const bool address, const uint_fast16_t value);
uint16_t portapack_io_update(const uint8_t value);
void portapack_lcd_command(const uint32_t value);
void portapack_lcd_write_data(const uint32_t value);
void portapack_lcd_data_write_command_and_data(
const uint_fast8_t command,
const uint8_t* data,
const size_t data_count);
void portapack_lcd_sleep_out(void);
void portapack_lcd_sleep_in(void);
void portapack_lcd_display_on(void);
void portapack_lcd_display_off(void);
bool portapack_present(void);
void portapack_backlight(const bool on);

View file

@ -274,17 +274,6 @@ void si5351c_enable_clock_outputs(si5351c_driver_t* const drv)
SI5351C_OUTPUT_DISABLE);
}
si5351c_regs_commit(drv);
#ifdef IS_H1_R9
if (IS_H1_R9) {
const platform_gpio_t* gpio = platform_gpio();
if (drv->clk[drv->clkout_id].output_enable) {
gpio_set(gpio->h1r9_clkout_en);
} else {
gpio_clear(gpio->h1r9_clkout_en);
}
}
#endif
}
void si5351c_set_int_mode(
@ -339,7 +328,7 @@ bool si5351c_clkin_signal_valid(si5351c_driver_t* const drv)
}
}
void si5351c_clkout_enable(si5351c_driver_t* const drv, bool enable)
static void si5351c_clkout_ms_enable(si5351c_driver_t* const drv, bool enable)
{
drv->clk[drv->clkout_id].output_enable = enable;
drv->clk[drv->clkout_id].power_down = !enable;
@ -351,12 +340,42 @@ void si5351c_clkout_enable(si5351c_driver_t* const drv, bool enable)
si5351c_enable_clock_outputs(drv);
}
void si5351c_clkout_enable(si5351c_driver_t* const drv, bool enable)
{
#ifdef IS_H1_R9
if (IS_H1_R9) {
const platform_gpio_t* gpio = platform_gpio();
/* CLKOUT is shared with MCU_CLK, enable MS when either on. */
bool mcu_clkin_enabled = gpio_read(gpio->h1r9_mcu_clk_en);
bool ms_needed = enable | mcu_clkin_enabled;
si5351c_clkout_ms_enable(drv, ms_needed);
/* Set GPIO to gate CLKOUT output downstream of MS. */
gpio_write(gpio->h1r9_clkout_en, enable);
}
#endif
#ifdef IS_NOT_H1_R9
if (IS_NOT_H1_R9) {
/* We have a dedicated CLKOUT multisynth. */
si5351c_clkout_ms_enable(drv, enable);
}
#endif
}
void si5351c_mcu_clkin_enable(si5351c_driver_t* const drv, bool enable)
{
#ifdef IS_H1_R9
if (IS_H1_R9) {
/* MCU clock is shared with CLKOUT. */
si5351c_clkout_enable(drv, enable);
const platform_gpio_t* gpio = platform_gpio();
/* MCU_CLK is shared with CLKOUT, enable MS when either on. */
bool clkout_enabled = gpio_read(gpio->h1r9_clkout_en);
bool ms_needed = enable | clkout_enabled;
si5351c_clkout_ms_enable(drv, ms_needed);
/* Set GPIO to gate MCU_CLK output downstream of MS. */
gpio_write(gpio->h1r9_mcu_clk_en, enable);
}
#endif
#ifdef IS_NOT_H1_R9