// Descripción: // Función de inicialización del TIMER0 // // Argumentos de Entrada: VOID // Argumentos de Salida: VOID // // Autores: Equipo docente de SDII //------------------------------------------------------------------------------ void timers_init (void) { mbar_writeByte(MCFSIM_PIVR,V_BASE); // Fija comienzo de vectores de interrupción en V_BASE. ACCESO_A_MEMORIA_LONG(DIR_VTMR0)= (ULONG)_prep_TOUT0; // Escribimos la dirección de la función para TMR0 mbar_writeShort(MCFSIM_TMR0, (PRESCALADO_TMR0-1)<<8|0x3D); // TMR0: PS=1-1=0 CE=00 OM=1 ORI=1 FRR=1 CLK=10 RST=1 mbar_writeShort(MCFSIM_TCN0, 0x0000); // Ponemos a 0 el contador del TIMER0 mbar_writeShort(MCFSIM_TRR0, CNT_INT0); // Fijamos la cuenta final del contador }
//------------------------------------------------------ // void rutina_tout3(void) // // Descripción: // Función de atención a la interrupción para TIMER3 //------------------------------------------------------ void rutina_tout3(void){ mbar_writeShort(MCFSIM_TER3,BORRA_REF); // Reset del bit de fin de cuenta if(estado.jugando == NO_JUGANDO) { if(cont_retardo > 0){ cont_retardo--; // Decrementa el contador cada 125us } } }
//------------------------------------------------------ void cambiaFrecuencia(void){ mbar_writeShort(MCFSIM_TCN0, 0x0000); // Ponemos a 0 el contador del TIMER0 if(melodia.frecTetris[melodia.notaActual] == 0) { mbar_writeShort(MCFSIM_TMR0, (PRESCALADO-1)<<8|0x28); } else { if(melodia.notaActual - UNO >= 0) { if(melodia.frecTetris[melodia.notaActual-1] == 0) { //Reiniciamos el contador tras un silencio mbar_writeShort(MCFSIM_TMR0, (PRESCALADO-1)<<8|0x2D); //Comentar que metemos en los registros } mbar_writeShort(MCFSIM_TRR0, MCF_CLK/(melodia.frecTetris[melodia.notaActual]*PRESCALADO*16*(MODIFICADOR_FREC-estado.nivel))); } mbar_writeShort(MCFSIM_TRR0, MCF_CLK/(melodia.frecTetris[melodia.notaActual]*PRESCALADO*16*(MODIFICADOR_FREC-estado.nivel))); } }
//------------------------------------------------------ // void rutina_tout2(void) // // Descripción: // Función de atención a la interrupción para TIMER2 //------------------------------------------------------ void rutina_tout2(void) { mbar_writeShort(MCFSIM_TER2,BORRA_REF); // Reset del bit de fin de cuenta if((estado.jugando==JUGANDO) && (estado.juego == JUEGO_TETRIS)) { actualizaTiempoMelodia(); } }
//------------------------------------------------------ // void rutina_tout1(void) // // Descripción: // Función de atención a la interrupción para TIMER1 //------------------------------------------------------ void rutina_tout1(void) { mbar_writeShort(MCFSIM_TER1,BORRA_REF); // Reset del bit de fin de cuenta if(estado.jugando==JUGANDO) { actualizaRelojes(); } }
phys_size_t initdram(int board_type) { u32 dramsize = 0; /* * Check to see if the SDRAM has already been initialized * by a run control tool */ if (!(mbar_readLong(MCFSIM_DCR) & 0x8000)) { u32 RC, temp; RC = (CONFIG_SYS_CLK / 1000000) >> 1; RC = (RC * 15) >> 4; /* Initialize DRAM Control Register: DCR */ mbar_writeShort(MCFSIM_DCR, (0x8400 | RC)); __asm__("nop"); mbar_writeLong(MCFSIM_DACR0, 0x00003224); __asm__("nop"); /* Initialize DMR0 */ dramsize = (CONFIG_SYS_SDRAM_SIZE << 20); temp = (dramsize - 1) & 0xFFFC0000; mbar_writeLong(MCFSIM_DMR0, temp | 1); __asm__("nop"); mbar_writeLong(MCFSIM_DACR0, 0x0000322c); mb(); __asm__("nop"); /* Write to this block to initiate precharge */ *(u32 *) (CONFIG_SYS_SDRAM_BASE) = 0xa5a5a5a5; mb(); __asm__("nop"); /* Set RE bit in DACR */ mbar_writeLong(MCFSIM_DACR0, mbar_readLong(MCFSIM_DACR0) | 0x8000); __asm__("nop"); /* Wait for at least 8 auto refresh cycles to occur */ udelay(500); /* Finish the configuration by issuing the MRS */ mbar_writeLong(MCFSIM_DACR0, mbar_readLong(MCFSIM_DACR0) | 0x0040); __asm__("nop"); *(u32 *) (CONFIG_SYS_SDRAM_BASE + 0x800) = 0xa5a5a5a5; mb(); }
void uart_port_conf(int port) { u16 temp; /* Setup Ports: */ switch (port) { case 0: temp = mbar_readShort(MCF_GPIO_PAR_UART) & 0xFFF3; temp |= (MCF_GPIO_PAR_UART_U0TXD | MCF_GPIO_PAR_UART_U0RXD); mbar_writeShort(MCF_GPIO_PAR_UART, temp); break; case 1: temp = mbar_readShort(MCF_GPIO_PAR_UART) & 0xF0FF; temp |= (MCF_GPIO_PAR_UART_U1RXD_UART1 | MCF_GPIO_PAR_UART_U1TXD_UART1); mbar_writeShort(MCF_GPIO_PAR_UART, temp); break; case 2: temp = mbar_readShort(MCF_GPIO_PAR_UART) & 0xCFFF; temp |= (0x3000); mbar_writeShort(MCF_GPIO_PAR_UART, temp); break; } }
//------------------------------------------------------ // void rutina_tout0(void) // // Descripción: // Función de atención a la interrupción para TIMER0 //------------------------------------------------------ void rutina_tout0(void) { static int sumaSeno[MAX_FRECS]; // Almacena todos los valores (el sumatorio) de la parte imaginaria de la DFT static int sumaCoseno[MAX_FRECS]; // Almacena todos los valores (el sumatorio) de la parte real de la DFT int dato = ADC_dato(); // Número obtenido tras interpretar el número leído a la entrada (int ADC_leeRxRAM() de m5272adc_dac.c) mbar_writeShort(MCFSIM_TER0,BORRA_REF); // Reset del bit de fin de cuenta /* Se incrementa contadorDFT para llevar la cuenta de cuantas interrupciones van. Recorremos con i las 20 frecuencias. Si estamos en la primera interrupción, ponemos cada componente de los arrays sumaSeno[] y sumaCoseno[] a 0. Después se rellena cada posición de dichos arrays (cada posición representa una frecuencia distinta) con el dato multiplpicado por un valor de sinusoide10HZ[]. Para el seno este valor es resto de dividir entre el numero de muestras (400) el valor del paso correspondiente a cada frecuencia (pasos[i]) multiplicado por contadorDFT. Para el coseno es similar, hay que sumar al producto pasos[i] * contadorDFT el desfase necesario para convertir el seno en un coseno. Sabemos que cos(x) = sen(x + pi/2). Este desfase se traduce como un desfase de la cuarta parte de NUM_MUESTRAS_PERIODO_10HZ, que son 100 muestras. Después, si hemos hecho todas las interrupciones necesarias (contadorDFT == n_dft), contadorDFT se reinicia a 0, realizamos el desescalado de los arrays del seno y del coseno, y en el array S_out[] guardamos para cada frecuencia el resultado que devuelva la función busquedaBinaria de sumaCoseno[k]^2 + sumaSeno[k]^2, es decir, el módulo de la DFT. El objetivo de busquedaBinaria es escalar dicho módulo. */ contadorDFT++; // Incrementamos contadorDFT if (contadorDFT == 1) { // Si contadorDFT es 1 memset(sumaSeno, 0, MAX_FRECS); // Todas las posiciones de sumaSeno[i] se ponen a 0 memset(sumaCoseno, 0, MAX_FRECS); // Todas las posiciones de sumaCoseno[i] se ponen a 0 } for (i = 0; i < n_frecs; i++) { // Para cada frecuencia sumaSeno[i] += (dato * (sinusoide10Hz[(pasos[i] * (contadorDFT - 1))%NUM_MUESTRAS_PERIODO_10HZ])); // Rellenamos sumaSeno[i] con los valores correspondientes a cada frecuencia sumaCoseno[i] += (dato * (sinusoide10Hz[((pasos[i] * (contadorDFT - 1)) + NUM_MUESTRAS_PERIODO_10HZ/4)%NUM_MUESTRAS_PERIODO_10HZ])); // Rellenamos sumaCoseno[i] con los valores correspondientes a cada frecuencia } if (contadorDFT == n_dft) { // Si hemos hecho todas las interrupciones necesarias contadorDFT = 0; // Reiniciamos contadorDFT for (j = 0; j < n_frecs; j++) { // Para cada frecuencia sumaSeno[j] >>= 10; // Desescalado de 1024 (mover a la derecha 10 bits) para que no se produzcan desbordamientos sumaCoseno[j] >>= 10; // Desescalado de 1024 (mover a la derecha 10 bits) para que no se produzcan desbordamientos S_out[j] = busquedaBinaria((sumaCoseno[j] * sumaCoseno[j]) + (sumaSeno[j] * sumaSeno[j])); // Almacenamos en S_out[j] el módulo cuantificado de la DFT de cada frecuencia if (j == 0) { dft_lcd = S_out[0]; frec_lcd = 0; } if (j > 0 && S_out[j] > dft_lcd) { dft_lcd = S_out[j]; frec_lcd = 10 * pasos[j]; } } }
void cpu_init_f(void) { #ifndef CONFIG_WATCHDOG /* Disable the watchdog if we aren't using it */ mbar_writeShort(MCF_WTM_WCR, 0); #endif /* FlexBus Chipselect */ init_fbcs(); #ifdef CONFIG_SYS_MCF_SYNCR /* Set clockspeed according to board header file */ mbar_writeLong(MCF_FMPLL_SYNCR, CONFIG_SYS_MCF_SYNCR); #else /* Set clockspeed to 100MHz */ mbar_writeLong(MCF_FMPLL_SYNCR, MCF_FMPLL_SYNCR_MFD(0) | MCF_FMPLL_SYNCR_RFD(0)); #endif while (!mbar_readByte(MCF_FMPLL_SYNSR) & MCF_FMPLL_SYNSR_LOCK) ; }
int watchdog_init(void) { mbar_writeShort(MCF_WTM_WCR, MCF_WTM_WCR_EN); return (0); }
int watchdog_disable(void) { mbar_writeShort(MCF_WTM_WCR, 0); return (0); }
void watchdog_reset(void) { mbar_writeShort(MCF_WTM_WSR, 0x5555); mbar_writeShort(MCF_WTM_WSR, 0xAAAA); }
/* * Breath some life into the CPU... * * Set up the memory map, * initialize a bunch of registers, * initialize the UPM's */ void cpu_init_f (void) { #ifndef CFG_PLL_BYPASS /* * Setup the PLL to run at the specified speed * */ volatile unsigned long cpll = mbar2_readLong(MCFSIM_PLLCR); unsigned long pllcr; #ifdef CFG_FAST_CLK pllcr = 0x925a3100; /* ~140MHz clock (PLL bypass = 0) */ #else pllcr = 0x135a4140; /* ~72MHz clock (PLL bypass = 0) */ #endif cpll = cpll & 0xfffffffe; /* Set PLL bypass mode = 0 (PSTCLK = crystal) */ mbar2_writeLong(MCFSIM_PLLCR, cpll); /* Set the PLL to bypass mode (PSTCLK = crystal) */ mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* set the clock speed */ pllcr ^= 0x00000001; /* Set pll bypass to 1 */ mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* Start locking (pll bypass = 1) */ udelay(0x20); /* Wait for a lock ... */ #endif /* #ifndef CFG_PLL_BYPASS */ /* * NOTE: by setting the GPIO_FUNCTION registers, we ensure that the UART pins * (UART0: gpio 30,27, UART1: gpio 31, 28) will be used as UART pins * which is their primary function. * ~Jeremy */ mbar2_writeLong(MCFSIM_GPIO_FUNC, CFG_GPIO_FUNC); mbar2_writeLong(MCFSIM_GPIO1_FUNC, CFG_GPIO1_FUNC); mbar2_writeLong(MCFSIM_GPIO_EN, CFG_GPIO_EN); mbar2_writeLong(MCFSIM_GPIO1_EN, CFG_GPIO1_EN); mbar2_writeLong(MCFSIM_GPIO_OUT, CFG_GPIO_OUT); mbar2_writeLong(MCFSIM_GPIO1_OUT, CFG_GPIO1_OUT); /* * dBug Compliance: * You can verify these values by using dBug's 'ird' * (Internal Register Display) command * ~Jeremy * */ mbar_writeByte(MCFSIM_MPARK, 0x30); /* 5249 Internal Core takes priority over DMA */ mbar_writeByte(MCFSIM_SYPCR, 0x00); mbar_writeByte(MCFSIM_SWIVR, 0x0f); mbar_writeByte(MCFSIM_SWSR, 0x00); mbar_writeLong(MCFSIM_IMR, 0xfffffbff); mbar_writeByte(MCFSIM_SWDICR, 0x00); mbar_writeByte(MCFSIM_TIMER1ICR, 0x00); mbar_writeByte(MCFSIM_TIMER2ICR, 0x88); mbar_writeByte(MCFSIM_I2CICR, 0x00); mbar_writeByte(MCFSIM_UART1ICR, 0x00); mbar_writeByte(MCFSIM_UART2ICR, 0x00); mbar_writeByte(MCFSIM_ICR6, 0x00); mbar_writeByte(MCFSIM_ICR7, 0x00); mbar_writeByte(MCFSIM_ICR8, 0x00); mbar_writeByte(MCFSIM_ICR9, 0x00); mbar_writeByte(MCFSIM_QSPIICR, 0x00); mbar2_writeLong(MCFSIM_GPIO_INT_EN, 0x00000080); mbar2_writeByte(MCFSIM_INTBASE, 0x40); /* Base interrupts at 64 */ mbar2_writeByte(MCFSIM_SPURVEC, 0x00); mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); /* Enable a 1 cycle pre-drive cycle on CS1 */ /* Setup interrupt priorities for gpio7 */ /* mbar2_writeLong(MCFSIM_INTLEV5, 0x70000000); */ /* IDE Config registers */ mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); mbar2_writeLong(MCFSIM_IDECONFIG2, 0x00000000); /* * Setup chip selects... */ mbar_writeShort(MCFSIM_CSAR1, CFG_CSAR1); mbar_writeShort(MCFSIM_CSCR1, CFG_CSCR1); mbar_writeLong(MCFSIM_CSMR1, CFG_CSMR1); mbar_writeShort(MCFSIM_CSAR0, CFG_CSAR0); mbar_writeShort(MCFSIM_CSCR0, CFG_CSCR0); mbar_writeLong(MCFSIM_CSMR0, CFG_CSMR0); /* enable instruction cache now */ icache_enable(); }
/* Function: timer2_inter_atendida Permite que se vuelva a activar la interrupcion. Hay que llamarla cada vez que se atiende una interrupcion de timer 2. */ void timer2_inter_atendida(void) { mbar_writeShort(MCFSIM_TER2, BORRA_REF); }
/* Function: timer1_init Inicializa el temporizador 0 con los valores definidos en su configuracion de constantes. See also:<Configuración del timer1><CONFIG_TIMER1><REFERENCIA_TIMER1> */ void timer2_init(void) { mbar_writeShort(MCFSIM_TMR2, CONFIG_TIMER2); mbar_writeShort(MCFSIM_TCN2, BORRA_CONTADOR); mbar_writeShort(MCFSIM_TRR2, REFERENCIA_TIMER2); }
/* Function: timer1_init Inicializa el temporizador 0 con los valores definidos en su configuracion de constantes. See also:<Configuración del timer1><CONFIG_TIMER1><REFERENCIA_TIMER1> */ void timer1_init(void) { mbar_writeShort(MCFSIM_TMR1, CONFIG_TIMER1); mbar_writeShort(MCFSIM_TCN1, BORRA_CONTADOR); mbar_writeShort(MCFSIM_TRR1, REFERENCIA_TIMER1); }
/* Function: timer0_init Inicializa el temporizador 0 con los valores definidos en su configuracion de constantes. See also:<Configuración del timer0><CONFIG_TIMER0><REFERENCIA_TIMER0> */ void timer0_init(void) { mbar_writeShort(MCFSIM_TMR0, CONFIG_TIMER0_APAGADO); mbar_writeShort(MCFSIM_TCN0, BORRA_CONTADOR); // Ponemos a 0 el contador del TIMER0 mbar_writeShort(MCFSIM_TRR0, REFERENCIA_TIMER0); }
//------------------------------------------------------ void pararMelodia(void) { mbar_writeShort(MCFSIM_TMR0, (PRESCALADO-1)<<8|0x28); //Apagamos el timer }
//------------------------------------------------------ void enciendeMelodia(void) { melodia.notaActual = 0; mbar_writeShort(MCFSIM_TMR0, (PRESCALADO-1)<<8|0x2D); //Comentar que metemos en los registros mbar_writeShort(MCFSIM_TRR0, MCF_CLK/(melodia.frecTetris[melodia.notaActual]*PRESCALADO*16*(MODIFICADOR_FREC-estado.nivel))); }