int main(void) { gpioInit(); __enable_irq(); DacInit(); DacWrite(0x0A,1); for(;;) { } return 0; }
int main(int argc, char **argv) { int fd = -1; int retval = EXIT_SUCCESS; if(argc < 2) { fprintf(stderr, "%s version %s-%s\n" "\nUsage:\n" "\tread addr: address\n" "\twrite addr: address value\n" "\tread analog mixed signals: -ams\n" "\tset slow DAC: -sdac AO0 AO1 AO2 AO3 [V]\n", argv[0], VERSION_STR, REVISION_STR); return EXIT_FAILURE; } if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL; /* Read from standard input */ if (strncmp(argv[1], "-ams", 4) == 0) { uint32_t addr = c_addrAms; amsReg_t* ams=NULL; // Map one page map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK); if(map_base == (void *) -1) FATAL; ams = map_base + (addr & MAP_MASK); AmsList(ams); if (map_base != (void*)(-1)) { if(munmap(map_base, MAP_SIZE) == -1) FATAL; map_base = (void*)(-1); } } else if (strncmp(argv[1], "-sdac", 5) == 0) { uint32_t addr = c_addrAms; amsReg_t* ams=NULL; double *val = NULL; ssize_t val_count = 0; parse_from_argv_par(argc, argv, &val, &val_count); if(val_count>SLOW_DAC_NUM){ val_count=SLOW_DAC_NUM; } // Map one page map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK); if(map_base == (void *) -1) FATAL; ams = map_base + (addr & MAP_MASK); if (val_count == 0) { DacRead(ams); } else{ DacWrite(ams, val, val_count); } if (map_base != (void*)(-1)) { if(munmap(map_base, MAP_SIZE) == -1) FATAL; map_base = (void*)(-1); } } else if (strncmp(argv[1], "-", 1) == 0) { unsigned long addr; unsigned long *val = NULL; int access_type = 'w'; ssize_t val_count = 0; while ( parse_from_stdin(&addr, &access_type, &val, &val_count) != -1) { if (addr == 0) { continue; } /* Map one page */ map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK); if(map_base == (void *) -1) FATAL; if (val_count == 0) { read_value(addr); } else { write_values(addr, access_type, val, val_count); } if (map_base != (void*)(-1)) { if(munmap(map_base, MAP_SIZE) == -1) FATAL; map_base = (void*)(-1); } #if DEBUG_MONITOR printf("addr/type: %lu/%c\n", addr, access_type); printf("val (%ld):", val_count); for (ssize_t i = 0; i < val_count; ++i) { printf("%lu ", val[i]); } if (val != NULL) { free(val); val = NULL; } printf("\n"); #endif } goto exit; } /* Read from command line */ else { unsigned long addr; unsigned long *val = NULL; int access_type = 'w'; ssize_t val_count = 0; parse_from_argv(argc, argv, &addr, &access_type, &val, &val_count); /* Map one page */ map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK); if(map_base == (void *) -1) FATAL; if (addr != 0) { if (val_count == 0) { read_value(addr); } else { write_values(addr, access_type, val, val_count); } } if (map_base != (void*)(-1)) { if(munmap(map_base, MAP_SIZE) == -1) FATAL; map_base = (void*)(-1); } #if DEBUG_MONITOR printf("addr/type: %lu/%c\n", addr, access_type); printf("val (%ld):", val_count); for (ssize_t i = 0; i < val_count; ++i) { printf("%lu ", val[i]); } if (val != NULL) { free(val); val = NULL; } printf("\n"); #endif } exit: if (map_base != (void*)(-1)) { if(munmap(map_base, MAP_SIZE) == -1) FATAL; } if (fd != -1) { close(fd); } return retval; }
//////////////////////////////////////////////////// // 功能: // 输入: // 输出: // 返回: // 说明: //////////////////////////////////////////////////// static void JzThreadPlayFile(DWORD p) { PAK_VFILE vfile; PAK_OBJECT obj; PMEDIA_TASK task; VIDEO_PARAM video; MEDIALIB_STATUS player_status; MESSAGE msg; int cur_time; int duration; int msgid; int ret,jmp_ret; int max_wsize; int max_time; short *pcm,*pData; int fade,begin_time; int obj_del = 1; int wlen; int block_num; int time_out; DWORD init_start_time,init_end_time; #ifdef MPLAYER_PRINTF_ENABEL syslog_set_global_level(PRINT_INFO); #endif // 获取打开信息 obj = (PAK_OBJECT)p; task = &obj->Task; vfile = &obj->File; init_start_time = TimerCount(); kdebug(mod_audio, PRINT_INFO, "mplayer init player time = %d\n",init_start_time); obj->PlayerType = task->ExterdType; #ifdef CONFIG_MAKE_BIOS task->ExterdType = 0; #endif pcm = NULL; obj->hDac = NULL; video.hMutex = NULL; //初始化mplayer使用变量 nMplayerDelay = 0; nMplayerSamplerate = 0; nMplayerChannels = 0; nMplayerAudioStart = 0; //初始化回调函数 if( (ret = MediaLibInit(obj)) < 0 ) { kdebug(mod_audio, PRINT_ERROR, "MediaLibInit failed\n"); *obj->bReady = -1; if( ret != -2 ) MediaLibClose(obj); goto ThreadEnd; } kdebug(mod_audio, PRINT_INFO, "mplayer MediaLibInit end = %d\n",TimerCount()); if( task->ExterdType ) { //防止SD卡播放时,拔出SD卡,导致MPLAYER在初始化阶段死机 obj->JzAvDecoder->fMplayerInit = 1; kdebug(mod_audio, PRINT_INFO, "set jump error addr\n"); jmp_ret = ksetjmp(obj->JzAvDecoder->AudioJumpBuf); if( jmp_ret == 1 ) { kdebug(mod_audio, PRINT_ERROR, "audio error, jump to end\n"); *obj->bReady = -1; if( pcm ) kfree(pcm); if( obj->hDac ) DacClose(obj->hDac); if(video.hMutex) kMutexDestroy(video.hMutex); MediaLibClose(obj); goto ThreadEnd; } } //打开音频库 if( MediaLibOpen(obj, 0) < 0 ) { //音频库打开失败 kdebug(mod_audio, PRINT_ERROR, "MediaLibOpen failed\n"); *obj->bReady = -1; MediaLibClose(obj); goto ThreadEnd; } kdebug(mod_audio, PRINT_INFO, "mplayer MediaLibOpen end = %d\n",TimerCount()); //得到音频库信息 if( MediaLibGetInfo(obj) < 0 ) { //得到音频库信息失败 kdebug(mod_audio, PRINT_ERROR, "MediaLibGetInfo failed\n"); *obj->bReady = -1; MediaLibClose(obj); goto ThreadEnd; } if( !obj->Info.bHasAudio ) { //没有音频数据,直接退出 *obj->bReady = -1; MediaLibClose(obj); goto ThreadEnd; } if(obj->Info.bHasVideo) { //有视频,但是播放区域为空,直接退出(MP3里面播放改名的RMVB等。。。。) if( !(task->ShowRect.w && task->ShowRect.h) ) { *obj->bReady = -1; MediaLibClose(obj); goto ThreadEnd; } } kdebug(mod_audio, PRINT_INFO, "mplayer MediaLibGetInfo end = %d\n",TimerCount()); if( obj->PlayerType ) { //设置视频的显示区域以及位置 if( task->ShowRect.w && task->ShowRect.h ) MplayerResizeVideo(obj,task); else { kdebug(mod_audio, PRINT_WARNING, "can't play video\n"); obj->JzAvDecoder->fIpuEnable = 1; } } else { obj->StartTime = task->ShowRect.x; obj->EndTime = task->ShowRect.y; } //申请播放PCM的内存 block_num = MAX_PCM_GET_LEN; pcm = (short*)kmalloc(block_num); if( pcm == NULL ) { kdebug(mod_audio, PRINT_ERROR, "memory lose pcm == null\n"); *obj->bReady = -1; MediaLibClose(obj); goto ThreadEnd; } kdebug(mod_audio, PRINT_INFO, "mplayer kmalloc pcm end = %d\n",TimerCount()); //MPLAYER播放器使用,用来设置从MPLAYER读到的PCM数据以及长度 if( obj->PlayerType ) { //外部播放器使用变量 pMediaPcmData = (BYTE*)pcm; nMediaPcmLen = 0; } // 打开DAC设备,并设置DAC设备采样率、声道 *obj->bReady = 1; obj->hDac = DacOpen(); if(obj->hDac == NULL) { kdebug(mod_audio, PRINT_ERROR, "dac open error\n"); kfree(pcm); MediaLibClose(obj); goto ThreadEnd; } if(DacSetSamplerate(obj->hDac, obj->Info.AudioSamplerate, obj->Info.AudioChannels) < 0) { kdebug(mod_audio, PRINT_ERROR, "set samplerate error\n"); kfree(pcm); DacClose(obj->hDac); MediaLibClose(obj); goto ThreadEnd; } kdebug(mod_audio, PRINT_INFO, "mplayer dacopen end = %d\n",TimerCount()); DacSetTempo(obj->hDac, obj->Task.Tempo); DacSetVolume(obj->hDac, obj->Task.Volume); kdebug(mod_audio, PRINT_INFO, "volume = %d, tempo=%d\n",obj->Task.Volume, obj->Task.Tempo); // 计算每次写入PCM数据最大值(1K的整数倍) max_wsize = 50 * (obj->Info.AudioSamplerate * obj->Info.AudioChannels * sizeof(short)) / 1000; max_wsize = ((max_wsize + 1023) / 1024) * 1024; max_time = (max_wsize * 1000) / (obj->Info.AudioSamplerate * obj->Info.AudioChannels * sizeof(short)); begin_time = MediaLibPlay(obj); if( begin_time < 0 ) { kdebug(mod_audio, PRINT_ERROR, "MediaLibPlay failed\n"); if(video.hMutex) kMutexDestroy(video.hMutex); *obj->bReady = -1; DacClose(obj->hDac); MediaLibClose(obj); kfree(pcm); goto ThreadEnd; } // 设置视频输出 if (obj->Info.bHasVideo) { // 启动视频解码线程 video.obj = obj; video.fPlayVideo = 1; video.hMutex = kMutexCreate(); video.audio_frame_time = 0; video.video_frame_time = 0; kdebug(mod_audio, PRINT_INFO, "create video thread\n"); KernelThread(PRIO_USER+2, AkThreadVideoPlay, (DWORD)&video, 0x8000); } else { video.obj = obj; video.hMutex = NULL; video.fPlayVideo = 0; video.audio_frame_time = 0; video.video_frame_time = 0; } // 发送WM_MEDIA_OPEN消息 if(task->hWnd) { msg.hWnd = task->hWnd; msg.Data.v = 0; msg.hWndSrc = 0; msg.MsgId = WM_MEDIA_OPEN; msg.Param = 0; #if defined(STC_EXP) sGuiMsgPutMsg(&msg); #else GuiMsgPutMsg(&msg); #endif } // 循环解压并播放 fade = 0; duration = 0; fPlayMedia = 1; obj->RecDuration = 0; if( task->ExterdType ) obj->JzAvDecoder->fMplayerInit = 0; init_end_time = TimerCount(); kdebug(mod_audio, PRINT_INFO, "mplayer start play time = %d\n",init_end_time); kdebug(mod_audio, PRINT_INFO, "playe init time = %dms\n",(init_end_time-init_start_time)*10); kdebug(mod_audio,PRINT_INFO,"obj->StartTime = %d, Obj->EndTime = %d\n",obj->StartTime,obj->EndTime); while(!obj->bClose && !obj->bTerminate) { // 解码音频数据 if(video.hMutex) kMutexWait(video.hMutex); //得到PCM数据 player_status = MediaLibGetStatus(obj); wlen = MediaLibGetPcm(obj,(BYTE*)pcm,block_num); // kprintf("wlen = %d\n",wlen); if((wlen<0) || (player_status==MEDIALIB_END) || (player_status==MEDIALIB_ERR)) { DacWriteEnd(obj->hDac, 0); if(MEDIALIB_ERR == player_status) { kdebug(mod_media, PRINT_ERROR, "media lib error!\n"); obj->bClose = 2; } else obj->bClose = 1; if(video.hMutex) kMutexRelease(video.hMutex); kdebug(mod_audio, PRINT_INFO, "wlen = %d, player_status = %d\n",wlen,player_status); break; } // 获取当前音频解码时间 cur_time = MediaLibGetAudioCurTime(obj); // kprintf("cur time = %d\n",cur_time); if( obj->StartTime ) { MediaLibSeek(obj,obj->StartTime); obj->StartTime = 0; wlen = 0; } if( obj->EndTime && cur_time >= obj->EndTime ) { //定时播放,如果播放时间到,则直接播放结束 DacWriteEnd(obj->hDac, 0); obj->bClose = 1; if(video.hMutex) kMutexRelease(video.hMutex); kprintf("play seek end: cur time = %d, end time = %d\n",cur_time,obj->EndTime); break; } if(video.hMutex) kMutexRelease(video.hMutex); if( nMplayerAudioStart == 0 && video.hMutex) { time_out = 100; nMplayerAudioStart = 1; while( nMplayerAudioStart != 3 && time_out--) sTimerSleep(10,NULL); if( !time_out ) kprintf("!!!!!!!! WARNNING : wait video time out !!!!!!!!\n"); nMplayerAudioStart = 4; } // 输出音频数据到DA pData = pcm; obj->RecDuration = cur_time; while(wlen > 0) { DWORD wsize; int ctl_code; // 写入PCM数据到DAC设备 wsize = (wlen > max_wsize) ? max_wsize : wlen; if(fade) { int s; short pcms; pcms = wsize / sizeof(short); for(s=0; s<pcms; s++) { int tmp; tmp = (int)pData[s]; tmp = (tmp * (pcms - s)) / pcms; pData[s] = (short)tmp; } DacWrite(obj->hDac, pData, wsize); DacWriteEnd(obj->hDac, 0); break; } else { if( DacWrite(obj->hDac, pData, wsize) == 0 ) { //出错,返回值为0 kdebug(mod_audio, PRINT_ERROR, "dac write is 0 \n"); obj->bClose = 1; break; } } // 提高当前时间精度 if( wsize == max_wsize ) obj->RecDuration += max_time; else obj->RecDuration += (wsize * 1000) / (obj->Info.AudioSamplerate * obj->Info.AudioChannels * sizeof(short)); pData += wsize / sizeof(short); wlen -= wsize; // 控制动作处理 if(video.hMutex) kMutexWait(video.hMutex); ctl_code = JzSrvProcMsg(obj); player_status = MediaLibGetStatus(obj); if(video.hMutex) kMutexRelease(video.hMutex); // 等待退出暂停状态 while( MEDIALIB_PAUSE == player_status && !obj->bClose && !obj->bTerminate) { sTimerSleep(100, NULL); if(video.hMutex) kMutexWait(video.hMutex); ctl_code = JzSrvProcMsg(obj); player_status = MediaLibGetStatus(obj); if(video.hMutex) kMutexRelease(video.hMutex); } // 检查是否退出 if(obj->bTerminate) { // if(fade == 0 && wlen == 0) // { // wlen = MediaLibGetPcm(obj,(BYTE*)pcm,block_num); // pData = pcm; // if(wlen < 0) // { // wlen = 0; // } // } kdebug(mod_audio, PRINT_INFO, "fade len:%d\n", wlen); fade = 1; } } } //如果是强行退出,则直接关闭MOS管,方式喀嚓声 if( obj->bTerminate && GetDacChannel() <= 1 ) { kdebug(mod_audio, PRINT_INFO, "terminate media, close mute mos\n"); } init_start_time = TimerCount(); kdebug(mod_audio, PRINT_INFO, "close meidia start : %d\n",init_start_time); // 是否用于视频的互斥量 if(video.hMutex) { //等待视频结束 while( 1 ) { if( !video.fPlayVideo ) break; sTimerSleep(10, NULL); } kMutexDestroy(video.hMutex); } // 关闭DAC设备 DacClose(obj->hDac); MediaLibClose(obj); kfree(pcm); init_end_time = TimerCount(); kdebug(mod_audio, PRINT_INFO, "close meidia end : %d - %dms\n",init_end_time, (init_end_time - init_start_time)*10); ThreadEnd: fPlayMedia = 0; WinClipMask(NULL); //MPLAYER播放器使用,用来设置从MPLAYER读到的PCM数据以及长度 if( obj->PlayerType ) { //外部播放器使用变量 pMediaPcmData = NULL; nMediaPcmLen = 0; } // 设置线程结束标志 msgid = 0; if(obj->bTerminate || (obj->bClose == 2)) { msgid = WM_MEDIA_TERMINATE; msg.MsgId = msgid; msg.hWnd = task->hWnd; } else if(obj->bClose) { msgid = WM_MEDIA_CLOSE; msg.MsgId = msgid; msg.hWnd = task->hWnd; } else { // 未启动播放即结束 msgid = 0; *obj->bReady = -1; } // 设置返回消息参数 if((obj->bTerminate == 2)) msg.Data.v = 1; else if(obj->bClose == 2) msg.Data.v = 2; else msg.Data.v = 0; // 删除对象 if(obj->bTerminate == 1) obj_del = 0; else JzSrvDestroyNotify(task); // 发送WM_MEDIA_CLOSE消息 if(msgid) { msg.hWndSrc = 0; msg.Param = 0; #if defined(STC_EXP) sGuiMsgPutMsg(&msg); #else GuiMsgPutMsg(&msg); #endif } // 增加Terminate标记,方便退出 if(!obj_del) obj->bTerminate++; kdebug(mod_audio, PRINT_INFO, "medialib close finish\n"); #ifdef MPLAYER_PRINTF_ENABEL syslog_set_global_level(PRINT_NOTICE); #endif #if defined(STC_EXP) sThreadTerminate(sThreadSelf()); #else ThreadTerminate(ThreadSelf()); #endif }