soft serial ok with GPS

Dependencies:   mbed

Committer:
eric11fr
Date:
Sun May 10 21:31:58 2020 +0000
Revision:
0:a563059f0473
serial_uart_ok with GPS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eric11fr 0:a563059f0473 1 #include "mbed.h"
eric11fr 0:a563059f0473 2
eric11fr 0:a563059f0473 3 // UART.C
eric11fr 0:a563059f0473 4 //
eric11fr 0:a563059f0473 5 // Generic software uart written in C, requiring a timer set to 3 times
eric11fr 0:a563059f0473 6 // the baud rate, and two software read/write pins for the receive and
eric11fr 0:a563059f0473 7 // transmit functions.
eric11fr 0:a563059f0473 8 //
eric11fr 0:a563059f0473 9 // * Received characters are buffered
eric11fr 0:a563059f0473 10 // * putchar(), getchar(), kbhit() and flush_input_buffer() are available
eric11fr 0:a563059f0473 11 // * There is a facility for background processing while waiting for input
eric11fr 0:a563059f0473 12 //
eric11fr 0:a563059f0473 13 // Colin Gittins, Software Engineer, Halliburton Energy Services
eric11fr 0:a563059f0473 14 //
eric11fr 0:a563059f0473 15 // The baud rate can be configured by changing the BAUD_RATE macro as
eric11fr 0:a563059f0473 16 // follows:
eric11fr 0:a563059f0473 17 //
eric11fr 0:a563059f0473 18 // #define BAUD_RATE 19200.0
eric11fr 0:a563059f0473 19 //
eric11fr 0:a563059f0473 20 // The function init_uart() must be called before any comms can take place
eric11fr 0:a563059f0473 21 //
eric11fr 0:a563059f0473 22 // Interface routines required:
eric11fr 0:a563059f0473 23 // 1. get_rx_pin_status()
eric11fr 0:a563059f0473 24 // Returns 0 or 1 dependent on whether the receive pin is high or low.
eric11fr 0:a563059f0473 25 // 2. set_tx_pin_high()
eric11fr 0:a563059f0473 26 // Sets the transmit pin to the high state.
eric11fr 0:a563059f0473 27 // 3. set_tx_pin_low()
eric11fr 0:a563059f0473 28 // Sets the transmit pin to the low state.
eric11fr 0:a563059f0473 29 // 4. idle()
eric11fr 0:a563059f0473 30 // Background functions to execute while waiting for input.
eric11fr 0:a563059f0473 31 // 5. timer_set( BAUD_RATE )
eric11fr 0:a563059f0473 32 // Sets the timer to 3 times the baud rate.
eric11fr 0:a563059f0473 33 // 6. set_timer_interrupt( timer_isr )
eric11fr 0:a563059f0473 34 // Enables the timer interrupt.
eric11fr 0:a563059f0473 35 //
eric11fr 0:a563059f0473 36 // Functions provided:
eric11fr 0:a563059f0473 37 // 1. void flush_input_buffer( void )
eric11fr 0:a563059f0473 38 // Clears the contents of the input buffer.
eric11fr 0:a563059f0473 39 // 2. char kbhit( void )
eric11fr 0:a563059f0473 40 // Tests whether an input character has been received.
eric11fr 0:a563059f0473 41 // 3. char getchar( void )
eric11fr 0:a563059f0473 42 // Reads a character from the input buffer, waiting if necessary.
eric11fr 0:a563059f0473 43 // 4. void turn_rx_on( void )
eric11fr 0:a563059f0473 44 // Turns on the receive function.
eric11fr 0:a563059f0473 45 // 5. void turn_rx_off( void )
eric11fr 0:a563059f0473 46 // Turns off the receive function.
eric11fr 0:a563059f0473 47 // 6. void putchar( char )
eric11fr 0:a563059f0473 48 // Writes a character to the serial port.
eric11fr 0:a563059f0473 49
eric11fr 0:a563059f0473 50 #include <stdio.h>
eric11fr 0:a563059f0473 51
eric11fr 0:a563059f0473 52 #define BAUD_RATE 9600
eric11fr 0:a563059f0473 53 #define IN_BUF_SIZE 256
eric11fr 0:a563059f0473 54
eric11fr 0:a563059f0473 55 #define TRUE 1
eric11fr 0:a563059f0473 56 #define FALSE 0
eric11fr 0:a563059f0473 57
eric11fr 0:a563059f0473 58 static unsigned char inbuf[IN_BUF_SIZE];
eric11fr 0:a563059f0473 59 static unsigned char qin = 0;
eric11fr 0:a563059f0473 60 static unsigned char qout = 0;
eric11fr 0:a563059f0473 61
eric11fr 0:a563059f0473 62 static char flag_rx_waiting_for_stop_bit;
eric11fr 0:a563059f0473 63 static char flag_rx_off;
eric11fr 0:a563059f0473 64 static char rx_mask;
eric11fr 0:a563059f0473 65 static char flag_rx_ready;
eric11fr 0:a563059f0473 66 static char flag_tx_ready;
eric11fr 0:a563059f0473 67 static char timer_rx_ctr;
eric11fr 0:a563059f0473 68 static char timer_tx_ctr;
eric11fr 0:a563059f0473 69 static char bits_left_in_rx;
eric11fr 0:a563059f0473 70 static char bits_left_in_tx;
eric11fr 0:a563059f0473 71 static char rx_num_of_bits;
eric11fr 0:a563059f0473 72 static char tx_num_of_bits;
eric11fr 0:a563059f0473 73 static int internal_rx_buffer;
eric11fr 0:a563059f0473 74 static int internal_tx_buffer;
eric11fr 0:a563059f0473 75 static int user_tx_buffer;
eric11fr 0:a563059f0473 76
eric11fr 0:a563059f0473 77 DigitalOut TX(D4);
eric11fr 0:a563059f0473 78 DigitalIn RX(D3);
eric11fr 0:a563059f0473 79 Ticker ticker;
eric11fr 0:a563059f0473 80
eric11fr 0:a563059f0473 81 Serial pc(USBTX, USBRX);
eric11fr 0:a563059f0473 82
eric11fr 0:a563059f0473 83
eric11fr 0:a563059f0473 84 //Background functions to execute while waiting for input.
eric11fr 0:a563059f0473 85 void idle(){
eric11fr 0:a563059f0473 86 wait_us(0.2);
eric11fr 0:a563059f0473 87 }
eric11fr 0:a563059f0473 88
eric11fr 0:a563059f0473 89 //Sets the transmit pin to the high state.
eric11fr 0:a563059f0473 90 void set_tx_pin_high() {
eric11fr 0:a563059f0473 91 TX = 1;
eric11fr 0:a563059f0473 92 }
eric11fr 0:a563059f0473 93
eric11fr 0:a563059f0473 94 //Sets the transmit pin to the low state.
eric11fr 0:a563059f0473 95 void set_tx_pin_low() {
eric11fr 0:a563059f0473 96 TX = 0;
eric11fr 0:a563059f0473 97 }
eric11fr 0:a563059f0473 98
eric11fr 0:a563059f0473 99 //Returns 0 or 1 dependent on whether the receive pin is high or low
eric11fr 0:a563059f0473 100 int get_rx_pin_status() {
eric11fr 0:a563059f0473 101 return RX.read();
eric11fr 0:a563059f0473 102 }
eric11fr 0:a563059f0473 103
eric11fr 0:a563059f0473 104 void timer_isr(void)
eric11fr 0:a563059f0473 105 {
eric11fr 0:a563059f0473 106 char mask, start_bit, flag_in;
eric11fr 0:a563059f0473 107
eric11fr 0:a563059f0473 108
eric11fr 0:a563059f0473 109 // Transmitter Section
eric11fr 0:a563059f0473 110 if ( flag_tx_ready )
eric11fr 0:a563059f0473 111 {
eric11fr 0:a563059f0473 112
eric11fr 0:a563059f0473 113 if ( --timer_tx_ctr<=0 )
eric11fr 0:a563059f0473 114 {
eric11fr 0:a563059f0473 115 mask = internal_tx_buffer&1;
eric11fr 0:a563059f0473 116 internal_tx_buffer >>= 1;
eric11fr 0:a563059f0473 117 if ( mask )
eric11fr 0:a563059f0473 118 {
eric11fr 0:a563059f0473 119 set_tx_pin_high();
eric11fr 0:a563059f0473 120 }
eric11fr 0:a563059f0473 121 else
eric11fr 0:a563059f0473 122 {
eric11fr 0:a563059f0473 123 set_tx_pin_low();
eric11fr 0:a563059f0473 124 }
eric11fr 0:a563059f0473 125 timer_tx_ctr = 3;
eric11fr 0:a563059f0473 126 if ( --bits_left_in_tx<=0 )
eric11fr 0:a563059f0473 127 {
eric11fr 0:a563059f0473 128 flag_tx_ready = FALSE;
eric11fr 0:a563059f0473 129 }
eric11fr 0:a563059f0473 130 }
eric11fr 0:a563059f0473 131 }
eric11fr 0:a563059f0473 132 // Receiver Section
eric11fr 0:a563059f0473 133 if ( flag_rx_off==FALSE )
eric11fr 0:a563059f0473 134 {
eric11fr 0:a563059f0473 135 if ( flag_rx_waiting_for_stop_bit )
eric11fr 0:a563059f0473 136 {
eric11fr 0:a563059f0473 137 if ( --timer_rx_ctr<=0 )
eric11fr 0:a563059f0473 138 {
eric11fr 0:a563059f0473 139 flag_rx_waiting_for_stop_bit = FALSE;
eric11fr 0:a563059f0473 140 flag_rx_ready = FALSE;
eric11fr 0:a563059f0473 141 internal_rx_buffer &= 0xFF;
eric11fr 0:a563059f0473 142 if ( internal_rx_buffer!=0xC2 )
eric11fr 0:a563059f0473 143 {
eric11fr 0:a563059f0473 144 inbuf[qin] = internal_rx_buffer;
eric11fr 0:a563059f0473 145 if ( ++qin>=IN_BUF_SIZE )
eric11fr 0:a563059f0473 146 {
eric11fr 0:a563059f0473 147 qin = 0;
eric11fr 0:a563059f0473 148 }
eric11fr 0:a563059f0473 149 }
eric11fr 0:a563059f0473 150 }
eric11fr 0:a563059f0473 151 }
eric11fr 0:a563059f0473 152 else // rx_test_busy
eric11fr 0:a563059f0473 153 {
eric11fr 0:a563059f0473 154 if ( flag_rx_ready==FALSE )
eric11fr 0:a563059f0473 155 {
eric11fr 0:a563059f0473 156 start_bit = get_rx_pin_status();
eric11fr 0:a563059f0473 157 // Test for Start Bit
eric11fr 0:a563059f0473 158 if ( start_bit==0 )
eric11fr 0:a563059f0473 159 {
eric11fr 0:a563059f0473 160 flag_rx_ready = TRUE;
eric11fr 0:a563059f0473 161 internal_rx_buffer = 0;
eric11fr 0:a563059f0473 162 timer_rx_ctr = 4;
eric11fr 0:a563059f0473 163 bits_left_in_rx = rx_num_of_bits;
eric11fr 0:a563059f0473 164 rx_mask = 1;
eric11fr 0:a563059f0473 165 }
eric11fr 0:a563059f0473 166 }
eric11fr 0:a563059f0473 167 else // rx_busy
eric11fr 0:a563059f0473 168 {
eric11fr 0:a563059f0473 169 if ( --timer_rx_ctr<=0 )
eric11fr 0:a563059f0473 170 { // rcv
eric11fr 0:a563059f0473 171 timer_rx_ctr = 3;
eric11fr 0:a563059f0473 172 flag_in = get_rx_pin_status();
eric11fr 0:a563059f0473 173 if ( flag_in )
eric11fr 0:a563059f0473 174 {
eric11fr 0:a563059f0473 175 internal_rx_buffer |= rx_mask;
eric11fr 0:a563059f0473 176 }
eric11fr 0:a563059f0473 177 rx_mask <<= 1;
eric11fr 0:a563059f0473 178 if ( --bits_left_in_rx<=0 )
eric11fr 0:a563059f0473 179 {
eric11fr 0:a563059f0473 180 flag_rx_waiting_for_stop_bit = TRUE;
eric11fr 0:a563059f0473 181 }
eric11fr 0:a563059f0473 182 }
eric11fr 0:a563059f0473 183 }
eric11fr 0:a563059f0473 184 }
eric11fr 0:a563059f0473 185 }
eric11fr 0:a563059f0473 186 }
eric11fr 0:a563059f0473 187
eric11fr 0:a563059f0473 188 void init_uart( void )
eric11fr 0:a563059f0473 189 {
eric11fr 0:a563059f0473 190 flag_tx_ready = FALSE;
eric11fr 0:a563059f0473 191 flag_rx_ready = FALSE;
eric11fr 0:a563059f0473 192 flag_rx_waiting_for_stop_bit = FALSE;
eric11fr 0:a563059f0473 193 flag_rx_off = FALSE;
eric11fr 0:a563059f0473 194 rx_num_of_bits = 8;//10
eric11fr 0:a563059f0473 195 tx_num_of_bits = 8;//10
eric11fr 0:a563059f0473 196
eric11fr 0:a563059f0473 197 set_tx_pin_low();
eric11fr 0:a563059f0473 198 ticker.attach_us(&timer_isr, 1000000.0 / (BAUD_RATE * 3.0));
eric11fr 0:a563059f0473 199
eric11fr 0:a563059f0473 200 }
eric11fr 0:a563059f0473 201
eric11fr 0:a563059f0473 202 char _getchar( void )
eric11fr 0:a563059f0473 203 {
eric11fr 0:a563059f0473 204 char ch;
eric11fr 0:a563059f0473 205
eric11fr 0:a563059f0473 206 do
eric11fr 0:a563059f0473 207 {
eric11fr 0:a563059f0473 208 while ( qout==qin )
eric11fr 0:a563059f0473 209 {
eric11fr 0:a563059f0473 210 idle();
eric11fr 0:a563059f0473 211 }
eric11fr 0:a563059f0473 212 ch = inbuf[qout] & 0xFF;
eric11fr 0:a563059f0473 213 if ( ++qout>=IN_BUF_SIZE )
eric11fr 0:a563059f0473 214 {
eric11fr 0:a563059f0473 215 qout = 0;
eric11fr 0:a563059f0473 216 }
eric11fr 0:a563059f0473 217 }
eric11fr 0:a563059f0473 218 while ( ch==0x0A || ch==0xC2 );
eric11fr 0:a563059f0473 219 return( ch );
eric11fr 0:a563059f0473 220 }
eric11fr 0:a563059f0473 221
eric11fr 0:a563059f0473 222 void _putchar( int ch )
eric11fr 0:a563059f0473 223 {
eric11fr 0:a563059f0473 224 while ( flag_tx_ready );
eric11fr 0:a563059f0473 225 user_tx_buffer = ch;
eric11fr 0:a563059f0473 226
eric11fr 0:a563059f0473 227 // invoke_UART_transmit
eric11fr 0:a563059f0473 228 timer_tx_ctr = 3;
eric11fr 0:a563059f0473 229 bits_left_in_tx = tx_num_of_bits;
eric11fr 0:a563059f0473 230 internal_tx_buffer = (user_tx_buffer<<1) | 0x200;;
eric11fr 0:a563059f0473 231 flag_tx_ready = TRUE;
eric11fr 0:a563059f0473 232 }
eric11fr 0:a563059f0473 233
eric11fr 0:a563059f0473 234 void flush_input_buffer( void )
eric11fr 0:a563059f0473 235 {
eric11fr 0:a563059f0473 236 qin = 0;
eric11fr 0:a563059f0473 237 qout = 0;
eric11fr 0:a563059f0473 238 }
eric11fr 0:a563059f0473 239
eric11fr 0:a563059f0473 240 char kbhit( void )
eric11fr 0:a563059f0473 241 {
eric11fr 0:a563059f0473 242 return( qin!=qout );
eric11fr 0:a563059f0473 243 }
eric11fr 0:a563059f0473 244
eric11fr 0:a563059f0473 245 void turn_rx_on( void )
eric11fr 0:a563059f0473 246 {
eric11fr 0:a563059f0473 247 flag_rx_off = FALSE;
eric11fr 0:a563059f0473 248 }
eric11fr 0:a563059f0473 249
eric11fr 0:a563059f0473 250 void turn_rx_off( void )
eric11fr 0:a563059f0473 251 {
eric11fr 0:a563059f0473 252 flag_rx_off = TRUE;
eric11fr 0:a563059f0473 253 }
eric11fr 0:a563059f0473 254
eric11fr 0:a563059f0473 255 void printStr(char* str){
eric11fr 0:a563059f0473 256 int i = 0;
eric11fr 0:a563059f0473 257 int len = strlen(str);
eric11fr 0:a563059f0473 258 for(i = 0; i<len; i++){
eric11fr 0:a563059f0473 259 wait(0.01);
eric11fr 0:a563059f0473 260 _putchar(str[i]);
eric11fr 0:a563059f0473 261 }
eric11fr 0:a563059f0473 262 }
eric11fr 0:a563059f0473 263
eric11fr 0:a563059f0473 264 int main() {
eric11fr 0:a563059f0473 265
eric11fr 0:a563059f0473 266 pc.baud(9600);
eric11fr 0:a563059f0473 267 pc.printf("test");
eric11fr 0:a563059f0473 268 init_uart();
eric11fr 0:a563059f0473 269
eric11fr 0:a563059f0473 270 //printStr("d\n\r");
eric11fr 0:a563059f0473 271 wait(0.01);
eric11fr 0:a563059f0473 272 //printStr("Voila!\n\r");
eric11fr 0:a563059f0473 273 //printStr("Voila!\n\r");
eric11fr 0:a563059f0473 274 while(1){
eric11fr 0:a563059f0473 275 // printStr("V");
eric11fr 0:a563059f0473 276 pc.putc( _getchar() );
eric11fr 0:a563059f0473 277 //wait(0.1);
eric11fr 0:a563059f0473 278 }
eric11fr 0:a563059f0473 279 }