Add Doxygen documentation comments to the HAL, GPIO and chip types
This commit is contained in:
parent
638883bf39
commit
9909c9f222
|
|
@ -1,20 +1,27 @@
|
||||||
|
/**
|
||||||
|
* @file GPIO.hpp
|
||||||
|
* @brief Logical types for the YMF262 pin-control interface (used by GPIO policies).
|
||||||
|
*/
|
||||||
#ifndef GPIO_HPP
|
#ifndef GPIO_HPP
|
||||||
#define GPIO_HPP
|
#define GPIO_HPP
|
||||||
|
|
||||||
|
/** @brief Logical activation state of a control line (CS, WR, IC...). */
|
||||||
enum class State{
|
enum class State{
|
||||||
ACTIVE,
|
ACTIVE, ///< Line asserted (the policy maps this to the correct electrical level)
|
||||||
INACTIVE
|
INACTIVE ///< Line deasserted
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief Selects what the data bus carries (drives the A0 line). */
|
||||||
enum class Port{
|
enum class Port{
|
||||||
DATA,
|
DATA, ///< Bus carries a data value
|
||||||
ADDRESS
|
ADDRESS ///< Bus carries a register address
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @brief Selects the register bank / array (drives the A1 line). */
|
||||||
enum class Bank{
|
enum class Bank{
|
||||||
BANK_0,
|
BANK_0, ///< First register array
|
||||||
BANK_1,
|
BANK_1, ///< Second register array (OPL3 extended registers)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
/**
|
||||||
|
* @file YMF262-HAL.hpp
|
||||||
|
* @brief Hardware Abstraction Layer for the Yamaha YMF262 (OPL3).
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef YMF262_HAL_HPP
|
#ifndef YMF262_HAL_HPP
|
||||||
#define YMF262_HAL_HPP
|
#define YMF262_HAL_HPP
|
||||||
|
|
||||||
|
|
@ -5,24 +10,42 @@
|
||||||
#include "GPIO.hpp"
|
#include "GPIO.hpp"
|
||||||
#include "YMF262-Types.hpp"
|
#include "YMF262-Types.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hardware Abstraction Layer for the Yamaha YMF262 (OPL3) integrated circuit.
|
||||||
|
*
|
||||||
|
* Choreographs the control protocol between the synthesizer IC and the
|
||||||
|
* microcontroller. The electrical handling of the pins is delegated to the
|
||||||
|
* GPIOPolicy (template parameter), allowing the logic to be tested with a
|
||||||
|
* mock without real hardware.
|
||||||
|
*
|
||||||
|
* @tparam GPIOPolicy Class type implementing the verbs for electrical pin control
|
||||||
|
* (set_a0, set_a1, set_cs, set_wr, set_ic, set_data_bus, delay_ticks).
|
||||||
|
*/
|
||||||
template <class GPIOPolicy>
|
template <class GPIOPolicy>
|
||||||
class YMF262_HAL{
|
class YMF262_HAL{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
GPIOPolicy& _gpio;
|
GPIOPolicy& _gpio; ///< Reference (not a copy) so tests can inspect the same policy instance
|
||||||
uint32_t _t_icw_ticks;
|
uint32_t _t_icw_ticks; ///< Reset Pulse Width
|
||||||
uint32_t _t_as_ticks;
|
uint32_t _t_as_ticks; ///< Address Setup Time
|
||||||
uint32_t _t_ah_ticks;
|
uint32_t _t_ah_ticks; ///< Address Hold Time
|
||||||
uint32_t _t_csw_ticks;
|
uint32_t _t_csw_ticks; ///< Chip Select Write Width
|
||||||
uint32_t _t_csr_ticks;
|
uint32_t _t_csr_ticks; ///< Chip Select Read Width
|
||||||
uint32_t _t_ww_ticks;
|
uint32_t _t_ww_ticks; ///< Write Pulse Width
|
||||||
uint32_t _t_wds_ticks;
|
uint32_t _t_wds_ticks; ///< Write Data Setup Time
|
||||||
uint32_t _t_wdh_ticks;
|
uint32_t _t_wdh_ticks; ///< Write Data Hold Time
|
||||||
uint32_t _t_rw_ticks;
|
uint32_t _t_rw_ticks; ///< Read Pulse Width
|
||||||
uint32_t _t_acc_ticks;
|
uint32_t _t_acc_ticks; ///< Read Data Access Time
|
||||||
uint32_t _t_rdh_ticks;
|
uint32_t _t_rdh_ticks; ///< Read Data Hold Time
|
||||||
uint32_t _t_recovery_ticks;
|
uint32_t _t_recovery_ticks; ///< Recovery between writes (32 φM cycles of the chip)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Performs a single bus write cycle (one of the two in a register write).
|
||||||
|
* @param bank Register bank (drives A1).
|
||||||
|
* @param port ADDRESS or DATA phase (drives A0).
|
||||||
|
* @param data Byte to place on the data bus.
|
||||||
|
*/
|
||||||
void write_bus(Bank bank, Port port, uint8_t data){
|
void write_bus(Bank bank, Port port, uint8_t data){
|
||||||
_gpio.set_a0(port);
|
_gpio.set_a0(port);
|
||||||
_gpio.set_a1(bank);
|
_gpio.set_a1(bank);
|
||||||
|
|
@ -57,20 +80,57 @@ class YMF262_HAL{
|
||||||
_t_rdh_ticks = (uint32_t)(10 * ticks_per_ns);
|
_t_rdh_ticks = (uint32_t)(10 * ticks_per_ns);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Boots the chip: resets it, then selects the operating mode.
|
||||||
|
*
|
||||||
|
* Order matters: the chip must be reset first (known state), then the
|
||||||
|
* mode is set explicitly. After reset the chip defaults to OPL2, so the
|
||||||
|
* mode is always set deliberately rather than relying on the default.
|
||||||
|
*
|
||||||
|
* @param mode Operating mode to configure after reset.
|
||||||
|
*/
|
||||||
void initialize(OPLMode mode){
|
void initialize(OPLMode mode){
|
||||||
initial_clear();
|
initial_clear();
|
||||||
set_OPL_Mode(mode);
|
set_OPL_Mode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes a value to a YMF262 register.
|
||||||
|
*
|
||||||
|
* Performs the chip's two-cycle write protocol: first the register
|
||||||
|
* address is latched, then the data value.
|
||||||
|
*
|
||||||
|
* @param bank Register bank to target (BANK_0 or BANK_1).
|
||||||
|
* @param reg Register address (0x00–0xFF).
|
||||||
|
* @param data Value to write.
|
||||||
|
*/
|
||||||
void write(Bank bank, uint8_t reg, uint8_t data){
|
void write(Bank bank, uint8_t reg, uint8_t data){
|
||||||
write_bus(bank,Port::ADDRESS,reg);
|
write_bus(bank,Port::ADDRESS,reg);
|
||||||
write_bus(bank,Port::DATA,data);
|
write_bus(bank,Port::DATA,data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Selects OPL2 (compatibility) or OPL3 mode.
|
||||||
|
*
|
||||||
|
* Writes the OPL3-enable bit in register 0x105 (bank ARRAY1).
|
||||||
|
* OPL3 mode unlocks the 4-operator channels and extra waveforms.
|
||||||
|
*
|
||||||
|
* @param mode OPLMode::OPL2 or OPLMode::OPL3.
|
||||||
|
*/
|
||||||
void set_OPL_Mode(OPLMode mode){
|
void set_OPL_Mode(OPLMode mode){
|
||||||
write(Bank::BANK_1, 0x105, (mode == OPLMode::OPL3) ? 0x01 : 0x00);
|
write(Bank::BANK_1, 0x105, (mode == OPLMode::OPL3) ? 0x01 : 0x00);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets the chip via the /IC (Initial Clear) line.
|
||||||
|
*
|
||||||
|
* Holds /IC active for the required Initial Clear Width, then releases it.
|
||||||
|
* Leaves the chip in a known default state (OPL2 mode).
|
||||||
|
*/
|
||||||
void initial_clear(){
|
void initial_clear(){
|
||||||
|
|
||||||
_gpio.set_ic(State::ACTIVE);
|
_gpio.set_ic(State::ACTIVE);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
#ifndef YMF262_MODES_HPP
|
/**
|
||||||
#define YMF262_MODES_HPP
|
* @file YMF262-Types.hpp
|
||||||
|
* @brief Chip-level types for the YMF262 (operating mode, and future chip concepts).
|
||||||
|
*/
|
||||||
|
#ifndef YMF262_TYPES_HPP
|
||||||
|
#define YMF262_TYPES_HPP
|
||||||
|
|
||||||
|
/** @brief YMF262 operating mode. */
|
||||||
enum class OPLMode {
|
enum class OPLMode {
|
||||||
OPL3,
|
OPL3, ///< Full OPL3: 4-operator channels and extended waveforms
|
||||||
OPL2
|
OPL2 ///< OPL2 compatibility mode (chip default after reset)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue