mirror of
https://github.com/equant/apple2idiot.git
synced 2024-06-28 20:29:40 +00:00
Low level ESP ram functions into Apple2Idiot arduino library
This commit is contained in:
parent
a93d5e7ef2
commit
467a7472d2
476
examples/foo/weather.ino
Normal file
476
examples/foo/weather.ino
Normal file
|
@ -0,0 +1,476 @@
|
|||
/*
|
||||
blah blah blah
|
||||
*/
|
||||
|
||||
#define DEBUG true
|
||||
|
||||
// Load Wi-Fi library
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
/**************/
|
||||
/* ESP32 Pins */
|
||||
/**************/
|
||||
|
||||
/* DATA BUS (numbers mean GPIO port) */
|
||||
#define D0R 12
|
||||
#define D1R 13
|
||||
#define D2R 14
|
||||
#define D3R 15
|
||||
#define D4R 16
|
||||
#define D5R 17
|
||||
#define D6R 18
|
||||
#define D7R 19
|
||||
//byte data_pins[] = {D0R, D1R, D2R, D3R, D4R, D5R, D6R, D7R};
|
||||
byte data_pins[] = {D7R, D6R, D5R, D4R, D3R, D2R, D1R, D0R}; // That's the way the Apple II likes it.
|
||||
#define DATA_BUS_SIZE 8
|
||||
|
||||
/* Address Bus */
|
||||
#define A0R 21
|
||||
#define A1R 22
|
||||
#define A2R 23
|
||||
#define A3R 25
|
||||
#define A4R 26
|
||||
#define A5R 27
|
||||
#define A6R 32
|
||||
#define A7R 33
|
||||
byte address_pins[] = {A0R, A1R, A2R, A3R, A4R, A5R, A6R, A7R};
|
||||
#define ADDRESS_BUS_SIZE 8
|
||||
|
||||
/* IDT7132S dual port ram chip enable */
|
||||
#define RW_PIN 5
|
||||
#define RW_WRITE LOW
|
||||
#define RW_READ HIGH
|
||||
|
||||
#define INPUT_35 35
|
||||
#define INPUT_34 34
|
||||
|
||||
//unsigned int data_byte = 0;
|
||||
// fisrt bit is a flag for if the data is from Apple or from ESP32.
|
||||
// /
|
||||
// / last bit is a flag for "more data waiting to be sent".
|
||||
// / /
|
||||
#define COMMAND_FROM_APPLE 0 // 0_______
|
||||
#define COMMAND_FROM_ESP 128 // 1_______
|
||||
#define COMMAND_MORE_DATA_WAITING 1 // _0000001
|
||||
#define COMMAND_NO_DATA_WAITING 0 // _0000001
|
||||
|
||||
#define COMMAND_GENERIC_MESSAGE 2 // _000001_
|
||||
#define COMMAND_FETCH_WEATHER 4 // _000010_
|
||||
#define COMMAND_SEND_LONG_STRING 12 // _000110_
|
||||
#define COMMAND_FORMAT_RAM 126 // _111111_
|
||||
|
||||
#define ETX 3 // ASCII "End of Text" (ETX) character
|
||||
|
||||
/************/
|
||||
/* Interupt */
|
||||
/************/
|
||||
|
||||
/* Variables shared between ISR and main code need to be volatile */
|
||||
volatile bool isr_handled = false;
|
||||
volatile uint32_t raw_register_read;
|
||||
volatile uint16_t raw_register1_read;
|
||||
|
||||
/**********************/
|
||||
/* WiFi and Webserver */
|
||||
/**********************/
|
||||
|
||||
// Replace with your network credentials
|
||||
const char* wifi_ssid = "GSO";
|
||||
//const char* wifi_ssid = "Pixel_8985";
|
||||
const char* wifi_password = "xerxes27";
|
||||
AsyncWebServer web_server(80);
|
||||
//WebServer web_server(80);
|
||||
|
||||
/*******************/
|
||||
/* Weather Service */
|
||||
/*******************/
|
||||
|
||||
const String weather_service_api_key= "0ab97bbbea58592d7c9d64067a34d2d0";
|
||||
const String weather_url = "http://api.openweathermap.org/data/2.5/weather?";
|
||||
|
||||
/*********/
|
||||
/* Misc. */
|
||||
/*********/
|
||||
|
||||
const long readLoopInterval = 10000; // millis
|
||||
unsigned long lastReadLoopTime = 0;
|
||||
//byte ram[ADDRESS_BUS_SIZE];
|
||||
//byte ram[256];
|
||||
byte ram[256];
|
||||
volatile byte ram_busy=0;
|
||||
//const unsigned int RAM_BUSY=666;
|
||||
#define RAM_BUSY 666
|
||||
|
||||
/*################################################
|
||||
# ISR #
|
||||
################################################*/
|
||||
|
||||
void IRAM_ATTR isrDEVSEL(void) {
|
||||
raw_register_read = REG_READ(GPIO_IN_REG);
|
||||
raw_register1_read = REG_READ(GPIO_IN1_REG);
|
||||
isr_handled = true;
|
||||
}
|
||||
|
||||
/*################################################
|
||||
# Functions #
|
||||
################################################*/
|
||||
|
||||
boolean set_address(int address) {
|
||||
if (ram_busy) {
|
||||
Serial.println("BUSY");
|
||||
return false;
|
||||
}
|
||||
ram_busy = true;
|
||||
//Serial.print(" Setting address (");
|
||||
//Serial.print(address);
|
||||
//Serial.println(")");
|
||||
//delay(20);
|
||||
Serial.print(" A:");
|
||||
for (byte i=0; i<ADDRESS_BUS_SIZE; i++) {
|
||||
//for (byte i=ADDRESS_BUS_SIZE; i>0; i--) {
|
||||
byte state = bitRead(address, i);
|
||||
digitalWrite(address_pins[i], state);
|
||||
Serial.print(state);
|
||||
}
|
||||
Serial.println();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int read_data(int address) {
|
||||
Serial.print("READ: ");
|
||||
Serial.println(address);
|
||||
byte data_bus_read = 0;
|
||||
if (set_address(address)) {
|
||||
digitalWrite(RW_PIN, RW_READ); // Should already be set to RW_READ, but just in case.
|
||||
Serial.print(" D:");
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
byte pin_state = digitalRead(data_pins[i]);
|
||||
data_bus_read += pin_state * pow(2,i);
|
||||
Serial.print(pin_state);
|
||||
}
|
||||
Serial.println();
|
||||
ram_busy = false;
|
||||
return data_bus_read;
|
||||
} else {
|
||||
return RAM_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
//signed int convert_to_signed_byte(byte byte_to_convert) {
|
||||
//if (abs(requested_byte_to_write) > 127) {
|
||||
//if (requested_byte_to_write < 0) {
|
||||
|
||||
boolean write_data(byte address, byte byte_to_write) {
|
||||
Serial.print("WRITE: ");
|
||||
Serial.print(byte_to_write);
|
||||
Serial.print(" -> ");
|
||||
Serial.println(address);
|
||||
if (set_address(address)) {
|
||||
//set_address(address);
|
||||
Serial.print(" D:");
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
byte bit_to_write = (byte_to_write >> i) & 0b00000001;
|
||||
pinMode(data_pins[i], OUTPUT);
|
||||
digitalWrite(data_pins[i], bit_to_write);
|
||||
Serial.print(bit_to_write);
|
||||
}
|
||||
Serial.println();
|
||||
digitalWrite(RW_PIN, RW_WRITE);
|
||||
delay(1);
|
||||
digitalWrite(RW_PIN, RW_READ);
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
pinMode(data_pins[i], INPUT);
|
||||
}
|
||||
ram_busy = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void store_ip_to_ram(byte offset) {
|
||||
IPAddress ip_address = WiFi.localIP();
|
||||
//for (int i=0; i < ADDRESS_BUS_SIZE; i++) {
|
||||
for (int i=0; i < 4; i++) {
|
||||
write_data(i+offset, ip_address[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void send_string_to_apple(String string_to_send, byte command_message) {
|
||||
if (string_to_send.length() > 15 - 1) { // - 1 because of null character at end of string.
|
||||
} else {
|
||||
int c=0;
|
||||
for (c=0; c < string_to_send.length(); c++) {
|
||||
write_data(c, string_to_send[c]);
|
||||
}
|
||||
write_data(c+1, ETX);
|
||||
write_data(15, COMMAND_FROM_ESP + command_message + COMMAND_NO_DATA_WAITING);
|
||||
}
|
||||
}
|
||||
|
||||
void fetch_weather(char* city_name) {
|
||||
HTTPClient http;
|
||||
//http.begin(String(weather_url) + "?q=Tucson,us&APPID=" + String(weather_service_api_key));
|
||||
const String request_url = weather_url + "q=Tucson,us&APPID=" + weather_service_api_key;
|
||||
Serial.println(request_url);
|
||||
http.begin(request_url);
|
||||
int httpCode = http.GET(); //Make the request
|
||||
delay(10);
|
||||
|
||||
if (httpCode > 0) { //Check for the returning code
|
||||
String payload = http.getString();
|
||||
//Serial.println(httpCode);
|
||||
Serial.println("++++++++++++++++++++++++");
|
||||
Serial.println(payload);
|
||||
Serial.println("++++++++++++++++++++++++");
|
||||
StaticJsonDocument<200> filter;
|
||||
filter["weather"][0]["main"] = true;
|
||||
filter["weather"][0]["description"] = true;
|
||||
filter["main"]["humidity"] = true;
|
||||
filter["main"]["temp"] = true;
|
||||
filter["wind"]["speed"] = true;
|
||||
filter["wind"]["deg"] = true;
|
||||
StaticJsonDocument<400> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload, DeserializationOption::Filter(filter));
|
||||
//DeserializationError error = deserializeJson(doc, payload);
|
||||
if (error) {
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
} else {
|
||||
//const char* main = doc["main"];
|
||||
Serial.println("----------------------");
|
||||
serializeJsonPretty(doc, Serial);
|
||||
Serial.println("----------------------");
|
||||
serializeJsonPretty(doc["wind"], Serial);
|
||||
Serial.println("----------------------");
|
||||
int temp = doc["main"]["humidity"];
|
||||
int humidity = doc["main"]["humidity"];
|
||||
float wind_speed = doc["wind"]["speed"];
|
||||
int wind_deg = doc["wind"]["speed"];
|
||||
String weather_description = doc["weather"][0]["description"];
|
||||
write_data(0, round(temp-273.15));
|
||||
write_data(1, round(humidity));
|
||||
write_data(2, round(wind_deg/10)); // divide by twn because 360 is too big for 8 bits
|
||||
write_data(3, round(wind_speed));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
Serial.println("Error on HTTP request");
|
||||
}
|
||||
|
||||
http.end(); //Free the resources
|
||||
}
|
||||
|
||||
void read_ram() {
|
||||
//for (int i=0; i < 16; i++) {
|
||||
for (int i=0; i < 256; i++) {
|
||||
unsigned int foo = read_data(i);
|
||||
ram[i] = foo;
|
||||
}
|
||||
}
|
||||
|
||||
String html_template_processor(const String& var) {
|
||||
Serial.println("html_template_processor()");
|
||||
String return_string = "";
|
||||
if (var == "RAM_TABLE") {
|
||||
read_ram();
|
||||
//for (int i=0; i < 16; i++) {
|
||||
for (int i=0; i < 256; i++) {
|
||||
return_string += "<tr><td>"+String(i)+"</td><td>" + String(ram[i]) + "</td></tr>\n";
|
||||
}
|
||||
return return_string;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
void www_weather(AsyncWebServerRequest *request) {
|
||||
fetch_weather("Tucson");
|
||||
request->send(SPIFFS, "/ram.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_root(AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/index.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_ram(AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/ram.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_write_byte(AsyncWebServerRequest *request) {
|
||||
Serial.println("www_write_byte()");
|
||||
String address;
|
||||
String data_byte;
|
||||
if (request->hasParam("address")) {
|
||||
address = request->getParam("address")->value();
|
||||
//Serial.println("Found address: "+address);
|
||||
if (request->hasParam("data")) {
|
||||
data_byte = request->getParam("data")->value();
|
||||
//Serial.println("Found data: "+data_byte);
|
||||
write_data(address.toInt(), data_byte.toInt());
|
||||
}
|
||||
}
|
||||
request->send(SPIFFS, "/ram.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_css(AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/a2i.css", "text/css");
|
||||
}
|
||||
|
||||
void prefill_ram_with_pattern_data() {
|
||||
write_data(15, 0); // notify Apple IIe we are done processing command byte
|
||||
write_data(14, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(13, 1); // notify Apple IIe we are done processing command byte
|
||||
write_data(12, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(11, 2); // notify Apple IIe we are done processing command byte
|
||||
write_data(10, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(9, 3); // notify Apple IIe we are done processing command byte
|
||||
write_data(8, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(7, 4); // notify Apple IIe we are done processing command byte
|
||||
write_data(6, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(5, 5); // notify Apple IIe we are done processing command byte
|
||||
write_data(4, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(3, 6); // notify Apple IIe we are done processing command byte
|
||||
write_data(2, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(1, 7); // notify Apple IIe we are done processing command byte
|
||||
write_data(0, 123); // notify Apple IIe we are done processing command byte
|
||||
}
|
||||
|
||||
/*################################################
|
||||
# Setup #
|
||||
################################################*/
|
||||
|
||||
void setup() {
|
||||
|
||||
/* Configure ESP32 Pins */
|
||||
pinMode(A0R, OUTPUT); digitalWrite(A0R, LOW);
|
||||
pinMode(A1R, OUTPUT); digitalWrite(A1R, LOW);
|
||||
pinMode(A2R, OUTPUT); digitalWrite(A2R, LOW);
|
||||
pinMode(A3R, OUTPUT); digitalWrite(A3R, LOW);
|
||||
pinMode(A4R, OUTPUT); digitalWrite(A4R, LOW);
|
||||
pinMode(A5R, OUTPUT); digitalWrite(A5R, LOW);
|
||||
pinMode(A6R, OUTPUT); digitalWrite(A6R, LOW);
|
||||
pinMode(A7R, OUTPUT); digitalWrite(A7R, LOW);
|
||||
pinMode(D0R, INPUT);
|
||||
pinMode(D1R, INPUT);
|
||||
pinMode(D2R, INPUT);
|
||||
pinMode(D3R, INPUT);
|
||||
pinMode(D4R, INPUT);
|
||||
pinMode(D5R, INPUT);
|
||||
pinMode(D6R, INPUT);
|
||||
pinMode(D7R, INPUT);
|
||||
pinMode(RW_PIN, OUTPUT); digitalWrite(RW_PIN, RW_READ);
|
||||
|
||||
pinMode(INPUT_34, INPUT);
|
||||
pinMode(INPUT_35, INPUT);
|
||||
|
||||
delay(10);
|
||||
//wifi_scan();
|
||||
|
||||
/* Connect to wifi */
|
||||
Serial.begin(115200);
|
||||
Serial.println("");
|
||||
Serial.println("Starting wifi...");
|
||||
Serial.print(" connecting to: ");
|
||||
Serial.println(wifi_ssid);
|
||||
|
||||
WiFi.begin(wifi_ssid, wifi_password);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(900);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected successfully");
|
||||
Serial.print("Got IP: ");
|
||||
Serial.println(WiFi.localIP()); //Show ESP32 IP on serial
|
||||
prefill_ram_with_pattern_data();
|
||||
store_ip_to_ram(0);
|
||||
//store_ip_to_ram(4);
|
||||
|
||||
/* Start webserver */
|
||||
if(!SPIFFS.begin()){
|
||||
Serial.println("An Error has occurred while mounting SPIFFS");
|
||||
}
|
||||
web_server.on("/", HTTP_GET, www_root);
|
||||
web_server.on("/a2i.css", HTTP_GET, www_css);
|
||||
web_server.on("/ram", HTTP_GET, www_ram);
|
||||
web_server.on("/write_byte", HTTP_GET, www_write_byte);
|
||||
web_server.on("/weather", HTTP_GET, www_weather);
|
||||
web_server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/plain", "Free Heap: " + String(ESP.getFreeHeap()) + " bytes.");
|
||||
});
|
||||
|
||||
//web_server.on("/hello", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
//request->send(200, "text/plain", "Hello World");
|
||||
//});
|
||||
|
||||
//web_server.on("/", www_root);
|
||||
web_server.begin();
|
||||
Serial.println("HTTP server started");
|
||||
delay(10);
|
||||
|
||||
/* Display file system contents */
|
||||
Serial.println("-----------------------------------------");
|
||||
File root_filesystem = SPIFFS.open("/");
|
||||
File f = root_filesystem.openNextFile();
|
||||
while(f){
|
||||
Serial.print("FILE: ");
|
||||
Serial.println(f.name());
|
||||
f = root_filesystem.openNextFile();
|
||||
}
|
||||
Serial.println("-----------------------------------------");
|
||||
|
||||
//attachInterrupt(DEVSEL_PIN, isrDEVSEL, LOW);
|
||||
}
|
||||
|
||||
/*################################################
|
||||
# Main #
|
||||
################################################*/
|
||||
|
||||
void loop() {
|
||||
//if (isr_handled) {
|
||||
//data_byte = raw_register_read >> 12 & 0b00000000000011111111;
|
||||
//isr_handled = false;
|
||||
//}
|
||||
|
||||
if ((millis() - lastReadLoopTime) > readLoopInterval) {
|
||||
//Serial.println("+++");
|
||||
unsigned int command_byte = read_data(15);
|
||||
if (command_byte == RAM_BUSY) {
|
||||
Serial.println("Command Read: RAM BUSY");
|
||||
}
|
||||
else if (command_byte < COMMAND_FROM_ESP) {
|
||||
// command came from apple (or webform).
|
||||
Serial.print("Command Read: ");
|
||||
Serial.println(command_byte);
|
||||
//write_data(15, 1); // notify Apple IIe we are processing command byte
|
||||
switch(command_byte) {
|
||||
case COMMAND_FETCH_WEATHER:
|
||||
Serial.println("Fetch Weather");
|
||||
fetch_weather("Tucson");
|
||||
break;
|
||||
case COMMAND_SEND_LONG_STRING:
|
||||
//send_string_to_apple("This is a long string", COMMAND_GENERIC_MESSAGE);
|
||||
send_string_to_apple("ABCDE", COMMAND_GENERIC_MESSAGE);
|
||||
case COMMAND_FORMAT_RAM:
|
||||
Serial.println("Calling prefill_ram_with_pattern_data()");
|
||||
prefill_ram_with_pattern_data();
|
||||
write_data(15, 0); // notify Apple IIe we are done processing command byte
|
||||
break;
|
||||
}
|
||||
/*
|
||||
byte c = 0;
|
||||
while (ram_busy && (c < 10)) {
|
||||
delay(10);
|
||||
c = c+1;
|
||||
Serial.print("_");
|
||||
}
|
||||
Serial.println("^^^^");
|
||||
write_data(15, 0); // notify Apple IIe we are done processing command byte
|
||||
read_data(15); // notify Apple IIe we are done processing command byte
|
||||
*/
|
||||
}
|
||||
lastReadLoopTime = millis();
|
||||
}
|
||||
}
|
22
examples/template/template.ino
Normal file
22
examples/template/template.ino
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
|
||||
Use this program with the Apple2idIOT card and the basic programs RRAM, WRAM and CMDROT to read/write and rot13
|
||||
a single string contained within the dual port ram on the card.
|
||||
|
||||
*/
|
||||
|
||||
// Load Wi-Fi library
|
||||
#include <WiFi.h>
|
||||
#include <Apple2Idiot.h>
|
||||
|
||||
Apple2Idiot a2i = Apple2Idiot();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
a2i.init();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
|
@ -1,12 +1,22 @@
|
|||
/*
|
||||
blah blah blah
|
||||
|
||||
Use this program with the Apple2idIOT card and the basic programs RRAM, WRAM and CMDROT to read/write and rot13
|
||||
a single string contained within the dual port ram on the card.
|
||||
|
||||
*/
|
||||
|
||||
#define DEBUG true
|
||||
|
||||
// Load Wi-Fi library
|
||||
#include <WiFi.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
/**********************/
|
||||
/* Default WiFi */
|
||||
/**********************/
|
||||
|
||||
// Replace with your network credentials
|
||||
const char* wifi_ssid = "ella";
|
||||
const char* wifi_password = "";
|
||||
|
||||
/**************/
|
||||
/* ESP32 Pins */
|
||||
|
@ -21,8 +31,7 @@ blah blah blah
|
|||
#define D5R 17
|
||||
#define D6R 18
|
||||
#define D7R 19
|
||||
//byte data_pins[] = {D0R, D1R, D2R, D3R, D4R, D5R, D6R, D7R};
|
||||
byte data_pins[] = {D7R, D6R, D5R, D4R, D3R, D2R, D1R, D0R}; // That's the way the Apple II likes it.
|
||||
byte data_pins[] = {D7R, D6R, D5R, D4R, D3R, D2R, D1R, D0R};
|
||||
#define DATA_BUS_SIZE 8
|
||||
|
||||
/* Address Bus */
|
||||
|
@ -36,6 +45,15 @@ byte data_pins[] = {D7R, D6R, D5R, D4R, D3R, D2R, D1R, D0R}; // That's the way
|
|||
#define A7R 33
|
||||
byte address_pins[] = {A0R, A1R, A2R, A3R, A4R, A5R, A6R, A7R};
|
||||
#define ADDRESS_BUS_SIZE 8
|
||||
#define ESP_COMMAND_ADDRESS 0
|
||||
#define APPLE_COMMAND_ADDRESS 1
|
||||
#define SHARED_RAM_START_ADDRESS 2
|
||||
#define RAM_BUSY 666
|
||||
#define MAX_STR_LEN 44 // arbitrary length.
|
||||
|
||||
#define COMMAND_GENERIC 0b10000000
|
||||
#define COMMAND_SCAN_WIFI 111
|
||||
#define COMMAND_CONNECT 112
|
||||
|
||||
/* IDT7132S dual port ram chip enable */
|
||||
#define RW_PIN 5
|
||||
|
@ -45,121 +63,59 @@ byte address_pins[] = {A0R, A1R, A2R, A3R, A4R, A5R, A6R, A7R};
|
|||
#define INPUT_35 35
|
||||
#define INPUT_34 34
|
||||
|
||||
//unsigned int data_byte = 0;
|
||||
// fisrt bit is a flag for if the data is from Apple or from ESP32.
|
||||
// /
|
||||
// / last bit is a flag for "more data waiting to be sent".
|
||||
// / /
|
||||
#define COMMAND_FROM_APPLE 0 // 0_______
|
||||
#define COMMAND_FROM_ESP 128 // 1_______
|
||||
#define COMMAND_MORE_DATA_WAITING 1 // _0000001
|
||||
#define COMMAND_NO_DATA_WAITING 0 // _0000001
|
||||
|
||||
#define COMMAND_GENERIC_MESSAGE 2 // _000001_
|
||||
#define COMMAND_FETCH_WEATHER 4 // _000010_
|
||||
#define COMMAND_SEND_LONG_STRING 12 // _000110_
|
||||
#define COMMAND_FORMAT_RAM 126 // _111111_
|
||||
|
||||
#define ETX 3 // ASCII "End of Text" (ETX) character
|
||||
|
||||
/************/
|
||||
/* Interupt */
|
||||
/************/
|
||||
|
||||
/* Variables shared between ISR and main code need to be volatile */
|
||||
volatile bool isr_handled = false;
|
||||
volatile uint32_t raw_register_read;
|
||||
volatile uint16_t raw_register1_read;
|
||||
|
||||
/**********************/
|
||||
/* WiFi and Webserver */
|
||||
/**********************/
|
||||
|
||||
// Replace with your network credentials
|
||||
const char* wifi_ssid = "GSO";
|
||||
//const char* wifi_ssid = "Pixel_8985";
|
||||
const char* wifi_password = "xerxes27";
|
||||
AsyncWebServer web_server(80);
|
||||
//WebServer web_server(80);
|
||||
|
||||
/*******************/
|
||||
/* Weather Service */
|
||||
/*******************/
|
||||
|
||||
const String weather_service_api_key= "0ab97bbbea58592d7c9d64067a34d2d0";
|
||||
const String weather_url = "http://api.openweathermap.org/data/2.5/weather?";
|
||||
#define ACK 0b00000110 // Acknowledge
|
||||
#define EOT 0b00000100 // End of transmit
|
||||
|
||||
/*********/
|
||||
/* Misc. */
|
||||
/*********/
|
||||
|
||||
const long readLoopInterval = 10000; // millis
|
||||
const long readLoopInterval = 100; // millis
|
||||
unsigned long lastReadLoopTime = 0;
|
||||
//byte ram[ADDRESS_BUS_SIZE];
|
||||
//byte ram[256];
|
||||
byte ram[256];
|
||||
volatile byte ram_busy=0;
|
||||
//const unsigned int RAM_BUSY=666;
|
||||
#define RAM_BUSY 666
|
||||
|
||||
/*################################################
|
||||
# ISR #
|
||||
################################################*/
|
||||
|
||||
void IRAM_ATTR isrDEVSEL(void) {
|
||||
raw_register_read = REG_READ(GPIO_IN_REG);
|
||||
raw_register1_read = REG_READ(GPIO_IN1_REG);
|
||||
isr_handled = true;
|
||||
}
|
||||
byte lastAppleCommand = 0;
|
||||
|
||||
/*################################################
|
||||
# Functions #
|
||||
################################################*/
|
||||
|
||||
void unbusy_ram() {
|
||||
set_address(ESP_COMMAND_ADDRESS);
|
||||
ram_busy = false;
|
||||
}
|
||||
|
||||
boolean set_address(int address) {
|
||||
if (ram_busy) {
|
||||
Serial.println("BUSY");
|
||||
return false;
|
||||
}
|
||||
ram_busy = true;
|
||||
//Serial.print(" Setting address (");
|
||||
//Serial.print(address);
|
||||
//Serial.println(")");
|
||||
//delay(20);
|
||||
Serial.print(" A:");
|
||||
for (byte i=0; i<ADDRESS_BUS_SIZE; i++) {
|
||||
//for (byte i=ADDRESS_BUS_SIZE; i>0; i--) {
|
||||
byte state = bitRead(address, i);
|
||||
digitalWrite(address_pins[i], state);
|
||||
Serial.print(state);
|
||||
}
|
||||
Serial.println();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int read_data(int address) {
|
||||
Serial.print("READ: ");
|
||||
Serial.println(address);
|
||||
byte read_data(int address) {
|
||||
byte data_bus_read = 0;
|
||||
if (set_address(address)) {
|
||||
digitalWrite(RW_PIN, RW_READ); // Should already be set to RW_READ, but just in case.
|
||||
Serial.print(" D:");
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
byte pin_state = digitalRead(data_pins[i]);
|
||||
data_bus_read += pin_state * pow(2,i);
|
||||
Serial.print(pin_state);
|
||||
}
|
||||
Serial.println();
|
||||
ram_busy = false;
|
||||
unbusy_ram();
|
||||
return data_bus_read;
|
||||
} else {
|
||||
return RAM_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
//signed int convert_to_signed_byte(byte byte_to_convert) {
|
||||
//if (abs(requested_byte_to_write) > 127) {
|
||||
//if (requested_byte_to_write < 0) {
|
||||
|
||||
boolean write_data(byte address, byte byte_to_write) {
|
||||
Serial.print("WRITE: ");
|
||||
|
@ -182,7 +138,7 @@ boolean write_data(byte address, byte byte_to_write) {
|
|||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
pinMode(data_pins[i], INPUT);
|
||||
}
|
||||
ram_busy = false;
|
||||
unbusy_ram();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -190,158 +146,55 @@ boolean write_data(byte address, byte byte_to_write) {
|
|||
}
|
||||
|
||||
|
||||
void store_ip_to_ram(byte offset) {
|
||||
IPAddress ip_address = WiFi.localIP();
|
||||
//for (int i=0; i < ADDRESS_BUS_SIZE; i++) {
|
||||
for (int i=0; i < 4; i++) {
|
||||
write_data(i+offset, ip_address[i]);
|
||||
unsigned int write_string_to_shared_ram(String string_to_send, unsigned int address) {
|
||||
//if (string_to_send.length() > 15 - 1) { // - 1 because of null character at end of string.
|
||||
write_data(ESP_COMMAND_ADDRESS, 12);
|
||||
unsigned int c = 0;
|
||||
for (c=0; c < string_to_send.length(); c++) {
|
||||
Serial.print("A(");
|
||||
Serial.print(c);
|
||||
Serial.print("): ");
|
||||
Serial.println(string_to_send[c]);
|
||||
write_data(address+c, string_to_send[c]);
|
||||
}
|
||||
write_data(address+c, ETX);
|
||||
//write_data(15, COMMAND_FROM_ESP + command_message + COMMAND_NO_DATA_WAITING);
|
||||
write_data(ESP_COMMAND_ADDRESS, 27);
|
||||
return address+c;
|
||||
}
|
||||
|
||||
void send_string_to_apple(String string_to_send, byte command_message) {
|
||||
if (string_to_send.length() > 15 - 1) { // - 1 because of null character at end of string.
|
||||
} else {
|
||||
int c=0;
|
||||
for (c=0; c < string_to_send.length(); c++) {
|
||||
write_data(c, string_to_send[c]);
|
||||
}
|
||||
write_data(c+1, ETX);
|
||||
write_data(15, COMMAND_FROM_ESP + command_message + COMMAND_NO_DATA_WAITING);
|
||||
String read_string_from_ram(int address) {
|
||||
byte c = 0;
|
||||
int i = 0;
|
||||
String read_string = "";
|
||||
while ( (i<MAX_STR_LEN) && (c!=ETX) ) {
|
||||
c = read_data(address+i);
|
||||
read_string = read_string + char(c);
|
||||
i++;
|
||||
}
|
||||
Serial.print("READ STRING:");
|
||||
Serial.println(read_string);
|
||||
return read_string;
|
||||
}
|
||||
|
||||
void fetch_weather(char* city_name) {
|
||||
HTTPClient http;
|
||||
//http.begin(String(weather_url) + "?q=Tucson,us&APPID=" + String(weather_service_api_key));
|
||||
const String request_url = weather_url + "q=Tucson,us&APPID=" + weather_service_api_key;
|
||||
Serial.println(request_url);
|
||||
http.begin(request_url);
|
||||
int httpCode = http.GET(); //Make the request
|
||||
delay(10);
|
||||
|
||||
if (httpCode > 0) { //Check for the returning code
|
||||
String payload = http.getString();
|
||||
//Serial.println(httpCode);
|
||||
Serial.println("++++++++++++++++++++++++");
|
||||
Serial.println(payload);
|
||||
Serial.println("++++++++++++++++++++++++");
|
||||
StaticJsonDocument<200> filter;
|
||||
filter["weather"][0]["main"] = true;
|
||||
filter["weather"][0]["description"] = true;
|
||||
filter["main"]["humidity"] = true;
|
||||
filter["main"]["temp"] = true;
|
||||
filter["wind"]["speed"] = true;
|
||||
filter["wind"]["deg"] = true;
|
||||
StaticJsonDocument<400> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload, DeserializationOption::Filter(filter));
|
||||
//DeserializationError error = deserializeJson(doc, payload);
|
||||
if (error) {
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.f_str());
|
||||
} else {
|
||||
//const char* main = doc["main"];
|
||||
Serial.println("----------------------");
|
||||
serializeJsonPretty(doc, Serial);
|
||||
Serial.println("----------------------");
|
||||
serializeJsonPretty(doc["wind"], Serial);
|
||||
Serial.println("----------------------");
|
||||
int temp = doc["main"]["humidity"];
|
||||
int humidity = doc["main"]["humidity"];
|
||||
float wind_speed = doc["wind"]["speed"];
|
||||
int wind_deg = doc["wind"]["speed"];
|
||||
String weather_description = doc["weather"][0]["description"];
|
||||
write_data(0, round(temp-273.15));
|
||||
write_data(1, round(humidity));
|
||||
write_data(2, round(wind_deg/10)); // divide by twn because 360 is too big for 8 bits
|
||||
write_data(3, round(wind_speed));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
Serial.println("Error on HTTP request");
|
||||
}
|
||||
|
||||
http.end(); //Free the resources
|
||||
}
|
||||
|
||||
void read_ram() {
|
||||
//for (int i=0; i < 16; i++) {
|
||||
for (int i=0; i < 256; i++) {
|
||||
void read_ram(int size_to_read=256);
|
||||
void read_ram(int size_to_read) {
|
||||
for (int i=0; i < size_to_read; i++) {
|
||||
unsigned int foo = read_data(i);
|
||||
ram[i] = foo;
|
||||
Serial.print(i);
|
||||
Serial.print(" ");
|
||||
Serial.println(foo);
|
||||
}
|
||||
}
|
||||
|
||||
String html_template_processor(const String& var) {
|
||||
Serial.println("html_template_processor()");
|
||||
String return_string = "";
|
||||
if (var == "RAM_TABLE") {
|
||||
read_ram();
|
||||
//for (int i=0; i < 16; i++) {
|
||||
for (int i=0; i < 256; i++) {
|
||||
return_string += "<tr><td>"+String(i)+"</td><td>" + String(ram[i]) + "</td></tr>\n";
|
||||
}
|
||||
return return_string;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
void www_weather(AsyncWebServerRequest *request) {
|
||||
fetch_weather("Tucson");
|
||||
request->send(SPIFFS, "/ram.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_root(AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/index.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_ram(AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/ram.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_write_byte(AsyncWebServerRequest *request) {
|
||||
Serial.println("www_write_byte()");
|
||||
String address;
|
||||
String data_byte;
|
||||
if (request->hasParam("address")) {
|
||||
address = request->getParam("address")->value();
|
||||
//Serial.println("Found address: "+address);
|
||||
if (request->hasParam("data")) {
|
||||
data_byte = request->getParam("data")->value();
|
||||
//Serial.println("Found data: "+data_byte);
|
||||
write_data(address.toInt(), data_byte.toInt());
|
||||
}
|
||||
}
|
||||
request->send(SPIFFS, "/ram.htm", String(), false, html_template_processor);
|
||||
}
|
||||
void www_css(AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/a2i.css", "text/css");
|
||||
}
|
||||
|
||||
void prefill_ram_with_pattern_data() {
|
||||
write_data(15, 0); // notify Apple IIe we are done processing command byte
|
||||
write_data(14, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(13, 1); // notify Apple IIe we are done processing command byte
|
||||
write_data(12, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(11, 2); // notify Apple IIe we are done processing command byte
|
||||
write_data(10, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(9, 3); // notify Apple IIe we are done processing command byte
|
||||
write_data(8, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(7, 4); // notify Apple IIe we are done processing command byte
|
||||
write_data(6, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(5, 5); // notify Apple IIe we are done processing command byte
|
||||
write_data(4, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(3, 6); // notify Apple IIe we are done processing command byte
|
||||
write_data(2, 123); // notify Apple IIe we are done processing command byte
|
||||
write_data(1, 7); // notify Apple IIe we are done processing command byte
|
||||
write_data(0, 123); // notify Apple IIe we are done processing command byte
|
||||
}
|
||||
|
||||
/*################################################
|
||||
# Setup #
|
||||
################################################*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
/* Configure ESP32 Pins */
|
||||
pinMode(A0R, OUTPUT); digitalWrite(A0R, LOW);
|
||||
|
@ -365,11 +218,6 @@ void setup() {
|
|||
pinMode(INPUT_34, INPUT);
|
||||
pinMode(INPUT_35, INPUT);
|
||||
|
||||
delay(10);
|
||||
//wifi_scan();
|
||||
|
||||
/* Connect to wifi */
|
||||
Serial.begin(115200);
|
||||
Serial.println("");
|
||||
Serial.println("Starting wifi...");
|
||||
Serial.print(" connecting to: ");
|
||||
|
@ -380,96 +228,123 @@ void setup() {
|
|||
delay(900);
|
||||
Serial.print(".");
|
||||
}
|
||||
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected successfully");
|
||||
Serial.print("Got IP: ");
|
||||
Serial.println(WiFi.localIP()); //Show ESP32 IP on serial
|
||||
prefill_ram_with_pattern_data();
|
||||
store_ip_to_ram(0);
|
||||
//store_ip_to_ram(4);
|
||||
|
||||
// Set WiFi to station mode and disconnect from an AP if it was previously connected
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect();
|
||||
delay(10);
|
||||
|
||||
/* Start webserver */
|
||||
if(!SPIFFS.begin()){
|
||||
Serial.println("An Error has occurred while mounting SPIFFS");
|
||||
}
|
||||
web_server.on("/", HTTP_GET, www_root);
|
||||
web_server.on("/a2i.css", HTTP_GET, www_css);
|
||||
web_server.on("/ram", HTTP_GET, www_ram);
|
||||
web_server.on("/write_byte", HTTP_GET, www_write_byte);
|
||||
web_server.on("/weather", HTTP_GET, www_weather);
|
||||
web_server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/plain", "Free Heap: " + String(ESP.getFreeHeap()) + " bytes.");
|
||||
});
|
||||
write_string_to_shared_ram("Starting Up!", SHARED_RAM_START_ADDRESS);
|
||||
write_data(ESP_COMMAND_ADDRESS, ACK);
|
||||
write_data(APPLE_COMMAND_ADDRESS, ACK);
|
||||
|
||||
//web_server.on("/hello", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
//request->send(200, "text/plain", "Hello World");
|
||||
//});
|
||||
|
||||
//web_server.on("/", www_root);
|
||||
web_server.begin();
|
||||
Serial.println("HTTP server started");
|
||||
delay(10);
|
||||
|
||||
/* Display file system contents */
|
||||
Serial.println("-----------------------------------------");
|
||||
File root_filesystem = SPIFFS.open("/");
|
||||
File f = root_filesystem.openNextFile();
|
||||
while(f){
|
||||
Serial.print("FILE: ");
|
||||
Serial.println(f.name());
|
||||
f = root_filesystem.openNextFile();
|
||||
}
|
||||
Serial.println("-----------------------------------------");
|
||||
|
||||
//attachInterrupt(DEVSEL_PIN, isrDEVSEL, LOW);
|
||||
Serial.println("Setup done");
|
||||
}
|
||||
|
||||
/*################################################
|
||||
# Main #
|
||||
################################################*/
|
||||
|
||||
void scan_wifi() {
|
||||
Serial.println("scan start");
|
||||
|
||||
// WiFi.scanNetworks will return the number of networks found
|
||||
int n = WiFi.scanNetworks();
|
||||
Serial.println("scan done");
|
||||
int address_counter = SHARED_RAM_START_ADDRESS + 1;
|
||||
if (n == 0) {
|
||||
Serial.println("no networks found");
|
||||
write_data(0, address_counter);
|
||||
} else {
|
||||
Serial.print(n);
|
||||
Serial.println(" networks found");
|
||||
write_data(n, address_counter);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
// Print SSID and RSSI for each network found
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": ");
|
||||
Serial.print(WiFi.SSID(i));
|
||||
Serial.print(" (");
|
||||
Serial.print(WiFi.RSSI(i));
|
||||
Serial.print(")");
|
||||
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
|
||||
delay(10);
|
||||
address_counter = write_string_to_shared_ram(WiFi.SSID(i), address_counter + 1);
|
||||
//address_counter = write_string_to_shared_ram(String(WiFi.RSSI(i)), address_counter + 1);
|
||||
//address_counter = write_string_to_shared_ram(WiFi.encryptionType(i), address_counter + 1);
|
||||
}
|
||||
}
|
||||
write_data(ESP_COMMAND_ADDRESS, EOT);
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void store_ip_to_ram(byte offset) {
|
||||
IPAddress ip_address = WiFi.localIP();
|
||||
//for (int i=0; i < ADDRESS_BUS_SIZE; i++) {
|
||||
for (int i=0; i < 4; i++) {
|
||||
write_data(i+offset, ip_address[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const char* wifi_ssid = "";
|
||||
const char* wifi_password = "";
|
||||
|
||||
void loop() {
|
||||
//if (isr_handled) {
|
||||
//data_byte = raw_register_read >> 12 & 0b00000000000011111111;
|
||||
//isr_handled = false;
|
||||
//}
|
||||
|
||||
if ((millis() - lastReadLoopTime) > readLoopInterval) {
|
||||
//Serial.println("+++");
|
||||
unsigned int command_byte = read_data(15);
|
||||
byte command_byte = read_data(APPLE_COMMAND_ADDRESS);
|
||||
if (command_byte == RAM_BUSY) {
|
||||
Serial.println("Command Read: RAM BUSY");
|
||||
}
|
||||
else if (command_byte < COMMAND_FROM_ESP) {
|
||||
// command came from apple (or webform).
|
||||
Serial.print("Command Read: ");
|
||||
else if (command_byte != lastAppleCommand){
|
||||
Serial.print("Command Switch command_byte: ");
|
||||
Serial.println(command_byte);
|
||||
//write_data(15, 1); // notify Apple IIe we are processing command byte
|
||||
switch(command_byte) {
|
||||
case COMMAND_FETCH_WEATHER:
|
||||
Serial.println("Fetch Weather");
|
||||
fetch_weather("Tucson");
|
||||
break;
|
||||
case COMMAND_SEND_LONG_STRING:
|
||||
//send_string_to_apple("This is a long string", COMMAND_GENERIC_MESSAGE);
|
||||
send_string_to_apple("ABCDE", COMMAND_GENERIC_MESSAGE);
|
||||
case COMMAND_FORMAT_RAM:
|
||||
Serial.println("Calling prefill_ram_with_pattern_data()");
|
||||
prefill_ram_with_pattern_data();
|
||||
write_data(15, 0); // notify Apple IIe we are done processing command byte
|
||||
case COMMAND_SCAN_WIFI:
|
||||
write_data(ESP_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
//String read_string = read_string_from_ram(SHARED_RAM_START_ADDRESS);
|
||||
//write_string_to_shared_ram(rot13(read_string), SHARED_RAM_START_ADDRESS);
|
||||
scan_wifi();
|
||||
write_data(APPLE_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
break;
|
||||
}
|
||||
/*
|
||||
byte c = 0;
|
||||
while (ram_busy && (c < 10)) {
|
||||
delay(10);
|
||||
c = c+1;
|
||||
Serial.print("_");
|
||||
switch(command_byte) {
|
||||
case COMMAND_CONNECT:
|
||||
write_data(ESP_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
int access_point_n = read_data(SHARED_RAM_START_ADDRESS);
|
||||
String ssid_as_String = WiFi.SSID(access_point_n);
|
||||
String password_as_String = read_string_from_ram(SHARED_RAM_START_ADDRESS+1);
|
||||
wifi_password = password_as_String.c_str();
|
||||
wifi_ssid = ssid_as_String.c_str();
|
||||
//wifi_password = read_string_from_ram(SHARED_RAM_START_ADDRESS+1);
|
||||
//wifi_ssid = WiFi.SSID(access_point_n);
|
||||
//WiFi.begin(wifi_ssid, wifi_password);
|
||||
Serial.print("password:");
|
||||
Serial.println(password_as_String);
|
||||
Serial.print("password:(");
|
||||
Serial.print(wifi_password);
|
||||
Serial.println(")");
|
||||
//WiFi.begin(wifi_ssid, wifi_password);
|
||||
WiFi.begin("GSO", "xerxes27");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(300);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected successfully");
|
||||
Serial.print("Got IP: ");
|
||||
Serial.println(WiFi.localIP()); //Show ESP32 IP on serial
|
||||
store_ip_to_ram(SHARED_RAM_START_ADDRESS);
|
||||
write_data(APPLE_COMMAND_ADDRESS, ACK);
|
||||
break;
|
||||
}
|
||||
Serial.println("^^^^");
|
||||
write_data(15, 0); // notify Apple IIe we are done processing command byte
|
||||
read_data(15); // notify Apple IIe we are done processing command byte
|
||||
*/
|
||||
lastAppleCommand = command_byte;
|
||||
write_data(ESP_COMMAND_ADDRESS, EOT); // notify Apple IIe we are done processing command byte
|
||||
}
|
||||
lastReadLoopTime = millis();
|
||||
}
|
||||
|
|
328
examples/wifi_scan.old/wifi_scan.ino
Normal file
328
examples/wifi_scan.old/wifi_scan.ino
Normal file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
|
||||
Use this program with the Apple2idIOT card and the basic programs RRAM, WRAM and CMDROT to read/write and rot13
|
||||
a single string contained within the dual port ram on the card.
|
||||
|
||||
*/
|
||||
|
||||
#define DEBUG true
|
||||
|
||||
// Load Wi-Fi library
|
||||
#include <WiFi.h>
|
||||
|
||||
/**************/
|
||||
/* ESP32 Pins */
|
||||
/**************/
|
||||
|
||||
/* DATA BUS (numbers mean GPIO port) */
|
||||
#define D0R 12
|
||||
#define D1R 13
|
||||
#define D2R 14
|
||||
#define D3R 15
|
||||
#define D4R 16
|
||||
#define D5R 17
|
||||
#define D6R 18
|
||||
#define D7R 19
|
||||
byte data_pins[] = {D7R, D6R, D5R, D4R, D3R, D2R, D1R, D0R};
|
||||
#define DATA_BUS_SIZE 8
|
||||
|
||||
/* Address Bus */
|
||||
#define A0R 21
|
||||
#define A1R 22
|
||||
#define A2R 23
|
||||
#define A3R 25
|
||||
#define A4R 26
|
||||
#define A5R 27
|
||||
#define A6R 32
|
||||
#define A7R 33
|
||||
byte address_pins[] = {A0R, A1R, A2R, A3R, A4R, A5R, A6R, A7R};
|
||||
#define ADDRESS_BUS_SIZE 8
|
||||
#define ESP_COMMAND_ADDRESS 0
|
||||
#define APPLE_COMMAND_ADDRESS 1
|
||||
#define SHARED_RAM_START_ADDRESS 2
|
||||
#define RAM_BUSY 666
|
||||
#define MAX_STR_LEN 44 // arbitrary length.
|
||||
|
||||
#define COMMAND_GENERIC 0b10000000
|
||||
#define COMMAND_SCAN_WIFI 111
|
||||
#define COMMAND_CONNECT 112
|
||||
|
||||
/* IDT7132S dual port ram chip enable */
|
||||
#define RW_PIN 5
|
||||
#define RW_WRITE LOW
|
||||
#define RW_READ HIGH
|
||||
|
||||
#define INPUT_35 35
|
||||
#define INPUT_34 34
|
||||
|
||||
#define ETX 3 // ASCII "End of Text" (ETX) character
|
||||
#define ACK 0b00000110 // Acknowledge
|
||||
#define EOT 0b00000100 // End of transmit
|
||||
|
||||
/*********/
|
||||
/* Misc. */
|
||||
/*********/
|
||||
|
||||
const long readLoopInterval = 100; // millis
|
||||
unsigned long lastReadLoopTime = 0;
|
||||
byte ram[256];
|
||||
volatile byte ram_busy=0;
|
||||
|
||||
byte lastAppleCommand = 0;
|
||||
|
||||
/*################################################
|
||||
# Functions #
|
||||
################################################*/
|
||||
|
||||
void unbusy_ram() {
|
||||
set_address(ESP_COMMAND_ADDRESS);
|
||||
ram_busy = false;
|
||||
}
|
||||
|
||||
boolean set_address(int address) {
|
||||
if (ram_busy) {
|
||||
Serial.println("BUSY");
|
||||
return false;
|
||||
}
|
||||
ram_busy = true;
|
||||
for (byte i=0; i<ADDRESS_BUS_SIZE; i++) {
|
||||
byte state = bitRead(address, i);
|
||||
digitalWrite(address_pins[i], state);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
byte read_data(int address) {
|
||||
byte data_bus_read = 0;
|
||||
if (set_address(address)) {
|
||||
digitalWrite(RW_PIN, RW_READ); // Should already be set to RW_READ, but just in case.
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
byte pin_state = digitalRead(data_pins[i]);
|
||||
data_bus_read += pin_state * pow(2,i);
|
||||
}
|
||||
ram_busy = false;
|
||||
unbusy_ram();
|
||||
return data_bus_read;
|
||||
} else {
|
||||
return RAM_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean write_data(byte address, byte byte_to_write) {
|
||||
Serial.print("WRITE: ");
|
||||
Serial.print(byte_to_write);
|
||||
Serial.print(" -> ");
|
||||
Serial.println(address);
|
||||
if (set_address(address)) {
|
||||
//set_address(address);
|
||||
Serial.print(" D:");
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
byte bit_to_write = (byte_to_write >> i) & 0b00000001;
|
||||
pinMode(data_pins[i], OUTPUT);
|
||||
digitalWrite(data_pins[i], bit_to_write);
|
||||
Serial.print(bit_to_write);
|
||||
}
|
||||
Serial.println();
|
||||
digitalWrite(RW_PIN, RW_WRITE);
|
||||
delay(1);
|
||||
digitalWrite(RW_PIN, RW_READ);
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
pinMode(data_pins[i], INPUT);
|
||||
}
|
||||
unbusy_ram();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int write_string_to_shared_ram(String string_to_send, unsigned int address) {
|
||||
//if (string_to_send.length() > 15 - 1) { // - 1 because of null character at end of string.
|
||||
write_data(ESP_COMMAND_ADDRESS, 12);
|
||||
unsigned int c = 0;
|
||||
for (c=0; c < string_to_send.length(); c++) {
|
||||
Serial.print("A(");
|
||||
Serial.print(c);
|
||||
Serial.print("): ");
|
||||
Serial.println(string_to_send[c]);
|
||||
write_data(address+c, string_to_send[c]);
|
||||
}
|
||||
write_data(address+c, ETX);
|
||||
//write_data(15, COMMAND_FROM_ESP + command_message + COMMAND_NO_DATA_WAITING);
|
||||
write_data(ESP_COMMAND_ADDRESS, 27);
|
||||
return address+c;
|
||||
}
|
||||
|
||||
String read_string_from_ram(int address) {
|
||||
byte c = 0;
|
||||
int i = 0;
|
||||
String read_string = "";
|
||||
while ( (i<MAX_STR_LEN) && (c!=ETX) ) {
|
||||
c = read_data(address+i);
|
||||
read_string = read_string + char(c);
|
||||
i++;
|
||||
}
|
||||
Serial.print("READ STRING:");
|
||||
Serial.println(read_string);
|
||||
return read_string;
|
||||
}
|
||||
|
||||
void read_ram(int size_to_read=256);
|
||||
void read_ram(int size_to_read) {
|
||||
for (int i=0; i < size_to_read; i++) {
|
||||
unsigned int foo = read_data(i);
|
||||
ram[i] = foo;
|
||||
Serial.print(i);
|
||||
Serial.print(" ");
|
||||
Serial.println(foo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*################################################
|
||||
# Setup #
|
||||
################################################*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
/* Configure ESP32 Pins */
|
||||
pinMode(A0R, OUTPUT); digitalWrite(A0R, LOW);
|
||||
pinMode(A1R, OUTPUT); digitalWrite(A1R, LOW);
|
||||
pinMode(A2R, OUTPUT); digitalWrite(A2R, LOW);
|
||||
pinMode(A3R, OUTPUT); digitalWrite(A3R, LOW);
|
||||
pinMode(A4R, OUTPUT); digitalWrite(A4R, LOW);
|
||||
pinMode(A5R, OUTPUT); digitalWrite(A5R, LOW);
|
||||
pinMode(A6R, OUTPUT); digitalWrite(A6R, LOW);
|
||||
pinMode(A7R, OUTPUT); digitalWrite(A7R, LOW);
|
||||
pinMode(D0R, INPUT);
|
||||
pinMode(D1R, INPUT);
|
||||
pinMode(D2R, INPUT);
|
||||
pinMode(D3R, INPUT);
|
||||
pinMode(D4R, INPUT);
|
||||
pinMode(D5R, INPUT);
|
||||
pinMode(D6R, INPUT);
|
||||
pinMode(D7R, INPUT);
|
||||
pinMode(RW_PIN, OUTPUT); digitalWrite(RW_PIN, RW_READ);
|
||||
|
||||
pinMode(INPUT_34, INPUT);
|
||||
pinMode(INPUT_35, INPUT);
|
||||
|
||||
write_string_to_shared_ram("Starting Up!", SHARED_RAM_START_ADDRESS);
|
||||
|
||||
// Set WiFi to station mode and disconnect from an AP if it was previously connected
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect();
|
||||
delay(10);
|
||||
|
||||
write_data(ESP_COMMAND_ADDRESS, ACK);
|
||||
write_data(APPLE_COMMAND_ADDRESS, ACK);
|
||||
|
||||
Serial.println("Setup done");
|
||||
}
|
||||
|
||||
/*################################################
|
||||
# Main #
|
||||
################################################*/
|
||||
|
||||
void scan_wifi() {
|
||||
Serial.println("scan start");
|
||||
|
||||
// WiFi.scanNetworks will return the number of networks found
|
||||
int n = WiFi.scanNetworks();
|
||||
Serial.println("scan done");
|
||||
int address_counter = SHARED_RAM_START_ADDRESS + 1;
|
||||
if (n == 0) {
|
||||
Serial.println("no networks found");
|
||||
write_data(0, address_counter);
|
||||
} else {
|
||||
Serial.print(n);
|
||||
Serial.println(" networks found");
|
||||
write_data(n, address_counter);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
// Print SSID and RSSI for each network found
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": ");
|
||||
Serial.print(WiFi.SSID(i));
|
||||
Serial.print(" (");
|
||||
Serial.print(WiFi.RSSI(i));
|
||||
Serial.print(")");
|
||||
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
|
||||
delay(10);
|
||||
address_counter = write_string_to_shared_ram(WiFi.SSID(i), address_counter + 1);
|
||||
//address_counter = write_string_to_shared_ram(String(WiFi.RSSI(i)), address_counter + 1);
|
||||
//address_counter = write_string_to_shared_ram(WiFi.encryptionType(i), address_counter + 1);
|
||||
}
|
||||
}
|
||||
write_data(ESP_COMMAND_ADDRESS, EOT);
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void store_ip_to_ram(byte offset) {
|
||||
IPAddress ip_address = WiFi.localIP();
|
||||
//for (int i=0; i < ADDRESS_BUS_SIZE; i++) {
|
||||
for (int i=0; i < 4; i++) {
|
||||
write_data(i+offset, ip_address[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const char* wifi_ssid = "";
|
||||
const char* wifi_password = "";
|
||||
|
||||
void loop() {
|
||||
|
||||
if ((millis() - lastReadLoopTime) > readLoopInterval) {
|
||||
byte command_byte = read_data(APPLE_COMMAND_ADDRESS);
|
||||
if (command_byte == RAM_BUSY) {
|
||||
Serial.println("Command Read: RAM BUSY");
|
||||
}
|
||||
else if (command_byte != lastAppleCommand){
|
||||
Serial.print("Command Switch command_byte: ");
|
||||
Serial.println(command_byte);
|
||||
switch(command_byte) {
|
||||
case COMMAND_SCAN_WIFI:
|
||||
write_data(ESP_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
//String read_string = read_string_from_ram(SHARED_RAM_START_ADDRESS);
|
||||
//write_string_to_shared_ram(rot13(read_string), SHARED_RAM_START_ADDRESS);
|
||||
scan_wifi();
|
||||
write_data(APPLE_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
break;
|
||||
}
|
||||
switch(command_byte) {
|
||||
case COMMAND_CONNECT:
|
||||
write_data(ESP_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
int access_point_n = read_data(SHARED_RAM_START_ADDRESS);
|
||||
String ssid_as_String = WiFi.SSID(access_point_n);
|
||||
String password_as_String = read_string_from_ram(SHARED_RAM_START_ADDRESS+1);
|
||||
wifi_password = password_as_String.c_str();
|
||||
wifi_ssid = ssid_as_String.c_str();
|
||||
//wifi_password = read_string_from_ram(SHARED_RAM_START_ADDRESS+1);
|
||||
//wifi_ssid = WiFi.SSID(access_point_n);
|
||||
//WiFi.begin(wifi_ssid, wifi_password);
|
||||
Serial.print("password:");
|
||||
Serial.println(password_as_String);
|
||||
Serial.print("password:(");
|
||||
Serial.print(wifi_password);
|
||||
Serial.println(")");
|
||||
//WiFi.begin(wifi_ssid, wifi_password);
|
||||
WiFi.begin("GSO", "xerxes27");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(300);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected successfully");
|
||||
Serial.print("Got IP: ");
|
||||
Serial.println(WiFi.localIP()); //Show ESP32 IP on serial
|
||||
store_ip_to_ram(SHARED_RAM_START_ADDRESS);
|
||||
write_data(APPLE_COMMAND_ADDRESS, ACK);
|
||||
break;
|
||||
}
|
||||
lastAppleCommand = command_byte;
|
||||
write_data(ESP_COMMAND_ADDRESS, EOT); // notify Apple IIe we are done processing command byte
|
||||
}
|
||||
lastReadLoopTime = millis();
|
||||
}
|
||||
}
|
116
examples/wifi_scan/wifi_scan.ino
Normal file
116
examples/wifi_scan/wifi_scan.ino
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Use this program with the Apple2idIOT card and the basic programs RRAM, WRAM and CMDROT to read/write and rot13
|
||||
a single string contained within the dual port ram on the card.
|
||||
*/
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <Apple2Idiot.h>
|
||||
|
||||
Apple2Idiot a2i = Apple2Idiot();
|
||||
|
||||
const char* wifi_ssid = "";
|
||||
const char* wifi_password = "";
|
||||
|
||||
const long readLoopInterval = 100; // millis
|
||||
unsigned long lastReadLoopTime = 0;
|
||||
|
||||
byte lastAppleCommand = 0;
|
||||
|
||||
/*################################################
|
||||
# Setup #
|
||||
################################################*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
a2i.init();
|
||||
|
||||
// Set WiFi to station mode and disconnect from an AP if it was previously connected
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect();
|
||||
|
||||
Serial.println("Setup done");
|
||||
}
|
||||
|
||||
/*################################################
|
||||
# Main #
|
||||
################################################*/
|
||||
|
||||
void scan_wifi() {
|
||||
Serial.println("scan start");
|
||||
|
||||
// WiFi.scanNetworks will return the number of networks found
|
||||
int n = WiFi.scanNetworks();
|
||||
Serial.println("scan done");
|
||||
int address_counter = SHARED_RAM_START_ADDRESS + 1;
|
||||
if (n == 0) {
|
||||
Serial.println("no networks found");
|
||||
a2i.write_data(0, address_counter);
|
||||
} else {
|
||||
Serial.print(n);
|
||||
Serial.println(" networks found");
|
||||
a2i.write_data(n, address_counter);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
// Print SSID and RSSI for each network found
|
||||
Serial.print(i + 1);
|
||||
Serial.print(": ");
|
||||
Serial.println(WiFi.SSID(i));
|
||||
delay(10);
|
||||
address_counter = a2i.write_string_to_shared_ram(WiFi.SSID(i), address_counter + 1);
|
||||
}
|
||||
}
|
||||
a2i.write_data(ESP_COMMAND_ADDRESS, EOT);
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void store_ip_to_ram(byte offset) {
|
||||
IPAddress ip_address = WiFi.localIP();
|
||||
//for (int i=0; i < ADDRESS_BUS_SIZE; i++) {
|
||||
for (int i=0; i < 4; i++) {
|
||||
a2i.write_data(i+offset, ip_address[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
if ((millis() - lastReadLoopTime) > readLoopInterval) {
|
||||
byte command_byte = a2i.read_data(APPLE_COMMAND_ADDRESS);
|
||||
if (command_byte == RAM_BUSY) {
|
||||
Serial.println("Command Read: RAM BUSY");
|
||||
}
|
||||
else if (command_byte != lastAppleCommand){
|
||||
Serial.print("Command Switch command_byte: ");
|
||||
Serial.println(command_byte);
|
||||
switch(command_byte) {
|
||||
case COMMAND_SCAN_WIFI:
|
||||
a2i.write_data(ESP_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
scan_wifi();
|
||||
a2i.write_data(APPLE_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
break;
|
||||
}
|
||||
switch(command_byte) {
|
||||
case COMMAND_CONNECT:
|
||||
a2i.write_data(ESP_COMMAND_ADDRESS, ACK); // notify Apple IIe we are processing command byte
|
||||
int access_point_n = a2i.read_data(SHARED_RAM_START_ADDRESS);
|
||||
String ssid_as_String = WiFi.SSID(access_point_n);
|
||||
String password_as_String = a2i.read_string_from_ram(SHARED_RAM_START_ADDRESS+1);
|
||||
wifi_password = password_as_String.c_str();
|
||||
wifi_ssid = ssid_as_String.c_str();
|
||||
WiFi.begin("GSO", "xerxes27");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(300);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.println("WiFi connected successfully");
|
||||
Serial.print("Got IP: ");
|
||||
Serial.println(WiFi.localIP()); //Show ESP32 IP on serial
|
||||
store_ip_to_ram(SHARED_RAM_START_ADDRESS);
|
||||
a2i.write_data(APPLE_COMMAND_ADDRESS, ACK);
|
||||
break;
|
||||
}
|
||||
lastAppleCommand = command_byte;
|
||||
a2i.write_data(ESP_COMMAND_ADDRESS, EOT); // notify Apple IIe we are done processing command byte
|
||||
}
|
||||
lastReadLoopTime = millis();
|
||||
}
|
||||
}
|
1
lib/Apple2Idiot/Apple2Idiot
Symbolic link
1
lib/Apple2Idiot/Apple2Idiot
Symbolic link
|
@ -0,0 +1 @@
|
|||
Apple2Idiot
|
142
lib/Apple2Idiot/Apple2Idiot.cpp
Normal file
142
lib/Apple2Idiot/Apple2Idiot.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
#include <Arduino.h>
|
||||
#include "Apple2Idiot.h"
|
||||
|
||||
byte data_pins[] = {D7R, D6R, D5R, D4R, D3R, D2R, D1R, D0R};
|
||||
byte address_pins[] = {A0R, A1R, A2R, A3R, A4R, A5R, A6R, A7R};
|
||||
volatile byte ram_busy=0;
|
||||
byte ram[256];
|
||||
|
||||
Apple2Idiot::Apple2Idiot() {
|
||||
}
|
||||
|
||||
void Apple2Idiot::init() {
|
||||
pinMode(A0R, OUTPUT); digitalWrite(A0R, LOW);
|
||||
pinMode(A1R, OUTPUT); digitalWrite(A1R, LOW);
|
||||
pinMode(A2R, OUTPUT); digitalWrite(A2R, LOW);
|
||||
pinMode(A3R, OUTPUT); digitalWrite(A3R, LOW);
|
||||
pinMode(A4R, OUTPUT); digitalWrite(A4R, LOW);
|
||||
pinMode(A5R, OUTPUT); digitalWrite(A5R, LOW);
|
||||
pinMode(A6R, OUTPUT); digitalWrite(A6R, LOW);
|
||||
pinMode(A7R, OUTPUT); digitalWrite(A7R, LOW);
|
||||
pinMode(D0R, INPUT);
|
||||
pinMode(D1R, INPUT);
|
||||
pinMode(D2R, INPUT);
|
||||
pinMode(D3R, INPUT);
|
||||
pinMode(D4R, INPUT);
|
||||
pinMode(D5R, INPUT);
|
||||
pinMode(D6R, INPUT);
|
||||
pinMode(D7R, INPUT);
|
||||
pinMode(RW_PIN, OUTPUT); digitalWrite(RW_PIN, RW_READ);
|
||||
pinMode(INPUT_34, INPUT);
|
||||
pinMode(INPUT_35, INPUT);
|
||||
|
||||
write_string_to_shared_ram("Starting Up!", SHARED_RAM_START_ADDRESS);
|
||||
|
||||
write_data(ESP_COMMAND_ADDRESS, ACK);
|
||||
write_data(APPLE_COMMAND_ADDRESS, ACK);
|
||||
}
|
||||
|
||||
void Apple2Idiot::unbusy_ram() {
|
||||
set_address(ESP_COMMAND_ADDRESS);
|
||||
ram_busy = false;
|
||||
}
|
||||
|
||||
boolean Apple2Idiot::set_address(int address) {
|
||||
if (ram_busy) {
|
||||
Serial.println("BUSY");
|
||||
return false;
|
||||
}
|
||||
ram_busy = true;
|
||||
for (byte i=0; i<ADDRESS_BUS_SIZE; i++) {
|
||||
byte state = bitRead(address, i);
|
||||
digitalWrite(address_pins[i], state);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
byte Apple2Idiot::read_data(int address) {
|
||||
byte data_bus_read = 0;
|
||||
if (set_address(address)) {
|
||||
digitalWrite(RW_PIN, RW_READ); // Should already be set to RW_READ, but just in case.
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
byte pin_state = digitalRead(data_pins[i]);
|
||||
data_bus_read += pin_state * pow(2,i);
|
||||
}
|
||||
ram_busy = false;
|
||||
unbusy_ram();
|
||||
return data_bus_read;
|
||||
} else {
|
||||
return RAM_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean Apple2Idiot::write_data(byte address, byte byte_to_write) {
|
||||
Serial.print("WRITE: ");
|
||||
Serial.print(byte_to_write);
|
||||
Serial.print(" -> ");
|
||||
Serial.println(address);
|
||||
if (set_address(address)) {
|
||||
//set_address(address);
|
||||
Serial.print(" D:");
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
byte bit_to_write = (byte_to_write >> i) & 0b00000001;
|
||||
pinMode(data_pins[i], OUTPUT);
|
||||
digitalWrite(data_pins[i], bit_to_write);
|
||||
Serial.print(bit_to_write);
|
||||
}
|
||||
Serial.println();
|
||||
digitalWrite(RW_PIN, RW_WRITE);
|
||||
delay(1);
|
||||
digitalWrite(RW_PIN, RW_READ);
|
||||
for (byte i=0; i<DATA_BUS_SIZE; i++) {
|
||||
pinMode(data_pins[i], INPUT);
|
||||
}
|
||||
unbusy_ram();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int Apple2Idiot::write_string_to_shared_ram(String string_to_send, unsigned int address) {
|
||||
//if (string_to_send.length() > 15 - 1) { // - 1 because of null character at end of string.
|
||||
write_data(ESP_COMMAND_ADDRESS, 12);
|
||||
unsigned int c = 0;
|
||||
for (c=0; c < string_to_send.length(); c++) {
|
||||
Serial.print("A(");
|
||||
Serial.print(c);
|
||||
Serial.print("): ");
|
||||
Serial.println(string_to_send[c]);
|
||||
write_data(address+c, string_to_send[c]);
|
||||
}
|
||||
write_data(address+c, ETX);
|
||||
//write_data(15, COMMAND_FROM_ESP + command_message + COMMAND_NO_DATA_WAITING);
|
||||
write_data(ESP_COMMAND_ADDRESS, 27);
|
||||
return address+c;
|
||||
}
|
||||
|
||||
String Apple2Idiot::read_string_from_ram(int address) {
|
||||
byte c = 0;
|
||||
int i = 0;
|
||||
String read_string = "";
|
||||
while ( (i<MAX_STR_LEN) && (c!=ETX) ) {
|
||||
c = read_data(address+i);
|
||||
read_string = read_string + char(c);
|
||||
i++;
|
||||
}
|
||||
Serial.print("READ STRING:");
|
||||
Serial.println(read_string);
|
||||
return read_string;
|
||||
}
|
||||
|
||||
void Apple2Idiot::read_ram(int size_to_read) {
|
||||
for (int i=0; i < size_to_read; i++) {
|
||||
unsigned int foo = read_data(i);
|
||||
ram[i] = foo;
|
||||
Serial.print(i);
|
||||
Serial.print(" ");
|
||||
Serial.println(foo);
|
||||
}
|
||||
}
|
65
lib/Apple2Idiot/Apple2Idiot.h
Normal file
65
lib/Apple2Idiot/Apple2Idiot.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
#ifndef APPLE2IDIOT
|
||||
#define APPLE2IDIOT
|
||||
#include <Arduino.h>
|
||||
|
||||
/* DATA BUS (numbers mean GPIO port) */
|
||||
#define D0R 12
|
||||
#define D1R 13
|
||||
#define D2R 14
|
||||
#define D3R 15
|
||||
#define D4R 16
|
||||
#define D5R 17
|
||||
#define D6R 18
|
||||
#define D7R 19
|
||||
#define DATA_BUS_SIZE 8
|
||||
|
||||
/* Address Bus */
|
||||
#define A0R 21
|
||||
#define A1R 22
|
||||
#define A2R 23
|
||||
#define A3R 25
|
||||
#define A4R 26
|
||||
#define A5R 27
|
||||
#define A6R 32
|
||||
#define A7R 33
|
||||
#define ADDRESS_BUS_SIZE 8
|
||||
#define ESP_COMMAND_ADDRESS 0
|
||||
#define APPLE_COMMAND_ADDRESS 1
|
||||
#define SHARED_RAM_START_ADDRESS 2
|
||||
#define RAM_BUSY 666
|
||||
#define MAX_STR_LEN 44 // arbitrary length.
|
||||
|
||||
#define COMMAND_GENERIC 0b10000000
|
||||
#define COMMAND_SCAN_WIFI 111
|
||||
#define COMMAND_CONNECT 112
|
||||
|
||||
/* IDT7132S dual port ram chip enable */
|
||||
#define RW_PIN 5
|
||||
#define RW_WRITE LOW
|
||||
#define RW_READ HIGH
|
||||
|
||||
#define ETX 3 // ASCII "End of Text" (ETX) character
|
||||
#define ACK 0b00000110 // Acknowledge
|
||||
#define EOT 0b00000100 // End of transmit
|
||||
|
||||
#define INPUT_35 35
|
||||
#define INPUT_34 34
|
||||
|
||||
|
||||
class Apple2Idiot {
|
||||
|
||||
private:
|
||||
void unbusy_ram();
|
||||
|
||||
public:
|
||||
Apple2Idiot();
|
||||
void init();
|
||||
boolean set_address(int address);
|
||||
byte read_data(int address);
|
||||
boolean write_data(byte address, byte byte_to_write);
|
||||
unsigned int write_string_to_shared_ram(String string_to_send, unsigned int address);
|
||||
String read_string_from_ram(int address);
|
||||
void read_ram(int size_to_read=256);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user