/*------------------------------------------------------------------- ** ** Soluciones del examen de Programación de Sistemas y Dispositivos ** Curso 2021-22, Primera Convocatoria, 19 de enero de 2022 ** **-----------------------------------------------------------------*/ /*------------------------------------------------------------------- ** Ejercicio 1 **-----------------------------------------------------------------*/ #include #include #include #include #define TICKS_PER_SEC (1000) /* Declaración de fifo de punteros a funciones */ #define BUFFER_LEN (512) typedef void (*pf_t)(void); typedef struct fifo { uint16 head; uint16 tail; uint16 size; pf_t buffer[BUFFER_LEN]; } fifo_t; void fifo_init( void ); void fifo_enqueue( pf_t pf ); pf_t fifo_dequeue( void ); boolean fifo_is_empty( void ); boolean fifo_is_full( void ); /* Declaración de recursos */ volatile fifo_t fifo; /* Declaración de tareas */ void Task1( void ); void Task2( void ); void Task3( void ); /* Declaración de RTI */ void isr_tick( void ) __attribute__ ((interrupt ("IRQ"))); void main( void ) { pf_t pf; sys_init(); timers_init(); fifo_init(); timer0_open_tick( isr_tick, TICKS_PER_SEC ); while( 1 ) { while( !fifo_is_empty() ) { pf = fifo_dequeue(); (*pf)(); } } } void isr_tick( void ) { static uint8 cont10ticks = 10; static uint8 cont20ticks = 20; static uint8 cont30ticks = 30; if( !(--cont10ticks) ) { cont10ticks = 10; fifo_enqueue( Task1 ); } if( !(--cont20ticks) ) { cont20ticks = 20; fifo_enqueue( Task2 ); } if( !(--cont30ticks) ) { cont30ticks = 30; fifo_enqueue( Task3 ); } I_ISPC = BIT_TIMER0; } /*------------------------------------------------------------------- ** Ejercicio 2 **-----------------------------------------------------------------*/ #include #include extern uint8 font[]; void lcd_putchar_upsidedown( uint16 x, uint16 y, uint8 color, char ch ) { uint8 line, row; uint8 *bitmap; bitmap = font + ch*16; for( line=0; line<16; line++ ) for( row=0; row<8; row++ ) if( bitmap[line] & (0x80 >> row) ) lcd_putpixel( x+7-row, y+15-line, color ); else lcd_putpixel( x+7-row, y+15-line, WHITE ); } /*------------------------------------------------------------------- ** Ejercicio 3 **-----------------------------------------------------------------*/ #include #include #include extern uint8 lcd_buffer[]; void lcd_snapshot( uint8 action, uint8 *capture ) { uint32 srcAddr, dstAddr; if( action ){ srcAddr = (uint32) lcd_buffer; dstAddr = (uint32) capture; } else { srcAddr = (uint32) capture; dstAddr = (uint32) lcd_buffer; } ZDISRC0 = (2 << 30) | (1 << 28) | srcAddr; // datos de 32b, dirección post-incrementada ZDIDES0 = (2 << 30) | (1 << 28) | dstAddr; // 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 #include #include #define FS (16000) void isr_timer0( void ) __attribute__ ((interrupt ("IRQ"))); uint16 counter, toggleWave; void iss_buzz( uint16 freqHz ) { if( freqHz ) { counter = 0; toggleWave = FS / (2*freqHz); timer0_open_tick( isr_timer0, FS ); } else timer0_close(); } void isr_timer0( void ) { static int16 sample = MAX_INT16; if( ++counter == toggleWave ){ counter = 0; sample = -sample; } iis_putSample( sample, sample ); I_ISPC = BIT_TIMER0; }