logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

PWM na AT91SAM7S64 z FreeRTOS - konfiguracja kanału 0 nie działa

nenpa8lo 07 Lip 2009 01:18 1446 3
REKLAMA
  • #1 6747248
    nenpa8lo
    Poziom 17  
    Posty: 260
    Pomógł: 15
    Witam,

    Pierwszy raz ustawiam PWM na SAM7S64. Całość działa na FreeRTOS. Chcę ustawić PWM na kanale 0 (pinA0) o okresie 1sek.
    void
    audio_hw_conf(void)
    {
      // Confiugre PIO (Parallel Input/Output Controller).
      AT91C_BASE_PIOA->PIO_PDR = AT91C_PWMC_CHID0;                                           // Enable peripheral function.
      AT91C_BASE_PIOA->PIO_ASR = AT91C_PWMC_CHID0;                                           // Peripheral function A.
    
    
      // Configure PMC (Power Management Controller).
      AT91C_BASE_PMC->PMC_PCER = AT91C_ID_PWMC;                                              // Power up PWM Controller.
    
    
      // Configure AIC (Advanced Interrupt Controller).
      AT91F_AIC_ConfigureIt(7, AT91C_AIC_PRIOR_1, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
                        &audio_pwm0_isr_wrapper);
      AT91C_BASE_AIC->AIC_IECR = 0x1 << 7;
    
    
      // Configure PWMC (Pulse Width Modulation Controller).
      AT91C_BASE_PWMC->PWMC_MR = 0;                                                          // Clear mode register.
      AT91C_BASE_PWMC->PWMC_CH[AT91C_PWMC_CHID0].PWMC_CMR =
      AT91C_PWMC_CPRE_MCK_1024 | AT91C_PWMC_CPOL;                                            // MCK/1024 and polarity 1.
      AT91C_BASE_PWMC->PWMC_CH[AT91C_PWMC_CHID0].PWMC_CPRDR = 0x00004650;                    // Period set to 1sec.
      AT91C_BASE_PWMC->PWMC_CH[AT91C_PWMC_CHID0].PWMC_CDTYR = 0x00002328;                    // 50% duty cycle.
      AT91C_BASE_PWMC->PWMC_IER = AT91C_PWMC_CHID0;                                          // Enable interrupt from chn0.
      AT91C_BASE_PWMC->PWMC_ENA = AT91C_PWMC_CHID0;                                          // Enable channel 0.
    }
    
    
    // Audio PWM channel 0 interrupt handler.
    
    void
    audio_pwm0_isr_handler (void)
    {
      //AT91C_BASE_PWMC->PWMC_CH[AT91C_PWMC_CHID0].CUPDR = newvalue
      AT91C_BASE_AIC->AIC_EOICR = 0;
    }
    
    
    // Audio PWM channel 0 wrapper.
    
    void
    audio_pwm0_isr_wrapper (void)
    {
      portSAVE_CONTEXT();
      audio_pwm0_isr_handler();
      portRESTORE_CONTEXT();
    }


    Czy jeszcze zapomniałem o jakimś rejestrze?
  • REKLAMA
  • #2 6751346
    nenpa8lo
    Poziom 17  
    Posty: 260
    Pomógł: 15
    Znalazłem błąd
    // Configure PMC (Power Management Controller).
      AT91C_BASE_PMC->PMC_PCER = AT91C_ID_PWMC;                                              // Power up PWM Controller.
    
    
    a powinn być
    // Configure PMC (Power Management Controller).
      AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PWMC;                                              // Power up PWM Controller.
    
    
    Niestety dalej nie działa.
  • REKLAMA
  • #3 6764569
    nenpa8lo
    Poziom 17  
    Posty: 260
    Pomógł: 15
    Znalazłem błąd w ustawieniu zegara, używany był slow clock. Teraz używam poniższej konfuguracji, ale dalej PWM nie działa. Nawet wywaliłem FreeRTOSa i coś jest nie tak:
     AT91PS_PMC     pPMC = AT91C_BASE_PMC;
    
        //* Set Flash Waite sate
    	//  Single Cycle Access at Up to 30 MHz, or 40
    	//  if MCK = 47923200 I have 50 Cycle for 1 useconde ( flied MC_FMR->FMCN
    	    AT91C_BASE_MC->MC_FMR = ((AT91C_MC_FMCN)&(75 <<16)) | AT91C_MC_FWS_1FWS ;
    
        //* Watchdog Disable
            AT91C_BASE_WDTC->WDTC_WDMR= AT91C_WDTC_WDDIS;
    
    	//* Set MCK at 47 923 200
        // 1 Enabling the Main Oscillator:
            // SCK = 1/32768 = 30.51 uSeconde
        	// Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms
           pPMC->PMC_MOR = ((( AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
            // Wait the startup time
            while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));
    	// 2 Checking the Main Oscillator Frequency (Optional)
    	// 3 Setting PLL and divider:
    		// - div by 5 Fin = 3,6864 =(18,432 / 5)
    		// - Mul 25+1: Fout =	95,8464 =(3,6864 *26)
    		// for 96 MHz the erroe is 0.16%
    		//eld out NOT USED = 0 Fi
           pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 5) |
                             (AT91C_CKGR_PLLCOUNT & (28<<8)) |
                             (AT91C_CKGR_MUL & (25<<16)));
    
            // Wait the startup time
            while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));
    	// 4. Selection of Master Clock and Processor Clock
            // select the PLL clock divided by 2
           pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 ;
            while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
    
            pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
            while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));
    }


    Mam minimoduł od propox z 18.432MHz i PLL na 1k5 1n i 10n.

    Trochę sporo pocenia na ustawienie tak prostej sprawy jak PWM.
  • #4 6779917
    nenpa8lo
    Poziom 17  
    Posty: 260
    Pomógł: 15
    Po długiej walce działa ;-) Błędy moje, jak i brak wiedzy.
    AT91C_BASE_PWMC->PWMC_CH[AT91C_PWMC_CHID0].PWMC_CMR =   AT91C_PWMC_CPRE_MCK_1024 | AT91C_PWMC_CPOL;
    odnosi się do indeksu 1 ponieważ AT91C_PWMC_CHID0 jest zdefiniowane jako 1<<0. Więc ustawienia dotyczące kanałów odnosiły się do kanału 1 a nie 0 tak jak chciałem.
    No a drugi błąd to po prosu w CPSR były wyłączone przerwania ;-)
REKLAMA