#define SD_MOSI 13 #define SD_MISO 12 #define SD_SCK 14 #define SD_CS 11 #include "FS.h" #include "SD.h" #include "SPI.h" #include "Wire.h" #include "Adafruit_GFX.h" #include "Adafruit_SSD1306.h" #include "SSD1306Ascii.h" #include "SSD1306AsciiWire.h" #include "fonts\TimesNewRoman16.h" #include "fonts\X11fixed7x14B.h" #define SSD1306 #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels SSD1306AsciiWire display; #define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's #define I2CSDA 8 //12 for Waveshare Tiny S3 #define I2CSCL 9 //13 for Waveshare Tiny S3 SPIClass hspi = SPIClass(HSPI); char string_buffer[256]; // Global string buffer for sending characters to S100 bus uint8_t sector_buffer[1024]; char current_drive_letter = '?'; char current_drive = 0; uint32_t sector = 0; uint32_t CPM_track = 0; uint32_t CPM_sector = 0; char error_flag = 0; // Flag for error flag LED char SD_CS_PIN; char S100_Data; #define CMD_INIT_DRIVE_1 0x80 //Initilized SD drive C: #define CMD_INIT_DRIVE_2 0x81 //Initilized drive D: (not used here) #define CMD_SEL_DRIVE_1 0x82 //**** (Re)select an already initilized drive C: #define CMD_SEL_DRIVE_2 0x83 //**** (Re)select an already initilized drive D: (Not used here) #define CMD_SET_TRK_SEC 0x84 //Set new current TRACK+SECTOR on current drive (new) #define CMD_READ_SECTOR 0x85 //**** Read data from the CURRENT sector (on current track,drive). #define CMD_WRITE_SECTOR 0x86 //**** Write data to the CURRENT sector (on current track,drive). #define CMD_FORMAT_SECTOR 0x87 //Format the CURRENT sector with E5's. #define CMD_RESET_ESP32 0x88 //Reset the ESP32 CPU #define CMD_INIT_CF_DRIVE_A 0x89 //Initilized CF card A: (OLED display info only) #define CMD_INIT_CF_DRIVE_B 0x8A //Initilized CF Card B: (OLED display info only) #define CMD_READ_CF_SECTOR 0x8B //Read data from the CURRENT CF card sector (on current track,drive). #define CMD_WRITE_CF_SECTOR 0x8C //Write data to the CURRENT CF card sector (on current track,drive). #define CMD_ESP32_READY 0x90 //Handshake on startup with tehS100 bus. #define CMD_S100_ACK 0x91 //Handshake returned to board from S100 bus. void Set_PARALLEL_Port_Output(){ for (int i = 0; i < 8; i++) { //Setup the PARALLEL port 8 bits GPIO35-GPIO42 to output mode pinMode(GPIO_NUM_42, OUTPUT); pinMode(GPIO_NUM_41, OUTPUT); pinMode(GPIO_NUM_40, OUTPUT); pinMode(GPIO_NUM_39, OUTPUT); pinMode(GPIO_NUM_38, OUTPUT); pinMode(GPIO_NUM_37, OUTPUT); pinMode(GPIO_NUM_36, OUTPUT); pinMode(GPIO_NUM_35, OUTPUT); } } void Set_PARALLEL_Port_Input(){ for (int i = 0; i < 8; i++) { //Setup the PARALLEL port 8 bits GPIO35-GPIO42 to input mode pinMode(GPIO_NUM_18, INPUT); pinMode(GPIO_NUM_17, INPUT); pinMode(GPIO_NUM_16, INPUT); pinMode(GPIO_NUM_15, INPUT); pinMode(GPIO_NUM_7, INPUT); pinMode(GPIO_NUM_6, INPUT); pinMode(GPIO_NUM_5, INPUT); pinMode(GPIO_NUM_4, INPUT); } } void Output_PARALLEL_Port(char PARALLEL_value){ gpio_set_level(GPIO_NUM_42, (PARALLEL_value & 0x80) >> 7); gpio_set_level(GPIO_NUM_41, (PARALLEL_value & 0x40) >> 6); gpio_set_level(GPIO_NUM_40, (PARALLEL_value & 0x20) >> 5); gpio_set_level(GPIO_NUM_39, (PARALLEL_value & 0x10) >> 4); gpio_set_level(GPIO_NUM_38, (PARALLEL_value & 0x08) >> 3); gpio_set_level(GPIO_NUM_37, (PARALLEL_value & 0x04) >> 2); gpio_set_level(GPIO_NUM_36, (PARALLEL_value & 0x02) >> 1); gpio_set_level(GPIO_NUM_35, (PARALLEL_value & 0x01)); gpio_set_level(GPIO_NUM_1,HIGH); // pulse U15 LE high gpio_set_level(GPIO_NUM_1,LOW); // return U15 LE low } char Input_PARALLEL_Port() { char PARALLEL_value; PARALLEL_value = digitalRead(GPIO_NUM_4) + (digitalRead(GPIO_NUM_5) << 1) + (digitalRead(GPIO_NUM_6) << 2) + (digitalRead(GPIO_NUM_7) << 3) + (digitalRead(GPIO_NUM_15) << 4) + (digitalRead(GPIO_NUM_16) << 5) + (digitalRead(GPIO_NUM_17) << 6) + (digitalRead(GPIO_NUM_18) << 7); gpio_set_level(GPIO_NUM_2,HIGH); // return U4A/U6A low gpio_set_level(GPIO_NUM_2,LOW); // pulse U4A/U6A high return(PARALLEL_value); } char GetData(){ //Get an S100 bus Command or byte char data; while(digitalRead(GPIO_NUM_20) == 0); // wait for data data=Input_PARALLEL_Port(); // get second CMD byte return(data); } char GetCMD(){ //Get an S100 bus Command char cmd; cmd=GetData(); // get first CMD byte if(cmd != 0x33){ // All valid commands must begin with 0x33 sprintf(string_buffer,"\r\r\nInvalid CMD (No initial 33H byte). Got %2x",cmd); Serial.printf(string_buffer); return (0); } else { cmd=GetData(); // get second CMD byte return(cmd); } } uint16_t GetSD_Sector(){ //Get a 16 bit value from S100 bus uint16_t data_word; CPM_track = GetData(); CPM_sector = GetData(); // get second CMD byte data_word = word(CPM_track,CPM_sector); return(data_word); } uint16_t GetDataWord(){ //Get a 16 bit value from S100 bus uint16_t data_word; uint16_t d1,d2; d1 = GetData(); d2 = GetData(); // get second byte data_word = word(d2,d1); return(data_word); } char SendData(char data){ //Send an S100 bus Command while(digitalRead(GPIO_NUM_21) == 1); Output_PARALLEL_Port(data); return(data); } void SendString(char string_buffer[]){ int x = strlen(string_buffer); for (int i = 0; x > 0; i++,x--) { SendData(string_buffer[i]); } SendData(0); // Must terminate a string with 0 return; } void SetErrorLED() { gpio_set_level(GPIO_NUM_10, 0); char error_flag = 1; // Flag for error flag LED } void ClearErrorLED() { gpio_set_level(GPIO_NUM_10, 1); char error_flag = 0; // Flag for error flag LED } void setup(){ Serial.begin(115200); Serial.println("In Setup"); pinMode(GPIO_NUM_20, INPUT); pinMode(GPIO_NUM_1, OUTPUT); pinMode(GPIO_NUM_2, OUTPUT); pinMode(GPIO_NUM_21, INPUT); pinMode(GPIO_NUM_11, OUTPUT); // CS SD Board 1 pinMode(GPIO_NUM_47, OUTPUT); // CS SD Board 2 pinMode(GPIO_NUM_19, INPUT); // Switch for diagnostic OLED diaplay pinMode(GPIO_NUM_10, OUTPUT); // Error LED gpio_set_level(GPIO_NUM_10, 1); // Clear error LED Set_PARALLEL_Port_Input(); Set_PARALLEL_Port_Output(); sector = 0; // initilize to Track 0, sector 0 CPM_track = 0; CPM_sector = 0; SD_CS_PIN = 47; Wire.begin(I2CSDA,I2CSCL); // enable & set I2C pins Wire.setClock(400000L); gpio_set_level(GPIO_NUM_11, 0); // Select card C: on startup gpio_set_level(GPIO_NUM_47, 0); display.begin(&Adafruit128x64, i2c_Address); // display.setFont(Adafruit5x7); //display.setFont(TimesNewRoman16); display.setFont(X11fixed7x14B); // display.set2X(); display.clear(); display.setCursor(0, 0); display.print("Simple IO Tests\r\nSD Board ready!\r\n(V1.0) 5/3/2025"); // verify OLED display is functional } // END OF SETUP void loop() { char cmd; char data, data1, data2; uint8_t cardType; uint16_t sectorSize; uint32_t sector_count; gpio_set_level(GPIO_NUM_2,HIGH); // Set U4A LOW will set U6A reset high gpio_set_level(GPIO_NUM_2,LOW); // Set U4A LOW will set U6A reset high ClearErrorLED(); // COMMENT IN/OUT THE TEST REQUIRED while(1) { // data = GetData(); // Get data Test // sprintf(string_buffer,"\r\nGot data (80H) = %x",data); // Serial.println(string_buffer); // data = GetData(); // sprintf(string_buffer,"\r\nGot data (81H) = %x",data); // Serial.println(string_buffer); // data = GetData(); // sprintf(string_buffer,"\r\nGot data (82H) = %x",data); // Serial.println(string_buffer); // data = GetData(); // Get String Test // sprintf(string_buffer,"\r\n(String test, Got data = %x",data); // Serial.println(string_buffer); // SendString(string_buffer); data1 = GetCMD(); // Get CMD Test data2 = GetCMD(); sprintf(string_buffer,"\r\n(String test, Got CMD1 = %x CMD2 = %x",data1,data2); Serial.println(string_buffer); SendString(string_buffer); } }