Skip to content

Instantly share code, notes, and snippets.

@bakueikozo
Last active August 24, 2024 18:15
Show Gist options
  • Save bakueikozo/740f48879a8bc0e2b6bcef2ed1766cc2 to your computer and use it in GitHub Desktop.
Save bakueikozo/740f48879a8bc0e2b6bcef2ed1766cc2 to your computer and use it in GitHub Desktop.
#include <93C46.h>
#define pCS 2
#define pSK 13
#define pDI 10
#define pDO 11
#define SPKEN 9
// Prints all words of the buffer
void debugPrint(word* buff, int len) {
Serial.print("\n\t00\t01\t02\t03\t04\t05\t06\t07\t08\t09\t0A\t0B\t0C\t0D\t0E\t0F");
for(int i = 0; i < len; i++) {
if(i % 16 == 0) {
Serial.println();
Serial.print(i, HEX);
}
Serial.print("\t");
if(buff[i] < 0x10) {
Serial.print("0");
}
Serial.print(buff[i], HEX);
}
}
int acs = 3;
int ask = pSK;
int adi = pDI;
int ado = pDO;
void yobikomi_init() {
pinMode(acs, OUTPUT);
pinMode(ask, OUTPUT);
pinMode(adi, OUTPUT);
pinMode(ado, INPUT);
pinMode(SPKEN,OUTPUT);
};
word readBuffer[32];
void yobikomi_setaddr(word start,word stop){
digitalWrite(acs, HIGH);
delayMicroseconds(1);
digitalWrite(acs, LOW);
delayMicroseconds(1);
yobikomi_send_bits(0x6, 4);
yobikomi_send_20bits_addr(stop);
delayMicroseconds(1);
digitalWrite(acs, HIGH);
delayMicroseconds(10);
digitalWrite(acs, LOW);
delayMicroseconds(1);
yobikomi_send_bits(0x5, 4);
yobikomi_send_20bits_addr(start);
delayMicroseconds(1);
digitalWrite(acs, HIGH);
char buf[128];
sprintf(buf,"set song addr=%x - %x\n",start,stop);
Serial.print(buf);
}
word yobikomi_play() {
word val = 0;
digitalWrite(acs, HIGH);
delayMicroseconds(1);
digitalWrite(acs, LOW);
delayMicroseconds(1);
yobikomi_send_bits(2, 4);
digitalWrite(acs, HIGH);
delayMicroseconds(1);
}
word yobikomi_rec() {
word val = 0;
digitalWrite(acs, HIGH);
delayMicroseconds(1);
digitalWrite(acs, LOW);
delayMicroseconds(1);
yobikomi_send_bits(1, 4);
digitalWrite(acs, HIGH);
delayMicroseconds(1);
}
word yobikomi_stop() {
word val = 0;
digitalWrite(acs, HIGH);
delayMicroseconds(1);
digitalWrite(acs, LOW);
delayMicroseconds(1);
yobikomi_send_bits(3, 4);
digitalWrite(acs, HIGH);
delayMicroseconds(1);
}
word yobikomi_getpos() {
word val = 0;
digitalWrite(acs, HIGH);
delayMicroseconds(1);
digitalWrite(acs, LOW);
delayMicroseconds(1);
yobikomi_send_bits(7, 4);
word pos = yobikomi_get_20bits_addr();
digitalWrite(acs, HIGH);
delayMicroseconds(1);
return pos;
}
byte yobikomi_status() {
word val = 0;
digitalWrite(acs, HIGH);
delayMicroseconds(1);
digitalWrite(acs, LOW);
delayMicroseconds(1);
yobikomi_send_bits(0x8, 4);
yobikomi_send_bits(0, 4);
byte bs = yobikomi_get_byte();
digitalWrite(acs, HIGH);
delayMicroseconds(1);
return bs;
}
void yobikomi_send_bits(word value, int len) {
for(int i = len-1; i>=0; i--)
{
bool toSend = (value & 1<<i);
// Send bit
digitalWrite(adi, toSend);
delayMicroseconds(1);
digitalWrite(ask, HIGH);
delayMicroseconds(1);
digitalWrite(ask, LOW);
digitalWrite(adi, LOW);
}
}
void yobikomi_send_20bits_addr(word val) {
for(int i = 19 ;i >= 0 ; i --){
bool toSend = (val & (1<<i));
digitalWrite(adi, toSend);
delayMicroseconds(1);
digitalWrite(ask, HIGH);
delayMicroseconds(1);
digitalWrite(ask, LOW);
digitalWrite(adi, LOW);
}
}
byte yobikomi_get_byte() {
byte val = 0;
for(int i = 7 ;i >= 0 ; i --){
delayMicroseconds(1);
digitalWrite(ask, HIGH);
delayMicroseconds(1);
byte in = digitalRead(ado) ? 1 : 0;
val = (val << 1) + in;
digitalWrite(ask, LOW);
}
return val;
}
word yobikomi_get_20bits_addr() {
word val = 0;
for(int i = 19 ;i >= 0 ; i --){
delayMicroseconds(1);
digitalWrite(ask, HIGH);
delayMicroseconds(1);
byte in = digitalRead(ado) ? 1 : 0;
val = (val << 1) + in;
digitalWrite(ask, LOW);
}
return val;
}
int leds[5] = { A0,A1,A2,A3,A4};
int buttons[5] = {6,7,4,12,5};
void setup()
{
Serial.begin(9600);
for(int n=0;n<5;n++){
pinMode(buttons[n],INPUT_PULLUP);
}
for(int n=0;n<5;n++){
pinMode(leds[n],OUTPUT);
digitalWrite(leds[n],HIGH);
delay(200);
digitalWrite(leds[n],LOW);
}
for(int n=0;n<5;n++){
digitalWrite(leds[4-n],HIGH);
delay(200);
digitalWrite(leds[4-n],LOW);
}
yobikomi_init();
eeprom_test();
// yobikomi_play();
digitalWrite(SPKEN,LOW);
// Serial.println("send play...");
}
eeprom_93C46 e = eeprom_93C46(pCS, pSK, pDI, pDO);
void eeprom_update(){
Serial.println("eeprom update ....");
e.ew_enable();
char buf[128];
int len = 8;
for(int i = 0; i < 24; i++) {
e.write(i,readBuffer[i]);
}
e.ew_disable();
eeprom_test();
}
void eeprom_test() {
e.set_mode(0);
char buf[128];
int len = 8;
for(int i = 0; i < 24; i++) {
if( (len % 16) == 0 ) {
Serial.print( "\n");
}
// Read by address
word r = e.read(i);
readBuffer[i] = r;
Serial.print( (r >> 8) & 0xff,HEX);
Serial.print( " ");
Serial.print( r & 0xff,HEX);
Serial.print( " | ");
}
sprintf(buf,"1ch song addr=%x - %x\n",readBuffer[0],readBuffer[2]);
Serial.println(buf);
sprintf(buf,"2ch song addr=%x - %x\n",readBuffer[4],readBuffer[6]);
Serial.println(buf);
// yobikomi_setaddr(readBuffer[4],readBuffer[6]);
for(int n=0;n<5;n++){
digitalWrite(leds[n],HIGH);
}
delay(200);
for(int n=0;n<5;n++){
digitalWrite(leds[n],LOW);
}
}
int recording = 0;
int playing = 0;
int state = -1;
void ledupdate(){
if(state == -1 ){
for(int n=0;n<5;n++){
digitalWrite(leds[n],LOW);
}
}else{
for(int n=0;n<5;n++){
if( state == n ){
digitalWrite(leds[n],HIGH);
}else{
digitalWrite(leds[n],LOW);
}
}
}
}
char buf[128];
word roundaddr(word a){
int block = (a >> 10) & 0x3 ;
int sector = ( a >> 4 ) & 0x7f;
int page = a & 0x0f;
sprintf(buf,"round %x -> %x-%x-%x",a,block,sector,page);
Serial.println(buf);
if( page != 0 ){
page = 0;
sector ++ ;
if( sector == 0x50 ){
sector=0;
block++;
}
}else{
}
word ret = (block << 10) + (sector << 4 )+ page;
sprintf(buf," -> %08x",ret);
Serial.println(buf);
return ret;
}
word inc(word a){
int block = (a >> 10) & 0x3 ;
int sector = ( a >> 4 ) & 0x7f;
int page = a & 0x0f;
sprintf(buf,"inc %x -> %x-%x-%x",a,block,sector,page);
Serial.println(buf);
page ++ ;
if( page == 0x10 ){
page = 0;
sector ++ ;
if( sector == 0x50 ){
sector=0;
block++;
}
}
word ret = (block << 10) + (sector << 4 )+ page;
sprintf(buf," -> %08x",ret);
Serial.println(buf);
return ret;
}
void loop() {
if( state == 0 || state == 1 ){
byte bs = yobikomi_status();
/*
Serial.print("state = ");
Serial.println(bs,HEX);*/
//delay(100);
if( bs == 0 ){
state = -1;
ledupdate();
}
}
for(int n=0;n<5;n++){
if( digitalRead(buttons[n]) == 0 ){
delay(10);
if( digitalRead(buttons[n]) == 0 ){
delay(10);
if( digitalRead(buttons[n]) == 0 ){
if( n == 0 || n == 1 ){
if( state == n ){
state = -1;
yobikomi_stop();
}else{
state = n;
yobikomi_setaddr(readBuffer[ state * 4 ],readBuffer[ state * 4 + 2]);
delay(1);
yobikomi_play();
}
ledupdate();
while(digitalRead(buttons[n]) == 0);
}
if( n == 2 || n == 3 ){
yobikomi_stop();
if( state == n ){
state = -1;
}else{
state = n;
}
ledupdate();
while(digitalRead(buttons[n]) == 0);
while(true){
digitalWrite(leds[4],HIGH);
digitalWrite(leds[n],HIGH);
delay(100);
digitalWrite(leds[4],LOW);
digitalWrite(leds[n],LOW);
delay(100);
word start,stop;
if(digitalRead(buttons[n]) == 0) {
digitalWrite(leds[n],HIGH);
delay(500);
if( n == 2){
// 1st ch
start = 0;
stop = 0x1CFF;
}else
{
if( readBuffer[2] == 0x1CFF ){
for(int t=0;t<5;t++){
for(int x=0;x<5;x++){
digitalWrite(leds[x],HIGH);
}
delay(100);
for(int x=0;x<5;x++){
digitalWrite(leds[x],LOW);
}
delay(100);
}
return;
}
// 2nd ch
start = inc(readBuffer[2]);
start = roundaddr( start );
Serial.println("set 2nd pointer to after 1st end\n");
stop = 0x1CFF;
}
yobikomi_setaddr(start,stop);
delay(1);
yobikomi_rec();
int lastsec = 0;
while(true){
unsigned long m = millis();
if( lastsec != (m / 1000 )){
word pos = yobikomi_getpos();
Serial.print("pos = ");
Serial.print(pos,HEX);
Serial.println("h");
lastsec = m / 1000;
}
if( (m % 1000) < 500){
digitalWrite(leds[4],HIGH);
}else{
digitalWrite(leds[4],LOW);
}
word pos=yobikomi_getpos();
if( pos == stop ){
// buffer full
Serial.println("reach end addr\n");
while(true){
digitalWrite(leds[4],HIGH);
delay(100);
digitalWrite(leds[4],LOW);
delay(100);
if(digitalRead(buttons[4]) == 0 ) {
readBuffer[ (state-2) * 4 ] = start;
readBuffer[ (state-2) * 4 + 2 ] = pos;
eeprom_update();
state = -1;
ledupdate();
yobikomi_stop();
return;
}
}
}
if(digitalRead(buttons[4]) == 0 ) {
readBuffer[ (state-2) * 4 ] = start;
readBuffer[ (state-2) * 4 + 2] = pos;
eeprom_update();
state = -1;
ledupdate();
yobikomi_stop();
return;
}
}
}
if(digitalRead(buttons[4]) == 0) {
state = -1;
ledupdate();
yobikomi_stop();
break;
}
}
}
}
}
}
}
if( Serial.available() ){
int r= Serial.read();
if( r == '1' || r == '2') {
recording = r - '0';
Serial.print("Record start ");
Serial.println(recording);
yobikomi_stop();
delay(1);
yobikomi_setaddr(readBuffer[(recording - 1) * 4],readBuffer[(recording - 1) * 4 + 2]);
delay(1);
yobikomi_rec();
}
if( recording && (r == 's'||r=='S')){
recording = 0;
Serial.println("Record stop");
yobikomi_stop();
yobikomi_play();
}
if(! recording && (r == 'p'||r=='P') ){
yobikomi_stop();
int p= (r == 'p' );
Serial.print("Ch:");
Serial.print(p+1);
Serial.print(" playing..\n");
yobikomi_setaddr(readBuffer[ p * 4],readBuffer[ p * 4 + 2]);
yobikomi_play();
}
if(!recording && (r == 'g' || r == 'G')){
word pos = yobikomi_getpos();
Serial.print("pos = ");
Serial.print(pos,HEX);
Serial.println("h");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment