SD card slot is on its own separate PCB connected via a 8-pin JST PH (?) jumper cable.
Tested with 2GB SD card formatted with FAT16. Cards smaller than 2GB might also work but are untested (since the smallest cards I got are 2GB).
(Official spec stated that it supports 128MB-2GB SD cards formatted with FAT16.)
FEM files are just type 0 (single track) MIDI files. Other types are not supported and the player refuses to load them.
The filename encodes the song information as a 5-character alphanumerical song ID (not necessarily needs to be unique. seems to affect the display order), followed by the song title (15 characters max, supports ASCII as well as Japanese characters, Latin alphabets other than those covered in ASCII range are not supported).
Some messages in the MIDI file e.g. program_change
as well as meta messages gets ignored by the player during playback and doesn't seem to cause any issue.
Only piano voice is present (if it's not already obvious enough).
Messages besides note_on
, note_off
and set_tempo
are not well tested. Channel usage besides 0 and 1 are not tested. Ticks-per-beat can be set to values other than 48 and the player seems to handle it fine.
The scripts below require Python and mido.
See femboy.py
for a type 1 to type 0 MIDI converter that should work well for simple MIDIs despite being really sloppily written.
See sweep.py
for a MIDI key sweep generator.
The player uses 88 individual solenoids controlled by 4 driver ICs for the key animation. For key scanning, it is implemented as a 11x8 matrix consisted of 3 shift registers (2 SIPO 74HC595 as drivers and 1 PISO 74HC165 as the sensor). Each key has its own anti-ghosting diode. NKRO is theoretically possible with this hardware implementation.
Connector: JST PH (6 pin)
Pinout:
# | Name | Description |
---|---|---|
1 | VCC | Power (~3.546V) |
2 | LATCH | Driver latch |
3 | CLK | Shift register clock input |
4 | DI | Driver data input |
5 | DO | Sensor data output |
6 | GND | Ground |
The key index, starting from the left most key, can be calculated with XXXXYYY
, where X is the driver column (from driver shift register #1 pin QA
i.e. column 0, to driver shift register #2 pin QC
i.e. column 10) and Y is the sensor row (from sensor shift register pin A
to pin H
i.e. row 0-7) all in binary.
Connector: JST EH (6 pin)
Pinout:
# | Name | Description |
---|---|---|
1 | VP | Solenoid power (~6.65V with 6.66V Vin) |
2 | VP | |
3 | VDD | Digital input power (~3.6V) |
4 | VDD | |
5 | PG | Solenoid ground |
6 | PG |
Connector: JST EH (12 pin)
Pinout:
# | Name | Description |
---|---|---|
1-8 | ~D0-~D7 | Parallel data (inverted) |
9 | RESET | Reset |
10 | XFER | Initiate transfer (active high) (?) |
11 | LATCH | Latch data (DDR?) (?) |
12 | DG | Digital input ground |
Seems to be a 8-bit DDR (double data rate) bus. Each transfer is 16 bits wide and are done in a single LATCH
pulse cycle.
- Starts from
XFER
andLATCH
set to low. - Host pulls
D0-D7
high (logic 0) and pullsXFER
high to initiate a transfer. - Host writes the high 8 bits data to
D0-D7
and pullsLATCH
high. - Host writes the low 8 bits data to
D0-D7
and pulls bothXFER
andLATCH
low.
Refresh rate: ~550Hz (~1.8ms interval)
Transfer rate: ~100kT/s
Nominal LATCH frequency: 400-450 kHz
Each transfer seems to have the following format:
CCDD
(C: command, D: data)
A list of currently known commands:
Command | Name | Description |
---|---|---|
0x0d | select |
Notify the chip with ID data that all subsequent transfers are targeting it. |
0x20-0x22 | set_solenoid_byte0 - set_solenoid_byte2 |
Set the solenoid state (byte 0-2, 24-bit bitfield) |
0x23 | set_solenoid_power (?) |
Unknown. Might be related to how much power to use for the solenoid. |
The 4 driver chips on board have the ID of 0x11
, 0x22
, 0x33
and 0x44
.
+------+-----------------------+-----------------------+-----------------------+-----------------------+
| Chip | 0x44 | 0x33 | 0x22 | 0x11 |
+------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Byte | 2 | 1 | 0 | 2 | 1 | 0 | 2 | 1 | 0 | 2 | 1 | 0 |
+------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Bit | 95-72 | 71-48 | 47-24 | 23-0 |
+------+-----------------------+-----------------------+-----------------------+-----------------------+
The leftmost key is bit 0 and the rightmost key is bit 87.
Bit 95-88 seems to be unused and probably should be kept as 0.
// 4 empty chip select commands
0d11
0d22
0d33
0d44
// Clear all solenoid status
0d11 231f 2000 2100 2200
0d22 231f 2000 2100 2200
0d33 231f 2000 2100 2200
0d44 231f 2000 2100 2200
Connector: JST PH (7 pin)
# | Name | Description |
---|---|---|
1 | VCC | Power (~3.55V) |
2 | VCC | |
3 | RX | Control panel UART RX (main board TX) |
4 | TX | Control panel UART TX (main board RX) |
5 | RESET | Control panel reset |
6 | GND | Ground |
7 | GND |
UART @ 9600 8n1. Only the high level menu contexts (enabled menu options, filenames, etc.) are sent over this connection. All graphical works are handled on the control panel microcontroller itself.
TODO