Övning 7 Timer, serieport
7.6 timer_1 Memory-Mapped addresses 0x920 status 0x924 control 0x928 periodl 0x92C periodh 0x930 snapl 0x934 snaph 15 0 Run TO (Time-Out) ITO cont start stop
timer_1 start D Q cl Q run stop 50 MHz clock write from program load -1 copy period copy counter snap-shot read from program zero D cl set Q Q clear from program read from program time-out
snaptime volatile int * const timer_1_base = ( (volatile int *) 0x920 ); unsigned int snaptime( void ) { unsigned int snaphigh; unsigned int snaplow; unsigned int snap; } timer_1_base[ 4 ] = 0; snaphigh = timer_1_base[ 5 ] & 0xffff; snaplow = timer_1_base[ 4 ] & 0xffff; snap = (snaphigh << 16) snaplow; return( snap );
7.1a Seriell kommunikation Bit för bit i stället för alla på en gång Sändare parallella data in skiftregister seriell kabel skiftregister parallella data ut Mottagare
7.1b Synkron seriell kommunikation Klocksignalen överförs på en extrasladd Synkroniseringskoder skickas då och då så att skiftregistren börjar på samma bit clock seriell kabel klocksignal clock
7.1b Asynkron seriell överföring Avkänningstidpunkter 0 x x x x x x x P 1 1 1 1 7-bitars ASCII en startbit (0) en Paritetsbit (P) Stoppbit(ar) (1:or) Synkroniseringsflank övergång från 1:a till 0:a
7.1 Tecknet '&' = 0x26 0x26 med 7 binära bitar = 010 0110 minst signifikant bit sänds först P = 1 så att vi får jämnt antal 1:or totalt 0 0 1 1 0 0 1 0 1 1 1 7-bitars ASCII en startbit (0) en Paritetsbit (P) Stoppbit(ar) (1:or) Synkroniseringsflank övergång från 1:a till 0:a
7.1g Olika bitfrekvens hos sändare och mottagare Rätt hastighet -12 V (1) +12 V (0) -12 V (1) avkänningstidpunk ter Om mottagaren är lite för snabb +12 V (0)
7.2 Serieport i nios2 RxDATA (RD) uart_0 0x860 0x864 0x868 TxDATA (WR) 31 16 15 8 7 6 0 STATUS RxRdy (IBF) TxRdy (OBE) läsning av RxDATA nollställer IBF skrivning till TxDATA nollställer OBE
7.3 Eko.text.align 2.global main main: call in_char # get character from keyboard mov r4,r2 # copy return-value to parameter call out_char # send to screen br main # do it again
Eko i C int in_char( void ); /* Extern funktion "importeras". */ void out_char( int ); /* Extern funktion "importeras". */ int main( void ) { int c; while( 1 ) /* Oändlig slinga. */ { c = in_char(); /* Vänta på tecken, läs ett. */ out_char( c ); /* Skriv tecknet till serieport. */ } }
7.3 Eko: in_char.equ uart_0,0x860.equ uart_rxrdybitmask,0x80.text.align 2.global in_char in_char: movia r8,uart_0 # set uart_0 address ldw r9,8(r8) # get uart_0 status andi r9,r9,uart_rxrdybitmask# check RxRdy bit beq r9,r0,in_char # wait if nothing new ldw r2,0(r8) # get new data, and clear RxRdy andi r2,r2,0xff # clear unspecified bits from ser-port ret # return to caller
7.3 Eko: out_char Nästan som in_char men inte riktigt.equ uart_0,0x860.equ uart_txrdybitmask,0x40.text.align 2.global out_char out_char: movia r8,uart_0 # set uart_0 address ldw r9,8(r8) # get uart_0 status andi r9,r9,uart_txrdybitmask # check TxRdy bit beq r9,r0,out_char # wait if busy stw r4,4(r8) # send new data ret # return to caller
out_char i C volatile unsigned int * const uart0 = (volatile unsigned int *) 0x860; #define UART_RECEIVE_BIT (0x80) /* RXRDY */ #define UART_TRANSMIT_BIT (0x40) /* TXRDY */ void out_char( int c ) { unsigned int tmp = 0; while( 0 == tmp ) { tmp = uart0[ 2 ] & UART_TRANSMIT_BIT; } uart0[ 1 ] = c & 0xff; }
in_char i C volatile unsigned int * const uart0 = (volatile unsigned int *) 0x860; #define UART_RECEIVE_BIT (1<<7) /* RXRDY */ #define UART_TRANSMIT_BIT (1<<6) /* TXRDY */ int in_char( void ) { while( 0 == (uart0[ 2 ] & UART_RECEIVE_BIT) ); return( uart0[ 0 ] & 0xff ); }
7.5 in_charx non-blocking input.text.align 2.global in_charx in_charx: movi r2,-1 # set return value for no-input case movia r8,uart_0 # set uart_0 address ldw r9,8(r8) # get uart_0 status andi r9,r9,uart_rxrdybitmask # check RxRdy bit beq r9,r0,endg # return if nothing new ldw r9,0(r8) # get new data andi r2,r9,0xff # tidy up input data endg: ret # return to caller
in_charx i C volatile unsigned int * const uart0 = (volatile unsigned int *) 0x860; #define UART_RECEIVE_BIT (1<<7) /* RXRDY */ #define UART_TRANSMIT_BIT (1<<6) /* TXRDY */ int in_char( void ) { /* Pre-load return value in case nothing new arrived. */ int r = -1; } if(uart0[2] & UART_RECEIVE_BIT) r = uart0[0] & 0xff; return( r );
in_charx i C volatile unsigned int * const uart0 = (volatile unsigned int *) 0x860; #define UART_RECEIVE_BIT (0x80) /* RXRDY, bit 7 */ #define UART_TRANSMIT_BIT (0x40) /* TXRDY, bit 6 */ int in_charx( void ) { } unsigned int tmp = uart0[ 2 ] & UART_RECEIVE_BIT; if( tmp ) return( uart0[ 0 ] & 0xff ); else return( -1 );
7.5 out_charx, non-blocking output.texṭ align 2.global out_charx out_charx: movi r2,-1 # set return value for busy case movia r8,uart_0 # set uart_0 address ldw r9,8(r8) # get uart_0 status andi r9,r9,uart_txrdybitmask # check TxRdy bit beq r9,r0,endp # return if busy stw r4,4(r8) # send data movi r2,1 # reset return value, indicates success endp: ret # return to caller
7.5 Eko non-blocking version.data.align 2.text.global main main: call in_charx # anything new? blt r2,r0,main # if not, wait mov r4,r2 # copy input to parameter put: push r4 # save r4 call out_charx # try to send pop r4 # restore r4 blt r2,r0,put # if transmitter busy, wait br main
7.6 Korsvis kommunikation Ena labbgruppen putty DE2 Andra labbgruppen putty DE2
7.6 Korsvis kommunikation Nya subrutiner behövs rec_charx START check_timer. tick, puttime send_char in_charx? NEJ rec_charx som in_charx men för annan serieport JA send_char send_char som out_char men för annan serieport rec_charx? NEJ send_char, out_char: blocking JA väntan blir högst 100 μs out_char
7.6 send_char volatile int * uart1_receive = (volatile int *) 0x880; volatile int * uart1_send = (volatile int *) 0x884; volatile int * uart1_status = (volatile int *) 0x888; #define UART_TRANSMIT_BIT (1 << 6) void send_char( int c ) { int status_check = 0; while( 0 == status_check ) status_check = *uart1_status & UART_TRANSMIT_BIT; } *uart1_send = c & 0xff;
7.6 rec_charx volatile int * uart1_receive = (volatile int *) 0x880; volatile int * uart1_send = (volatile int *) 0x884; volatile int * uart1_status = (volatile int *) 0x888; int rec_charx( void ) { /* Pre-load return value in case nothing new arrived. */ int returnvalue = -1; /* If RxRdy status bit is set, read new input. */ if( *uart1_status & 0x80 ) returnvalue = *uart1_receive & 0xff; } return( returnvalue ); /* Return to caller. */