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

📄 livemidi.c

📁 iar workbrench for scr16c sound
💻 C
字号:
/*
 *-----------------------------------------------------------------------------
 *                                                                             
 *               @@@@@@@      *   @@@@@@@@@           *                                     
 *              @       @             @               *                            
 *              @             *       @      ****     *                                 
 *               @@@@@@@      *       @     *    *    *                              
 *        ___---        @     *       @     ******    *                                 
 *  ___---      @       @     *       @     *         *                             
 *   -_          @@@@@@@  _   *       @      ****     *                               
 *     -_                 _ -                                                     
 *       -_          _ -                                                       
 *         -_   _ -        s   e   m   i   c   o   n   d   u   c   t   o   r 
 *           -                                                                    
 *                                                                               
 * (C) Copyright SiTel Semiconductor BV, unpublished work.
 * This computer program includes Confidential, Proprietary Information and
 * is a Trade Secret of SiTel Semiconductor BV.
 * All use, disclosure, and/or reproduction is prohibited unless authorized
 * in writing. All Rights Reserved.
 * This source-code is solely intended as example code. The code may only be 
 * used for study and demo purposes. SiTel Semiconductor can not be held liable 
 * for damages or project-delays caused by bugs in this code.
 *----------------------------------------------------------------------------
********************************************************************************
**
** Project:      Example Midi Player
**
** Description   : Midi player
**
** Limitations   : Ansi-C
**
** Errors        : none
**
** Author        : Jose Mortensen (jmortensen@cfl.rr.com)
**
********************************************************************************
**
** $Author: helsloot $
** $Date: Tue May  2 14:56:40 2006 $
** $Source: /services/syncdata/hazelaar/8500/server_vault/applab/14430/sw/midiplayer_combined/applications/src/livemidi.c.rca $
** $Revision: 1.3 $
** $State: Experimental $
**
*******************************************************************************/

#include "midilib.h"

/*********************************************************************
 *  THE MIDI LIBRARY CONTROL VARS                                    *
 *********************************************************************/

   __no_init gdsp_scp_t      scp_code[128]   @ SHARED_BASE_ADDR;
   __no_init gdsp_mem_t      gdsp_mem   @ "SHARED_RAM";
   __no_init sound_state_t   sound      @ "DATA_RAM";
   __no_init int16           dacout     @ 0xbfe6;  

   __no_init uint16 pre_scale @ 0x8100;
   __no_init uint16 volume @ 0x8102;
   __no_init uint16 assert_code @ 0x8104;
 
   #define SONG_LENGTH  6000
   uint8           song_data[SONG_LENGTH];       
   mtrk_chunk_t    song_track;
   uint32          ticks;
   

   // midi tx rx buffers
   #define UART_BUFFER_SIZE 128
   
   uint8 uart_buffer[UART_BUFFER_SIZE];

   uint8 *  p_uart_rx = uart_buffer;
   uint8 *  p_midi_rx = uart_buffer;


   // Keyboard control
   typedef enum {
      idle = 0,
      play,
      record,
      hold,
      reset,
      bdown = 11,
      click,
      bdown2 = 21,
      double_click,
      } state_t;
      
   int16    dev_state;

   
   
   #define COUTER_SENSIBILITY 20
   #define COUTER_HOLD       400


/*********************************************************************
 *  INITIALIZATION STUFF                                             *
 *********************************************************************/

void chip_init()
{
   __disable_interrupt();

   SET_FREEZE_REG_bit.FRZ_WDOG = 1;              // turn off watchdog
   BAT_CTRL_REG_bit.REG_ON = 1;                  // disable battery control on P1.7
  
   CODEC_MIC_REG = 0x0004;                     // Set MIC powered down
   CODEC_LSR_REG = 0x0892;                       // Loud speaker 
   CODEC_VREF_REG = 0x0014;
   CODEC_ADDA_REG = 0x0000;    // power the ADDA
   CODEC_TONE_REG = 0x0317;

   CLASSD_CTRL_REG = 0x0008;

    // -- CODEC2 Inits ?!?!?
   *((uint16 *)0xFFE230) = 0000;
   *((uint16 *)0xFFE232) = 0012;
   *((uint16 *)0xFFE234) = 0000;
   *((uint16 *)0xFFE236) = 0000;

    // setting 20Mhz to CR16C, 40 Mhz GenDSP
   CLK_CTRL_REG = 0x001a;                        // Switch Xtal as SCLK                
   PLL_DIV_REG = 0x6180;

#ifdef __CODEC_16KHZ__
   PER_DIV_REG = 0x0009;
   CODEC_DIV_REG = 0x0092;                      // 16kHz CODEC
#else
   PER_DIV_REG = 0x0009;
   CODEC_DIV_REG = 0x0089;                      // 8kHz CODEC
#endif

   DSP_ADDR_REG = 0x0000;                        // set scp offset to 0
   DSP_STATUS_REG = 0x0000;                      // Clear DSP status                     
   DSP_CTRL_REG = 0x0000;                        // Power up                           


   ACS3_CTRL_REG = 0x20;                         // maximum access speed to flash                 
   CLK_DIV_REG = 1;                              // CR16C 10 MHz 

   // Interrupt Setting.
   INT0_PRIORITY_REG_bit.DSP_INT_PRIO =  0x0007; // 0 - 7
   DSP_INT_MASK_REG = MIDI_IRQ; 
   RESET_INT_PENDING_REG = 0xFFFF;               // clear all interrupts pending
   __set_PSR_I_bit();
   __enable_interrupt();
}



void enable_uart(void)
{
   __disable_interrupt();
   P0_DIR_REG_bit.P0_0_DIR = 1;              // P0.0 output TX
   P0_DIR_REG_bit.P0_1_DIR = 0;              // P0.1 input RX
   P0_IN_OUT_DATA_REG_bit.P0_1_DATA = 0;     // Pull down at RX pin
   P0_MODE_REG_bit.P0_0_MODE = 1 ;           // UART TX switched to P0.0
   P0_UART_CTRL_REG_bit.BAUDRATE = 0x3;      // Enable UART Baud 115200
   P0_UART_CTRL_REG_bit.UART_TEN = 0x1;      // Enable UART TX
   P0_UART_CTRL_REG_bit.UART_REN = 0x1;      // Enable UART RX
   
   
   INT1_PRIORITY_REG_bit.UART_RI_INT_PRIO = 1;  // Receive priority

   RESET_INT_PENDING_REG = 0xFFFF;           // clear all interrupts pending
   __enable_interrupt();
   
 }


void timer_init(void)
{
/* Timer Setup*/
   
   TIMER1_RELOAD_M_REG = (0x1680>>2); // 50 ms
   TIMER1_RELOAD_N_REG = (0x1680>>2); // 50 ms
   
   
   TIMER_CTRL_REG_bit.CLK_DIV8 = 0; // 
   TIMER_CTRL_REG_bit.CLK_CTRL1 = 1; // 115.2 Khz
   TIMER_CTRL_REG_bit.TIM1_MODE = 1; // timer mode 2
   TIMER_CTRL_REG_bit.TIM1_CTRL = 1; // enable timer 1
   
   INT0_PRIORITY_REG_bit.TIM1_INT_PRIO = 1;                    // 
}

/*********************************************************************
 *  THE MIDI SEQUENCER INTERRUPT  ( Used by the sequencer if enabled)*
 *********************************************************************/


#pragma vector=DSP_INT
__interrupt 
void midi_interrupt(void)
{
   uint16 status;
   status = DSP_STATUS_REG;
   RESET_INT_PENDING_REG_bit.DSP_INT_PEND = 1;
}

/*********************************************************************
 *  THE MIDI SERIAL INTERRUPT                                        *
 *********************************************************************/

#pragma vector=UART_RI_INT
__interrupt
void rx_interrupt (void)
{ 
   __disable_interrupt();
   
   *p_uart_rx = P0_UART_RX_TX_REG;
   
   P0_CLEAR_RX_INT_REG = 1;                        // clear RX reg
   RESET_INT_PENDING_REG_bit.UART_RI_INT_PEND = 1; // reset interrupt


   P0_UART_CTRL_REG_bit.UART_REN = 0x1;            // Enable UART RX
   P0_UART_CTRL_REG_bit.UART_TEN = 0x1;            // Enable UART TX
   P0_UART_RX_TX_REG = *p_uart_rx++;               // Transmit a Byte
   
   if ( p_uart_rx >= uart_buffer + UART_BUFFER_SIZE) {// flip pointer
      p_uart_rx = uart_buffer;
   }
   
   // ??? 
   if (RESET_INT_PENDING_REG_bit.UART_TI_INT_PEND != 1) {
      RESET_INT_PENDING_REG_bit.UART_TI_INT_PEND = 1;
   }
   P0_CLEAR_TX_INT_REG = 1;
   
   // Detect buffer overrun
   if (p_uart_rx == p_midi_rx)   {
      assert_code |= 0x8000;
      dev_state = hold;
   }
   __enable_interrupt();
}   



#pragma vector=TIM1_INT
__interrupt
void timer_interrupt (void)
{
   
   static uint16 led = 0;
   static uint16 counter = 0;
   static uint16 btn_state = idle;

   int16 dev_state_next = dev_state;
   uint16 button;
   P0_DIR_REG_bit.P0_0_DIR = 0;
   button = !P0_IN_OUT_DATA_REG_bit.P0_0_DATA;

   counter ++;
   ticks++;
         
   switch (btn_state) {
      case idle: // idle
         if (button) {
            btn_state = bdown;
            counter = 0;
         }
         break;
      case bdown: // 
         if (!button) {
            btn_state = click;
            counter = 0;
         }
         if (counter > COUTER_HOLD) {
            assert_code |= 2;
            dev_state_next = hold;
         }
         break;
      case click: //record
         if (counter > COUTER_SENSIBILITY) {
         
            if (dev_state == idle) dev_state_next = play;
            if ((dev_state == play) || (dev_state == record)) {
               dev_state_next = idle;
            }
            
            btn_state = idle;
         } else  {
            if (button) {
               btn_state = bdown2;
               counter = 0;
            }
         }
         break;
      case bdown2:
         if (!button) {
            btn_state = double_click;
            counter = 0;
         }
         break;
      case double_click:
         if (counter > COUTER_SENSIBILITY) {
            dev_state_next = record;
            btn_state = idle;
         }     
         break;
   }
   
   dev_state = dev_state_next;
   
   switch (dev_state) {
      case idle: 
         led = 0;
         break;
      case play:
         led = 1;
          break;
      case record:
         led = (counter>>2)&1;
         break;
      case hold:
         led = (counter>>1)&1;
         break;
   }
   
   P0_DIR_REG_bit.P0_3_DIR = 1;
   P0_IN_OUT_DATA_REG_bit.P0_3_DATA = led&1;

   RESET_INT_PENDING_REG_bit.TIM1_INT_PEND = 1;
 
}


/*********************************************************************
 *  THE MAIN LOOP                                                    *
 *********************************************************************/


void record_song()
{
   uint16 len;
   uint32 old_timecode= 0;
   uint32 timecode;
   
   __disable_interrupt();

   
   /* set up midi buffer */
   song_track.length = 0;  // end of track marker
   song_track.pdata = song_data;
   song_track.pos = song_data;
   song_track.time = 0;
   song_track.end = 1;  
   song_track.running_status = 0;


   ticks = 0;
   
   __enable_interrupt();

   while (dev_state == record) {
   
      if (p_midi_rx != p_uart_rx) { // data available
        
         timecode = ticks - old_timecode;
         len = midilib_serial((uint8 *)song_track.pos, timecode, *p_midi_rx++);         
                 
         if (len > 0) { // message stored
            old_timecode = ticks;
         }
         
         if (len > 7) { // message stored
            assert_code |=0x4000;
            dev_state = hold;
         }
         
         song_track.pos += len;
         song_track.length += len;
        
         if (song_track.length > (SONG_LENGTH - 10)) dev_state = idle;
         
         if ( p_midi_rx >= uart_buffer + UART_BUFFER_SIZE) p_midi_rx = uart_buffer;
      }
   }
   *(uint8 *)song_track.pos++ = 0x01;
   *(uint8 *)song_track.pos++ = 0xff;
   *(uint8 *)song_track.pos++ = 0xf2;
   song_track.length += 3;

}

void play_song() 
{
   __disable_interrupt();

   /* set up midi buffer */
   song_track.pdata = song_data;
   song_track.pos = song_data;
   song_track.time = 0;
   song_track.end = 0;
   song_track.running_status = 0;
   
   ticks = 0;

   __enable_interrupt();
   
   while (dev_state == play) {
      sound_cleanup();
      midi_getevent(&song_track, ticks);

      if (p_midi_rx != p_uart_rx) { // data available
         //midilib_serial(NULL, 0, *p_midi_rx++);         
         p_midi_rx++;
         if ( p_midi_rx >= uart_buffer + UART_BUFFER_SIZE) p_midi_rx = uart_buffer;
      }


      if (song_track.end == 1) dev_state = idle;
   }  
}

void my_assert(void)
{
   assert_code |= 0x0001;
   dev_state = hold;
}

int main()
{
   uint16 sample_freq_sh = 5;
   pre_scale = 0x100;
   volume = 0x7fff;
   dev_state = idle;   
   assert_code = 0;   

   // Initialization   
   midilib_init_serial(&gdsp_mem, &sound, scp_code, &dacout, sample_freq_sh);
   midilib_volume(volume, pre_scale);
   midilib_assert_handler(my_assert);
   chip_init();
   enable_uart();
   timer_init();
      

   /* set up song buffer */
   song_track.length = 0;
   song_track.pdata = song_data;
   song_track.pos = song_data;
   song_track.time = 0;
   song_track.end = 1;  
   song_track.running_status = 0;

   
   while (1) {
   
      if (p_midi_rx != p_uart_rx) { // data available
         midilib_serial(NULL, 0, *p_midi_rx++);         
         if ( p_midi_rx >= uart_buffer + UART_BUFFER_SIZE) p_midi_rx = uart_buffer;
      }
      
      if (dev_state == play) {
         __disable_interrupt();
         DSP_CTRL_REG_bit.GDSP_PD = 1;
         midilib_init_serial(&gdsp_mem, &sound, scp_code, &dacout, sample_freq_sh);
         midilib_volume(volume, pre_scale);
         DSP_CTRL_REG_bit.GDSP_PD = 0;
         __enable_interrupt();
         
         play_song();
         __disable_interrupt();
         DSP_CTRL_REG_bit.GDSP_PD = 1;
         midilib_init_serial(&gdsp_mem, &sound, scp_code, &dacout, sample_freq_sh);
         midilib_volume(volume, pre_scale);
         DSP_CTRL_REG_bit.GDSP_PD = 0;
         __enable_interrupt();
      }
      
      if (dev_state == record) {
          __disable_interrupt();
         DSP_CTRL_REG_bit.GDSP_PD = 1;
         midilib_init_serial(&gdsp_mem, &sound, scp_code, &dacout, sample_freq_sh);
         midilib_volume(volume, pre_scale);
         DSP_CTRL_REG_bit.GDSP_PD = 0;
         __enable_interrupt();

        record_song();

         __disable_interrupt();
         DSP_CTRL_REG_bit.GDSP_PD = 1;
         midilib_init_serial(&gdsp_mem, &sound, scp_code, &dacout, sample_freq_sh);
         midilib_volume(volume, pre_scale);
         DSP_CTRL_REG_bit.GDSP_PD = 0;
         __enable_interrupt();
      }
       
    };
}






⌨️ 快捷键说明

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