ALPHA WORK IN PROGRESS. DO NOT USE IN PRODUCTION CODE. based on:\\ IAR Application Note G - 001 Generic Software UART\\ mbed/trunk/Serial.h\\ the venerable Andy Kirkham's MAX3100\\
SoftwareSerial.cpp
00001 #include "mbed.h" 00002 #include "SoftwareSerial.h" 00003 00004 namespace chag { 00005 00006 /*unsigned char SoftwareSerial::inbuf[SOFTWARE_SERIAL_RX_BUFFER_SIZE]; 00007 unsigned char SoftwareSerial::qin = 0; 00008 unsigned char SoftwareSerial::qout = 0; 00009 char SoftwareSerial::flag_rx_waiting_for_stop_bit; 00010 char SoftwareSerial::flag_rx_off; 00011 char SoftwareSerial::rx_mask; 00012 char SoftwareSerial::flag_rx_ready; 00013 char SoftwareSerial::flag_tx_ready; 00014 char SoftwareSerial::timer_rx_ctr; 00015 char SoftwareSerial::timer_tx_ctr; 00016 char SoftwareSerial::bits_left_in_rx; 00017 char SoftwareSerial::bits_left_in_tx; 00018 char SoftwareSerial::rx_num_of_bits; 00019 char SoftwareSerial::tx_num_of_bits; 00020 char SoftwareSerial::internal_rx_buffer; 00021 char SoftwareSerial::internal_tx_buffer; 00022 char SoftwareSerial::user_tx_buffer; 00023 */ 00024 00025 DigitalOut led1(LED1); 00026 DigitalOut led2(LED2); 00027 DigitalOut led3(LED3); 00028 DigitalOut led4(LED4); 00029 00030 00031 SoftwareSerial::SoftwareSerial(PinName tx, PinName rx, const char *name) { 00032 // save pins 00033 00034 this->tx = (tx == NC) ? (DigitalOut *)NULL : new DigitalOut(tx); 00035 this->rx = (rx == NC) ? (DigitalIn *)NULL : new DigitalIn(rx); 00036 00037 flag_tx_ready = false; 00038 flag_rx_ready = false; 00039 flag_rx_waiting_for_stop_bit = false; 00040 flag_rx_off = (rx == NC); 00041 rx_num_of_bits = 10; 00042 tx_num_of_bits = 10; 00043 00044 set_tx_pin_low(); 00045 00046 baud(9600); 00047 } 00048 00049 void SoftwareSerial::baud(int baudrate) { 00050 baud_rate = baudrate; 00051 ticker.detach(); 00052 00053 ticker.attach_us(this, &SoftwareSerial::timer_isr, 1000000.0 / (baudrate * 3.0)); 00054 00055 //timer_set( baud_rate ); // Sets the timer to 3 times the baud rate. 00056 //set_timer_interrupt( &SoftwareSerial::timer_isr ); 00057 } 00058 00059 // putc, etc 00060 00061 int SoftwareSerial::readable() { 00062 return( kbhit() ); 00063 } 00064 00065 int SoftwareSerial::writeable() { 00066 return ( 1 ); 00067 } 00068 00069 // end 00070 00071 00072 int SoftwareSerial::get_rx_pin_status() { 00073 // Returns 0 or 1 dependent on whether the receive pin is high or low. 00074 return( rx->read() ); 00075 } 00076 00077 void SoftwareSerial::set_tx_pin_high() { 00078 // Sets the transmit pin to the high state. 00079 tx->write(1); 00080 //led4 = 1; 00081 } 00082 00083 void SoftwareSerial::set_tx_pin_low() { 00084 // Sets the transmit pin to the low state. 00085 tx->write(0); 00086 //led4 = 0; 00087 } 00088 00089 void SoftwareSerial::idle() { 00090 // Background functions to execute while waiting for input. 00091 00092 } 00093 00094 00095 // protected/private members 00096 00097 void SoftwareSerial::timer_isr( void ) { 00098 char mask, start_bit, flag_in; 00099 00100 // Transmitter Section 00101 if ( flag_tx_ready ) { 00102 if( --timer_tx_ctr<=0 ) { 00103 mask = internal_tx_buffer&1; 00104 internal_tx_buffer >>= 1; 00105 if ( mask ) { 00106 set_tx_pin_high(); 00107 } else { 00108 set_tx_pin_low(); 00109 } 00110 timer_tx_ctr = 3; 00111 if ( --bits_left_in_tx<=0 ) { 00112 flag_tx_ready = false; 00113 } 00114 } 00115 } 00116 00117 // Receiver Section 00118 if ( flag_rx_off==false ) { 00119 if ( flag_rx_waiting_for_stop_bit ) { 00120 if ( --timer_rx_ctr<=0 ) { 00121 flag_rx_waiting_for_stop_bit = false; 00122 flag_rx_ready = false; 00123 internal_rx_buffer &= 0xFF; 00124 if ( internal_rx_buffer!=0xC2 ) { 00125 inbuf[qin] = internal_rx_buffer; 00126 if ( ++qin>=SOFTWARE_SERIAL_RX_BUFFER_SIZE ) { 00127 qin = 0; 00128 } 00129 } 00130 } 00131 } else { // rx_test_busy 00132 if ( flag_rx_ready==false ) { 00133 start_bit = get_rx_pin_status(); 00134 // Test for Start Bit 00135 if ( start_bit==0 ) { 00136 flag_rx_ready = true; 00137 internal_rx_buffer = 0; 00138 timer_rx_ctr = 4; 00139 bits_left_in_rx = rx_num_of_bits; 00140 rx_mask = 1; 00141 } 00142 } else { // rx_busy 00143 if ( --timer_rx_ctr<=0 ) { // rcv 00144 timer_rx_ctr = 3; 00145 flag_in = get_rx_pin_status(); 00146 if ( flag_in ) { 00147 internal_rx_buffer |= rx_mask; 00148 } 00149 rx_mask <<= 1; 00150 if ( --bits_left_in_rx<=0 ) { 00151 flag_rx_waiting_for_stop_bit = true; 00152 } 00153 } 00154 } 00155 } 00156 } 00157 } 00158 00159 int SoftwareSerial::getc( void ) { 00160 char ch; 00161 00162 do { 00163 while ( qout==qin ) { 00164 idle(); 00165 } 00166 ch = inbuf[qout] & 0xFF; 00167 if ( ++qout>=SOFTWARE_SERIAL_RX_BUFFER_SIZE ) { 00168 qout = 0; 00169 } 00170 } while ( ch==0x0A || ch==0xC2 ); 00171 return( (int)ch ); 00172 } 00173 00174 int SoftwareSerial::putc( int c ) { 00175 led1 = !led1; 00176 while ( flag_tx_ready ); 00177 user_tx_buffer = c; 00178 00179 // invoke_UART_transmit 00180 timer_tx_ctr = 3; 00181 bits_left_in_tx = tx_num_of_bits; 00182 internal_tx_buffer = (user_tx_buffer<<1) | 0x200; 00183 flag_tx_ready = true; 00184 return(1); 00185 } 00186 00187 void SoftwareSerial::flush_input_buffer( void ) { 00188 qin = 0; 00189 qout = 0; 00190 } 00191 00192 char SoftwareSerial::kbhit( void ) { 00193 return( qin!=qout ); 00194 } 00195 00196 void SoftwareSerial::turn_rx_on( void ) { 00197 flag_rx_off = false; 00198 } 00199 00200 void SoftwareSerial::turn_rx_off( void ) { 00201 flag_rx_off = true; 00202 } 00203 00204 00205 } // end namespace
Generated on Tue Jul 12 2022 21:57:00 by 1.7.2