mirror of
https://github.com/FYSETC/ESPWebDAV.git
synced 2026-02-20 02:01:22 +01:00
rearrange the code
This commit is contained in:
@@ -566,3 +566,4 @@ void ESPWebDAV::handleDelete(ResourceType resource) {
|
||||
send("200 OK", NULL, "");
|
||||
}
|
||||
|
||||
ESPWebDAV dav;
|
||||
|
||||
@@ -4,11 +4,9 @@
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG_INIT(...) { Serial.begin(__VA_ARGS__); }
|
||||
#define DBG_PRINT(...) { Serial.print(__VA_ARGS__); }
|
||||
#define DBG_PRINTLN(...) { Serial.println(__VA_ARGS__); }
|
||||
#else
|
||||
#define DBG_INIT(...) {}
|
||||
#define DBG_PRINT(...) {}
|
||||
#define DBG_PRINTLN(...) {}
|
||||
#endif
|
||||
@@ -83,7 +81,4 @@ protected:
|
||||
int _contentLength;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern ESPWebDAV dav;
|
||||
|
||||
365
ESPWebDAV.ino
365
ESPWebDAV.ino
@@ -1,120 +1,29 @@
|
||||
// Using the WebDAV server with Rigidbot 3D printer.
|
||||
// Printer controller is a variation of Rambo running Marlin firmware
|
||||
|
||||
#include "ESP8266WiFi.h"
|
||||
#include "ESPWebDAV.h"
|
||||
#include "serial.h"
|
||||
#include "parser.h"
|
||||
#include "Config.h"
|
||||
#include "config.h"
|
||||
#include "network.h"
|
||||
#include "gcode.h"
|
||||
|
||||
// LED is connected to GPIO2 on this board
|
||||
#define INIT_LED {pinMode(2, OUTPUT);}
|
||||
#define LED_ON {digitalWrite(2, LOW);}
|
||||
#define LED_OFF {digitalWrite(2, HIGH);}
|
||||
|
||||
#define HOSTNAME "FYSETC"
|
||||
#define SERVER_PORT 80
|
||||
#define SPI_BLOCKOUT_PERIOD 20000UL
|
||||
#define WIFI_CONNECT_TIMEOUT 30000UL
|
||||
|
||||
#define SD_CS 4
|
||||
#define MISO 12
|
||||
#define MOSI 13
|
||||
#define SCLK 14
|
||||
#define CS_SENSE 5
|
||||
|
||||
ESPWebDAV dav;
|
||||
String statusMessage;
|
||||
bool initFailed = false;
|
||||
|
||||
volatile long spiBlockoutTime = 0;
|
||||
bool weHaveBus = false;
|
||||
bool wifiConnected = false;
|
||||
|
||||
bool wifiConnect(const char*ssid,const char*password) {
|
||||
if(ssid == NULL || password==NULL) {
|
||||
SERIAL_ECHOLN("Please set the wifi ssid and password first");
|
||||
}
|
||||
|
||||
//
|
||||
wifiConnected = false;
|
||||
|
||||
// Set hostname first
|
||||
WiFi.hostname(HOSTNAME);
|
||||
// Reduce startup surge current
|
||||
WiFi.setAutoConnect(false);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
// Wait for connection
|
||||
unsigned long timeout = millis();
|
||||
while(WiFi.status() != WL_CONNECTED) {
|
||||
blink();
|
||||
DBG_PRINT(".");
|
||||
if(millis() > timeout + WIFI_CONNECT_TIMEOUT)
|
||||
return false;
|
||||
}
|
||||
|
||||
DBG_PRINTLN("");
|
||||
DBG_PRINT("Connected to "); DBG_PRINTLN(ssid);
|
||||
DBG_PRINT("IP address: "); DBG_PRINTLN(WiFi.localIP());
|
||||
DBG_PRINT("RSSI: "); DBG_PRINTLN(WiFi.RSSI());
|
||||
DBG_PRINT("Mode: "); DBG_PRINTLN(WiFi.getPhyMode());
|
||||
|
||||
wifiConnected = true;
|
||||
|
||||
config.save(ssid,password);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void startDAVServer() {
|
||||
// Check to see if other master is using the SPI bus
|
||||
while(millis() < spiBlockoutTime)
|
||||
blink();
|
||||
|
||||
takeBusControl();
|
||||
|
||||
// start the SD DAV server
|
||||
if(!dav.init(SD_CS, SPI_FULL_SPEED, SERVER_PORT)) {
|
||||
statusMessage = "Failed to initialize SD Card";
|
||||
DBG_PRINT("ERROR: "); DBG_PRINTLN(statusMessage);
|
||||
// indicate error on LED
|
||||
errorBlink();
|
||||
initFailed = true;
|
||||
}
|
||||
else
|
||||
blink();
|
||||
|
||||
relenquishBusControl();
|
||||
DBG_PRINTLN("WebDAV server started");
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
void setup() {
|
||||
// ----- GPIO -------
|
||||
// Detect when other master uses SPI bus
|
||||
pinMode(CS_SENSE, INPUT);
|
||||
attachInterrupt(CS_SENSE, []() {
|
||||
if(!weHaveBus)
|
||||
spiBlockoutTime = millis() + SPI_BLOCKOUT_PERIOD;
|
||||
}, FALLING);
|
||||
|
||||
DBG_INIT(115200);
|
||||
DBG_PRINTLN("");
|
||||
SERIAL_INIT(115200);
|
||||
INIT_LED;
|
||||
blink();
|
||||
|
||||
// wait for other master to assert SPI bus first
|
||||
delay(SPI_BLOCKOUT_PERIOD);
|
||||
network.setup();
|
||||
|
||||
// ----- WIFI -------
|
||||
if(config.load() == 1) { // Connected before
|
||||
if(wifiConnect(config.ssid(), config.password())) {
|
||||
startDAVServer();
|
||||
}
|
||||
else {
|
||||
if(!network.start()) {
|
||||
SERIAL_ECHOLN("");
|
||||
SERIAL_ECHOLN("Connect fail, please set the wifi config and connect again");
|
||||
}
|
||||
}
|
||||
@@ -123,260 +32,18 @@ void setup() {
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_CMD_SIZE 96
|
||||
#define BUFSIZE 4
|
||||
|
||||
/**
|
||||
* GCode Command Queue
|
||||
* A simple ring buffer of BUFSIZE command strings.
|
||||
*
|
||||
* Commands are copied into this buffer by the command injectors
|
||||
* (immediate, serial, sd card) and they are processed sequentially by
|
||||
* the main loop. The process_next_command function parses the next
|
||||
* command and hands off execution to individual handler functions.
|
||||
*/
|
||||
uint8_t commands_in_queue = 0, // Count of commands in the queue
|
||||
cmd_queue_index_r = 0, // Ring buffer read (out) position
|
||||
cmd_queue_index_w = 0; // Ring buffer write (in) position
|
||||
|
||||
uint32_t command_sd_pos[BUFSIZE];
|
||||
volatile uint32_t current_command_sd_pos;
|
||||
|
||||
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
||||
|
||||
static bool send_ok[BUFSIZE];
|
||||
|
||||
// Number of characters read in the current line of serial input
|
||||
static int serial_count; // = 0;
|
||||
|
||||
/**
|
||||
* Once a new command is in the ring buffer, call this to commit it
|
||||
*/
|
||||
inline void _commit_command(bool say_ok) {
|
||||
send_ok[cmd_queue_index_w] = say_ok;
|
||||
if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0;
|
||||
commands_in_queue++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a command from RAM into the main command buffer.
|
||||
* Return true if the command was successfully added.
|
||||
* Return false for a full buffer, or if the 'command' is a comment.
|
||||
*/
|
||||
inline bool _enqueuecommand(const char* cmd, bool say_ok=false) {
|
||||
if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
|
||||
strcpy(command_queue[cmd_queue_index_w], cmd);
|
||||
_commit_command(say_ok);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all commands waiting on the serial port and queue them.
|
||||
* Exit when the buffer is full or when no more characters are
|
||||
* left on the serial port.
|
||||
*/
|
||||
void get_serial_commands() {
|
||||
static char serial_line_buffer[MAX_CMD_SIZE];
|
||||
static bool serial_comment_mode = false;
|
||||
|
||||
/**
|
||||
* Loop while serial characters are incoming and the queue is not full
|
||||
*/
|
||||
int c;
|
||||
while (commands_in_queue < BUFSIZE && (c = Serial.read()) >= 0) {
|
||||
|
||||
char serial_char = c;
|
||||
|
||||
/**
|
||||
* If the character ends the line
|
||||
*/
|
||||
if (serial_char == '\n' || serial_char == '\r') {
|
||||
|
||||
serial_comment_mode = false; // end of line == end of comment
|
||||
|
||||
// Skip empty lines and comments
|
||||
if (!serial_count) { continue; }
|
||||
|
||||
serial_line_buffer[serial_count] = 0; // Terminate string
|
||||
serial_count = 0; // Reset buffer
|
||||
|
||||
char* command = serial_line_buffer;
|
||||
|
||||
while (*command == ' ') command++; // Skip leading spaces
|
||||
|
||||
// Add the command to the queue
|
||||
_enqueuecommand(serial_line_buffer, true);
|
||||
}
|
||||
else if (serial_count >= MAX_CMD_SIZE - 1) {
|
||||
// Keep fetching, but ignore normal characters beyond the max length
|
||||
// The command will be injected when EOL is reached
|
||||
}
|
||||
else if (serial_char == '\\') { // Handle escapes
|
||||
if ((c = MYSERIAL0.read()) >= 0 && !serial_comment_mode) // if we have one more character, copy it over
|
||||
serial_line_buffer[serial_count++] = (char)c;
|
||||
// otherwise do nothing
|
||||
}
|
||||
else { // it's not a newline, carriage return or escape char
|
||||
if (serial_char == ';') serial_comment_mode = true;
|
||||
if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char;
|
||||
}
|
||||
} // queue has space, serial has data
|
||||
}
|
||||
|
||||
/**
|
||||
* M50: Set the Wifi ssid
|
||||
*/
|
||||
inline void gcode_M50() {
|
||||
for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
|
||||
config.ssid(parser.string_arg);
|
||||
SERIAL_ECHO(config.ssid());
|
||||
}
|
||||
|
||||
/**
|
||||
* M50: Set the Wifi password
|
||||
*/
|
||||
inline void gcode_M51() {
|
||||
for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
|
||||
config.password(parser.string_arg);
|
||||
SERIAL_ECHO(config.password());
|
||||
}
|
||||
|
||||
/**
|
||||
* M52: Connect the wifi
|
||||
*/
|
||||
inline void gcode_M52() {
|
||||
if(wifiConnect(config.ssid(), config.password())) {
|
||||
startDAVServer();
|
||||
}
|
||||
else {
|
||||
SERIAL_ECHOLN("Connect fail, please set the wifi config and connect again");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* M53: Check wifi status
|
||||
*/
|
||||
inline void gcode_M53() {
|
||||
if(WiFi.status() != WL_CONNECTED) {
|
||||
SERIAL_ECHOLN("Wifi not connected");
|
||||
SERIAL_ECHOLN("Please set the wifi ssid with M50 and password with M51 , and start connection with M52");
|
||||
}
|
||||
else {
|
||||
DBG_PRINTLN("");
|
||||
DBG_PRINT("Connected to "); SERIAL_ECHOLN(WiFi.SSID());
|
||||
DBG_PRINT("IP address: "); DBG_PRINTLN(WiFi.localIP());
|
||||
DBG_PRINT("RSSI: "); DBG_PRINTLN(WiFi.RSSI());
|
||||
DBG_PRINT("Mode: "); DBG_PRINTLN(WiFi.getPhyMode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the parsed command and dispatch it to its handler
|
||||
*/
|
||||
void process_parsed_command() {
|
||||
//SERIAL_ECHOLNPAIR("command_letter:", parser.command_letter);
|
||||
//SERIAL_ECHOLNPAIR("codenum:", parser.codenum);
|
||||
|
||||
// Handle a known G, M, or T
|
||||
switch (parser.command_letter) {
|
||||
case 'G': switch (parser.codenum) {
|
||||
default: parser.unknown_command_error();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M': switch (parser.codenum) {
|
||||
case 50: gcode_M50(); break;
|
||||
case 51: gcode_M51(); break;
|
||||
case 52: gcode_M52(); break;
|
||||
case 53: gcode_M53(); break;
|
||||
default: parser.unknown_command_error();
|
||||
}
|
||||
break;
|
||||
|
||||
default: parser.unknown_command_error();
|
||||
}
|
||||
|
||||
SERIAL_ECHOLN("ok");
|
||||
}
|
||||
|
||||
void process_next_command() {
|
||||
char * const current_command = command_queue[cmd_queue_index_r];
|
||||
current_command_sd_pos = command_sd_pos[cmd_queue_index_r];
|
||||
|
||||
// Parse the next command in the queue
|
||||
parser.parse(current_command);
|
||||
process_parsed_command();
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
void loop() {
|
||||
// ------------------------
|
||||
if(millis() < spiBlockoutTime)
|
||||
blink();
|
||||
// handle the request
|
||||
network.handle();
|
||||
|
||||
// do it only if there is a need to read FS
|
||||
if(wifiConnected) {
|
||||
if(dav.isClientWaiting()) {
|
||||
if(initFailed)
|
||||
return dav.rejectClient(statusMessage);
|
||||
|
||||
// has other master been using the bus in last few seconds
|
||||
if(millis() < spiBlockoutTime)
|
||||
return dav.rejectClient("Marlin is reading from SD card");
|
||||
|
||||
// a client is waiting and FS is ready and other SPI master is not using the bus
|
||||
takeBusControl();
|
||||
dav.handleClient();
|
||||
relenquishBusControl();
|
||||
}
|
||||
}
|
||||
// Handle gcode
|
||||
gcode.Handle();
|
||||
|
||||
// Get the serial input
|
||||
if (commands_in_queue < BUFSIZE) get_serial_commands();
|
||||
|
||||
if (commands_in_queue) {
|
||||
process_next_command();
|
||||
|
||||
// The queue may be reset by a command handler or by code invoked by idle() within a handler
|
||||
if (commands_in_queue) {
|
||||
--commands_in_queue;
|
||||
if (++cmd_queue_index_r >= BUFSIZE) cmd_queue_index_r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// blink
|
||||
statusBlink();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------
|
||||
void takeBusControl() {
|
||||
// ------------------------
|
||||
weHaveBus = true;
|
||||
LED_ON;
|
||||
pinMode(MISO, SPECIAL);
|
||||
pinMode(MOSI, SPECIAL);
|
||||
pinMode(SCLK, SPECIAL);
|
||||
pinMode(SD_CS, OUTPUT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------
|
||||
void relenquishBusControl() {
|
||||
// ------------------------
|
||||
pinMode(MISO, INPUT);
|
||||
pinMode(MOSI, INPUT);
|
||||
pinMode(SCLK, INPUT);
|
||||
pinMode(SD_CS, INPUT);
|
||||
LED_OFF;
|
||||
weHaveBus = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ------------------------
|
||||
void blink() {
|
||||
// ------------------------
|
||||
@@ -386,8 +53,6 @@ void blink() {
|
||||
delay(400);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------
|
||||
void errorBlink() {
|
||||
// ------------------------
|
||||
@@ -402,7 +67,7 @@ void errorBlink() {
|
||||
void statusBlink() {
|
||||
static unsigned long time = 0;
|
||||
if(millis() > time + 1000 ) {
|
||||
if(wifiConnected) {
|
||||
if(network.isConnected()) {
|
||||
LED_ON;
|
||||
delay(50);
|
||||
LED_OFF;
|
||||
@@ -412,4 +77,8 @@ void statusBlink() {
|
||||
}
|
||||
time = millis();
|
||||
}
|
||||
|
||||
// SPI bus not ready
|
||||
//if(millis() < spiBlockoutTime)
|
||||
// blink();
|
||||
}
|
||||
|
||||
14
config.cpp
14
config.cpp
@@ -48,4 +48,18 @@ void Config::save(const char*ssid,const char*password) {
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void Config::save() {
|
||||
if(data.ssid == NULL || data.psw == NULL)
|
||||
return;
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
data.flag = 1;
|
||||
uint8_t *p = (uint8_t*)(&data);
|
||||
for (int i = 0; i < sizeof(data); i++)
|
||||
{
|
||||
EEPROM.write(i, *(p + i));
|
||||
}
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
Config config;
|
||||
|
||||
1
config.h
1
config.h
@@ -24,6 +24,7 @@ public:
|
||||
char* password();
|
||||
void password(char* password);
|
||||
void save(const char*ssid,const char*password);
|
||||
void save();
|
||||
|
||||
protected:
|
||||
CONFIG_TYPE data;
|
||||
|
||||
181
gcode.cpp
Normal file
181
gcode.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
#include "gcode.h"
|
||||
#include "config.h"
|
||||
#include "parser.h"
|
||||
#include "network.h"
|
||||
#include "serial.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
Gcode gcode;
|
||||
|
||||
void Gcode::Handle() {
|
||||
// Get the serial input
|
||||
if (commands_in_queue < BUFSIZE) get_serial_commands();
|
||||
|
||||
if (commands_in_queue) {
|
||||
process_next_command();
|
||||
|
||||
// The queue may be reset by a command handler or by code invoked by idle() within a handler
|
||||
if (commands_in_queue) {
|
||||
--commands_in_queue;
|
||||
if (++cmd_queue_index_r >= BUFSIZE) cmd_queue_index_r = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Once a new command is in the ring buffer, call this to commit it
|
||||
*/
|
||||
void Gcode::_commit_command(bool say_ok) {
|
||||
send_ok[cmd_queue_index_w] = say_ok;
|
||||
if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0;
|
||||
commands_in_queue++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a command from RAM into the main command buffer.
|
||||
* Return true if the command was successfully added.
|
||||
* Return false for a full buffer, or if the 'command' is a comment.
|
||||
*/
|
||||
bool Gcode::_enqueuecommand(const char* cmd, bool say_ok) {
|
||||
if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
|
||||
strcpy(command_queue[cmd_queue_index_w], cmd);
|
||||
_commit_command(say_ok);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all commands waiting on the serial port and queue them.
|
||||
* Exit when the buffer is full or when no more characters are
|
||||
* left on the serial port.
|
||||
*/
|
||||
void Gcode::get_serial_commands() {
|
||||
static char serial_line_buffer[MAX_CMD_SIZE];
|
||||
static bool serial_comment_mode = false;
|
||||
|
||||
/**
|
||||
* Loop while serial characters are incoming and the queue is not full
|
||||
*/
|
||||
int c;
|
||||
while (commands_in_queue < BUFSIZE && (c = Serial.read()) >= 0) {
|
||||
|
||||
char serial_char = c;
|
||||
|
||||
/**
|
||||
* If the character ends the line
|
||||
*/
|
||||
if (serial_char == '\n' || serial_char == '\r') {
|
||||
|
||||
serial_comment_mode = false; // end of line == end of comment
|
||||
|
||||
// Skip empty lines and comments
|
||||
if (!serial_count) { continue; }
|
||||
|
||||
serial_line_buffer[serial_count] = 0; // Terminate string
|
||||
serial_count = 0; // Reset buffer
|
||||
|
||||
char* command = serial_line_buffer;
|
||||
|
||||
while (*command == ' ') command++; // Skip leading spaces
|
||||
|
||||
// Add the command to the queue
|
||||
_enqueuecommand(serial_line_buffer, true);
|
||||
}
|
||||
else if (serial_count >= MAX_CMD_SIZE - 1) {
|
||||
// Keep fetching, but ignore normal characters beyond the max length
|
||||
// The command will be injected when EOL is reached
|
||||
}
|
||||
else if (serial_char == '\\') { // Handle escapes
|
||||
if ((c = MYSERIAL0.read()) >= 0 && !serial_comment_mode) // if we have one more character, copy it over
|
||||
serial_line_buffer[serial_count++] = (char)c;
|
||||
// otherwise do nothing
|
||||
}
|
||||
else { // it's not a newline, carriage return or escape char
|
||||
if (serial_char == ';') serial_comment_mode = true;
|
||||
if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char;
|
||||
}
|
||||
} // queue has space, serial has data
|
||||
}
|
||||
|
||||
/**
|
||||
* M50: Set the Wifi ssid
|
||||
*/
|
||||
void Gcode::gcode_M50() {
|
||||
for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
|
||||
config.ssid(parser.string_arg);
|
||||
SERIAL_ECHO(config.ssid());
|
||||
}
|
||||
|
||||
/**
|
||||
* M50: Set the Wifi password
|
||||
*/
|
||||
void Gcode::gcode_M51() {
|
||||
for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
|
||||
config.password(parser.string_arg);
|
||||
SERIAL_ECHO(config.password());
|
||||
}
|
||||
|
||||
/**
|
||||
* M52: Connect the wifi
|
||||
*/
|
||||
void Gcode::gcode_M52() {
|
||||
if(!network.start()) {
|
||||
SERIAL_ECHOLN("");
|
||||
SERIAL_ECHOLN("Connect fail, please set the wifi config and connect again");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* M53: Check wifi status
|
||||
*/
|
||||
void Gcode::gcode_M53() {
|
||||
if(WiFi.status() != WL_CONNECTED) {
|
||||
SERIAL_ECHOLN("Wifi not connected");
|
||||
SERIAL_ECHOLN("Please set the wifi ssid with M50 and password with M51 , and start connection with M52");
|
||||
}
|
||||
else {
|
||||
SERIAL_ECHOLN("");
|
||||
SERIAL_ECHO("Connected to "); SERIAL_ECHOLN(WiFi.SSID());
|
||||
SERIAL_ECHO("IP address: "); SERIAL_ECHOLN(WiFi.localIP());
|
||||
SERIAL_ECHO("RSSI: "); SERIAL_ECHOLN(WiFi.RSSI());
|
||||
SERIAL_ECHO("Mode: "); SERIAL_ECHOLN(WiFi.getPhyMode());
|
||||
SERIAL_ECHO("Asscess to SD at the Run prompt : \\\\"); SERIAL_ECHO(WiFi.localIP());SERIAL_ECHOLN("\\DavWWWRoot");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the parsed command and dispatch it to its handler
|
||||
*/
|
||||
void Gcode::process_parsed_command() {
|
||||
//SERIAL_ECHOLNPAIR("command_letter:", parser.command_letter);
|
||||
//SERIAL_ECHOLNPAIR("codenum:", parser.codenum);
|
||||
|
||||
// Handle a known G, M, or T
|
||||
switch (parser.command_letter) {
|
||||
case 'G': switch (parser.codenum) {
|
||||
default: parser.unknown_command_error();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M': switch (parser.codenum) {
|
||||
case 50: gcode_M50(); break;
|
||||
case 51: gcode_M51(); break;
|
||||
case 52: gcode_M52(); break;
|
||||
case 53: gcode_M53(); break;
|
||||
default: parser.unknown_command_error();
|
||||
}
|
||||
break;
|
||||
|
||||
default: parser.unknown_command_error();
|
||||
}
|
||||
|
||||
SERIAL_ECHOLN("ok");
|
||||
}
|
||||
|
||||
void Gcode::process_next_command() {
|
||||
char * const current_command = command_queue[cmd_queue_index_r];
|
||||
current_command_sd_pos = command_sd_pos[cmd_queue_index_r];
|
||||
|
||||
// Parse the next command in the queue
|
||||
parser.parse(current_command);
|
||||
process_parsed_command();
|
||||
}
|
||||
53
gcode.h
Normal file
53
gcode.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef _GCODE_H_
|
||||
#define _GCODE_H_
|
||||
|
||||
#define MAX_CMD_SIZE 96
|
||||
#define BUFSIZE 4
|
||||
|
||||
/**
|
||||
* GCode
|
||||
*
|
||||
* - Handle gcode
|
||||
*/
|
||||
class Gcode {
|
||||
public:
|
||||
void Handle();
|
||||
|
||||
private:
|
||||
void _commit_command(bool say_ok);
|
||||
bool _enqueuecommand(const char* cmd, bool say_ok=false);
|
||||
void get_serial_commands();
|
||||
void gcode_M50();
|
||||
void gcode_M51();
|
||||
void gcode_M52();
|
||||
void gcode_M53();
|
||||
void process_parsed_command();
|
||||
void process_next_command();
|
||||
|
||||
/**
|
||||
* GCode Command Queue
|
||||
* A simple ring buffer of BUFSIZE command strings.
|
||||
*
|
||||
* Commands are copied into this buffer by the command injectors
|
||||
* (immediate, serial, sd card) and they are processed sequentially by
|
||||
* the main loop. The process_next_command function parses the next
|
||||
* command and hands off execution to individual handler functions.
|
||||
*/
|
||||
unsigned char commands_in_queue = 0, // Count of commands in the queue
|
||||
cmd_queue_index_r = 0, // Ring buffer read (out) position
|
||||
cmd_queue_index_w = 0; // Ring buffer write (in) position
|
||||
|
||||
unsigned long command_sd_pos[BUFSIZE];
|
||||
volatile unsigned long current_command_sd_pos;
|
||||
|
||||
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
||||
|
||||
bool send_ok[BUFSIZE];
|
||||
|
||||
// Number of characters read in the current line of serial input
|
||||
int serial_count; // = 0;
|
||||
};
|
||||
|
||||
extern Gcode gcode;
|
||||
|
||||
#endif
|
||||
141
network.cpp
Normal file
141
network.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "network.h"
|
||||
#include "serial.h"
|
||||
#include "config.h"
|
||||
#include "ESP8266WiFi.h"
|
||||
#include "ESPWebDAV.h"
|
||||
|
||||
volatile long Network::_spiBlockoutTime = 0;
|
||||
bool Network::_weHaveBus = false;
|
||||
|
||||
void Network::setup() {
|
||||
// ----- GPIO -------
|
||||
// Detect when other master uses SPI bus
|
||||
pinMode(CS_SENSE, INPUT);
|
||||
attachInterrupt(CS_SENSE, []() {
|
||||
if(!_weHaveBus)
|
||||
_spiBlockoutTime = millis() + SPI_BLOCKOUT_PERIOD;
|
||||
}, FALLING);
|
||||
|
||||
// wait for other master to assert SPI bus first
|
||||
delay(SPI_BLOCKOUT_PERIOD);
|
||||
}
|
||||
|
||||
bool Network::start() {
|
||||
wifiConnected = false;
|
||||
|
||||
// Set hostname first
|
||||
WiFi.hostname(HOSTNAME);
|
||||
// Reduce startup surge current
|
||||
WiFi.setAutoConnect(false);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
|
||||
WiFi.begin(config.ssid(), config.password());
|
||||
|
||||
// Wait for connection
|
||||
unsigned int timeout = 0;
|
||||
while(WiFi.status() != WL_CONNECTED) {
|
||||
//blink();
|
||||
SERIAL_ECHO(".");
|
||||
timeout++;
|
||||
if(timeout++ > WIFI_CONNECT_TIMEOUT/100)
|
||||
return false;
|
||||
else
|
||||
delay(100);
|
||||
}
|
||||
|
||||
SERIAL_ECHOLN("");
|
||||
SERIAL_ECHO("Connected to "); SERIAL_ECHOLN(config.ssid());
|
||||
SERIAL_ECHO("IP address: "); SERIAL_ECHOLN(WiFi.localIP());
|
||||
SERIAL_ECHO("RSSI: "); SERIAL_ECHOLN(WiFi.RSSI());
|
||||
SERIAL_ECHO("Mode: "); SERIAL_ECHOLN(WiFi.getPhyMode());
|
||||
SERIAL_ECHO("Asscess to SD at the Run prompt : \\\\"); SERIAL_ECHO(WiFi.localIP());SERIAL_ECHOLN("\\DavWWWRoot");
|
||||
|
||||
wifiConnected = true;
|
||||
|
||||
config.save();
|
||||
|
||||
startDAVServer();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Network::startDAVServer() {
|
||||
// Check to see if other master is using the SPI bus
|
||||
while(millis() < _spiBlockoutTime) {
|
||||
//blink();
|
||||
}
|
||||
|
||||
takeBusControl();
|
||||
|
||||
// start the SD DAV server
|
||||
if(!dav.init(SD_CS, SPI_FULL_SPEED, SERVER_PORT)) {
|
||||
DBG_PRINT("ERROR: "); DBG_PRINTLN("Failed to initialize SD Card");
|
||||
// indicate error on LED
|
||||
//errorBlink();
|
||||
initFailed = true;
|
||||
}
|
||||
else {
|
||||
//blink();
|
||||
}
|
||||
|
||||
relenquishBusControl();
|
||||
DBG_PRINTLN("WebDAV server started");
|
||||
}
|
||||
|
||||
bool Network::isConnected() {
|
||||
return wifiConnected;
|
||||
}
|
||||
|
||||
// a client is waiting and FS is ready and other SPI master is not using the bus
|
||||
bool Network::ready() {
|
||||
if(!isConnected()) return false;
|
||||
|
||||
// do it only if there is a need to read FS
|
||||
if(!dav.isClientWaiting()) return false;
|
||||
|
||||
if(initFailed) {
|
||||
dav.rejectClient("Failed to initialize SD Card");
|
||||
return false;
|
||||
}
|
||||
|
||||
// has other master been using the bus in last few seconds
|
||||
if(millis() < _spiBlockoutTime) {
|
||||
dav.rejectClient("Marlin is reading from SD card");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Network::handle() {
|
||||
if(network.ready()) {
|
||||
takeBusControl();
|
||||
dav.handleClient();
|
||||
relenquishBusControl();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
void Network::takeBusControl() {
|
||||
// ------------------------
|
||||
_weHaveBus = true;
|
||||
//LED_ON;
|
||||
pinMode(MISO_PIN, SPECIAL);
|
||||
pinMode(MOSI_PIN, SPECIAL);
|
||||
pinMode(SCLK_PIN, SPECIAL);
|
||||
pinMode(SD_CS, OUTPUT);
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
void Network::relenquishBusControl() {
|
||||
// ------------------------
|
||||
pinMode(MISO_PIN, INPUT);
|
||||
pinMode(MOSI_PIN, INPUT);
|
||||
pinMode(SCLK_PIN, INPUT);
|
||||
pinMode(SD_CS, INPUT);
|
||||
//LED_OFF;
|
||||
_weHaveBus = false;
|
||||
}
|
||||
|
||||
|
||||
Network network;
|
||||
37
network.h
Normal file
37
network.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef _NETWORK_H_
|
||||
#define _NETWORK_H_
|
||||
|
||||
#define HOSTNAME "FYSETC"
|
||||
#define SERVER_PORT 80
|
||||
|
||||
#define SD_CS 4
|
||||
#define MISO_PIN 12
|
||||
#define MOSI_PIN 13
|
||||
#define SCLK_PIN 14
|
||||
#define CS_SENSE 5
|
||||
|
||||
#define SPI_BLOCKOUT_PERIOD 20000UL
|
||||
#define WIFI_CONNECT_TIMEOUT 30000UL
|
||||
|
||||
class Network {
|
||||
public:
|
||||
Network() { initFailed = false;}
|
||||
static void setup();
|
||||
static void takeBusControl();
|
||||
static void relenquishBusControl();
|
||||
bool start();
|
||||
void startDAVServer();
|
||||
bool isConnected();
|
||||
void handle();
|
||||
bool ready();
|
||||
|
||||
private:
|
||||
bool wifiConnected;
|
||||
bool initFailed;
|
||||
static volatile long _spiBlockoutTime;
|
||||
static bool _weHaveBus;
|
||||
};
|
||||
|
||||
extern Network network;
|
||||
|
||||
#endif
|
||||
1
parser.h
1
parser.h
@@ -10,6 +10,7 @@
|
||||
|
||||
//#include "enum.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "macros.h"
|
||||
|
||||
#define strtof strtod
|
||||
|
||||
Reference in New Issue
Block a user