// IEC Send byte standard function // // Sends the byte and can signal EOI // boolean IEC::sendByte(byte data, boolean signalEOI) { // Listener must have accepted previous data if(timeoutWait(m_dataPin, true)) return false; // Say we're ready writeCLOCK(false); // Wait for listener to be ready if(timeoutWait(m_dataPin, false)) return false; if(signalEOI) { // TODO: Make this like sd2iec and may not need a fixed delay here. // Signal eoi by waiting 200 us delayMicroseconds(TIMING_EOI_WAIT); // get eoi acknowledge: if(timeoutWait(m_dataPin, true)) return false; if(timeoutWait(m_dataPin, false)) return false; } delayMicroseconds(TIMING_NO_EOI); // Send bits for(byte n = 0; n < 8; n++) { // TODO: Here check whether data pin goes low, if so end (enter cleanup)! writeCLOCK(true); // set data writeDATA((data bitand 1) ? false : true); delayMicroseconds(TIMING_BIT); writeCLOCK(false); delayMicroseconds(TIMING_BIT); data >>= 1; } writeCLOCK(true); writeDATA(false); // TODO: Maybe make the following ending more like sd2iec instead. // Line stabilization delay delayMicroseconds(TIMING_STABLE_WAIT); // Wait for listener to accept data if(timeoutWait(m_dataPin, true)) return false; return true; } // sendByte
void Adafruit_Thermal::writeBytes(uint8_t a, uint8_t b, uint8_t c) { timeoutWait(); PRINTER_PRINT(a); PRINTER_PRINT(b); PRINTER_PRINT(c); timeoutSet(3 * BYTE_TIME); }
void Adafruit_Thermal::writeBytes(uint8_t a, uint8_t b, uint8_t c) { timeoutWait(); stream->write(a); stream->write(b); stream->write(c); timeoutSet(3 * BYTE_TIME); }
void Adafruit_Thermal::printBitmap(int w, int h, Stream *fromStream) { int rowBytes, rowBytesClipped, rowStart, chunkHeight, chunkHeightLimit, x, y, i, c; rowBytes = (w + 7) / 8; // Round up to next byte boundary rowBytesClipped = (rowBytes >= 48) ? 48 : rowBytes; // 384 pixels max width // Est. max rows to write at once, assuming 256 byte printer buffer. chunkHeightLimit = 256 / rowBytesClipped; if(chunkHeightLimit > maxChunkHeight) chunkHeightLimit = maxChunkHeight; else if(chunkHeightLimit < 1) chunkHeightLimit = 1; for(rowStart=0; rowStart < h; rowStart += chunkHeightLimit) { // Issue up to chunkHeightLimit rows at a time: chunkHeight = h - rowStart; if(chunkHeight > chunkHeightLimit) chunkHeight = chunkHeightLimit; writeBytes(ASCII_DC2, '*', chunkHeight, rowBytesClipped); for(y=0; y < chunkHeight; y++) { for(x=0; x < rowBytesClipped; x++) { while((c = fromStream->read()) < 0); timeoutWait(); stream->write((uint8_t)c); } for(i = rowBytes - rowBytesClipped; i>0; i--) { while((c = fromStream->read()) < 0); } } timeoutSet(chunkHeight * dotPrintTime); } prevByte = '\n'; }
void Adafruit_Thermal::printBitmap( int w, int h, const uint8_t *bitmap, bool fromProgMem) { int rowBytes, rowBytesClipped, rowStart, chunkHeight, chunkHeightLimit, x, y, i; rowBytes = (w + 7) / 8; // Round up to next byte boundary rowBytesClipped = (rowBytes >= 48) ? 48 : rowBytes; // 384 pixels max width // Est. max rows to write at once, assuming 256 byte printer buffer. chunkHeightLimit = 256 / rowBytesClipped; if(chunkHeightLimit > maxChunkHeight) chunkHeightLimit = maxChunkHeight; else if(chunkHeightLimit < 1) chunkHeightLimit = 1; for(i=rowStart=0; rowStart < h; rowStart += chunkHeightLimit) { // Issue up to chunkHeightLimit rows at a time: chunkHeight = h - rowStart; if(chunkHeight > chunkHeightLimit) chunkHeight = chunkHeightLimit; writeBytes(ASCII_DC2, '*', chunkHeight, rowBytesClipped); for(y=0; y < chunkHeight; y++) { for(x=0; x < rowBytesClipped; x++, i++) { timeoutWait(); stream->write(fromProgMem ? pgm_read_byte(bitmap + i) : *(bitmap+i)); } i += rowBytes - rowBytesClipped; } timeoutSet(chunkHeight * dotPrintTime); } prevByte = '\n'; }
void connManager() { time_t curTime; iFuseConn_t *tmpIFuseConn; ListNode *node; List *TimeOutList = newListNoRegion(); while ( 1 ) { curTime = time( NULL ); /* exceed high water mark for number of connection ? */ if ( listSize( ConnectedConn ) > HIGH_NUM_CONN ) { LOCK_STRUCT( *ConnectedConn ); int disconnTarget = _listSize( ConnectedConn ) - HIGH_NUM_CONN; node = ConnectedConn->list->head; while ( node != NULL ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { listAppendNoRegion( TimeOutList, tmpIFuseConn ); } node = node->next; } UNLOCK_STRUCT( *ConnectedConn ); node = TimeOutList->head; int disconned = 0; while ( node != NULL && disconned < disconnTarget ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; LOCK_STRUCT( *tmpIFuseConn ); if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { removeFromConcurrentList2( FreeConn, tmpIFuseConn ); removeFromConcurrentList2( ConnectedConn, tmpIFuseConn ); if ( tmpIFuseConn->status == 0 ) { /* no struct is referring to it, we can unlock it and free it */ UNLOCK_STRUCT( *tmpIFuseConn ); /* rodsLog(LOG_ERROR, "[FREE IFUSE CONN] %s:%d %p", __FILE__, __LINE__, tmpIFuseConn); */ _freeIFuseConn( tmpIFuseConn ); } else { /* set to timed out */ _ifuseDisconnect( tmpIFuseConn ); UNLOCK_STRUCT( *tmpIFuseConn ); } disconned ++; } else { UNLOCK_STRUCT( *tmpIFuseConn ); } node = node->next; } clearListNoRegion( TimeOutList ); } notifyWait( &connReqWait.mutex, &connReqWait.cond ); timeoutWait( &ConnManagerLock, &ConnManagerCond, CONN_MANAGER_SLEEP_TIME ); } deleteListNoRegion( TimeOutList ); }
void _waitForConn() { connReqWait_t myConnReqWait; bzero( &myConnReqWait, sizeof( myConnReqWait ) ); initConnReqWaitMutex( &myConnReqWait ); addToConcurrentList( ConnReqWaitQue, &myConnReqWait ); while ( myConnReqWait.state == 0 ) { timeoutWait( &myConnReqWait.mutex, &myConnReqWait.cond, CONN_REQ_SLEEP_TIME ); } deleteConnReqWaitMutex( &myConnReqWait ); }
// this routine will set the direction on the bus back to normal // (the way it was when the computer was switched on) boolean IEC::undoTurnAround(void) { writeDATA(true); delayMicroseconds(TIMING_BIT); writeCLOCK(false); delayMicroseconds(TIMING_BIT); // wait until the computer releases the clock line if(timeoutWait(m_clockPin, true)) return false; return true; } // undoTurnAround
// IEC turnaround boolean IEC::turnAround(void) { // Wait until clock is released if(timeoutWait(m_clockPin, false)) return false; writeDATA(false); delayMicroseconds(TIMING_BIT); writeCLOCK(true); delayMicroseconds(TIMING_BIT); return true; } // turnAround
// The underlying method for all high-level printing (e.g. println()). // The inherited Print class handles the rest! size_t Adafruit_Thermal::write(uint8_t c) { if(c != 0x13) { // Strip carriage returns timeoutWait(); stream->write(c); unsigned long d = BYTE_TIME; if((c == '\n') || (column == maxColumn)) { // If newline or wrap d += (prevByte == '\n') ? ((charHeight+lineSpacing) * dotFeedTime) : // Feed line ((charHeight*dotPrintTime)+(lineSpacing*dotFeedTime)); // Text line column = 0; c = '\n'; // Treat wrap as newline on next pass } else { column++; } timeoutSet(d); prevByte = c; } return 1; }
void Adafruit_Thermal::writeBytes(uint8_t a) { timeoutWait(); PRINTER_PRINT(a); timeoutSet(BYTE_TIME); }
size_t Adafruit_Thermal::write(uint8_t c) { #else void Adafruit_Thermal::write(uint8_t c) { #endif if(c != 0x13) { // Strip carriage returns timeoutWait(); PRINTER_PRINT(c); unsigned long d = BYTE_TIME; if((c == '\n') || (column == maxColumn)) { // If newline or wrap d += (prevByte == '\n') ? ((charHeight+lineSpacing) * dotFeedTime) : // Feed line ((charHeight*dotPrintTime)+(lineSpacing*dotFeedTime)); // Text line column = 0; c = '\n'; // Treat wrap as newline on next pass } else { column++; } timeoutSet(d); prevByte = c; } #if ARDUINO >= 100 return 1; #endif } void Adafruit_Thermal::begin(int heatTime) { _printer = new SERIAL_IMPL(_RX_Pin, _TX_Pin); _printer->begin(BAUDRATE); // The printer can't start receiving data immediately upon power up -- // it needs a moment to cold boot and initialize. Allow at least 1/2 // sec of uptime before printer can receive data. timeoutSet(500000); wake(); reset(); // Description of print settings from page 23 of the manual: // ESC 7 n1 n2 n3 Setting Control Parameter Command // Decimal: 27 55 n1 n2 n3 // Set "max heating dots", "heating time", "heating interval" // n1 = 0-255 Max printing dots, Unit (8dots), Default: 7 (64 dots) // n2 = 3-255 Heating time, Unit (10us), Default: 80 (800us) // n3 = 0-255 Heating interval, Unit (10us), Default: 2 (20us) // The more max heating dots, the more peak current will cost // when printing, the faster printing speed. The max heating // dots is 8*(n1+1). The more heating time, the more density, // but the slower printing speed. If heating time is too short, // blank page may occur. The more heating interval, the more // clear, but the slower printing speed. writeBytes(27, 55); // Esc 7 (print settings) writeBytes(20); // Heating dots (20=balance of darkness vs no jams) writeBytes(heatTime); // Library default = 255 (max) writeBytes(250); // Heat interval (500 uS = slower, but darker) // Description of print density from page 23 of the manual: // DC2 # n Set printing density // Decimal: 18 35 n // D4..D0 of n is used to set the printing density. Density is // 50% + 5% * n(D4-D0) printing density. // D7..D5 of n is used to set the printing break time. Break time // is n(D7-D5)*250us. // (Unsure of the default value for either -- not documented) #define printDensity 40 // 120% (? can go higher, text is darker but fuzzy) #define printBreakTime 4 // 500 uS writeBytes(18, 35); // DC2 # (print density) writeBytes((printBreakTime << 5) | printDensity); dotPrintTime = 30000; // See comments near top of file for dotFeedTime = 2100; // an explanation of these values. }
void connManager() { time_t curTime; iFuseConn_t *tmpIFuseConn; ListNode *node; List *TimeOutList = newListNoRegion(); while ( 1 ) { curTime = time( NULL ); /* exceed high water mark for number of connection ? */ if ( listSize( ConnectedConn ) > HIGH_NUM_CONN ) { LOCK_STRUCT( *ConnectedConn ); int disconnTarget = _listSize( ConnectedConn ) - HIGH_NUM_CONN; node = ConnectedConn->list->head; while ( node != NULL ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { listAppendNoRegion( TimeOutList, tmpIFuseConn ); } node = node->next; } UNLOCK_STRUCT( *ConnectedConn ); node = TimeOutList->head; int disconned = 0; while ( node != NULL && disconned < disconnTarget ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; LOCK_STRUCT( *tmpIFuseConn ); if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { removeFromConcurrentList2( FreeConn, tmpIFuseConn ); removeFromConcurrentList2( ConnectedConn, tmpIFuseConn ); if ( tmpIFuseConn->status == 0 ) { /* no struct is referring to it, we can unlock it and free it */ UNLOCK_STRUCT( *tmpIFuseConn ); /* rodsLog(LOG_ERROR, "[FREE IFUSE CONN] %s:%d %p", __FILE__, __LINE__, tmpIFuseConn); */ _freeIFuseConn( tmpIFuseConn ); } else { /* set to timed out */ _ifuseDisconnect( tmpIFuseConn ); UNLOCK_STRUCT( *tmpIFuseConn ); } disconned ++; } else { UNLOCK_STRUCT( *tmpIFuseConn ); } node = node->next; } clearListNoRegion( TimeOutList ); } while ( listSize( ConnectedConn ) <= MAX_NUM_CONN || listSize( FreeConn ) != 0 ) { /* signal one in the wait queue */ connReqWait_t *myConnReqWait = ( connReqWait_t * ) removeFirstElementOfConcurrentList( ConnReqWaitQue ); /* if there is no conn req left, exit loop */ if ( myConnReqWait == NULL ) { break; } myConnReqWait->state = 1; notifyTimeoutWait( &myConnReqWait->mutex, &myConnReqWait->cond ); } #if 0 rodsSleep( CONN_MANAGER_SLEEP_TIME, 0 ); #else timeoutWait( &ConnManagerLock, &ConnManagerCond, CONN_MANAGER_SLEEP_TIME ); #endif } deleteListNoRegion( TimeOutList ); }
// IEC Recieve byte standard function // // Returns data recieved // Might set flags in iec_state // // TODO: m_iec might be better returning bool and returning read byte as reference in order to indicate any error. byte IEC::receiveByte(void) { m_state = noFlags; // Wait for talker ready if(timeoutWait(m_clockPin, false)) { #ifdef CONSOLE_DEBUG // Log(Information, FAC_IEC, "T1"); #endif return 0; } // Say we're ready writeDATA(false); // Record how long CLOCK is high, more than 200 us means EOI byte n = 0; while(readCLOCK() and (n < 20)) { delayMicroseconds(10); // this loop should cycle in about 10 us... n++; } if(n >= TIMING_EOI_THRESH) { // EOI intermission m_state or_eq eoiFlag; // Acknowledge by pull down data more than 60 us writeDATA(true); delayMicroseconds(TIMING_BIT); writeDATA(false); // but still wait for clk if(timeoutWait(m_clockPin, true)) { #ifdef CONSOLE_DEBUG // Log(Information, FAC_IEC, "T2"); #endif return 0; } } // Sample ATN if(false == readATN()) m_state or_eq atnFlag; byte data = 0; // Get the bits, sampling on clock rising edge: for(n = 0; n < 8; n++) { data >>= 1; if(timeoutWait(m_clockPin, false)) { #ifdef CONSOLE_DEBUG // Log(Information, FAC_IEC, "T3"); #endif return 0; } data or_eq (readDATA() ? (1 << 7) : 0); if(timeoutWait(m_clockPin, true)) { #ifdef CONSOLE_DEBUG // Log(Information, FAC_IEC, "T4"); #endif return 0; } } // Signal we accepted data: writeDATA(true); return data; } // receiveByte
void Adafruit_Thermal::writeBytes(uint8_t a) { timeoutWait(); stream->write(a); timeoutSet(BYTE_TIME); }