Fix jerky SD card printing when no network cable

Fixed problem whereby gcode files printed from SD card that used lots of
small fast moves in sequence would print jerkily if a network cable had
not been connected since reset.
Fixed problem whereby object height and filament needed were not
retrieved from the SD card file to be printed if the filename contained
spaces.
Added support for deprecated M190 command, because slic3r appears to
generate it sometimes
Added support for M564 command to allow movement without limits, copied
from RepRapPro dev branch
This commit is contained in:
David Crocker 2014-05-05 18:47:22 +01:00
parent 6c1aeb0277
commit ceae4df7a1
7 changed files with 223 additions and 140 deletions

View file

@ -24,8 +24,8 @@ Licence: GPL
#define CONFIGURATION_H
#define NAME "RepRapFirmware"
#define VERSION "0.58f-dc42"
#define DATE "2014-05-02"
#define VERSION "0.59beta2-dc42"
#define DATE "2014-05-04"
#define LAST_AUTHOR "dc42"
// Other firmware that we might switch to be compatible with.

View file

@ -66,6 +66,7 @@ void GCodes::Init()
active = true;
longWait = platform->Time();
dwellTime = longWait;
limitAxes = true;
axisIsHomed[X_AXIS] = axisIsHomed[Y_AXIS] = axisIsHomed[Z_AXIS] = false;
fanMaxPwm = 1.0;
coolingInverted = false;
@ -413,7 +414,7 @@ int GCodes::SetUpMove(GCodeBuffer *gb)
}
}
LoadMoveBufferFromGCode(gb, false, !checkEndStops);
LoadMoveBufferFromGCode(gb, false, !checkEndStops && limitAxes);
moveAvailable = true;
return (checkEndStops) ? 2 : 1;
}
@ -425,7 +426,9 @@ bool GCodes::ReadMove(float m[], bool& ce)
if (!moveAvailable)
return false;
for (int8_t i = 0; i <= DRIVES; i++) // 1 more for feedrate
{
m[i] = moveBuffer[i];
}
ce = checkEndStops;
moveAvailable = false;
checkEndStops = false;
@ -450,7 +453,9 @@ bool GCodes::DoFileCannedCycles(const char* fileName)
platform->Message(HOST_MESSAGE, fileName);
platform->Message(HOST_MESSAGE, "\n");
if (!Pop())
{
platform->Message(HOST_MESSAGE, "Cannot pop the stack.\n");
}
return true;
}
fileBeingPrinted.Set(f);
@ -481,7 +486,6 @@ bool GCodes::DoFileCannedCycles(const char* fileName)
}
doFilePrint(cannedCycleGCode);
return false;
}
@ -1783,16 +1787,20 @@ bool GCodes::ActOnGcode(GCodeBuffer *gb)
ELECTRONICS, DATE);
break;
case 109: // Deprecated
case 109: // Set extruder temperature and wait - deprecated
case 190: // Set bed temperature and wait - deprecated
if (gb->Seen('S'))
{
reprap.GetHeat()->SetActiveTemperature(1, gb->GetFValue()); // 0 is the bed
reprap.GetHeat()->Activate(1);
uint8_t heater = (code == 190) ? 0 : 1;
reprap.GetHeat()->SetActiveTemperature(heater, gb->GetFValue());
reprap.GetHeat()->Activate(heater);
}
/* no break */
case 116: // Wait for everything, especially set temperatures
if (!AllMovesAreFinishedAndMoveBufferIsLoaded())
{
return false;
}
result = reprap.GetHeat()->AllHeatersAtSetTemperatures();
break;
@ -1833,6 +1841,8 @@ bool GCodes::ActOnGcode(GCodeBuffer *gb)
platform->Message(HOST_MESSAGE, "M141 - heated chamber not yet implemented\n");
break;
// case 190 is earlier because it falls through to case 116
case 201: // Set axis accelerations
for (int8_t drive = 0; drive < DRIVES; drive++)
{
@ -2032,24 +2042,12 @@ bool GCodes::ActOnGcode(GCodeBuffer *gb)
}
break;
// case 876: // TEMPORARY - this will go away...
// if(gb->Seen('P'))
// {
// iValue = gb->GetIValue();
// if(iValue != 1)
// platform->SetHeatOn(0);
// else
// platform->SetHeatOn(1);
// }
// break;
case 900:
result = DoFileCannedCycles("homex.g");
break;
case 901:
result = DoFileCannedCycles("homey.g");
break;
case 564: // Think outside the box?
if(gb->Seen('S'))
{
limitAxes = (gb->GetIValue() != 0);
}
break;
case 906: // Set Motor currents
for (uint8_t i = 0; i < DRIVES; i++)

View file

@ -230,6 +230,7 @@ class GCodes
bool cannedCycleMoveQueued;
bool zProbesSet;
float longWait;
bool limitAxes; // Don't think outside the box.
bool axisIsHomed[3]; // these record which of the axes have been homed
float fanMaxPwm; // the M106 S value that represents 100% fan speed
bool waitingForMoveToComplete;

View file

@ -289,128 +289,200 @@ uint8_t ethernet_phy_set_link(Emac *p_emac, uint8_t uc_phy_addr,
* \param uc_phy_addr PHY address.
*
* Return EMAC_OK if successfully, EMAC_TIMEOUT if timeout (in which case we can keep calling this).
* This has been refactored as a state machine, because we must not spend much time calling this when
* no network cable is connected, otherwise it slows down printing.
*/
uint8_t ethernet_phy_auto_negotiate(Emac *p_emac, uint8_t uc_phy_addr)
{
static bool negotiationInProgress = false;
static uint8_t state = 0;
static uint8_t ul_retry_count;
static uint32_t ul_value;
static uint32_t ul_phy_anar;
uint32_t ul_value;
uint32_t ul_phy_anar;
uint32_t ul_phy_analpar;
uint32_t ul_retry_count = 0;
uint8_t uc_fd = 0;
uint8_t uc_speed = 0;
uint8_t uc_rc = EMAC_TIMEOUT;
if (!negotiationInProgress)
switch(state)
{
emac_enable_management(p_emac, true);
case 0:
{
emac_enable_management(p_emac, true);
/* Set up control register */
uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMCR, &ul_value);
if (uc_rc != EMAC_OK) {
emac_enable_management(p_emac, false);
return uc_rc;
}
/* Set up control register */
uint8_t uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMCR, &ul_value);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
ul_value &= ~MII_AUTONEG; /* Remove auto-negotiation enable */
ul_value &= ~(MII_LOOPBACK | MII_POWER_DOWN);
ul_value |= MII_ISOLATE; /* Electrically isolate PHY */
uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
if (uc_rc != EMAC_OK) {
emac_enable_management(p_emac, false);
return uc_rc;
++state;
}
break;
/*
* Set the Auto_negotiation Advertisement Register.
* MII advertising for Next page.
* 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
*/
ul_phy_anar = MII_TX_FDX | MII_TX_HDX | MII_10_FDX | MII_10_HDX |
MII_AN_IEEE_802_3;
uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_ANAR, ul_phy_anar);
if (uc_rc != EMAC_OK) {
emac_enable_management(p_emac, false);
return uc_rc;
}
case 1:
{
ul_value &= ~MII_AUTONEG; /* Remove auto-negotiation enable */
ul_value &= ~(MII_LOOPBACK | MII_POWER_DOWN);
ul_value |= MII_ISOLATE; /* Electrically isolate PHY */
uint8_t uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
/* Read & modify control register */
uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMCR, &ul_value);
if (uc_rc != EMAC_OK) {
emac_enable_management(p_emac, false);
return uc_rc;
++state;
}
ul_value |= MII_SPEED_SELECT | MII_AUTONEG | MII_DUPLEX_MODE;
uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
if (uc_rc != EMAC_OK) {
emac_enable_management(p_emac, false);
return uc_rc;
break;
case 2:
{
/*
* Set the Auto_negotiation Advertisement Register.
* MII advertising for Next page.
* 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
*/
ul_phy_anar = MII_TX_FDX | MII_TX_HDX | MII_10_FDX | MII_10_HDX | MII_AN_IEEE_802_3;
uint8_t uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_ANAR, ul_phy_anar);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
++state;
}
/* Restart auto negotiation */
ul_value |= MII_RESTART_AUTONEG;
ul_value &= ~MII_ISOLATE;
uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
if (uc_rc != EMAC_OK) {
break;
case 3:
{
/* Read & modify control register */
uint8_t uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMCR, &ul_value);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
++state;
}
break;
case 4:
{
ul_value |= MII_SPEED_SELECT | MII_AUTONEG | MII_DUPLEX_MODE;
uint8_t uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
++state;
}
break;
case 5:
{
/* Restart auto negotiation */
ul_value |= MII_RESTART_AUTONEG;
ul_value &= ~MII_ISOLATE;
uint8_t uc_rc = emac_phy_write(p_emac, uc_phy_addr, MII_BMCR, ul_value);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
ul_retry_count = 0;
++state;
}
break;
case 6:
{
/* Check if auto negotiation is completed */
uint8_t uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMSR, &ul_value);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
/* Done successfully */
if (!(ul_value & MII_AUTONEG_COMP))
{
++ul_retry_count;
if (ul_retry_count >= 10000) // timeout check
{
state = 0; // start again
}
return EMAC_TIMEOUT;
}
++state;
}
break;
case 7:
{
uint32_t ul_phy_analpar;
/* Get the auto negotiate link partner base page */
uint8_t uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_ANLPAR, &ul_phy_analpar);
if (uc_rc != EMAC_OK)
{
emac_enable_management(p_emac, false);
state = 0;
return uc_rc;
}
// The rest only happens once. so we do it all in one go
uint8_t uc_fd = false;
uint8_t uc_speed = false;
/* Set up the EMAC link speed */
if ((ul_phy_anar & ul_phy_analpar) & MII_TX_FDX)
{
/* Set MII for 100BaseTX and Full Duplex */
uc_speed = true;
uc_fd = true;
}
else if ((ul_phy_anar & ul_phy_analpar) & MII_10_FDX)
{
/* Set MII for 10BaseT and Full Duplex */
uc_speed = false;
uc_fd = true;
}
else if ((ul_phy_anar & ul_phy_analpar) & MII_TX_HDX)
{
/* Set MII for 100BaseTX and half Duplex */
uc_speed = true;
uc_fd = false;
}
else if ((ul_phy_anar & ul_phy_analpar) & MII_10_HDX)
{
/* Set MII for 10BaseT and half Duplex */
uc_speed = false;
uc_fd = false;
}
emac_set_speed(p_emac, uc_speed);
emac_enable_full_duplex(p_emac, uc_fd);
emac_enable_rmii(p_emac, ETH_PHY_MODE);
emac_enable_transceiver_clock(p_emac, true);
emac_enable_management(p_emac, false);
return uc_rc;
state = 0; // in case we get called again
return EMAC_OK;
}
}
negotiationInProgress = true; // auto negotiation is in progress
/* Check if auto negotiation is completed */
while (1) {
uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_BMSR, &ul_value);
if (uc_rc != EMAC_OK) {
emac_enable_management(p_emac, false);
negotiationInProgress = false;
return uc_rc;
}
/* Done successfully */
if (ul_value & MII_AUTONEG_COMP) {
break;
}
/* Timeout check */
if (++ul_retry_count >= 20) {
return EMAC_TIMEOUT;
}
}
negotiationInProgress = false;
/* Get the auto negotiate link partner base page */
uc_rc = emac_phy_read(p_emac, uc_phy_addr, MII_ANLPAR, &ul_phy_analpar);
if (uc_rc != EMAC_OK) {
emac_enable_management(p_emac, false);
return uc_rc;
}
/* Set up the EMAC link speed */
if ((ul_phy_anar & ul_phy_analpar) & MII_TX_FDX) {
/* Set MII for 100BaseTX and Full Duplex */
uc_speed = true;
uc_fd = true;
} else if ((ul_phy_anar & ul_phy_analpar) & MII_10_FDX) {
/* Set MII for 10BaseT and Full Duplex */
uc_speed = false;
uc_fd = true;
} else if ((ul_phy_anar & ul_phy_analpar) & MII_TX_HDX) {
/* Set MII for 100BaseTX and half Duplex */
uc_speed = true;
uc_fd = false;
} else if ((ul_phy_anar & ul_phy_analpar) & MII_10_HDX) {
/* Set MII for 10BaseT and half Duplex */
uc_speed = false;
uc_fd = false;
}
emac_set_speed(p_emac, uc_speed);
emac_enable_full_duplex(p_emac, uc_fd);
emac_enable_rmii(p_emac, ETH_PHY_MODE);
emac_enable_transceiver_clock(p_emac, true);
emac_enable_management(p_emac, false);
return uc_rc;
return EMAC_TIMEOUT; // this just means that we needs to be called again
}
/**

View file

@ -260,7 +260,6 @@ bool ethernet_establish_link(void)
{
/* Auto Negotiate, work in RMII mode */
if (ethernet_phy_auto_negotiate(EMAC, BOARD_EMAC_PHY_ADDR) != EMAC_OK) {
LWIP_DEBUGF(LWIP_DBG_TRACE, ("Auto Negotiate ERROR!\r"));
return false;
}
@ -269,7 +268,6 @@ bool ethernet_establish_link(void)
LWIP_DEBUGF(LWIP_DBG_TRACE,("Set link ERROR!\r"));
return false;
}
/**@todo debug*/
#ifdef FREERTOS_USED
/* Restore the priority of the current task. */

Binary file not shown.

View file

@ -644,11 +644,25 @@ void Webserver::ParseGetPost()
{
i++;
j = 0;
while (clientLine[i] != ' ')
for(;;)
{
clientQualifier[j] = clientLine[i];
j++;
i++;
char c = clientLine[i++];
if (c == ' ')
{
break;
}
else if (c == '%' && isalnum(clientLine[i]) && isalnum(clientLine[i + 1]))
{
c = clientLine[i++];
unsigned int v = (isdigit(c)) ? (c - '0') : ((toupper(c) - 'A') + 10);
c = clientLine[i++];
v = (v << 4) + ((isdigit(c)) ? (c - '0') : ((toupper(c) - 'A') + 10));
clientQualifier[j++] = (char)v;
}
else
{
clientQualifier[j++] = c;
}
}
clientQualifier[j] = 0;
}