⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 sharp s Lh75401 PWM audio的例子
💻 C
字号:
/*********************************************************************** 
 * $Workfile:   main.c  $ 
 * $Revision:   1.0  $ 
 * $Author:   AnvikE  $ 
 * $Date:   Jul 03 2003 17:32:14  $ 
 * 
 * Project:     kev75401 BSP (board support package)
 * 
 * Description: 
 *  
 * 
 * Revision History: 
 * $Log:
 *********************************************************************** 
 * 
 *  Copyright (c) 2002 Sharp Microelectronics of the Americas 
 * 
 *  All rights reserved 
 * 
 *  SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION 
 *  OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE, 
 *  AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 *  SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE. 
 * 
 *  SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 *  FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 *  SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE 
 *  FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS. 
 * 
 **********************************************************************/

/* 
 * kev75401 board specific code 
 * location - [sharpmcu/software/csps/lh754xx/bsps/kev75401/include]
 */
#include "kev75401.h"
/* 
 * kev75401 pcm specific code 
 * location - .
 */
#include "pcm.h"
/* 
 * kev75401 frame buffer 
 * location - .
 */
#include "framebuffer.h"
/* 
 * demo 
 * location - .
 */
#include "demo.h"
/*
 * chip specific interrupt driver 
 * location - [sharpmcu/software/csps/lh754xx/include]
 */
#include "lh754xx_vic_driver.h"
/*
 * chip specific timer0 driver 
 * location - [sharpmcu/software/csps/lh754xx/include]
 */
#include "lh754xx_timer0_driver.h"
/*
 * chip specific timer1/2 driver 
 * location - [sharpmcu/software/csps/lh754xx/include]
 */
#include "lh754xx_timer_driver.h"
/*
 * chip specific lcd driver 
 * location - [sharpmcu/software/csps/lh754xx/include]
 */
#include "lh754xx_clcdc_driver.h"
#include "lh754xx_lq064d343.h"
#include "lh754xx_lq035q7db02.h"
/*
 * abl generic window manager 
 * location - [sharpmcu/software/abl/include]
 */
#include "abl_swim.h"
#include "abl_fonts.h"
#include "abl_swim_font.h"

INT_32 pwm0 = 0; /* PWM output to the chip */
INT_32 pwm1 = 0; /* PWM output to the chip */
INT_32 tmr0 = 0; /* PCM output to the chip */
INT_32 vic0 = 0; /* VIC driver */
INT_32 lcd0 = 0; /* CLCDC driver */

/*
 * Note: This is required by the Chip related drivers 
 */
INT_32 board_xtal_freq = BOARD_XTAL_FREQ;

/* get a reference to the user irq handler */ 
EXTERN void __user_irq_handler (void);

#define TIMER_MUX_REG (0xFFFE500C)
#define TIMER0_PWM_IO_EN _SBF(1,2)
#define TIMER1_PWM_IO_EN _SBF(8,2)
#define TIMER2_PWM_IO_EN _SBF(12,2)

/* These values are calulates based on a 25.8 Mhz timer clock */

/* Fmax  = 25.8Mhz -> bit clock 
   nbits = log(Fmax/asr)/log2

   ex: 
   audio sample rate    (asr)       = 8000Hz at 16 bits per sample
   Fmax                 (bit clock) = 25.8 Mhz
   max nbits resolution (nbits)     = log(25800000/8000)/log2

   So we get 11 bits out of the original 16 bit sample. 

   For pwm we want to present the audio energy on a carrier 
   of say 100X the sampling frequency. But since Fmax stays fixed
   this means that we get less bits of resolution per sample 
   nbits = log(Fmax*osr/asr)/log2 
   where osr = oversampling rate (say 10X) 

   One possible solution to deal with the lesser bits per sample 
   is to perform a windowing function for every one of the N over 
   samples. This however requires more processor bandwidth since 
   the duty cycle will change based on the current window which requires
   the processot to service N interrupts where N is the over sample 
   multiplier 

   To handle the windowing function do the following
    
   1 - On the first new sample window interrupt, convert the new pcm audio 
       sample into a sample of max desired bits of resolution from the 
       original value (say 11 bits).
   2 - Take the first value from that sample that can be respesented 
       by the nbits due to the over sampling factor (say 5 bits). 
   3 - For each sample extract the next 5 bit value from the sample 
       window and present it to the filters. 
   4 - Once N samples have been written start at step 1 and repeat 

   ex: based on the first example 
       osr   = 100
       nbits = log(3225/100)/log2 = 5 bits = 32 counts max  
       
       we know the max raw counts = 3225 so we have 100 sample windows (osr).
       so at the beginning of each sample window take current sample value 
       and find the current window, this will give us the relative position
       in the sample from the first 5 bits. Now mask off the 5 bits at this new 
       window position, convert it into LSB of the duty cycle and present 
       this data to the filters.

       by performing this technique all of the energy of the original 11 bit 
       sample is presented to the filters as smaller chunks at a much 
       higher frequency for the N over samples.
       */

/************************************************************************
*
* Function: c_entry
*
* Purpose:
*    To demostrate using chip specific, platform independent, and board
*    specific drivers.
*
* Processing:
*     
* Parameters: 
*     None
*
* Outputs: 
*     None
*
* Returns: 
*     None
*
* Notes: 
*
************************************************************************/

void c_entry (void)
{
    INT_32    hclk   = 0;
    INT_32    idx    = 0;
    VIC_CFG_T vic;

    /* Lock interrupts at the core */
    INT_LOCK();

    /* Install the default interrupt vectors at 0x0 */
    (void) kev75401_install_vectors (0);

    /* Get the system clock rate */
    SYS_CLK_GET (hclk); 

    /* Init the ssp - used to enable lcd, and seven-segment led etc ... */
    kev75401_init_ssp (hclk);

    /* Open (init) the vectored interrupt controller */
    vic0 = vic_open (VIC_BASE, 0);

    /* Install the default interrupt handler */
    vic_ioctl 
        (vic0, VIC_INSTALL_USER_SW_DISPATCHER, (INT_32)__user_irq_handler);

    /* Install the pwm timer interrupt handler */
    vic.source  = VIC_TIMER0;
    vic.vector  = VIC_VECT_0;
    /* Determine which mode we want to run in. Single ended or
       Differential mode */
    /* run the pwm audio in differential mode */
    vic.handler = (INT_32)pcm_to_pwm_sample;        
    /* Add the interrupt to the vic vector table */
    vic_ioctl (vic0, VIC_ENABLE_INT_VEC, (INT_32)&vic);
    /* Add the source level interrupt handler */
    vic_ioctl (vic0, VIC_ADD_HANDLER, (INT_32)&vic);
    /* Set the source to generate an irq */
    vic_ioctl (vic0, VIC_SET_INT_SRC_IRQ, vic.source);
    /* Enable the source level interrupt in the vic */
    vic_ioctl (vic0, VIC_ENABLE_INT_SRC, vic.source);

    /* Open LCD with lq035q7db02 display  */
    lcd0 = lcd_open (LCD_BASE, (INT_32)&lh754xx_lq035q7db02);
    /* Create a grey background */
    for (idx = 0; idx < NELEMENTS(framebuffer); idx++)
    {
        framebuffer[idx] = LIGHTGRAY;
    }
    /* Set frame buffer and enable display */
    lcd_ioctl (lcd0, LCD_SET_FB, (INT_32)framebuffer);
    /* enable the board specific portion of the lcd controller */
    kev75401_lcd_output_enable ();
    kev75401_lcd_power_on ();
    kev75401_lcd_backlight_on ();
    /* Enable power to the controller */
    lcd_ioctl (lcd0, LCD_PW_ENABLE, 0);

    /* Timer 0 acts like the interval counter */ 
    tmr0 = timer0_open (TIMER0_BASE, 0);
    /* Get a timer clock of 25.8 Mhz */
    timer0_ioctl (tmr0, TIMER_SET_CLK_RATE, TIMER_HCLK_DIV_2);
    /* Set up the device to act like a free running counter */
    timer0_ioctl (tmr0, TIMER_SET_CNT_MODE, 0);
    /* Enable an interrupt on CMP1 match */
    timer0_ioctl (tmr0, TIMER_ENABLE_INT, TIMER_CMP1_EN);

    /* Timer 1 drives the +ve side of the op amp  */ 
    pwm0 = timer_open (TIMER1_BASE, 0);
    /* Set the timer clock */
    timer_ioctl (pwm0, TIMER_SET_CLK_RATE, TIMER_HCLK_DIV_2);
    /* Enable PWM mode on timer 0 */
    timer_ioctl (pwm0, TIMER_SET_PWM_MODE, 0);
    /* Set up the external pins to act like pwm output */
    *(volatile UNS_32*)TIMER_MUX_REG &= ~_SBF(8,3);
    *(volatile UNS_32*)TIMER_MUX_REG |= TIMER1_PWM_IO_EN;

    /* Timer 2 drives the -ve side of the op amp  */ 
    pwm1 = timer_open (TIMER2_BASE, 0);
    /* Set the timer clock */
    timer_ioctl (pwm1, TIMER_SET_CLK_RATE, TIMER_HCLK_DIV_2);
    /* Enable PWM mode on timer 0 */
    timer_ioctl (pwm1, TIMER_SET_PWM_MODE, 0);
    /* Set up the external pins to act like pwm output */
    *(volatile UNS_32*)TIMER_MUX_REG &= ~_SBF(12,3);
    *(volatile UNS_32*)TIMER_MUX_REG |= TIMER2_PWM_IO_EN;

    /* Init the touchscreen controller driver */
    kev75401_init_tsc (hclk, FALSE);

    /* Init the demo */
    demo_init ();

    /* Enable irqs at the core */
    INT_UNLOCK();

    /* Enter the demo loop */
    demo (hclk);
}



/* EOF */




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -