Skip to content

Commit d44a5e7

Browse files
committed
FF.CFG: New option notify-volume= for notifying on insert/eject via speaker.
Refs #716
1 parent 8b203cd commit d44a5e7

File tree

6 files changed

+125
-0
lines changed

6 files changed

+125
-0
lines changed

examples/FF.CFG

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ nav-scroll-pause = 300
273273
# Values: 0 <= N <= 20
274274
step-volume = 10
275275

276+
# Speaker volume for insert, eject, and slot-number notifications.
277+
# Slot number is indicated by a sequence of beeps when an image is mounted
278+
# iff "slotnr" is specified. The slot number is then notified by a sequence of
279+
# long beeps (each counting +5), followed by a sequence of short beeps
280+
# (each counting +1).
281+
# Values: N[,slotnr] (0 <= N <= 15)
282+
notify-volume = 0
283+
276284
# Report the specified version number to host software
277285
# Values: <quoted-string> ("" means report real version)
278286
# eg. da-report-version = "v3.0.0.0"

inc/config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ struct packed ff_cfg {
167167
uint8_t max_cyl;
168168
uint16_t osd_display_order;
169169
uint8_t osd_columns;
170+
#define NOTIFY_volume_mask 15
171+
#define NOTIFY_slotnr (1<<4)
172+
uint8_t notify_volume;
170173
};
171174

172175
extern struct ff_cfg ff_cfg;

inc/util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ extern uint8_t display_type;
120120
/* Speaker. */
121121
void speaker_init(void);
122122
void speaker_pulse(void);
123+
void speaker_notify_insert(unsigned int slotnr);
124+
void speaker_notify_eject(void);
123125

124126
/* Display: 3-digit 7-segment display */
125127
void led_7seg_init(void);

scripts/mk_config.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ def main(argv):
4646
else:
4747
opts += ['DISPLAY_' + x]
4848
val = '|'.join(opts)
49+
elif opt == "notify-volume":
50+
opts = []
51+
for x in val.split(","):
52+
vol = re.match("([0-9]+)", x)
53+
if vol:
54+
opts.append(vol.group(1))
55+
else:
56+
opts.append('NOTIFY_' + x)
57+
val = '|'.join(opts)
4958
elif opt == "display-order" or opt == "osd-display-order":
5059
if val == "default":
5160
val = "DORD_" + val

src/gotek/speaker.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,88 @@ void speaker_pulse(void)
5959
timer_set(&pulse.timer, now + volume*volume*(TIME_MHZ/3));
6060
}
6161

62+
static void speaker_hz(unsigned int hz, unsigned int ms)
63+
{
64+
unsigned int vol = (ff_cfg.notify_volume & NOTIFY_volume_mask) + 1;
65+
unsigned int period = STK_MHZ * 1000000 / hz;
66+
unsigned int period_on = period * vol * vol / (2*400);
67+
unsigned int nr = hz * ms / 1000;
68+
while (nr--) {
69+
gpio_write_pin(gpio_spk, pin_spk, TRUE);
70+
delay_ticks(period_on);
71+
gpio_write_pin(gpio_spk, pin_spk, FALSE);
72+
delay_ticks(period - period_on);
73+
}
74+
}
75+
76+
static void speaker_lock(void)
77+
{
78+
uint32_t oldpri;
79+
oldpri = IRQ_save(TIMER_IRQ_PRI);
80+
timer_cancel(&pulse.timer);
81+
pulse.state = STATE_masked;
82+
IRQ_restore(oldpri);
83+
}
84+
85+
static void speaker_unlock(void)
86+
{
87+
pulse.state = STATE_idle;
88+
}
89+
90+
static void speaker_notify_slot(unsigned int nr)
91+
{
92+
while (nr >= 5) {
93+
speaker_hz(1500, 100);
94+
nr -= 5;
95+
if (nr != 0)
96+
delay_ms(120);
97+
}
98+
99+
while (nr != 0) {
100+
speaker_hz(1500, 40);
101+
nr -= 1;
102+
if (nr != 0)
103+
delay_ms(120);
104+
}
105+
}
106+
107+
void speaker_notify_insert(unsigned int slotnr)
108+
{
109+
if ((ff_cfg.notify_volume & NOTIFY_volume_mask) == 0)
110+
return;
111+
112+
speaker_lock();
113+
114+
speaker_hz(880, 40); /* a5 */
115+
delay_ms(20);
116+
speaker_hz(784, 40); /* g5 */
117+
delay_ms(20);
118+
speaker_hz(1046, 60); /* c6 */
119+
120+
if (ff_cfg.notify_volume & NOTIFY_slotnr) {
121+
delay_ms(300);
122+
speaker_notify_slot(slotnr);
123+
}
124+
125+
speaker_unlock();
126+
}
127+
128+
void speaker_notify_eject(void)
129+
{
130+
if ((ff_cfg.notify_volume & NOTIFY_volume_mask) == 0)
131+
return;
132+
133+
speaker_lock();
134+
135+
speaker_hz(932, 40); /* a#5 */
136+
delay_ms(20);
137+
speaker_hz(831, 40); /* g#5 */
138+
delay_ms(20);
139+
speaker_hz(659, 60); /* e5 */
140+
141+
speaker_unlock();
142+
}
143+
62144
/*
63145
* Local variables:
64146
* mode: C

src/main.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,25 @@ static void read_ff_cfg(void)
12801280
break;
12811281
}
12821282

1283+
case FFCFG_notify_volume: {
1284+
char *p, *q;
1285+
ff_cfg.notify_volume = 0;
1286+
for (p = opts.arg; *p != '\0'; p = q) {
1287+
for (q = p; *q && *q != ','; q++)
1288+
continue;
1289+
if (*q == ',')
1290+
*q++ = '\0';
1291+
if (!strcmp(p, "slotnr")) {
1292+
ff_cfg.notify_volume |= NOTIFY_slotnr;
1293+
} else {
1294+
ff_cfg.notify_volume &= ~NOTIFY_volume_mask;
1295+
ff_cfg.notify_volume |= strtol(p, NULL, 10)
1296+
& NOTIFY_volume_mask;
1297+
}
1298+
}
1299+
break;
1300+
}
1301+
12831302
case FFCFG_da_report_version:
12841303
memset(ff_cfg.da_report_version, 0,
12851304
sizeof(ff_cfg.da_report_version));
@@ -2689,8 +2708,10 @@ static int floppy_main(void *unused)
26892708
b = B_SELECT;
26902709
} else {
26912710
floppy_arena_teardown();
2711+
speaker_notify_insert(cfg.slot_nr);
26922712
fres = F_call_cancellable(run_floppy, &b);
26932713
floppy_cancel();
2714+
speaker_notify_eject();
26942715
assert_volume_connected();
26952716
if ((b != 0) && (display_type == DT_LCD_OLED)) {
26962717
/* Immediate visual indication of button press. */

0 commit comments

Comments
 (0)