HP85 GPIB Disk Emulator  1.0
HP85GPIBDiskEmulator
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
rs232.c
Go to the documentation of this file.
1 
13 #include "user_config.h"
14 #include "rs232.h"
15 
17 struct _uart uarts[UARTS];
18 
22 void uart_rx_flush(uint8_t uart)
23 {
24  if(uart >= UARTS)
25  return;
26 
27  cli();
28 
29  uarts[uart].rx_count = 0;
30  uarts[uart].rx_head = 0;
31  uarts[uart].rx_tail = 0;
32  uarts[uart].rx_flow = 0;
33  uarts[uart].rx_error = 0;
34 
35  sei();
36 }
37 
38 
45 int uart0_getchar( void *f __attribute__((unused)))
46 {
47  return( uart_getchar(0) );
48 }
49 
50 
58 int uart0_putchar(int c, void *f __attribute__((unused)))
59 {
60  uart_putchar(c, 0);
61  return(c);
62 }
63 
64 
73 uint16_t uart_ubr(uint32_t baud, int *u2x, uint32_t *actual)
74 {
75  double div;
76  uint32_t ubr_regi;
77 
78 // Calculating Baud Rate
79 // (U2X = 0)
80 // BAUD = Fosc/(16*(UBRn+1))
81 // UBRn = Fosc/(16*Baud) -1
82 // (U2X = 1)
83 // BAUD = Fosc/(8*(UBRn+1))
84 // UBRn = Fosc/(8*Baud) -1
85 
87  *u2x = 1;
88  div = 8;
89  ubr_regi = round( ((double)F_CPU/(div*(double)baud)) - 1.0 );
90 
91 // For lower baud rates use 16 divider if the UBRR register overflows
92 // URBRR register is only a 12 bit register!
93  if(ubr_regi > 4095)
94  {
96  *u2x = 0;
97  div = 16.0;
98  ubr_regi = round( ((double)F_CPU/(div*(double)baud)) - 1.0 );
99  }
100 //overflow, baud rate was too low - so we clip to maximum allowed
101  if(ubr_regi > 4095)
102  ubr_regi = 4095;
103 
104  *actual = ((double)F_CPU/(div*((double)(ubr_regi+1))));
105 
106  return(ubr_regi);
107 }
108 
109 
117 uint32_t uart_init(uint8_t uart, uint32_t baud)
118 {
119  uint16_t ubr_register;
120  uint32_t actual;
121  int u2x = 0;
122 
123  if(uart >= UARTS)
124  return(0);
125 
126  ubr_register = uart_ubr(baud,(int*)&u2x,(uint32_t *)&actual);
127 
128  if(uart == 0) /* uart == 0( first serial ) */
129  {
130  uart_rx_flush(0);
131 
132  cli();
133 
134  GPIO_PIN_LATCH_HI(RX0);
135  GPIO_PIN_LATCH_HI(TX0);
136  GPIO_PIN_DIR_IN(RX0);
137  GPIO_PIN_DIR_OUT(TX0);
138 
139  UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
140 
141  if(u2x)
142  UCSR0A = (1<<U2X0);
143 
144  UBRR0H = (uint8_t) 0xff & (ubr_register >> 8);
145  UBRR0L = (uint8_t) 0xff & (ubr_register);
146 
147  sei();
148 
149 //@brief see posix.c this attaches uart functions to putchar() and getchar()
150  fdevopen((void *)uart0_putchar, (void *)uart0_getchar);
151  }
152 #if UARTS > 1
153  if(uart == 1) /* uart == 0( first serial ) */
154  {
155  uart_rx_flush(1);
156 
157  cli();
158 
159  GPIO_PIN_LATCH_HI(RX1);
160  GPIO_PIN_LATCH_HI(TX1);
161  GPIO_PIN_DIR_IN(RX1);
162  GPIO_PIN_DIR_OUT(TX1);
163 
164  UCSR1B = (1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
165 
166  if(u2x)
167  UCSR1A = (1<<U2X1);
168 
169  UBRR1H = (uint8_t) 0xff & (ubr_register >> 8);
170  UBRR1L = (uint8_t) 0xff & (ubr_register);
171 
172  sei();
173 
174 //@brief see posix.c this attaches uart functions to putchar() and getchar()
175  fdevopen((void *)uart1_putchar, (void *)uart1_getchar);
176  }
177 #endif
178  return(actual);
180 }
181 
182 
185 ISR(USART0_RX_vect)
186 {
187  uart_rx_interrupt(0, UDR0);
188 }
189 
190 
191 #if UARTS > 1
192 ISR(USART1_RX_vect)
195 {
196  uart_rx_interrupt(1, UDR1);
197 }
198 #endif
199 
207 void uart_rx_interrupt(uint8_t uart, uint8_t data)
208 {
209  if (uarts[uart].rx_count < RX_BUF_SIZE )
210  {
211 // MG 10 June 2020 mask off bit 7
212  uarts[uart].rx_buf[uarts[uart].rx_head++] = data & 0x7f;
213  uarts[uart].rx_count++;
214  if (uarts[uart].rx_head >= RX_BUF_SIZE )
215  uarts[uart].rx_head = 0;
216  }
217  else // Overflow
218  {
219  uarts[uart].rx_error |= RX_OVERFLOW;
220  }
221 }
222 
223 
227 int uart_peek_tail(uint8_t uart)
228 {
229  uint8_t c;
230 
231  if(uart >= UARTS)
232  return(EOF);
233 
234  cli();
235  c = uarts[uart].rx_buf[uarts[uart].rx_tail];
236  sei();
237  return (c & 0xff);
238 }
239 
240 
249 int uart_get_tail(uint8_t uart)
250 {
251  uint8_t c;
252 
253  if (uart >= UARTS)
254  {
255  return(EOF);
256  }
257 
258  while(uart_rx_count(uart) < 1)
259  ;
260 
261  cli();
262  c = uarts[uart].rx_buf[uarts[uart].rx_tail++];
263  if (uarts[uart].rx_tail >= RX_BUF_SIZE)
264  uarts[uart].rx_tail = 0;
265  uarts[uart].rx_count--;
266  sei();
267 
268  return (c & 0xff);
269 }
270 
271 
277 int uart_rx_count(uint8_t uart)
278 {
279  int count;
280 
281  if(uart >= UARTS)
282  return(EOF);
283 
284  cli();
285 
286  count = uarts[uart].rx_count;
287 
288  sei();
289 
290  return (count );
291 }
292 
293 
299 int uart_rx_byte(uint8_t uart)
300 {
301  return( uart_get_tail(uart) & 0xff);
302 }
303 
304 
312 int uart_getchar(uint8_t uart)
313 {
314  uint8_t c;
315 
316  if(uart >= UARTS)
317  return(EOF);
318 #if 0
319  while(1)
320  {
321  c = uart_rx_byte(uart);
322  if(c == '\n')
323  continue;
324  break;
325  }
326  if(c == '\r')
327  c = '\n';
328 #endif
329  c = uart_rx_byte(uart);
330  uart_tx_byte(c, uart);
331  if(c == '\r')
332  {
333  c = '\n';
334  uart_tx_byte(c, uart);
335  }
336 //FIXME ECHO
337  return (c);
338 }
339 
340 
347 int uart_tx_byte(int c, uint8_t uart)
348 {
349  if(uart == 0)
350  {
351  while (!BIT_TST(UCSR0A, UDRE0))
352  ;
353  UDR0 = c & 0x7f;
354  return(c);
355  }
356 #ifdef UARTS > 1
357  if(uart == 1)
358  {
359  while (!BIT_TST(UCSR1A, UDRE1))
360  ;
361  UDR1 = c & 0x7f;
362  return(c);
363  }
364 #endif
365  return(EOF);
366 }
367 
368 
376 int uart_putchar(int c, int uart)
377 {
378  uart_tx_byte(c, uart);
379 
380  if( c == '\n' )
381  uart_tx_byte('\r', uart);
382 
383  return(c);
384 }
385 
386 
394 int uart_keyhit(uint8_t uart)
395 {
396  return ( uart_rx_count( uart ) );
397 }
398 
399 
403 int uart_put(int c)
404 {
405  return( uart0_putchar(c,0) );
406 }
407 
408 
411 int uart_get(void)
412 {
413  return(uart0_getchar(0));
414 }
415 
416 
421 int get_line (char *buff, int len)
422 {
423  int c;
424  int i = 0;
425 
426  memset(buff,0,len);
427  while(1)
428  {
429  c = uart_get() & 0x7f;
430  uart_put(c);
431  if (c == '\n' || c == '\r')
432  break;
433 
434  if (c == '\b')
435  {
436  if(i > 0)
437  i--;
438  buff[i] = 0;
439  continue;
440  }
441 
442  if (i < (len - 1) ) /* Visible chars */
443  {
444  buff[i++] = c;
445  }
446  else
447  {
448  break;
449  }
450  }
451  buff[i++] = 0;
452  uart_put('\n');
453 
454  return(strlen(buff));
455 }
_uart::rx_count
int rx_count
Definition: rs232.h:39
uart_keyhit
int uart_keyhit(uint8_t uart)
Do we have receive characters waiting ?.
Definition: rs232.c:394
uart_init
uint32_t uart_init(uint8_t uart, uint32_t baud)
UART initialization function that works with avr-libc functions.
Definition: rs232.c:117
RX_OVERFLOW
#define RX_OVERFLOW
Definition: rs232.h:21
uart_put
int uart_put(int c)
Transmit a character on UART 0.
Definition: rs232.c:403
rs232.h
RS232 Driver AVR8.
uart_get
int uart_get(void)
Receive a character from UART 0.
Definition: rs232.c:411
uart_tx_byte
int uart_tx_byte(int c, uint8_t uart)
Transmit 1 byte on uart.
Definition: rs232.c:347
_uart::rx_flow
uint8_t rx_flow
Definition: rs232.h:38
uart_putchar
int uart_putchar(int c, int uart)
Transmit 1 byte on uart.
Definition: rs232.c:376
UARTS
#define UARTS
Definition: rs232.h:44
uart0_putchar
int uart0_putchar(int c, void *f __attribute__((unused)))
UART transmit character function using avr-libc.
Definition: rs232.c:58
uart_rx_flush
void uart_rx_flush(uint8_t uart)
Flush receive ring buffer for specified uart.
Definition: rs232.c:22
uart_getchar
int uart_getchar(uint8_t uart)
Receive character from uart with option CR/LF conversion.
Definition: rs232.c:312
_uart::rx_buf
uint8_t rx_buf[RX_BUF_SIZE+1]
Definition: rs232.h:41
ISR
ISR(USART0_RX_vect)
UART 0 Receive Interrupt runction.
Definition: rs232.c:185
uart_rx_interrupt
void uart_rx_interrupt(uint8_t uart, uint8_t data)
UART Receive Interrupt task.
Definition: rs232.c:207
uart_peek_tail
int uart_peek_tail(uint8_t uart)
Return character waiting in ring buffer without removing it.
Definition: rs232.c:227
uart_rx_byte
int uart_rx_byte(uint8_t uart)
Recive character character from uart.
Definition: rs232.c:299
strlen
MEMSPACE size_t WEAK_ATR strlen(const char *str)
String Length.
Definition: stringsup.c:144
uart_get_tail
int uart_get_tail(uint8_t uart)
Return next character from ring buffer.
Definition: rs232.c:249
user_config.h
Master Include for FatFs, RTC, Timers AVR8 - Part of HP85 disk emulator.
BIT_TST
#define BIT_TST(x, y)
Definition: bits.h:19
_uart::rx_tail
uint8_t rx_tail
Definition: rs232.h:37
_uart
Definition: rs232.h:34
uarts
struct _uart uarts[UARTS]
Uart ring buffers.
Definition: rs232.c:17
uart_ubr
uint16_t uart_ubr(uint32_t baud, int *u2x, uint32_t *actual)
UART baud rate caluculation We compute the best values of baud rate register and prescale.
Definition: rs232.c:73
RX_BUF_SIZE
#define RX_BUF_SIZE
Definition: rs232.h:18
fdevopen
MEMSPACE FILE * fdevopen(int(*put)(char, FILE *), int(*get)(FILE *))
Device open functions.
Definition: posix.c:1912
_uart::rx_error
uint8_t rx_error
Definition: rs232.h:40
get_line
int get_line(char *buff, int len)
Get a line from UART 0 up to a maximum of len bytes.
Definition: rs232.c:421
uart0_getchar
int uart0_getchar(void *f __attribute__((unused)))
UART receive character function using avr-libc.
Definition: rs232.c:45
EOF
#define EOF
Definition: ff.h:349
uart_rx_count
int uart_rx_count(uint8_t uart)
return count of character count waiting in UART ring buffer.
Definition: rs232.c:277
_uart::rx_head
uint8_t rx_head
Definition: rs232.h:36