Skip to content

Commit a5f9f3b

Browse files
committed
mtm_hardware.dacout: add gain=1 or gain=2 argument
1 parent 38b0233 commit a5f9f3b

3 files changed

Lines changed: 31 additions & 5 deletions

File tree

ports/raspberrypi/boards/mtm_computer/module/DACOut.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,19 @@ static const uint16_t mcp4822_pio_program[] = {
128128
#define MCP4822_CLOCKS_PER_SAMPLE 86
129129

130130

131+
// MCP4822 gain bit (bit 13) position in the PIO program:
132+
// Instruction 6 = channel A gain bit
133+
// Instruction 18 = channel B gain bit
134+
// 1x gain: set pins, 1 (0xE001) — bit 13 = 1
135+
// 2x gain: set pins, 0 (0xE000) — bit 13 = 0
136+
#define MCP4822_PIO_GAIN_INSTR_A 6
137+
#define MCP4822_PIO_GAIN_INSTR_B 18
138+
#define MCP4822_PIO_GAIN_1X 0xE001 // set pins, 1
139+
#define MCP4822_PIO_GAIN_2X 0xE000 // set pins, 0
140+
131141
void common_hal_mtm_hardware_dacout_construct(mtm_hardware_dacout_obj_t *self,
132142
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi,
133-
const mcu_pin_obj_t *cs) {
143+
const mcu_pin_obj_t *cs, uint8_t gain) {
134144

135145
// SET pins span from MOSI to CS. MOSI must have a lower GPIO number
136146
// than CS, with at most 4 pins between them (SET count max is 5).
@@ -141,14 +151,21 @@ void common_hal_mtm_hardware_dacout_construct(mtm_hardware_dacout_obj_t *self,
141151

142152
uint8_t set_count = cs->number - mosi->number + 1;
143153

154+
// Build a mutable copy of the PIO program and patch the gain bit
155+
uint16_t program[MP_ARRAY_SIZE(mcp4822_pio_program)];
156+
memcpy(program, mcp4822_pio_program, sizeof(mcp4822_pio_program));
157+
uint16_t gain_instr = (gain == 2) ? MCP4822_PIO_GAIN_2X : MCP4822_PIO_GAIN_1X;
158+
program[MCP4822_PIO_GAIN_INSTR_A] = gain_instr;
159+
program[MCP4822_PIO_GAIN_INSTR_B] = gain_instr;
160+
144161
// Initial SET pin state: CS high (bit at CS position), others low
145162
uint32_t cs_bit_position = cs->number - mosi->number;
146163
pio_pinmask32_t initial_set_state = PIO_PINMASK32_FROM_VALUE(1u << cs_bit_position);
147164
pio_pinmask32_t initial_set_dir = PIO_PINMASK32_FROM_VALUE((1u << set_count) - 1);
148165

149166
common_hal_rp2pio_statemachine_construct(
150167
&self->state_machine,
151-
mcp4822_pio_program, MP_ARRAY_SIZE(mcp4822_pio_program),
168+
program, MP_ARRAY_SIZE(mcp4822_pio_program),
152169
44100 * MCP4822_CLOCKS_PER_SAMPLE, // Initial frequency; play() adjusts
153170
NULL, 0, // No init program
154171
NULL, 0, // No may_exec

ports/raspberrypi/boards/mtm_computer/module/DACOut.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ typedef struct {
2121

2222
void common_hal_mtm_hardware_dacout_construct(mtm_hardware_dacout_obj_t *self,
2323
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi,
24-
const mcu_pin_obj_t *cs);
24+
const mcu_pin_obj_t *cs, uint8_t gain);
2525

2626
void common_hal_mtm_hardware_dacout_deinit(mtm_hardware_dacout_obj_t *self);
2727
bool common_hal_mtm_hardware_dacout_deinited(mtm_hardware_dacout_obj_t *self);

ports/raspberrypi/boards/mtm_computer/module/mtm_hardware.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@
2929
//| clock: microcontroller.Pin,
3030
//| mosi: microcontroller.Pin,
3131
//| cs: microcontroller.Pin,
32+
//| *,
33+
//| gain: int = 1,
3234
//| ) -> None:
3335
//| """Create a DACOut object associated with the given SPI pins.
3436
//|
3537
//| :param ~microcontroller.Pin clock: The SPI clock (SCK) pin
3638
//| :param ~microcontroller.Pin mosi: The SPI data (SDI/MOSI) pin
3739
//| :param ~microcontroller.Pin cs: The chip select (CS) pin
40+
//| :param int gain: DAC output gain, 1 for 1x (0-2.048V) or 2 for 2x (0-4.096V). Default 1.
3841
//|
3942
//| Simple 8ksps 440 Hz sine wave::
4043
//|
@@ -72,11 +75,12 @@
7275
//| ...
7376
//|
7477
static mp_obj_t mtm_hardware_dacout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
75-
enum { ARG_clock, ARG_mosi, ARG_cs };
78+
enum { ARG_clock, ARG_mosi, ARG_cs, ARG_gain };
7679
static const mp_arg_t allowed_args[] = {
7780
{ MP_QSTR_clock, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
7881
{ MP_QSTR_mosi, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
7982
{ MP_QSTR_cs, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
83+
{ MP_QSTR_gain, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
8084
};
8185
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
8286
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -85,8 +89,13 @@ static mp_obj_t mtm_hardware_dacout_make_new(const mp_obj_type_t *type, size_t n
8589
const mcu_pin_obj_t *mosi = validate_obj_is_free_pin(args[ARG_mosi].u_obj, MP_QSTR_mosi);
8690
const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj, MP_QSTR_cs);
8791

92+
mp_int_t gain = args[ARG_gain].u_int;
93+
if (gain != 1 && gain != 2) {
94+
mp_raise_ValueError(MP_COMPRESSED_ROM_TEXT("gain must be 1 or 2"));
95+
}
96+
8897
mtm_hardware_dacout_obj_t *self = mp_obj_malloc_with_finaliser(mtm_hardware_dacout_obj_t, &mtm_hardware_dacout_type);
89-
common_hal_mtm_hardware_dacout_construct(self, clock, mosi, cs);
98+
common_hal_mtm_hardware_dacout_construct(self, clock, mosi, cs, (uint8_t)gain);
9099

91100
return MP_OBJ_FROM_PTR(self);
92101
}

0 commit comments

Comments
 (0)