* Simulator of microcontrollers (serial.cc)
*
* Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
- *
+ *
* To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
*
*/
#include <fcntl.h>
#include <sys/time.h>
#include <strings.h>
+#include <assert.h>
// prj
#include "globals.h"
#include "serialcl.h"
#include "regs51.h"
#include "uc51cl.h"
+#include "cmdutil.h"
cl_serial::cl_serial(class cl_uc *auc):
cl_serial::~cl_serial(void)
{
+ if (serial_in != serial_out && serial_in)
+ {
+#ifdef HAVE_TERMIOS_H
+ if (isatty(fileno(serial_in)))
+ tcsetattr(fileno(serial_in), TCSANOW, &saved_attributes_in);
+#endif
+ fclose(serial_in);
+ }
if (serial_out)
{
+#ifdef HAVE_TERMIOS_H
if (isatty(fileno(serial_out)))
- tcsetattr(fileno(serial_out), TCSANOW, &saved_attributes_out);
+ tcsetattr(fileno(serial_out), TCSANOW, &saved_attributes_out);
+#endif
fclose(serial_out);
}
- if (serial_in)
- {
- if (isatty(fileno(serial_in)))
- tcsetattr(fileno(serial_in), TCSANOW, &saved_attributes_in);
- fclose(serial_in);
- }
delete serial_in_file_option;
delete serial_out_file_option;
}
int
cl_serial::init(void)
{
+#ifdef HAVE_TERMIOS_H
int i;
struct termios tattr;
+#endif
set_name("mcs51_uart");
sfr= uc->address_space(MEM_SFR_ID);
serial_in= fopen(fni, "r");
if ((fno= serial_out_file_option->get_value((char*)0)))
serial_out= fopen(fno, "w");*/
-
+
//serial_in = (FILE*)application->args->get_parg(0, "Ser_in");
//serial_out= (FILE*)application->args->get_parg(0, "Ser_out");
serial_in = (FILE*)serial_in_file_option->get_value((void*)0);
serial_out= (FILE*)serial_out_file_option->get_value((void*)0);
- if (serial_in)
+
+ if (serial_in != serial_out && serial_in)
{
// making `serial' unbuffered
if (setvbuf(serial_in, NULL, _IONBF, 0))
- perror("Unbuffer serial input channel");
+ perror("Unbuffer serial input channel");
+#ifdef _WIN32
+ if (CH_SERIAL != get_handle_type((HANDLE)_get_osfhandle(fileno(serial_in))))
+#elif defined HAVE_TERMIOS_H
// setting O_NONBLOCK
if ((i= fcntl(fileno(serial_in), F_GETFL, 0)) < 0)
- perror("Get flags of serial input");
+ perror("Get flags of serial input");
i|= O_NONBLOCK;
if (fcntl(fileno(serial_in), F_SETFL, i) < 0)
- perror("Set flags of serial input");
+ perror("Set flags of serial input");
// switching terminal to noncanonical mode
if (isatty(fileno(serial_in)))
- {
- tcgetattr(fileno(serial_in), &saved_attributes_in);
- tcgetattr(fileno(serial_in), &tattr);
- tattr.c_lflag&= ~(ICANON|ECHO);
- tattr.c_cc[VMIN] = 1;
- tattr.c_cc[VTIME]= 0;
- tcsetattr(fileno(serial_in), TCSAFLUSH, &tattr);
- }
+ {
+ tcgetattr(fileno(serial_in), &saved_attributes_in);
+ tcgetattr(fileno(serial_in), &tattr);
+ tattr.c_lflag&= ~(ICANON|ECHO);
+ tattr.c_cc[VMIN] = 1;
+ tattr.c_cc[VTIME]= 0;
+ tcsetattr(fileno(serial_in), TCSAFLUSH, &tattr);
+ }
else
- fprintf(stderr, "Warning: serial input interface connected to a "
- "non-terminal file.\n");
+#endif
+ fprintf(stderr, "Warning: serial input interface connected to a "
+ "non-terminal file.\n");
}
if (serial_out)
{
// making `serial' unbuffered
if (setvbuf(serial_out, NULL, _IONBF, 0))
- perror("Unbuffer serial output channel");
+ perror("Unbuffer serial output channel");
+#ifdef _WIN32
+ if (CH_SERIAL != get_handle_type((HANDLE)_get_osfhandle(fileno(serial_out))))
+#elif defined HAVE_TERMIOS_H
// setting O_NONBLOCK
if ((i= fcntl(fileno(serial_out), F_GETFL, 0)) < 0)
- perror("Get flags of serial output");
+ perror("Get flags of serial output");
i|= O_NONBLOCK;
if (fcntl(fileno(serial_out), F_SETFL, i) < 0)
- perror("Set flags of serial output");
+ perror("Set flags of serial output");
// switching terminal to noncanonical mode
if (isatty(fileno(serial_out)))
- {
- tcgetattr(fileno(serial_out), &saved_attributes_out);
- tcgetattr(fileno(serial_out), &tattr);
- tattr.c_lflag&= ~(ICANON|ECHO);
- tattr.c_cc[VMIN] = 1;
- tattr.c_cc[VTIME]= 0;
- tcsetattr(fileno(serial_out), TCSAFLUSH, &tattr);
- }
+ {
+ tcgetattr(fileno(serial_out), &saved_attributes_out);
+ tcgetattr(fileno(serial_out), &tattr);
+ tattr.c_lflag&= ~(ICANON|ECHO);
+ tattr.c_cc[VMIN] = 1;
+ tattr.c_cc[VTIME]= 0;
+ tcsetattr(fileno(serial_out), TCSAFLUSH, &tattr);
+ }
else
- fprintf(stderr, "Warning: serial output interface connected to a "
- "non-terminal file.\n");
+#endif
+ fprintf(stderr, "Warning: serial output interface connected to a "
+ "non-terminal file.\n");
}
class cl_hw *t2= uc->get_hw(HW_TIMER, 2, 0);
cl_serial::added_to_uc(void)
{
uc->it_sources->add(new cl_it_src(bmES , SCON, bmTI , 0x0023, false,
- "serial transmit", 6));
+ "serial transmit", 6));
uc->it_sources->add(new cl_it_src(bmES , SCON, bmRI , 0x0023, false,
- "serial receive", 6));
+ "serial receive", 6));
}
t_mem
_bmREN= *val & bmREN;
_bits= 8;
switch (_mode)
- {
- case 0:
- _bits= 8;
- _divby= 12;
- break;
- case 1:
- _bits= 10;
- _divby= _bmSMOD?16:32;
- break;
- case 2:
- _bits= 11;
- _divby= _bmSMOD?16:32;
- break;
- case 3:
- _bits= 11;
- _divby= _bmSMOD?16:32;
- break;
- }
+ {
+ case 0:
+ _bits= 8;
+ _divby= 12;
+ break;
+ case 1:
+ _bits= 10;
+ _divby= _bmSMOD?16:32;
+ break;
+ case 2:
+ _bits= 11;
+ _divby= _bmSMOD?16:32;
+ break;
+ case 3:
+ _bits= 11;
+ _divby= _bmSMOD?16:32;
+ break;
+ }
}
else if (cell == pcon)
{
_bmSMOD= *val & bmSMOD;
/*switch (_mode)
- {
- case 1:
- _divby= _bmSMOD?16:32;
- break;
- case 2:
- _divby= _bmSMOD?16:32;
- break;
- case 3:
- _divby= _bmSMOD?16:32;
- break;
- }*/
+ {
+ case 1:
+ _divby= _bmSMOD?16:32;
+ break;
+ case 2:
+ _divby= _bmSMOD?16:32;
+ break;
+ case 3:
+ _divby= _bmSMOD?16:32;
+ break;
+ }*/
if (_mode)
- _divby= _bmSMOD?16:32;
+ _divby= _bmSMOD?16:32;
}
}
if (s_sending)
{
while (*tr_src >= _divby)
- {
- (*tr_src)-= _divby;
- s_tr_bit++;
- //printf("serial bit sent %d\n",uc->ticks->ticks);
- }
+ {
+ (*tr_src)-= _divby;
+ s_tr_bit++;
+ //printf("serial bit sent %d\n",uc->ticks->ticks);
+ }
}
if (s_receiving)
{
while (*rec_src >= _divby)
- {
- (*rec_src)-= _divby;
- s_rec_bit++;
- }
+ {
+ (*rec_src)-= _divby;
+ s_rec_bit++;
+ }
}
return(0);
}
s_sending= DD_FALSE;
scon->set_bit1(bmTI);
if (serial_out)
- {
- putc(s_out, serial_out);
- fflush(serial_out);
- }
+ {
+ putc(s_out, serial_out);
+ fflush(serial_out);
+ }
s_tr_bit-= _bits;
//printf("serial out %d bit rems %d\n",s_tr_bit,uc->ticks->ticks);
}
serial_in &&
!s_receiving)
{
- fd_set set; static struct timeval timeout= {0,0};
- FD_ZERO(&set);
- FD_SET(fileno(serial_in), &set);
- int i= select(fileno(serial_in)+1, &set, NULL, NULL, &timeout);
- if (i > 0 &&
- FD_ISSET(fileno(serial_in), &set))
- {
- s_receiving= DD_TRUE;
- s_rec_bit= 0;
- s_rec_tick= /*uc51->*/s_rec_t1= 0;
- }
+#ifdef _WIN32
+ HANDLE handle = (HANDLE)_get_osfhandle(fileno(serial_in));
+ assert(INVALID_HANDLE_VALUE != handle);
+
+ if (input_avail(handle))
+#else
+ if (input_avail(fileno(serial_in)))
+#endif
+ {
+ s_receiving= DD_TRUE;
+ s_rec_bit= 0;
+ s_rec_tick= /*uc51->*/s_rec_t1= 0;
+ }
}
if (s_receiving &&
(s_rec_bit >= _bits))
{
if (::read(fileno(serial_in), &c, 1) == 1)
- {
- s_in= c;
- sbuf->set(s_in);
- received(c);
- }
+ {
+ s_in= c;
+ sbuf->set(s_in);
+ received(c);
+ }
s_receiving= DD_FALSE;
s_rec_bit-= _bits;
}
-
+
int l;
s_tr_tick+= (l= cycles * uc->clock_per_cycle());
s_rec_tick+= l;
if (where->cathegory == HW_TIMER)
{
if (where->id == 1)
- {
- //printf("serial: timer overflowed %ld\n", uc->ticks->ticks);
- s_rec_t1++;
- s_tr_t1++;
- }
+ {
+ //printf("serial: timer overflowed %ld\n", uc->ticks->ticks);
+ s_rec_t1++;
+ s_tr_t1++;
+ }
if (where->id == 2 /*&& there_is_t2*/)
- {
- switch (he)
- {
- case EV_T2_MODE_CHANGED:
- {
- if (!t2_baud)
- s_rec_t1= s_tr_t1= 0;
- t_mem *d= (t_mem *)params;
- t2_baud= *d & (bmRCLK | bmTCLK);
- break;
- }
- case EV_OVERFLOW:
- //printf("T2 \abaud ov r%d t%d\n",s_rec_t1,s_tr_t1);
- s_rec_t1++;
- s_tr_t1++;
- break;
- default: break;
- }
- }
+ {
+ switch (he)
+ {
+ case EV_T2_MODE_CHANGED:
+ {
+ if (!t2_baud)
+ s_rec_t1= s_tr_t1= 0;
+ t_mem *d= (t_mem *)params;
+ t2_baud= *d & (bmRCLK | bmTCLK);
+ break;
+ }
+ case EV_OVERFLOW:
+ //printf("T2 \abaud ov r%d t%d\n",s_rec_t1,s_tr_t1);
+ s_rec_t1++;
+ s_tr_t1++;
+ break;
+ default: break;
+ }
+ }
}
}
void
-cl_serial::print_info(class cl_console *con)
+cl_serial::print_info(class cl_console_base *con)
{
char *modes[]= { "Shift, fixed clock",
- "8 bit UART timer clocked",
- "9 bit UART fixed clock",
- "9 bit UART timer clocked" };
+ "8 bit UART timer clocked",
+ "9 bit UART fixed clock",
+ "9 bit UART timer clocked" };
int sc= scon->get();
con->dd_printf("%s[%d]", id_string, id);
if (mode == 1 || mode == 2)
con->dd_printf(" (timer%d)", (t2_baud)?2:1);
con->dd_printf(" MultiProc=%s",
- (mode&2)?((sc&bmSM2)?"ON":"OFF"):"none");
+ (mode&2)?((sc&bmSM2)?"ON":"OFF"):"none");
con->dd_printf(" irq=%s", (sfr->get(IE)&bmES)?"en":"dis");
con->dd_printf(" prio=%d", uc->it_priority(bmPS));
con->dd_printf("\n");
con->dd_printf(" irq=%c", (sc&bmTI)?'1':'0');
con->dd_printf("\n");
/*con->dd_printf("s_rec_t1=%d s_rec_bit=%d s_rec_tick=%d\n",
- s_rec_t1, s_rec_bit, s_rec_tick);
+ s_rec_t1, s_rec_bit, s_rec_tick);
con->dd_printf("s_tr_t1=%d s_tr_bit=%d s_tr_tick=%d\n",
- s_tr_t1, s_tr_bit, s_tr_tick);
- con->dd_printf("divby=%d bits=%d\n", _divby, _bits);*/
+ s_tr_t1, s_tr_bit, s_tr_tick);
+ con->dd_printf("divby=%d bits=%d\n", _divby, _bits);*/
}