#include #include #include #include #include #include "libsys.h" #define PI 3.1415926535897932384626433832795 #define SAMPLE_RATE 48000 #define BUF_SIZE (2*4800) #define REC_BUF_SIZE (5*60*2*SAMPLE_RATE) INT32 *buffer; INT32 *rec_buffer; UINT32 buf_size; INT32 * volatile pPtr_r; INT32 * volatile pPtr_w; UINT32 gcnt, led_cnt; volatile INT32 sample_left, sample_right; #define AC97_REG_RESET 0x00 #define AC97_REG_VOLO_MST 0x02 #define AC97_REG_VOLO_HP 0x04 #define AC97_REG_VOLO_MONO 0x06 #define AC97_REG_VOLI_BEEP 0x0A #define AC97_REG_VOLI_PHONE 0x0C #define AC97_REG_VOLI_MIC 0x0E #define AC97_REG_VOLI_LINE 0x10 #define AC97_REG_VOLI_CD 0x12 #define AC97_REG_VOLI_VIDEO 0x14 #define AC97_REG_VOLI_AUX 0x16 #define AC97_REG_VOLI_PCM 0x18 #define AC97_REG_REC_SRC 0x1A #define AC97_REG_REC_GAIN 0x1C #define AC97_REG_EXTCTRL 0x2A #define AC97_REG_RATE_DAC 0x2C #define AC97_REG_RATE_ADC 0x32 UINT32 ac97_status(UINT32 reg) { UINT32 offset; volatile UINT32 *pAC_stat = (UINT32*)sys_ac97_stat; volatile UINT32 *pAC_stat_ac = (UINT32*)sys_ac97_acstat; offset = (reg & 0x7E); // Wait if previous command is still pending while(*pAC_stat & 1); *(pAC_stat_ac + offset) = 0; // Wait for data valid while(!(*pAC_stat & 2)); return *pAC_stat_ac; } void ac97_ctrl(UINT32 reg, UINT16 value) { UINT32 offset; volatile UINT32 *pAC_stat = (UINT32*)sys_ac97_stat; volatile UINT32 *pAC_ctrl_ac = (UINT32*)sys_ac97_acctrl; offset = (reg & 0x7E); // Wait if previous command is still pending while(*pAC_stat & 1); *(pAC_ctrl_ac + offset) = value; } void ac97_isr_rec(void) { int i, size; volatile UINT32 *pReg = (UINT32*)sys_led_port; volatile UINT32 *pAC_stat = (UINT32*)sys_ac97_stat; volatile INT32 *pAC_pcm = (INT32*)sys_ac97_pcm; if (!gcnt) { gcnt = SAMPLE_RATE; *pReg = led_cnt++; } gcnt--; *pPtr_w++ = pAC_pcm[3]; if (pPtr_w == &buffer[buf_size]) pPtr_w = buffer; *pPtr_w++ = pAC_pcm[4]; if (pPtr_w == &buffer[buf_size]) pPtr_w = buffer; CP0_TR_write(pAC_pcm[3]); CP0_TR_write(pAC_pcm[4]); } void ac97_isr_play(void) { int i, size; volatile UINT32 *pReg = (UINT32*)sys_led_port; volatile UINT32 *pAC_stat = (UINT32*)sys_ac97_stat; volatile INT32 *pAC_pcm = (INT32*)sys_ac97_pcm; if (!gcnt) { gcnt = SAMPLE_RATE; *pReg = led_cnt++; } gcnt--; *pAC_pcm = *pPtr_r++; if (pPtr_r == &buffer[buf_size]) pPtr_r = buffer; } void ac97_isr_pass(void) { int i, size; volatile UINT32 *pReg = (UINT32*)sys_led_port; volatile UINT32 *pAC_stat = (UINT32*)sys_ac97_stat; volatile INT32 *pAC_pcm = (INT32*)sys_ac97_pcm; if (!gcnt) { gcnt = SAMPLE_RATE; *pReg = led_cnt++; } gcnt--; if (*pAC_stat & 0x08) { CP0_TR_write(pAC_pcm[3]); CP0_TR_write(pAC_pcm[4]); *pPtr_w++ = pAC_pcm[3]; if (pPtr_w == &buffer[buf_size]) pPtr_w = buffer; *pPtr_w++ = pAC_pcm[4]; if (pPtr_w == &buffer[buf_size]) pPtr_w = buffer; } if (pPtr_r != pPtr_w) { *pAC_pcm = *pPtr_r++; if (pPtr_r == &buffer[buf_size]) pPtr_r = buffer; } } int main (void) { int result, i, j; volatile UINT32 *pReg = (UINT32*)sys_led_port; volatile UINT32 *pAC_ctrl = (UINT32*)sys_ac97_ctrl; volatile UINT32 *pAC_stat = (UINT32*)sys_ac97_stat; volatile UINT32 *pAC_ctrl_ac = (UINT32*)sys_ac97_acctrl; volatile UINT32 *pAC_stat_ac = (UINT32*)sys_ac97_acstat; volatile UINT32 *pAC_pcm = (UINT32*)sys_ac97_pcm; double phi, dphi, y, mean; char sel, cmd; char buf[1024]; // setbuf(stderr, NULL); // fprintf(stderr, "AC-97 Test\n"); fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); ac97_ctrl(AC97_REG_VOLO_MST, 0); ac97_ctrl(AC97_REG_VOLO_HP, 0); ac97_ctrl(AC97_REG_VOLI_LINE, 0x8808); ac97_ctrl(AC97_REG_VOLI_PCM, 0x0808); ac97_ctrl(AC97_REG_REC_SRC, 0x0404); ac97_ctrl(AC97_REG_REC_GAIN, 0); ac97_ctrl(AC97_REG_EXTCTRL, 1); ac97_ctrl(AC97_REG_RATE_DAC, SAMPLE_RATE); ac97_ctrl(AC97_REG_RATE_ADC, SAMPLE_RATE); led_cnt = 0; gcnt = SAMPLE_RATE; fprintf(stderr, "DAC-Rate : %d\n", ac97_status(AC97_REG_RATE_DAC)); fprintf(stderr, "ADC-Rate : %d\n", ac97_status(AC97_REG_RATE_ADC)); while(1) { fprintf(stderr, "Aufnehmen und Abspielen (1)\n"); fprintf(stderr, "Sinus Ton (2)\n"); fprintf(stderr, "Pass through (3)\n"); fprintf(stderr, "Eingabe: "); scanf("%c", &sel); // sel = 0x31; if (sel == 0x31) { buf_size = REC_BUF_SIZE; buffer = (INT32*)malloc(REC_BUF_SIZE*sizeof(INT32)); // memset(buffer, 0, sizeof(REC_BUF_SIZE*sizeof(INT32))); pPtr_r = buffer; pPtr_w = buffer; ac97_ctrl(AC97_REG_VOLI_LINE, 0x0808); cmd = 0; while(1) { switch (cmd) { case 'r': ac97_ctrl(AC97_REG_VOLI_LINE, 0x0808); pPtr_w = buffer; fprintf(stderr, "Aufnahme\n"); interrupt_register(5, ac97_isr_rec); interrupt_enable(5); *pAC_ctrl = 0x24; break; case 'p': ac97_ctrl(AC97_REG_VOLI_LINE, 0x8808); pPtr_r = buffer; fprintf(stderr, "Wiedergabe\n"); interrupt_register(5, ac97_isr_play); interrupt_enable(5); *pAC_ctrl = 0x12; break; case ' ': ac97_ctrl(AC97_REG_VOLI_LINE, 0x0808); fprintf(stderr, "Stop\n"); memset(buffer, 0, sizeof(REC_BUF_SIZE*sizeof(INT32))); *pAC_ctrl = 0x00; pPtr_r = buffer; pPtr_w = buffer; break; default: fprintf(stderr, "Aufnahme (R)\n"); fprintf(stderr, "Wiedergabe (P)\n"); fprintf(stderr, "Stop (Space)\n"); break; } cmd = readchar(); } } if (sel == 0x32) { buf_size = BUF_SIZE; buffer = (INT32*)malloc(REC_BUF_SIZE*sizeof(INT32)); memset(buffer, 0, sizeof(REC_BUF_SIZE*sizeof(INT32))); pPtr_r = buffer; pPtr_w = buffer; dphi = 120*2*PI/BUF_SIZE; phi = 0; for (i=0; i < BUF_SIZE/2; i++) { y = cos(phi); buffer[2*i+0] = (INT32)(32000*y); buffer[2*i+1] = (INT32)(32000*y); phi = fmod((phi + dphi), 2.0*PI); } fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); interrupt_register(5, ac97_isr_play); interrupt_enable(5); *pAC_ctrl = 0x12; fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); while(1) { fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); } } if (sel == 0x33) { buf_size = BUF_SIZE; buffer = (INT32*)malloc(BUF_SIZE*sizeof(INT32)); memset(buffer, 0, sizeof(BUF_SIZE*sizeof(INT32))); pPtr_r = buffer; pPtr_w = buffer; interrupt_register(5, ac97_isr_pass); interrupt_enable(5); *pAC_ctrl = 0x32; fprintf(stderr, "Status : %8.8X\n", *pAC_ctrl); while(1) { sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); sprintf(buf, "Status : %8.8X\n", pPtr_r); // print_word(*pAC_ctrl); sputs("\n"); } } } return 0; }