/*------------------------------------------------------------------- ** ** Soluciones del examen de Programación de Sistemas y Dispositivos ** Curso 2020-21, Segunda Convocatoria, 8 de julio de 2021 ** **-----------------------------------------------------------------*/ /*------------------------------------------------------------------- ** Ejercicio 1 **-----------------------------------------------------------------*/ #include #include #include #include #include #include #include void keypad_isr( void ) __attribute__ ((interrupt ("IRQ"))); volatile boolean flag; volatile char ch; void main( void ) { sys_init(); uart0_init(); segs_init(); keypad_init(); flag = FALSE; keypad_open( keypad_isr ); while( 1 ) if( flag ) { segs_putchar( ch ); ch += ( ch < 10 ? '0' : 'a'-10 ); uart0_putchar( ch ); flag = FALSE; } } void keypad_isr( void ) { ch = keypad_getchar(); if( ch != KEYPAD_FAILURE ) flag = TRUE; I_ISPC = BIT_KEYPAD; } /*------------------------------------------------------------------- ** Ejercicio 2 **-----------------------------------------------------------------*/ #include #include #include #define Fin ((uint32)8000000U) #define CLK_NORMAL (0) #define CLK_SLOW (1) void uart0_putClockFreq( void ) { uint8 slow_bit, slow_val; uint8 mdiv, pdiv, sdiv; slow_bit = ( CLKSLOW & (1 << 4) ) >> 4; slow_val = CLKSLOW & 0xf; mdiv = (PLLCON & (0xff << 12) ) >> 12; pdiv = (PLLCON & (0x3f << 4) ) >> 4; sdiv = PLLCON & 0x3; if( slow_bit == CLK_SLOW ) { uart0_puts( "El microcontrolador está en modo SLOW a una frecuencia de " ); if( slow_val ) uart0_putint( Fin / (2*slow_val) ); // Ver pag. 40 del tema 1 else uart0_putint( Fin ); uart0_puts( " hercios\n" ); } else { uart0_puts( "El microcontrolador está en modo NORMAL a una frecuencia de " ); uart0_putint( ((mdiv + 8)*Fin) / ((pdiv+2) << sdiv) ); // Ver pag. 38 del tema 1 uart0_puts( " hercios\n" ); } } /*------------------------------------------------------------------- ** Ejercicio 2 **-----------------------------------------------------------------*/ extern uint8 lcd_buffer[]; void lcd_clearDMA( void ) { uint32 zero; zero = 0; ZDISRC0 = (2 << 30) | (3 << 28) | (uint32) &zero; // datos de 32b, dirección fija ZDIDES0 = (2 << 30) | (1 << 28) | (uint32) lcd_buffer; // recomendada, dirección post-incrementada ZDICNT0 = (2 << 28) | (1 << 26) | LCD_BUFFER_SIZE; // whole service, unit transfer, polling mode, no autoreload ZDICNT0 |= (1 << 20); // Enable DMA (según manual debe hacerse en escritura separada a la escritura del resto de registros) ZDCON0 = 1; // start DMA } /*------------------------------------------------------------------- ** Ejercicio 4 **-----------------------------------------------------------------*/ #include #include extern uint8 font[]; extern uint8 lcd_buffer[]; void lcd_putchar_inverted( uint16 x, uint16 y, uint8 color, char ch ) { uint8 row, col; uint8 *bitmap; bitmap = font + ch*16; for( row=0; row<16; row++ ) for( col=0; col<8; col++ ) if( bitmap[row] & (0x80 >> col) ) lcd_putpixel( x+col, y+row, WHITE ); else lcd_putpixel( x+col, y+row, color ); }