// // The receive routine called by the interrupt handler // void SoftwareSerial::recv() { DebugPulse(_DEBUG_PIN2, 1); uint8_t d = 0; // If RX line is high, then we don't see any start bit // so interrupt is probably not for us if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) { // Disable further interrupts during reception, this prevents // triggering another interrupt directly after we return, which can // cause problems at higher baudrates. setRxIntMsk(false); // Wait approximately 1/2 of a bit width to "center" the sample tunedDelay(_rx_delay_centering); DebugPulse(_DEBUG_PIN2, 1); // Read each of the 8 bits for (uint8_t i = 8; i > 0; --i) { tunedDelay(_rx_delay_intrabit); d >>= 1; DebugPulse(_DEBUG_PIN2, 1); if (rx_pin_read()) d |= 0x80; } DebugPulse(_DEBUG_PIN2, 1); if (_inverse_logic) d = ~d; // if buffer full, set the overflow flag and return uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; if (next != _receive_buffer_head) { // save new data in buffer: tail points to where byte goes _receive_buffer[_receive_buffer_tail] = d; // save new byte _receive_buffer_tail = next; } else { DebugPulse(_DEBUG_PIN1, 1); _buffer_overflow = true; } // skip the stop bit tunedDelay(_rx_delay_stopbit); DebugPulse(_DEBUG_PIN1, 1); // Re-enable interrupts when we're sure to be inside the stop bit setRxIntMsk(true); }
// // The receive routine called by the interrupt handler // void SoftwareSerial::recv() { uint8_t d = 0; io_outpb(CROSSBARBASE + 0x90 + pinMap[_receivePin], 0x01); // switch to GPIO // If RX line is high, then we don't see any start bit // so interrupt is probably not for us if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) { // Wait approximately 1/2 of a bit width to "center" the sample tunedDelay(_rx_delay_centering); //DebugPulse(_DEBUG_PIN2, 1); // Read each of the 8 bits for (uint8_t i=0x1; i; i <<= 1) { tunedDelay(_rx_delay_intrabit); //DebugPulse(_DEBUG_PIN2, 1); uint8_t noti = ~i; if (rx_pin_read()) d |= i; else // else clause added to ensure function timing is ~balanced d &= noti; } // skip the stop bit tunedDelay(_rx_delay_stopbit); //DebugPulse(_DEBUG_PIN2, 1); if (_inverse_logic) d = ~d; // if buffer full, set the overflow flag and return if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head) { // save new data in buffer: tail points to where byte goes _receive_buffer[_receive_buffer_tail] = d; // save new byte _receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF; } else { _buffer_overflow = true; } } io_outpb(CROSSBARBASE + 0x90 + pinMap[_receivePin], 0x08); // switch to Encoder }
void EasyVRBridge::loop(uint8_t a_rx, uint8_t a_tx, uint8_t b_rx, uint8_t b_tx) { uint8_t rx_mask; volatile uint8_t *rx_reg; uint8_t tx_mask; volatile uint8_t *tx_reg; uint8_t vrx_mask; volatile uint8_t *vrx_reg; uint8_t vtx_mask; volatile uint8_t *vtx_reg; pinMode(a_rx, INPUT); digitalWrite(a_rx, HIGH); pinMode(a_tx, OUTPUT); digitalWrite(a_tx, HIGH); pinMode(b_rx, INPUT); digitalWrite(b_rx, HIGH); pinMode(b_tx, OUTPUT); digitalWrite(b_tx, HIGH); rx_mask = digitalPinToBitMask(a_rx); rx_reg = portInputRegister(digitalPinToPort(a_rx)); tx_mask = digitalPinToBitMask(a_tx); tx_reg = portOutputRegister(digitalPinToPort(a_tx)); vrx_mask = digitalPinToBitMask(b_rx); vrx_reg = portInputRegister(digitalPinToPort(b_rx)); vtx_mask = digitalPinToBitMask(b_tx); vtx_reg = portOutputRegister(digitalPinToPort(b_tx)); for (;;) { vtx_pin_write(rx_pin_read()); tx_pin_write(vrx_pin_read()); } }
void GSM3SoftSerial::recv() { bool firstByte=true; byte thisHead; uint8_t d = 0; bool morebytes=false; bool fullbuffer; bool capturado_fullbuffer = 0; int i; byte oldTail; // If RX line is high, then we don't see any start bit // so interrupt is probably not for us io_outpb(CROSSBARBASE + 0x90 + PIN86[__RXPIN__].gpN, 0x01); // switch to GPIO if (!rx_pin_read()) { do { oldTail=cb.getTail(); // Wait approximately 1/2 of a bit width to "center" the sample tunedDelay(_rx_delay_centering); fullbuffer=(cb.availableBytes()<6); if(fullbuffer&&(!capturado_fullbuffer)) tx_pin_write(LOW); // Read each of the 8 bits for (uint8_t i=0x1; i; i <<= 1) { tunedDelay(_rx_delay_intrabit); uint8_t noti = ~i; if (rx_pin_read()) d |= i; else // else clause added to ensure function timing is ~balanced d &= noti; if(fullbuffer&&(!capturado_fullbuffer)) { if((uint8_t)__XOFF__ & i) tx_pin_write(HIGH); else tx_pin_write(LOW); } } if(fullbuffer&&(!capturado_fullbuffer)) { tunedDelay(_rx_delay_intrabit); tx_pin_write(HIGH); } // So, we know the buffer is full, and we have sent a XOFF if (fullbuffer) { capturado_fullbuffer =1; _flags |=_GSMSOFTSERIALFLAGS_SENTXOFF_; } // skip the stop bit if (!fullbuffer) tunedDelay(_rx_delay_stopbit); if(keepThisChar(&d)) { cb.write(d); if(firstByte) { firstByte=false; thisHead=cb.getTail(); } } // This part is new. It is used to detect the end of a "paragraph" // Caveat: the old fashion would let processor a bit of time between bytes, // that here is lost // This active waiting avoids drifting morebytes=false; // TO-DO. This PARAGRAPHGUARD is empyric. We should test it for every speed for(i=0;i<__PARAGRAPHGUARD__;i++) { tunedDelay(1); if(!rx_pin_read()) { morebytes=true; break; } } }while(morebytes); // If we find a line feed, we are at the end of a paragraph // check! if (fullbuffer) { // And... go handle it! if(mgr) mgr->manageMsg(thisHead, cb.getTail()); } else if(d==10) { // And... go handle it! if(mgr) mgr->manageMsg(thisHead, cb.getTail()); } else if (d==32) { // And... go handle it! if(mgr) mgr->manageMsg(thisHead, cb.getTail()); } } io_outpb(CROSSBARBASE + 0x90 + PIN86[__RXPIN__].gpN, 0x08); // switch to Encoder }