📄 livemidi.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 + -