Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1dbb4731f | ||
|
|
202a97b6a8 | ||
|
|
c2ff760ead | ||
|
|
fbb6651567 | ||
|
|
0ce3d25ede | ||
|
|
59b029acca | ||
|
|
42b7f7703d |
3 changed files with 157 additions and 30 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue