This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
reprapfirmware-dc42/Line.cpp
David Crocker efe13ef2f1 Version 1.09k
Added F (probing speed) and T (travel speed) parameters to M558 command
Removed M210 command because home feed rates are defined in the homing
files
Increased UART interrupt priority to avoid dropping characters sent by
PanelDue
Bug fix: M558 P3 did not leave the Z probe control pin high
Bug fix: in version 1.09j only, the move following a G92 E0 command was
sometimes executed from an incorrect start point
Fixed bugs with reads/writes from/to the SD card that spanned one or
more whole sectors
Updated to latest Atmel HSMCI driver
2015-09-20 15:14:00 +01:00

174 lines
4 KiB
C++

#include "Arduino.h"
#include "Line.h"
//***************************************************************************************************
// Serial/USB class
Line::Line(Stream& p_iface) : iface(p_iface)
{
}
uint8_t Line::Status() const
{
return inputNumChars == 0 ? (uint8_t)IOStatus::nothing : (uint8_t)IOStatus::byteAvailable;
}
// This is only ever called on initialisation, so we know the buffer won't overflow
void Line::InjectString(char* string)
{
int i = 0;
while(string[i])
{
inBuffer[(inputGetIndex + inputNumChars) % lineInBufsize] = string[i];
inputNumChars++;
i++;
}
}
int Line::Read(char& b)
{
if (inputNumChars == 0)
return 0;
b = inBuffer[inputGetIndex];
inputGetIndex = (inputGetIndex + 1) % lineInBufsize;
--inputNumChars;
return 1;
}
void Line::Init()
{
inputGetIndex = 0;
inputNumChars = 0;
outputGetIndex = 0;
outputNumChars = 0;
ignoringOutputLine = false;
inWrite = 0;
outputColumn = 0;
timeLastCharWritten = 0;
}
void Line::Spin()
{
// Read the serial data in blocks to avoid excessive flow control
if (inputNumChars <= lineInBufsize / 2)
{
int16_t target = iface.available() + (int16_t) inputNumChars;
if (target > lineInBufsize)
{
target = lineInBufsize;
}
while ((int16_t) inputNumChars < target)
{
int incomingByte = iface.read();
if (incomingByte < 0)
break;
inBuffer[(inputGetIndex + inputNumChars) % lineInBufsize] = (char) incomingByte;
++inputNumChars;
}
}
TryFlushOutput();
}
// Write a character to USB.
// If 'important' is true then we don't return until we have either written it to the USB port,
// or put it in the buffer, or we have timed out waiting for the buffer to empty. The purpose of the timeout is to
// avoid getting a software watchdog reset if we are writing important data (e.g. debug) and there is no consumer for the data.
// Otherwise, if the buffer is full then we append ".\n" to the end of it, return immediately and ignore the rest
// of the data we are asked to print until we get a new line.
void Line::Write(char b, bool important)
{
if (b == '\n')
{
outputColumn = 0;
}
else
{
++outputColumn;
}
if (ignoringOutputLine)
{
// We have already failed to write some characters of this message line, so don't write any of it.
// But try to start sending again after this line finishes.
if (b == '\n')
{
ignoringOutputLine = false;
}
}
else
{
for(;;)
{
TryFlushOutput();
if (outputNumChars == 0 && iface.canWrite() != 0)
{
// We can write the character directly into the USB output buffer
++inWrite;
iface.write(b);
--inWrite;
timeLastCharWritten = millis();
break;
}
else if ( outputNumChars + 2 < lineOutBufSize // save 2 spaces in the output buffer
|| (b == '\n' && outputNumChars < lineOutBufSize) //...unless writing newline
)
{
outBuffer[(outputGetIndex + outputNumChars) % lineOutBufSize] = b;
++outputNumChars;
break;
}
else if (!important || millis() - timeLastCharWritten >= 100)
{
// Output is being consumed too slowly, so throw away some data
if (outputNumChars + 2 == lineOutBufSize)
{
// We still have our 2 free characters, so append ".\n" to the line to indicate it was incomplete
outBuffer[(outputGetIndex + outputNumChars) % lineOutBufSize] = '.';
++outputNumChars;
outBuffer[(outputGetIndex + outputNumChars) % lineOutBufSize] = '\n';
++outputNumChars;
}
else
{
// As we don't have 2 spare characters in the buffer, we can't have written any of the current line.
// So ignore the whole line.
}
ignoringOutputLine = true;
break;
}
}
}
}
void Line::Write(const char* b, bool important)
{
while (*b)
{
Write(*b++, important);
}
}
void Line::TryFlushOutput()
{
while (outputNumChars != 0 && iface.canWrite() != 0)
{
++inWrite;
iface.write(outBuffer[outputGetIndex]);
--inWrite;
timeLastCharWritten = millis();
outputGetIndex = (outputGetIndex + 1) % lineOutBufSize;
--outputNumChars;
}
}
void Line::Flush()
{
while (outputNumChars != 0)
{
TryFlushOutput();
}
}
// End