mirror of https://github.com/zrafa/xinu-avr.git
28 changed files with 987 additions and 118 deletions
@ -0,0 +1,58 @@
|
||||
/* ttycontrol.c - ttycontrol */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttycontrol - Control a tty device by setting modes |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
devcall ttycontrol( |
||||
struct dentry *devptr, /* Entry in device switch table */ |
||||
int32 func, /* Function to perform */ |
||||
int32 arg1, /* Argument 1 for request */ |
||||
int32 arg2 /* Argument 2 for request */ |
||||
) |
||||
{ |
||||
struct ttycblk *typtr; /* Pointer to tty control block */ |
||||
char ch; /* Character for lookahead */ |
||||
|
||||
typtr = &ttytab[devptr->dvminor]; |
||||
|
||||
/* Process the request */ |
||||
|
||||
switch ( func ) { |
||||
|
||||
case TC_NEXTC: |
||||
wait(typtr->tyisem); |
||||
ch = *typtr->tyitail; |
||||
signal(typtr->tyisem); |
||||
return (devcall)ch; |
||||
|
||||
case TC_MODER: |
||||
typtr->tyimode = TY_IMRAW; |
||||
return (devcall)OK; |
||||
|
||||
case TC_MODEC: |
||||
typtr->tyimode = TY_IMCOOKED; |
||||
return (devcall)OK; |
||||
|
||||
case TC_MODEK: |
||||
typtr->tyimode = TY_IMCBREAK; |
||||
return (devcall)OK; |
||||
|
||||
case TC_ICHARS: |
||||
return(semcount(typtr->tyisem)); |
||||
|
||||
case TC_ECHO: |
||||
typtr->tyiecho = TRUE; |
||||
return (devcall)OK; |
||||
|
||||
case TC_NOECHO: |
||||
typtr->tyiecho = FALSE; |
||||
return (devcall)OK; |
||||
|
||||
default: |
||||
return (devcall)SYSERR; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,41 @@
|
||||
/* ttygetc.c - ttygetc */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttygetc - Read one character from a tty device (interrupts disabled) |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
devcall ttygetc( |
||||
struct dentry *devptr /* Entry in device switch table */ |
||||
) |
||||
{ |
||||
char ch; /* Character to return */ |
||||
struct ttycblk *typtr; /* Pointer to ttytab entry */ |
||||
|
||||
typtr = &ttytab[devptr->dvminor]; |
||||
|
||||
/* Wait for a character in the buffer and extract one character */ |
||||
|
||||
|
||||
// struct sentry * semptr;
|
||||
// semptr = &semtab[typtr->tyisem];
|
||||
// while(--(semptr->scount) < 0);
|
||||
wait(typtr->tyisem); |
||||
ch = *typtr->tyihead++; |
||||
|
||||
/* Wrap around to beginning of buffer, if needed */ |
||||
|
||||
if (typtr->tyihead >= &typtr->tyibuff[TY_IBUFLEN]) { |
||||
typtr->tyihead = typtr->tyibuff; |
||||
} |
||||
|
||||
/* In cooked mode, check for the EOF character */ |
||||
|
||||
if ( (typtr->tyimode == TY_IMCOOKED) && (typtr->tyeof) && |
||||
(ch == typtr->tyeofch) ) { |
||||
return (devcall)EOF; |
||||
} |
||||
|
||||
return (devcall)ch; |
||||
} |
||||
@ -0,0 +1,272 @@
|
||||
/* ttyhandle_in.c - ttyhandle_in, erase1, eputc, echoch */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
local void erase1(struct ttycblk *, struct uart_csreg *); |
||||
local void echoch(char, struct ttycblk *, struct uart_csreg *); |
||||
local void eputc(char, struct ttycblk *, struct uart_csreg *); |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttyhandle_in - Handle one arriving char (interrupts disabled) |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
// void ttyhandle_in (
|
||||
// struct ttycblk *typtr, /* Pointer to ttytab entry */
|
||||
// struct uart_csreg *csrptr /* Address of UART's CSR */
|
||||
// )
|
||||
void ttyhandle_in ( |
||||
struct ttycblk *typtr, /* Pointer to ttytab entry */ |
||||
struct uart_csreg *csrptr, /* Address of UART's CSR */ |
||||
char c /* AVR char received */ |
||||
) |
||||
{ |
||||
char ch; /* Next char from device */ |
||||
int32 avail; /* Chars available in buffer */ |
||||
|
||||
ch = c; |
||||
|
||||
/* Compute chars available */ |
||||
|
||||
avail = semcount(typtr->tyisem); |
||||
if (avail < 0) { /* One or more processes waiting*/ |
||||
avail = 0; |
||||
} |
||||
|
||||
/* Handle raw mode */ |
||||
|
||||
if (typtr->tyimode == TY_IMRAW) { |
||||
if (avail >= TY_IBUFLEN) { /* No space => ignore input */ |
||||
return; |
||||
} |
||||
|
||||
/* Place char in buffer with no editing */ |
||||
|
||||
*typtr->tyitail++ = ch; |
||||
|
||||
/* Wrap buffer pointer */ |
||||
|
||||
if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) { |
||||
typtr->tyitail = typtr->tyibuff; |
||||
} |
||||
|
||||
/* Signal input semaphore and return */ |
||||
signal(typtr->tyisem); |
||||
return; |
||||
} |
||||
|
||||
/* Handle cooked and cbreak modes (common part) */ |
||||
|
||||
if ( (ch == TY_RETURN) && typtr->tyicrlf ) { |
||||
ch = TY_NEWLINE; |
||||
} |
||||
|
||||
/* If flow control is in effect, handle ^S and ^Q */ |
||||
|
||||
// STM32 specific: if (typtr->tyoflow) {
|
||||
// STM32 specific: if (ch == typtr->tyostart) { /* ^Q starts output */
|
||||
// STM32 specific: typtr->tyoheld = FALSE;
|
||||
// STM32 specific: ttykickout(csrptr);
|
||||
// STM32 specific: return;
|
||||
// STM32 specific: } else if (ch == typtr->tyostop) { /* ^S stops output */
|
||||
// STM32 specific: typtr->tyoheld = TRUE;
|
||||
// STM32 specific: return;
|
||||
// STM32 specific: }
|
||||
// STM32 specific: }
|
||||
|
||||
typtr->tyoheld = FALSE; /* Any other char starts output */ |
||||
|
||||
if (typtr->tyimode == TY_IMCBREAK) { /* Just cbreak mode */ |
||||
|
||||
/* If input buffer is full, send bell to user */ |
||||
|
||||
if (avail >= TY_IBUFLEN) { |
||||
eputc(typtr->tyifullc, typtr, csrptr); |
||||
} else { /* Input buffer has space for this char */ |
||||
*typtr->tyitail++ = ch; |
||||
|
||||
/* Wrap around buffer */ |
||||
|
||||
if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) { |
||||
typtr->tyitail = typtr->tyibuff; |
||||
} |
||||
if (typtr->tyiecho) { /* Are we echoing chars?*/ |
||||
echoch(ch, typtr, csrptr); |
||||
} |
||||
signal(typtr->tyisem); |
||||
} |
||||
return; |
||||
|
||||
} else { /* Just cooked mode (see common code above) */ |
||||
|
||||
/* Line kill character arrives - kill entire line */ |
||||
|
||||
if (ch == typtr->tyikillc && typtr->tyikill) { |
||||
typtr->tyitail -= typtr->tyicursor; |
||||
if (typtr->tyitail < typtr->tyibuff) { |
||||
typtr->tyitail += TY_IBUFLEN; |
||||
} |
||||
typtr->tyicursor = 0; |
||||
eputc(TY_RETURN, typtr, csrptr); |
||||
eputc(TY_NEWLINE, typtr, csrptr); |
||||
return; |
||||
} |
||||
|
||||
/* Erase (backspace) character */ |
||||
|
||||
if ( ((ch==typtr->tyierasec) || (ch==typtr->tyierasec2)) |
||||
&& typtr->tyierase) { |
||||
if (typtr->tyicursor > 0) { |
||||
typtr->tyicursor--; |
||||
erase1(typtr, csrptr); |
||||
} |
||||
return; |
||||
} |
||||
|
||||
/* End of line */ |
||||
|
||||
if ( (ch == TY_NEWLINE) || (ch == TY_RETURN) ) { |
||||
if (typtr->tyiecho) { |
||||
echoch(ch, typtr, csrptr); |
||||
} |
||||
*typtr->tyitail++ = ch; |
||||
if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) { |
||||
typtr->tyitail = typtr->tyibuff; |
||||
} |
||||
/* Make entire line (plus \n or \r) available */ |
||||
signaln(typtr->tyisem, typtr->tyicursor + 1); |
||||
typtr->tyicursor = 0; /* Reset for next line */ |
||||
return; |
||||
} |
||||
|
||||
/* Character to be placed in buffer - send bell if */ |
||||
/* buffer has overflowed */ |
||||
|
||||
avail = semcount(typtr->tyisem); |
||||
if (avail < 0) { |
||||
avail = 0; |
||||
} |
||||
if ((avail + typtr->tyicursor) >= TY_IBUFLEN-1) { |
||||
eputc(typtr->tyifullc, typtr, csrptr); |
||||
return; |
||||
} |
||||
|
||||
/* EOF character: recognize at beginning of line, but */ |
||||
/* print and ignore otherwise. */ |
||||
|
||||
if (ch == typtr->tyeofch && typtr->tyeof) { |
||||
if (typtr->tyiecho) { |
||||
echoch(ch, typtr, csrptr); |
||||
} |
||||
if (typtr->tyicursor != 0) { |
||||
return; |
||||
} |
||||
*typtr->tyitail++ = ch; |
||||
signal(typtr->tyisem); |
||||
return; |
||||
} |
||||
|
||||
|
||||
/* Echo the character */ |
||||
|
||||
if (typtr->tyiecho) { |
||||
echoch(ch, typtr, csrptr); |
||||
} |
||||
|
||||
/* Insert in the input buffer */ |
||||
|
||||
typtr->tyicursor++; |
||||
*typtr->tyitail++ = ch; |
||||
|
||||
/* Wrap around if needed */ |
||||
|
||||
if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) { |
||||
typtr->tyitail = typtr->tyibuff; |
||||
} |
||||
return; |
||||
} |
||||
} |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* erase1 - Erase one character honoring erasing backspace |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
local void erase1( |
||||
struct ttycblk *typtr, /* Ptr to ttytab entry */ |
||||
struct uart_csreg *csrptr /* Address of UART's CSRs */ |
||||
) |
||||
{ |
||||
char ch; /* Character to erase */ |
||||
|
||||
if ( (--typtr->tyitail) < typtr->tyibuff) { |
||||
typtr->tyitail += TY_IBUFLEN; |
||||
} |
||||
|
||||
/* Pick up char to erase */ |
||||
|
||||
ch = *typtr->tyitail; |
||||
if (typtr->tyiecho) { /* Are we echoing? */ |
||||
if (ch < TY_BLANK || ch == 0177) { /* Nonprintable */ |
||||
if (typtr->tyevis) { /* Visual cntl chars */ |
||||
eputc(TY_BACKSP, typtr, csrptr); |
||||
if (typtr->tyieback) { /* Erase char */ |
||||
eputc(TY_BLANK, typtr, csrptr); |
||||
eputc(TY_BACKSP, typtr, csrptr); |
||||
} |
||||
} |
||||
eputc(TY_BACKSP, typtr, csrptr);/* Bypass up arr*/ |
||||
if (typtr->tyieback) { |
||||
eputc(TY_BLANK, typtr, csrptr); |
||||
eputc(TY_BACKSP, typtr, csrptr); |
||||
} |
||||
} else { /* A normal character that is printable */ |
||||
eputc(TY_BACKSP, typtr, csrptr); |
||||
if (typtr->tyieback) { /* erase the character */ |
||||
eputc(TY_BLANK, typtr, csrptr); |
||||
eputc(TY_BACKSP, typtr, csrptr); |
||||
} |
||||
} |
||||
} |
||||
return; |
||||
} |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* echoch - Echo a character with visual and output crlf options |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
local void echoch( |
||||
char ch, /* Character to echo */ |
||||
struct ttycblk *typtr, /* Ptr to ttytab entry */ |
||||
struct uart_csreg *csrptr /* Address of UART's CSRs */ |
||||
) |
||||
{ |
||||
if ((ch==TY_NEWLINE || ch==TY_RETURN) && typtr->tyecrlf) { |
||||
eputc(TY_RETURN, typtr, csrptr); |
||||
eputc(TY_NEWLINE, typtr, csrptr); |
||||
} else if ( (ch<TY_BLANK||ch==0177) && typtr->tyevis) { |
||||
eputc(TY_UPARROW, typtr, csrptr);/* print ^x */ |
||||
eputc(ch+0100, typtr, csrptr); /* Make it printable */ |
||||
} else { |
||||
eputc(ch, typtr, csrptr); |
||||
} |
||||
} |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* eputc - Put one character in the echo queue |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
local void eputc( |
||||
char ch, /* Character to echo */ |
||||
struct ttycblk *typtr, /* Ptr to ttytab entry */ |
||||
struct uart_csreg *csrptr /* Address of UART's CSRs */ |
||||
) |
||||
{ |
||||
*typtr->tyetail++ = ch; |
||||
|
||||
/* Wrap around buffer, if needed */ |
||||
|
||||
if (typtr->tyetail >= &typtr->tyebuff[TY_EBUFLEN]) { |
||||
typtr->tyetail = typtr->tyebuff; |
||||
} |
||||
ttykickout(csrptr); |
||||
return; |
||||
} |
||||
@ -0,0 +1,85 @@
|
||||
/* ttyhandle_out.c - ttyhandle_out */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttyhandle_out - Handle an output on a tty device by sending more |
||||
* characters to the device FIFO (interrupts disabled) |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
void ttyhandle_out( |
||||
struct ttycblk *typtr, /* Ptr to ttytab entry */ |
||||
struct uart_csreg *csrptr /* Address of UART's CSRs */ |
||||
) |
||||
{ |
||||
|
||||
int32 ochars; /* Number of output chars sent */ |
||||
/* to the UART */ |
||||
int32 avail; /* Available chars in output buf*/ |
||||
int32 uspace; /* Space left in onboard UART */ |
||||
/* output FIFO */ |
||||
//uint32 ier = 0;
|
||||
|
||||
/* If output is currently held, simply ignore the call */ |
||||
|
||||
if (typtr->tyoheld) { |
||||
return; |
||||
} |
||||
|
||||
/* If echo and output queues empty, turn off interrupts */ |
||||
|
||||
if ( (typtr->tyehead == typtr->tyetail) && |
||||
(semcount(typtr->tyosem) >= TY_OBUFLEN) ) { |
||||
// STM32 specific: csrptr->cr1 &= ~(1 << UART_INTR_TX); /* deshabilita interrupciones */
|
||||
//ier = csrptr->ier;
|
||||
//csrptr->ier = ier & ~UART_IER_ETBEI;
|
||||
return; |
||||
} |
||||
|
||||
/* Initialize uspace to the available space in the Tx FIFO */ |
||||
|
||||
//uspace = UART_FIFO_SIZE - csrptr->txfifo_lvl;
|
||||
uspace = UART_FIFO_SIZE; |
||||
|
||||
|
||||
/* While onboard FIFO is not full and the echo queue is */ |
||||
/* nonempty, xmit chars from the echo queue */ |
||||
|
||||
while ( (uspace>0) && typtr->tyehead != typtr->tyetail) { |
||||
// STM32 specific: csrptr->dr = *typtr->tyehead++; /* ENVIA CARACERES POR UART */
|
||||
serial_put_char(*typtr->tyohead++); /* ENVIA CARACERES POR UART */ |
||||
if (typtr->tyehead >= &typtr->tyebuff[TY_EBUFLEN]) { |
||||
typtr->tyehead = typtr->tyebuff; |
||||
} |
||||
uspace--; |
||||
} |
||||
|
||||
/* While onboard FIFO is not full and the output queue is */ |
||||
/* nonempty, transmit chars from the output queue */ |
||||
|
||||
ochars = 0; |
||||
avail = TY_OBUFLEN - semcount(typtr->tyosem); |
||||
while ( (uspace>0) && (avail > 0) ) { |
||||
//while(!(csrptr->sr & UART_TC));
|
||||
//while(csrptr->sr &= ~(1 << UART_TEST));
|
||||
// STM32 specific: csrptr->dr = *typtr->tyohead++; /* ENVIA CARACERES POR UART */
|
||||
serial_put_char(*typtr->tyohead++); /* ENVIA CARACERES POR UART */ |
||||
if (typtr->tyohead >= &typtr->tyobuff[TY_OBUFLEN]) { |
||||
typtr->tyohead = typtr->tyobuff; |
||||
} |
||||
avail--; |
||||
uspace--; |
||||
ochars++; |
||||
} |
||||
if (ochars > 0) { |
||||
signaln(typtr->tyosem, ochars); |
||||
} |
||||
|
||||
if ( (typtr->tyehead == typtr->tyetail) && |
||||
(semcount(typtr->tyosem) >= TY_OBUFLEN) ) { |
||||
// STM32 specific: csrptr->cr1 &= ~(1 << UART_INTR_TX); /* deshabilita interrupcines de transmición */
|
||||
//ier = csrptr->ier;
|
||||
//csrptr->ier = (ier & ~UART_IER_ETBEI);
|
||||
} |
||||
return; |
||||
} |
||||
@ -0,0 +1,122 @@
|
||||
/* ttyhandler.c - ttyhandler */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttyhandler - Handle an interrupt for a tty (serial) device |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
void ttyhandler(uint32 xnum, char c, int flag) { |
||||
struct dentry *devptr; /* Address of device control blk*/ |
||||
struct ttycblk *typtr; /* Pointer to ttytab entry */
|
||||
struct uart_csreg *csrptr; /* Address of UART's CSR */ |
||||
// uint32 iir = 0; /* Interrupt identification */
|
||||
// uint32 lsr = 0; /* Line status */
|
||||
//
|
||||
//
|
||||
/* Get CSR address of the device (assume console for now) */ |
||||
|
||||
devptr = (struct dentry *) &devtab[CONSOLE]; |
||||
// STM32 specific: csrptr = (struct uart_csreg *) devptr->dvcsr;
|
||||
|
||||
/* Obtain a pointer to the tty control block */ |
||||
|
||||
typtr = &ttytab[devptr->dvminor]; |
||||
|
||||
/* Test type of UART interrupt */ |
||||
|
||||
// STM32 specific: uint8 flags = csrptr->sr & 0xFF;
|
||||
//kprintf("%x", flags);
|
||||
// STM32 specific: if (flags & UART_RXNE) {
|
||||
// STM32 specific: ttyhandle_in(typtr, csrptr);
|
||||
// STM32 specific: return;
|
||||
// STM32 specific: }
|
||||
|
||||
// STM32 specific: else if (flags & UART_TC) {
|
||||
// STM32 specific: ttyhandle_out(typtr, csrptr);
|
||||
// STM32 specific: return;
|
||||
|
||||
// STM32 specific: }
|
||||
|
||||
|
||||
/* AVR */ |
||||
if (flag) /* TX */ |
||||
ttyhandle_out(typtr, csrptr); |
||||
else /* RX */ |
||||
ttyhandle_in(typtr, csrptr, c); |
||||
|
||||
|
||||
// switch(flags) {
|
||||
//
|
||||
// case UART_TC_TXE:
|
||||
// case UART_TC:
|
||||
// ttyhandle_out(typtr, csrptr);
|
||||
// return;
|
||||
// case UART_RXNE:
|
||||
// ttyhandle_in(typtr, csrptr);
|
||||
// return;
|
||||
//
|
||||
// default:
|
||||
// kprintf("Unknown status\n");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// /* Decode hardware interrupt request from UART device */
|
||||
//
|
||||
// /* Check interrupt identification register */
|
||||
// iir = csrptr->iir;
|
||||
// if (iir & UART_IIR_IRQ) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// /* Decode the interrupt cause based upon the value extracted */
|
||||
// /* from the UART interrupt identification register. Clear */
|
||||
// /* the interrupt source and perform the appropriate handling */
|
||||
// /* to coordinate with the upper half of the driver */
|
||||
//
|
||||
// /* Decode the interrupt cause */
|
||||
//
|
||||
// iir &= UART_IIR_IDMASK; /* Mask off the interrupt ID */
|
||||
// switch (iir) {
|
||||
//
|
||||
// /* Receiver line status interrupt (error) */
|
||||
//
|
||||
// case UART_IIR_RLSI:
|
||||
// lsr = csrptr->lsr;
|
||||
// if(lsr & UART_LSR_BI) { /* Break Interrupt */
|
||||
//
|
||||
// /* Read the RHR register to acknowledge */
|
||||
//
|
||||
// lsr = csrptr->buffer;
|
||||
// }
|
||||
// return;
|
||||
//
|
||||
// /* Receiver data available or timed out */
|
||||
//
|
||||
// case UART_IIR_RDA:
|
||||
// case UART_IIR_RTO:
|
||||
//
|
||||
// resched_cntl(DEFER_START);
|
||||
//
|
||||
// /* While chars avail. in UART buffer, call ttyhandle_in */
|
||||
//
|
||||
// while ( (csrptr->lsr & UART_LSR_DR) != 0) {
|
||||
// ttyhandle_in(typtr, csrptr);
|
||||
// }
|
||||
//
|
||||
// resched_cntl(DEFER_STOP);
|
||||
//
|
||||
// return;
|
||||
//
|
||||
// /* Transmitter output FIFO is empty (i.e., ready for more) */
|
||||
//
|
||||
// case UART_IIR_THRE:
|
||||
// ttyhandle_out(typtr, csrptr);
|
||||
// return;
|
||||
//
|
||||
// /* Modem status change (simply ignore) */
|
||||
//
|
||||
// case UART_IIR_MSC:
|
||||
// return;
|
||||
// }
|
||||
} |
||||
@ -0,0 +1,83 @@
|
||||
/* ttyinit.c - ttyinit */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
struct ttycblk ttytab[Ntty]; |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttyinit - Initialize buffers and modes for a tty line |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
devcall ttyinit( |
||||
struct dentry *devptr /* Entry in device switch table */ |
||||
) |
||||
{ |
||||
struct ttycblk *typtr; /* Pointer to ttytab entry */ |
||||
struct uart_csreg *uptr; /* Address of UART's CSRs */ |
||||
|
||||
typtr = &ttytab[ devptr->dvminor ]; |
||||
|
||||
/* Initialize values in the tty control block */ |
||||
|
||||
typtr->tyihead = typtr->tyitail = /* Set up input queue */ |
||||
&typtr->tyibuff[0]; /* as empty */ |
||||
typtr->tyisem = semcreate(0); /* Input semaphore */ |
||||
typtr->tyohead = typtr->tyotail = /* Set up output queue */ |
||||
&typtr->tyobuff[0]; /* as empty */ |
||||
typtr->tyosem = semcreate(TY_OBUFLEN); /* Output semaphore */ |
||||
typtr->tyehead = typtr->tyetail = /* Set up echo queue */ |
||||
&typtr->tyebuff[0]; /* as empty */ |
||||
typtr->tyimode = TY_IMCOOKED; /* Start in cooked mode */ |
||||
typtr->tyiecho = TRUE; /* Echo console input */ |
||||
typtr->tyieback = TRUE; /* Honor erasing bksp */ |
||||
typtr->tyevis = TRUE; /* Visual control chars */ |
||||
typtr->tyecrlf = TRUE; /* Echo CRLF for NEWLINE*/ |
||||
typtr->tyicrlf = TRUE; /* Map CR to NEWLINE */ |
||||
typtr->tyierase = TRUE; /* Do erasing backspace */ |
||||
typtr->tyierasec = TY_BACKSP; /* Primary erase char */ |
||||
typtr->tyierasec2= TY_BACKSP2; /* Alternate erase char */ |
||||
typtr->tyeof = TRUE; /* Honor eof on input */ |
||||
typtr->tyeofch = TY_EOFCH; /* End-of-file character*/ |
||||
typtr->tyikill = TRUE; /* Allow line kill */ |
||||
typtr->tyikillc = TY_KILLCH; /* Set line kill to ^U */ |
||||
typtr->tyicursor = 0; /* Start of input line */ |
||||
typtr->tyoflow = TRUE; /* Handle flow control */ |
||||
typtr->tyoheld = FALSE; /* Output not held */ |
||||
typtr->tyostop = TY_STOPCH; /* Stop char is ^S */ |
||||
typtr->tyostart = TY_STRTCH; /* Start char is ^Q */ |
||||
typtr->tyocrlf = TRUE; /* Send CRLF for NEWLINE*/ |
||||
typtr->tyifullc = TY_FULLCH; /* Send ^G when buffer */ |
||||
/* is full */ |
||||
|
||||
/* Initialize UART */ |
||||
struct gpio_csreg *gptr;
|
||||
struct clock_csreg *cptr; |
||||
|
||||
/* Enable 'clock' on peripherals */ |
||||
cptr = (struct clock_csreg *)CLOCK_BASE; |
||||
cptr->apb2enr |= (1 << IOPAEN) | (1 << USART1EN); |
||||
|
||||
/* Set in and output mode */ |
||||
gptr = (struct gpio_csreg *)(0x40010800); |
||||
gptr->crh = 0x44444894; |
||||
|
||||
/* Enable peripheral */ |
||||
uptr = (struct uart_csreg *)(0x40013800); |
||||
uptr->cr1 &= ~(1 << UART_EN); |
||||
|
||||
/* Set baudrate 115200 */ |
||||
uptr->brr = 0x00000045; |
||||
|
||||
uptr->cr1 |= (1 << UART_TX_EN) | (1 << UART_RX_EN); /* Enable lines */ |
||||
uptr->cr1 |= (1 << UART_INTR_RX) | (1 << UART_INTR_TX); /* Enable interrupts */
|
||||
|
||||
/* Set and enable interrupt vector */ |
||||
set_evec(devptr->dvirq, (uint32)devptr->dvintr); |
||||
*NVIC_ISER1 |= (1 << 5); |
||||
|
||||
/* Start the device */ |
||||
uptr->cr1 |= (1 << UART_EN); |
||||
|
||||
// ttykickout(uptr);
|
||||
return OK; |
||||
} |
||||
@ -0,0 +1,25 @@
|
||||
/* ttykickout.c - ttykickout */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
#include <avr/interrupt.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttykickout - "Kick" the hardware for a tty device, causing it to |
||||
* generate an output interrupt (interrupts disabled) |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
void ttykickout( |
||||
struct uart_csreg *csrptr /* Address of UART's CSRs */ |
||||
) |
||||
{ |
||||
/* Force the UART hardware generate an output interrupt */ |
||||
// STM32 specific csrptr->cr1 |= (1 << UART_INTR_TX);
|
||||
// STM32 specific *NVIC_STIR = 0x25; /* Generate general UART interrupt */
|
||||
|
||||
cli(); |
||||
ttyhandler(1, 'X', 1); /* 1, 'X' arguments useless */ |
||||
sei(); |
||||
|
||||
return; |
||||
} |
||||
@ -0,0 +1,44 @@
|
||||
/* ttyputc.c - ttyputc */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttyputc - Write one character to a tty device (interrupts disabled) |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
devcall ttyputc( |
||||
struct dentry *devptr, /* Entry in device switch table */ |
||||
char ch /* Character to write */ |
||||
) |
||||
{ |
||||
//struct uart_csreg * uptr;
|
||||
struct ttycblk *typtr; /* Pointer to tty control block */ |
||||
|
||||
//uptr = (struct uart_csreg *)devptr->csreg;
|
||||
typtr = &ttytab[devptr->dvminor]; |
||||
|
||||
/* Handle output CRLF by sending CR first */ |
||||
|
||||
if ( ch==TY_NEWLINE && typtr->tyocrlf ) { |
||||
ttyputc(devptr, TY_RETURN); |
||||
} |
||||
|
||||
|
||||
wait(typtr->tyosem); /* Wait for space in queue */ |
||||
*typtr->tyotail++ = ch; |
||||
|
||||
/* Wrap around to beginning of buffer, if needed */ |
||||
|
||||
if (typtr->tyotail >= &typtr->tyobuff[TY_OBUFLEN]) { |
||||
typtr->tyotail = typtr->tyobuff; |
||||
} |
||||
|
||||
/* Start output in case device is idle */ |
||||
//while () {
|
||||
//
|
||||
// uptr->dr =
|
||||
//}
|
||||
ttykickout((struct uart_csreg *)devptr->dvcsr); |
||||
|
||||
return OK; |
||||
} |
||||
@ -0,0 +1,68 @@
|
||||
/* ttyread.c - ttyread */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttyread - Read character(s) from a tty device (interrupts disabled) |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
devcall ttyread( |
||||
struct dentry *devptr, /* Entry in device switch table */ |
||||
char *buff, /* Buffer of characters */ |
||||
int32 count /* Count of character to read */ |
||||
) |
||||
{ |
||||
struct ttycblk *typtr; /* Pointer to tty control block */ |
||||
int32 avail; /* Characters available in buff.*/ |
||||
int32 nread; /* Number of characters read */ |
||||
int32 firstch; /* First input character on line*/ |
||||
char ch; /* Next input character */ |
||||
|
||||
if (count < 0) { |
||||
return SYSERR; |
||||
} |
||||
typtr= &ttytab[devptr->dvminor]; |
||||
|
||||
if (typtr->tyimode != TY_IMCOOKED) { |
||||
|
||||
/* For count of zero, return all available characters */ |
||||
|
||||
if (count == 0) { |
||||
avail = semcount(typtr->tyisem); |
||||
if (avail == 0) { |
||||
return 0; |
||||
} else { |
||||
count = avail; |
||||
} |
||||
} |
||||
for (nread = 0; nread < count; nread++) { |
||||
*buff++ = (char) ttygetc(devptr); |
||||
} |
||||
return nread; |
||||
} |
||||
|
||||
/* Block until input arrives */ |
||||
|
||||
firstch = ttygetc(devptr); |
||||
|
||||
/* Check for End-Of-File */ |
||||
|
||||
if (firstch == EOF) { |
||||
return EOF; |
||||
} |
||||
|
||||
/* Read up to a line */ |
||||
|
||||
ch = (char) firstch; |
||||
*buff++ = ch; |
||||
nread = 1; |
||||
while ( (nread < count) && (ch != TY_NEWLINE) && |
||||
(ch != TY_RETURN) ) { |
||||
ch = ttygetc(devptr); |
||||
*buff++ = ch; |
||||
nread++; |
||||
} |
||||
return nread; |
||||
|
||||
return OK; |
||||
} |
||||
@ -0,0 +1,29 @@
|
||||
/* ttywrite.c - ttywrite */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ttywrite - Write character(s) to a tty device (interrupts disabled) |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
devcall ttywrite( |
||||
struct dentry *devptr, /* Entry in device switch table */ |
||||
char *buff, /* Buffer of characters */ |
||||
int32 count /* Count of character to write */ |
||||
) |
||||
{ |
||||
/* Handle negative and zero counts */ |
||||
|
||||
if (count < 0) { |
||||
return SYSERR; |
||||
} else if (count == 0){ |
||||
return OK; |
||||
} |
||||
|
||||
/* Write count characters one at a time */ |
||||
|
||||
for (; count>0 ; count--) { |
||||
ttyputc(devptr, *buff++); |
||||
} |
||||
return OK; |
||||
} |
||||
Loading…
Reference in new issue