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\\

Dependents:   SoftwareUART

Committer:
chag
Date:
Sat Mar 17 17:25:55 2012 +0000
Revision:
0:25b087be2989

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chag 0:25b087be2989 1 #include "mbed.h"
chag 0:25b087be2989 2 #include "SoftwareSerial.h"
chag 0:25b087be2989 3
chag 0:25b087be2989 4 namespace chag {
chag 0:25b087be2989 5
chag 0:25b087be2989 6 /*unsigned char SoftwareSerial::inbuf[SOFTWARE_SERIAL_RX_BUFFER_SIZE];
chag 0:25b087be2989 7 unsigned char SoftwareSerial::qin = 0;
chag 0:25b087be2989 8 unsigned char SoftwareSerial::qout = 0;
chag 0:25b087be2989 9 char SoftwareSerial::flag_rx_waiting_for_stop_bit;
chag 0:25b087be2989 10 char SoftwareSerial::flag_rx_off;
chag 0:25b087be2989 11 char SoftwareSerial::rx_mask;
chag 0:25b087be2989 12 char SoftwareSerial::flag_rx_ready;
chag 0:25b087be2989 13 char SoftwareSerial::flag_tx_ready;
chag 0:25b087be2989 14 char SoftwareSerial::timer_rx_ctr;
chag 0:25b087be2989 15 char SoftwareSerial::timer_tx_ctr;
chag 0:25b087be2989 16 char SoftwareSerial::bits_left_in_rx;
chag 0:25b087be2989 17 char SoftwareSerial::bits_left_in_tx;
chag 0:25b087be2989 18 char SoftwareSerial::rx_num_of_bits;
chag 0:25b087be2989 19 char SoftwareSerial::tx_num_of_bits;
chag 0:25b087be2989 20 char SoftwareSerial::internal_rx_buffer;
chag 0:25b087be2989 21 char SoftwareSerial::internal_tx_buffer;
chag 0:25b087be2989 22 char SoftwareSerial::user_tx_buffer;
chag 0:25b087be2989 23 */
chag 0:25b087be2989 24
chag 0:25b087be2989 25 DigitalOut led1(LED1);
chag 0:25b087be2989 26 DigitalOut led2(LED2);
chag 0:25b087be2989 27 DigitalOut led3(LED3);
chag 0:25b087be2989 28 DigitalOut led4(LED4);
chag 0:25b087be2989 29
chag 0:25b087be2989 30
chag 0:25b087be2989 31 SoftwareSerial::SoftwareSerial(PinName tx, PinName rx, const char *name) {
chag 0:25b087be2989 32 // save pins
chag 0:25b087be2989 33
chag 0:25b087be2989 34 this->tx = (tx == NC) ? (DigitalOut *)NULL : new DigitalOut(tx);
chag 0:25b087be2989 35 this->rx = (rx == NC) ? (DigitalIn *)NULL : new DigitalIn(rx);
chag 0:25b087be2989 36
chag 0:25b087be2989 37 flag_tx_ready = false;
chag 0:25b087be2989 38 flag_rx_ready = false;
chag 0:25b087be2989 39 flag_rx_waiting_for_stop_bit = false;
chag 0:25b087be2989 40 flag_rx_off = (rx == NC);
chag 0:25b087be2989 41 rx_num_of_bits = 10;
chag 0:25b087be2989 42 tx_num_of_bits = 10;
chag 0:25b087be2989 43
chag 0:25b087be2989 44 set_tx_pin_low();
chag 0:25b087be2989 45
chag 0:25b087be2989 46 baud(9600);
chag 0:25b087be2989 47 }
chag 0:25b087be2989 48
chag 0:25b087be2989 49 void SoftwareSerial::baud(int baudrate) {
chag 0:25b087be2989 50 baud_rate = baudrate;
chag 0:25b087be2989 51 ticker.detach();
chag 0:25b087be2989 52
chag 0:25b087be2989 53 ticker.attach_us(this, &SoftwareSerial::timer_isr, 1000000.0 / (baudrate * 3.0));
chag 0:25b087be2989 54
chag 0:25b087be2989 55 //timer_set( baud_rate ); // Sets the timer to 3 times the baud rate.
chag 0:25b087be2989 56 //set_timer_interrupt( &SoftwareSerial::timer_isr );
chag 0:25b087be2989 57 }
chag 0:25b087be2989 58
chag 0:25b087be2989 59 // putc, etc
chag 0:25b087be2989 60
chag 0:25b087be2989 61 int SoftwareSerial::readable() {
chag 0:25b087be2989 62 return( kbhit() );
chag 0:25b087be2989 63 }
chag 0:25b087be2989 64
chag 0:25b087be2989 65 int SoftwareSerial::writeable() {
chag 0:25b087be2989 66 return ( 1 );
chag 0:25b087be2989 67 }
chag 0:25b087be2989 68
chag 0:25b087be2989 69 // end
chag 0:25b087be2989 70
chag 0:25b087be2989 71
chag 0:25b087be2989 72 int SoftwareSerial::get_rx_pin_status() {
chag 0:25b087be2989 73 // Returns 0 or 1 dependent on whether the receive pin is high or low.
chag 0:25b087be2989 74 return( rx->read() );
chag 0:25b087be2989 75 }
chag 0:25b087be2989 76
chag 0:25b087be2989 77 void SoftwareSerial::set_tx_pin_high() {
chag 0:25b087be2989 78 // Sets the transmit pin to the high state.
chag 0:25b087be2989 79 tx->write(1);
chag 0:25b087be2989 80 //led4 = 1;
chag 0:25b087be2989 81 }
chag 0:25b087be2989 82
chag 0:25b087be2989 83 void SoftwareSerial::set_tx_pin_low() {
chag 0:25b087be2989 84 // Sets the transmit pin to the low state.
chag 0:25b087be2989 85 tx->write(0);
chag 0:25b087be2989 86 //led4 = 0;
chag 0:25b087be2989 87 }
chag 0:25b087be2989 88
chag 0:25b087be2989 89 void SoftwareSerial::idle() {
chag 0:25b087be2989 90 // Background functions to execute while waiting for input.
chag 0:25b087be2989 91
chag 0:25b087be2989 92 }
chag 0:25b087be2989 93
chag 0:25b087be2989 94
chag 0:25b087be2989 95 // protected/private members
chag 0:25b087be2989 96
chag 0:25b087be2989 97 void SoftwareSerial::timer_isr( void ) {
chag 0:25b087be2989 98 char mask, start_bit, flag_in;
chag 0:25b087be2989 99
chag 0:25b087be2989 100 // Transmitter Section
chag 0:25b087be2989 101 if ( flag_tx_ready ) {
chag 0:25b087be2989 102 if( --timer_tx_ctr<=0 ) {
chag 0:25b087be2989 103 mask = internal_tx_buffer&1;
chag 0:25b087be2989 104 internal_tx_buffer >>= 1;
chag 0:25b087be2989 105 if ( mask ) {
chag 0:25b087be2989 106 set_tx_pin_high();
chag 0:25b087be2989 107 } else {
chag 0:25b087be2989 108 set_tx_pin_low();
chag 0:25b087be2989 109 }
chag 0:25b087be2989 110 timer_tx_ctr = 3;
chag 0:25b087be2989 111 if ( --bits_left_in_tx<=0 ) {
chag 0:25b087be2989 112 flag_tx_ready = false;
chag 0:25b087be2989 113 }
chag 0:25b087be2989 114 }
chag 0:25b087be2989 115 }
chag 0:25b087be2989 116
chag 0:25b087be2989 117 // Receiver Section
chag 0:25b087be2989 118 if ( flag_rx_off==false ) {
chag 0:25b087be2989 119 if ( flag_rx_waiting_for_stop_bit ) {
chag 0:25b087be2989 120 if ( --timer_rx_ctr<=0 ) {
chag 0:25b087be2989 121 flag_rx_waiting_for_stop_bit = false;
chag 0:25b087be2989 122 flag_rx_ready = false;
chag 0:25b087be2989 123 internal_rx_buffer &= 0xFF;
chag 0:25b087be2989 124 if ( internal_rx_buffer!=0xC2 ) {
chag 0:25b087be2989 125 inbuf[qin] = internal_rx_buffer;
chag 0:25b087be2989 126 if ( ++qin>=SOFTWARE_SERIAL_RX_BUFFER_SIZE ) {
chag 0:25b087be2989 127 qin = 0;
chag 0:25b087be2989 128 }
chag 0:25b087be2989 129 }
chag 0:25b087be2989 130 }
chag 0:25b087be2989 131 } else { // rx_test_busy
chag 0:25b087be2989 132 if ( flag_rx_ready==false ) {
chag 0:25b087be2989 133 start_bit = get_rx_pin_status();
chag 0:25b087be2989 134 // Test for Start Bit
chag 0:25b087be2989 135 if ( start_bit==0 ) {
chag 0:25b087be2989 136 flag_rx_ready = true;
chag 0:25b087be2989 137 internal_rx_buffer = 0;
chag 0:25b087be2989 138 timer_rx_ctr = 4;
chag 0:25b087be2989 139 bits_left_in_rx = rx_num_of_bits;
chag 0:25b087be2989 140 rx_mask = 1;
chag 0:25b087be2989 141 }
chag 0:25b087be2989 142 } else { // rx_busy
chag 0:25b087be2989 143 if ( --timer_rx_ctr<=0 ) { // rcv
chag 0:25b087be2989 144 timer_rx_ctr = 3;
chag 0:25b087be2989 145 flag_in = get_rx_pin_status();
chag 0:25b087be2989 146 if ( flag_in ) {
chag 0:25b087be2989 147 internal_rx_buffer |= rx_mask;
chag 0:25b087be2989 148 }
chag 0:25b087be2989 149 rx_mask <<= 1;
chag 0:25b087be2989 150 if ( --bits_left_in_rx<=0 ) {
chag 0:25b087be2989 151 flag_rx_waiting_for_stop_bit = true;
chag 0:25b087be2989 152 }
chag 0:25b087be2989 153 }
chag 0:25b087be2989 154 }
chag 0:25b087be2989 155 }
chag 0:25b087be2989 156 }
chag 0:25b087be2989 157 }
chag 0:25b087be2989 158
chag 0:25b087be2989 159 int SoftwareSerial::getc( void ) {
chag 0:25b087be2989 160 char ch;
chag 0:25b087be2989 161
chag 0:25b087be2989 162 do {
chag 0:25b087be2989 163 while ( qout==qin ) {
chag 0:25b087be2989 164 idle();
chag 0:25b087be2989 165 }
chag 0:25b087be2989 166 ch = inbuf[qout] & 0xFF;
chag 0:25b087be2989 167 if ( ++qout>=SOFTWARE_SERIAL_RX_BUFFER_SIZE ) {
chag 0:25b087be2989 168 qout = 0;
chag 0:25b087be2989 169 }
chag 0:25b087be2989 170 } while ( ch==0x0A || ch==0xC2 );
chag 0:25b087be2989 171 return( (int)ch );
chag 0:25b087be2989 172 }
chag 0:25b087be2989 173
chag 0:25b087be2989 174 int SoftwareSerial::putc( int c ) {
chag 0:25b087be2989 175 led1 = !led1;
chag 0:25b087be2989 176 while ( flag_tx_ready );
chag 0:25b087be2989 177 user_tx_buffer = c;
chag 0:25b087be2989 178
chag 0:25b087be2989 179 // invoke_UART_transmit
chag 0:25b087be2989 180 timer_tx_ctr = 3;
chag 0:25b087be2989 181 bits_left_in_tx = tx_num_of_bits;
chag 0:25b087be2989 182 internal_tx_buffer = (user_tx_buffer<<1) | 0x200;
chag 0:25b087be2989 183 flag_tx_ready = true;
chag 0:25b087be2989 184 return(1);
chag 0:25b087be2989 185 }
chag 0:25b087be2989 186
chag 0:25b087be2989 187 void SoftwareSerial::flush_input_buffer( void ) {
chag 0:25b087be2989 188 qin = 0;
chag 0:25b087be2989 189 qout = 0;
chag 0:25b087be2989 190 }
chag 0:25b087be2989 191
chag 0:25b087be2989 192 char SoftwareSerial::kbhit( void ) {
chag 0:25b087be2989 193 return( qin!=qout );
chag 0:25b087be2989 194 }
chag 0:25b087be2989 195
chag 0:25b087be2989 196 void SoftwareSerial::turn_rx_on( void ) {
chag 0:25b087be2989 197 flag_rx_off = false;
chag 0:25b087be2989 198 }
chag 0:25b087be2989 199
chag 0:25b087be2989 200 void SoftwareSerial::turn_rx_off( void ) {
chag 0:25b087be2989 201 flag_rx_off = true;
chag 0:25b087be2989 202 }
chag 0:25b087be2989 203
chag 0:25b087be2989 204
chag 0:25b087be2989 205 } // end namespace