UniverSpace 2022 / Mbed 2 deprecated IniSat_TP5_Trame

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers soft_uart.cpp Source File

soft_uart.cpp

00001 // Software UART
00002 //
00003 // Generic software uart written in C, requiring a timer set to 3 times
00004 // the baud rate, and two software read/write pins for the receive and
00005 // transmit functions.
00006 //
00007 // * Received characters are buffered
00008 // * putchar(), getchar(), kbhit() and flush_input_buffer() are available
00009 // * There is a facility for background processing while waiting for input
00010 //
00011 // Colin Gittins, Software Engineer, Halliburton Energy Services
00012 //
00013 // The baud rate can be configured by changing the BAUD_RATE macro as
00014 // follows:
00015 //
00016 // #define BAUD_RATE            19200.0
00017 //
00018 // The function init_uart() must be called before any comms can take place
00019 //
00020 // Interface routines required:
00021 // 1. get_rx_pin_status()
00022 //    Returns 0 or 1 dependent on whether the receive pin is high or low.
00023 // 2. set_tx_pin_high()
00024 //    Sets the transmit pin to the high state.
00025 // 3. set_tx_pin_low()
00026 //    Sets the transmit pin to the low state.
00027 // 4. idle()
00028 //    Background functions to execute while waiting for input.
00029 // 5. timer_set( BAUD_RATE )
00030 //    Sets the timer to 3 times the baud rate.
00031 // 6. set_timer_interrupt( timer_isr )
00032 //    Enables the timer interrupt.
00033 //
00034 // Functions provided:
00035 // 1. void flush_input_buffer( void )
00036 //    Clears the contents of the input buffer.
00037 // 2. char kbhit( void )
00038 //    Tests whether an input character has been received.
00039 // 3. char getchar( void )
00040 //    Reads a character from the input buffer, waiting if necessary.
00041 // 4. void turn_rx_on( void )
00042 //    Turns on the receive function.
00043 // 5. void turn_rx_off( void )
00044 //    Turns off the receive function.
00045 // 6. void putchar( char )
00046 //    Writes a character to the serial port.
00047 #include "mbed.h"
00048 #include <stdio.h>
00049  
00050 #define BAUD_RATE       9600
00051 #define IN_BUF_SIZE     256
00052  
00053 #define TRUE 1
00054 #define FALSE 0
00055  
00056 static unsigned char        inbuf[IN_BUF_SIZE];
00057 static unsigned char        qin = 0;
00058 static unsigned char        qout = 0;
00059  
00060 static char             flag_rx_waiting_for_stop_bit;
00061 static char             flag_rx_off;
00062 static char             rx_mask;
00063 static char             flag_rx_ready;
00064 static char             flag_tx_ready;
00065 static char             timer_rx_ctr;
00066 static char             timer_tx_ctr;
00067 static char             bits_left_in_rx;
00068 static char             bits_left_in_tx;
00069 static char             rx_num_of_bits;
00070 static char             tx_num_of_bits;
00071 static int              internal_rx_buffer;
00072 static int              internal_tx_buffer;
00073 static int              user_tx_buffer;
00074  
00075 DigitalOut TX(PA_4);
00076 DigitalIn RX(PA_3);
00077 Ticker ticker;
00078 
00079 //Background functions to execute while waiting for input.
00080 void idle(){
00081     wait_us(0.2);
00082 }
00083  
00084 //Sets the transmit pin to the high state.
00085 void set_tx_pin_high() {
00086     TX = 1;
00087 }
00088  
00089 //Sets the transmit pin to the low state.
00090 void set_tx_pin_low() {
00091     TX = 0;
00092 }
00093  
00094 //Returns 0 or 1 dependent on whether the receive pin is high or low
00095 int get_rx_pin_status() {
00096     return RX.read();
00097 }
00098  
00099 void timer_isr(void) {
00100     
00101 char mask, start_bit, flag_in;
00102  
00103 // Transmitter Section
00104     if ( flag_tx_ready )
00105     {
00106         
00107         if ( --timer_tx_ctr <= 0 )
00108         {
00109             mask = internal_tx_buffer&1;
00110             internal_tx_buffer >>= 1;
00111             if ( mask )
00112             {
00113                 set_tx_pin_high();          
00114             }
00115             else
00116             {
00117                 set_tx_pin_low();
00118             }
00119             timer_tx_ctr = 3;
00120             if ( --bits_left_in_tx <= 0 )
00121             {
00122                 flag_tx_ready = FALSE;
00123             }
00124         }
00125     }
00126 // Receiver Section
00127     if ( flag_rx_off == FALSE )
00128         {
00129         if ( flag_rx_waiting_for_stop_bit )
00130             {
00131             if ( --timer_rx_ctr <= 0 )
00132                 {
00133                 flag_rx_waiting_for_stop_bit = FALSE;
00134                 flag_rx_ready = FALSE;
00135                 internal_rx_buffer &= 0xFF;
00136                 if ( internal_rx_buffer != 0xC2 )
00137                     {
00138                     inbuf[qin] = internal_rx_buffer;
00139                     if ( ++qin >= IN_BUF_SIZE )
00140                         {
00141                             qin = 0;
00142                         }
00143                     }
00144                 }
00145             }
00146         else        // rx_test_busy
00147             {
00148             if ( flag_rx_ready==FALSE )
00149                 {
00150                 start_bit = get_rx_pin_status();
00151 // Test for Start Bit
00152                 if ( start_bit == 0 )
00153                     {
00154                     flag_rx_ready = TRUE;
00155                     internal_rx_buffer = 0;
00156                     timer_rx_ctr = 4;
00157                     bits_left_in_rx = rx_num_of_bits;
00158                     rx_mask = 1;
00159                     }
00160                 }
00161             else    // rx_busy
00162                 {
00163                 if ( --timer_rx_ctr<=0 )
00164                     {               // rcv
00165                     timer_rx_ctr = 3;
00166                     flag_in = get_rx_pin_status();
00167                     if ( flag_in )
00168                         {
00169                         internal_rx_buffer |= rx_mask;
00170                         }
00171                     rx_mask <<= 1;
00172                     if ( --bits_left_in_rx<=0 )
00173                         {
00174                         flag_rx_waiting_for_stop_bit = TRUE;
00175                         }
00176                     }
00177                 }
00178             }
00179         }
00180     }
00181  
00182 void Init_Soft_UART(void) {
00183     flag_tx_ready = FALSE;
00184     flag_rx_ready = FALSE;
00185     flag_rx_waiting_for_stop_bit = FALSE;
00186     flag_rx_off = FALSE;
00187     rx_num_of_bits = 8;     //10
00188     tx_num_of_bits = 10;     //10
00189  
00190     set_tx_pin_high();
00191     ticker.attach_us(&timer_isr, 1000000.0 / (BAUD_RATE * 3.0));
00192     }
00193  
00194 char _getchar(void) {
00195     char        ch;
00196     do
00197         {
00198         while (qout == qin)
00199             {
00200             idle();
00201             }
00202         ch = inbuf[qout] & 0xFF;
00203         if (++qout >= IN_BUF_SIZE)
00204             {
00205             qout = 0;
00206             }
00207         }
00208     while (ch == 0x0A || ch == 0xC2);
00209     return(ch);
00210     }
00211  
00212 void _putchar(char ch) {
00213     while ( flag_tx_ready );
00214     user_tx_buffer = ch;
00215  
00216 // invoke_UART_transmit
00217     timer_tx_ctr = 3;
00218     bits_left_in_tx = tx_num_of_bits;
00219     internal_tx_buffer = (user_tx_buffer<<1) | 0x200;;
00220     flag_tx_ready = TRUE;
00221     }
00222  
00223 void flush_input_buffer(void) {
00224     qin = 0;
00225     qout = 0;
00226     }
00227  
00228 char kbhit(void) {
00229     return( qin!=qout );
00230     }
00231  
00232 void turn_rx_on(void) {
00233     flag_rx_off = FALSE;
00234     }
00235  
00236 void turn_rx_off(void) {
00237     flag_rx_off = TRUE;
00238     }
00239     
00240 void printStr(char* str) {
00241     int i = 0;
00242     int len = strlen(str); 
00243     for(i = 0; i<len; i++){
00244         wait(0.01);
00245         _putchar(str[i]);
00246     }
00247 }
00248