v1

Dependencies:   mbed Servo

Committer:
eric11fr
Date:
Tue Oct 27 22:22:14 2020 +0000
Revision:
4:34a8e94c6fd5
Parent:
0:b8bade04f24f
Child:
1:d8964d9ff503
test menu via xbee

Who changed what in which revision?

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