static int Init(void) { g_BlitterWaitQueue = semaphore_create_fifo(0); g_BlitEngineQueue = semaphore_create_fifo(1); return 0; }
EMBX_EVENT EMBX_OS_EventCreate(void) { EMBX_EVENT ev = NULL; /* This is not multithread safe - perhaps use an atomic test&set ? */ if (!cacheInitialised) { cacheInitialised = 1; (void) EMBX_OS_MUTEX_INIT(&cacheLock); } EMBX_OS_MUTEX_TAKE(&cacheLock); if ((ev = cacheHead) != NULL) { cacheHead = cacheHead->next; /* Mark desc as being in use */ ev->next = (EMBX_EVENT) EMBX_HANDLE_VALID; EMBX_OS_MUTEX_RELEASE(&cacheLock); } else { EMBX_OS_MUTEX_RELEASE(&cacheLock); /* Dynamically allocate a new cache container * and initialise the event inside it */ ev = EMBX_OS_MemAlloc(sizeof(*ev)); if (ev) { /* Mark desc as being in use */ ev->next = (EMBX_EVENT) EMBX_HANDLE_VALID; ev->event = semaphore_create_fifo(0); } } return ev; }
/******************************************************************************* Name : EnterCriticalSection Description : Used to protect critical sections of Init/Open/Close/Term Parameters : None Assumptions : Limitations : Returns : Nothing *******************************************************************************/ static void EnterCriticalSection(void) { static BOOL InstancesAccessControlInitialized = FALSE; #if !defined(ST_OSLINUX) task_lock(); #endif if (!InstancesAccessControlInitialized) { InstancesAccessControlInitialized = TRUE; InstancesAccessControl_p = semaphore_create_fifo(1); } #if !defined(ST_OSLINUX) task_unlock(); #endif semaphore_wait(InstancesAccessControl_p); }
int main(int argc, char **argv) { stm_display_plane_t *pPlane; stm_display_buffer_t buffer_setup; char *fbuffer; void *fbufferphys; interrupt_t *vsync_interrupt=0; interrupt_t *hdmi_interrupt=0; int err; int seconds; int clip; int rgb; int dvi; stm_plane_id_t planeid; osclock_t lasttime; kernel_initialize(NULL); kernel_start(); kernel_timeslice(OS21_TRUE); framerate_sem = semaphore_create_fifo(0); frameupdate_sem = semaphore_create_fifo(0); hotplug_sem = semaphore_create_fifo(0); task_create(displayupdate_task_fn, 0, OS21_DEF_MIN_STACK_SIZE, MAX_USER_PRIORITY, "displayupdate", 0); pDev = stm_display_get_device(0); if(!pDev) { printf("Unable to create device instance\n"); return 1; } if(argc<2) usage(); argc--; argv++; seconds = 60; rgb = 0; dvi = 0; clip = 0; while(argc>0) { switch(**argv) { case 'C': { printf("Clipping video signal selected\n"); clip = 1; break; } case 'd': { printf("Setting DVI mode on HDMI output\n"); dvi = 1; break; } case 'h': { int refresh; argc--; argv++; if(argc <= 0) { fprintf(stderr,"Missing HD vertical refresh frequency\n"); usage(); } refresh = atoi(*argv); switch(refresh) { case 50: printf("Setting 1280x720-50\n"); MODE = STVTG_TIMING_MODE_720P50000_74250; STANDARD = STM_OUTPUT_STD_SMPTE296M; framerate = 50; break; case 59: printf("Setting 1280x720-59\n"); MODE = STVTG_TIMING_MODE_720P59940_74176; STANDARD = STM_OUTPUT_STD_SMPTE296M; framerate = 60; break; case 60: printf("Setting 1280x720-60\n"); MODE = STVTG_TIMING_MODE_720P60000_74250; STANDARD = STM_OUTPUT_STD_SMPTE296M; framerate = 60; break; default: fprintf(stderr,"Unsupported HD vertical refresh frequency\n"); usage(); } break; } case 'r': { printf("Setting Component RGB Outputs\n"); rgb = 1; break; } case 'p': { int refresh; argc--; argv++; if(argc <= 0) { fprintf(stderr,"Missing 1080p vertical refresh frequency\n"); usage(); } refresh = atoi(*argv); switch(refresh) { case 23: printf("Setting 1920x1080-23\n"); MODE = STVTG_TIMING_MODE_1080P23976_74176; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 24; break; case 24: printf("Setting 1920x1080-24\n"); MODE = STVTG_TIMING_MODE_1080P24000_74250; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 24; break; case 25: printf("Setting 1920x1080-25\n"); MODE = STVTG_TIMING_MODE_1080P25000_74250; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 25; break; case 29: printf("Setting 1920x1080-29\n"); MODE = STVTG_TIMING_MODE_1080P29970_74176; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 30; break; case 30: printf("Setting 1920x1080-30\n"); MODE = STVTG_TIMING_MODE_1080P30000_74250; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 30; break; case 50: printf("Setting 1920x1080-50\n"); MODE = STVTG_TIMING_MODE_1080P50000_148500; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 50; break; case 59: printf("Setting 1920x1080-59\n"); MODE = STVTG_TIMING_MODE_1080P59940_148352; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 60; break; case 60: printf("Setting 1920x1080-60\n"); MODE = STVTG_TIMING_MODE_1080P60000_148500; STANDARD = STM_OUTPUT_STD_SMPTE274M; framerate = 60; break; default: fprintf(stderr,"Unsupported HD vertical refresh frequency\n"); usage(); } break; } case 's': { int refresh; argc--; argv++; if(argc <= 0) { fprintf(stderr,"Missing SD vertical refresh frequency\n"); usage(); } refresh = atoi(*argv); switch(refresh) { case 50: printf("Setting 720x576-50\n"); MODE = STVTG_TIMING_MODE_576P50000_27000; STANDARD = STM_OUTPUT_STD_SMPTE293M; framerate = 50; break; case 59: printf("Setting 720x480-59\n"); MODE = STVTG_TIMING_MODE_480P59940_27000; STANDARD = STM_OUTPUT_STD_SMPTE293M; framerate = 60; break; case 60: printf("Setting 720x480-60\n"); MODE = STVTG_TIMING_MODE_480P60000_27027; STANDARD = STM_OUTPUT_STD_SMPTE293M; framerate = 60; break; default: fprintf(stderr,"Unsupported SD vertical refresh frequency\n"); usage(); } break; } case 't': { argc--; argv++; if(argc <= 0) { fprintf(stderr,"Missing seconds\n"); usage(); } seconds = atoi(*argv); if(seconds<0) usage(); break; } case 'v': { int refresh; argc--; argv++; if(argc <= 0) { fprintf(stderr,"Missing vertical refresh frequency\n"); usage(); } refresh = atoi(*argv); switch(refresh) { case 59: printf("Setting 640x480-59\n"); MODE = STVTG_TIMING_MODE_480P59940_25180; STANDARD = STM_OUTPUT_STD_VESA; framerate = 60; break; case 60: printf("Setting 640x480-60\n"); MODE = STVTG_TIMING_MODE_480P60000_25200; STANDARD = STM_OUTPUT_STD_VESA; framerate = 60; break; default: fprintf(stderr,"Unsupported vertical refresh frequency\n"); usage(); } break; } default: fprintf(stderr,"Unknown option '%s'\n",*argv); usage(); } argc--; argv++; } planeid = OUTPUT_GDP1; vsync_interrupt = get_main_vtg_interrupt(); setup_soc(); if(!vsync_interrupt) { printf("Cannot find VSYNC interrupt handler\n"); return 1; } err = interrupt_install(vsync_interrupt, vsync_isr, pDev); err += interrupt_enable(vsync_interrupt); if(err>0) { printf("Unable to install and enable VSYNC interrupt\n"); return 1; } fbuffer = (char *)malloc(FBSIZE); if(!fbuffer) { printf("Unable to allocate framebuffer\n"); return 1; } memset(fbuffer, 0x00, FBSIZE); create_test_pattern(fbuffer, FBWIDTH, FBHEIGHT, FBSTRIDE); cache_purge_data(fbuffer, FBSIZE); pOutput = stm_display_get_output(pDev, 0); if(!pOutput) { printf("Unable to get output\n"); return 1; } setup_analogue_voltages(pOutput); stm_display_output_set_control(pOutput, STM_CTRL_SIGNAL_RANGE, clip?STM_SIGNAL_VIDEO_RANGE:STM_SIGNAL_FILTER_SAV_EAV); pDVO = get_dvo_output(pDev); { pHDMI = get_hdmi_output(pDev); if(pHDMI) { /* * Now we have a HDMI output pointer to handle hotplug interrupts, * we can enable the interrupt handlers. */ hdmi_interrupt = get_hdmi_interrupt(); if(hdmi_interrupt) { err = interrupt_install(hdmi_interrupt, hdmi_isr, pHDMI); err += interrupt_enable(hdmi_interrupt); } if(err>0) { printf("Unable to install and enable hdmi interrupts\n"); return 1; } stm_display_output_set_control(pHDMI, STM_CTRL_SIGNAL_RANGE, clip?STM_SIGNAL_VIDEO_RANGE:STM_SIGNAL_FILTER_SAV_EAV); } else { printf("Hmmm, no HDMI output available\n"); } } pModeLine = stm_display_output_get_display_mode(pOutput, MODE); if(!pModeLine) { printf("Unable to use requested display mode\n"); return 1; } pPlane = stm_display_get_plane(pDev, planeid); if(!pPlane) { printf("Unable to get graphics plane\n"); return 1; } if(stm_display_plane_connect_to_output(pPlane, pOutput)<0) { printf("Unable to display plane on output\n"); return 1; } if(stm_display_plane_lock(pPlane)<0) { printf("Unable to lock plane's buffer queue\n"); return 1; } memset(&buffer_setup, 0, sizeof(buffer_setup)); vmem_virt_to_phys(fbuffer, &fbufferphys); buffer_setup.src.ulVideoBufferAddr = (ULONG)fbufferphys; buffer_setup.src.ulVideoBufferSize = FBSIZE; buffer_setup.src.ulStride = FBSTRIDE; buffer_setup.src.ulPixelDepth = FBDEPTH; buffer_setup.src.ulColorFmt = FBPIXFMT; buffer_setup.src.Rect.width = FBWIDTH; buffer_setup.src.Rect.height = FBHEIGHT; buffer_setup.dst.Rect.width = FBWIDTH; buffer_setup.dst.Rect.height = FBHEIGHT; buffer_setup.info.ulFlags = STM_PLANE_PRESENTATION_PERSISTENT; printf("Clock is running at %ld ticks per second\n",(long)time_ticks_per_sec()); ULONG format=0; format = rgb?STM_VIDEO_OUT_RGB:STM_VIDEO_OUT_YUV; stm_display_output_set_control(pOutput, STM_CTRL_VIDEO_OUT_SELECT, format); if(pHDMI) { ULONG format = 0; format |= rgb?STM_VIDEO_OUT_RGB:STM_VIDEO_OUT_YUV; format |= dvi?STM_VIDEO_OUT_DVI:STM_VIDEO_OUT_HDMI; stm_display_output_set_control(pHDMI, STM_CTRL_VIDEO_OUT_SELECT, format); } if(stm_display_output_start(pOutput, pModeLine, STANDARD)<0) { printf("Unable to start display\n"); return 1; } if(pDVO) { printf("Info: Attempting to start DVO\n"); if(stm_display_output_start(pDVO, pModeLine, STANDARD)<0) { printf("Info: Unable to start DVO\n"); } } lasttime = time_now(); // VTG Start time (approx) if(stm_display_plane_queue_buffer(pPlane, &buffer_setup)<0) { printf("Unable to queue framebuffer for display on graphics plane\n"); return 1; } task_create(hotplug_task_fn, 0, OS21_DEF_MIN_STACK_SIZE, MIN_USER_PRIORITY, "hotplug", 0); if(seconds == 0) { task_delay(time_ticks_per_sec()*5); task_priority_set(NULL,MIN_USER_PRIORITY); silent_hotplug = 1; err = get_yesno(); } else { while(seconds>0) { osclock_t now,delta; semaphore_wait(framerate_sem); now = time_now(); delta = time_minus(now,lasttime); printf("%d frames took %ld ticks.\n",framerate, (long)delta); lasttime = now; seconds--; } err = 0; } stm_display_plane_flush(pPlane); stm_display_plane_disconnect_from_output(pPlane, pOutput); stm_display_output_stop(pOutput); interrupt_disable(vsync_interrupt); interrupt_disable(hdmi_interrupt); stm_display_plane_release(pPlane); if(pDVO) stm_display_output_release(pDVO); if(pHDMI) stm_display_output_release(pHDMI); stm_display_output_release(pOutput); stm_display_release_device(pDev); return err; }
/******************************************************************************* Name : Init Description : API specific initialisations Parameters : pointer on device and initialisation parameters Assumptions : pointer on device is not NULL Limitations : Returns : ST_ErrorCode_t for the API Init function *******************************************************************************/ static ST_ErrorCode_t Init(stcc_Device_t * const Device_p, const STCC_InitParams_t * const InitParams_p) { ST_ErrorCode_t ErrCode = ST_NO_ERROR; STEVT_OpenParams_t EVTOpenParams; STVBI_OpenParams_t VBIOpenParams; STEVT_DeviceSubscribeParams_t SubscribeParams; U8 ErrorRecovery = STCC_RECOVERY_ERROR_NONE; U32 i,j; /* Test initialisation parameters and exit if some are invalid. */ if (InitParams_p->CPUPartition_p == NULL) { CC_Defense(ST_ERROR_BAD_PARAMETER); return(ST_ERROR_BAD_PARAMETER); } /* Allocate dynamic data structure */ Device_p->DeviceData_p = (stcc_DeviceData_t *) memory_allocate(InitParams_p->CPUPartition_p, sizeof(stcc_DeviceData_t)); if (Device_p->DeviceData_p == NULL) { /* Error of allocation */ CC_Defense(ST_ERROR_NO_MEMORY); return(ST_ERROR_NO_MEMORY); } memset(Device_p->DeviceData_p, 0x00 , sizeof(stcc_DeviceData_t)); /* Initialise the allocated structure: most of variables are set-up by */ /* init (handles, init parameters, etc), so just initialise the rest. */ /* Default inits */ Device_p->DeviceData_p->InitParams.CPUPartition_p = InitParams_p->CPUPartition_p; Device_p->DeviceData_p->Task.IsRunning = FALSE; Device_p->DeviceData_p->Task.ToBeDeleted = FALSE; Device_p->DeviceData_p->CCDecodeStarted = FALSE; Device_p->DeviceData_p->FirstSlot = BAD_SLOT; Device_p->DeviceData_p->NbUsedSlot = 0; Device_p->DeviceData_p->LastPacket708 = FALSE; for(i =0; i<NB_SLOT; i++) { for(j =0; j<NB_CCDATA; j++) { Device_p->DeviceData_p->CaptionSlot[i].CC_Data[j].Field = 0x0; Device_p->DeviceData_p->CaptionSlot[i].CC_Data[j].Byte1 = 0x0; Device_p->DeviceData_p->CaptionSlot[i].CC_Data[j].Byte2 = 0x0; } Device_p->DeviceData_p->CaptionSlot[i].DataLength = 0; Device_p->DeviceData_p->CaptionSlot[i].PTS.PTS = 0xfffffff; Device_p->DeviceData_p->CaptionSlot[i].SlotAvailable = 1; Device_p->DeviceData_p->CaptionSlot[i].Next = BAD_SLOT; Device_p->DeviceData_p->CaptionSlot[i].Previous = BAD_SLOT; } for(i=0; i<NB_COPIES; i++) { Device_p->DeviceData_p->Copies[i].Used = STCC_EMPTY; Device_p->DeviceData_p->Copies[i].Length = 0; } /* Check bad parameter */ if ((InitParams_p->MaxOpen > STCC_MAX_OPEN) || (InitParams_p->EvtHandlerName[0] == '\0') || (InitParams_p->VBIName[0] == '\0') || (InitParams_p->VIDName[0] == '\0') || (InitParams_p->VTGName[0] == '\0') || (strlen(InitParams_p->EvtHandlerName) > sizeof(ST_DeviceName_t)) || (strlen(InitParams_p->VBIName) > sizeof(ST_DeviceName_t)) || (strlen(InitParams_p->VTGName) > sizeof(ST_DeviceName_t)) || (strlen(InitParams_p->VIDName) > sizeof(ST_DeviceName_t)) ) { ErrCode = ST_ERROR_BAD_PARAMETER; } if (ErrCode == ST_NO_ERROR) { /* Save Max open & strings */ Device_p->DeviceData_p->InitParams.MaxOpen = InitParams_p->MaxOpen; strcpy(Device_p->DeviceData_p->InitParams.EvtHandlerName, InitParams_p->EvtHandlerName); strcpy(Device_p->DeviceData_p->InitParams.VBIName, InitParams_p->VBIName); strcpy(Device_p->DeviceData_p->InitParams.VIDName, InitParams_p->VIDName); strcpy(Device_p->DeviceData_p->InitParams.VTGName, InitParams_p->VTGName); } if (ErrCode == ST_NO_ERROR) { /* Save ouput mode */ Device_p->DeviceData_p->OutputMode = STCC_OUTPUT_MODE_NONE; Device_p->DeviceData_p->FormatMode = STCC_FORMAT_MODE_DETECT; ErrCode = STEVT_Open(InitParams_p->EvtHandlerName, &EVTOpenParams, &Device_p->DeviceData_p->EVTHandle); if(ErrCode != ST_NO_ERROR) { ErrCode = ST_ERROR_BAD_PARAMETER; ErrorRecovery = STCC_RECOVERY_ERROR_HANDLER; } if(ErrCode == ST_NO_ERROR) { /* Open params for VBI */ VBIOpenParams.Configuration.VbiType = STVBI_VBI_TYPE_CLOSEDCAPTION; VBIOpenParams.Configuration.Type.CC.Mode = STVBI_CCMODE_BOTH; ErrCode = STVBI_Open(Device_p->DeviceData_p->InitParams.VBIName, &VBIOpenParams,&Device_p->DeviceData_p->VBIHandle); if(ErrCode != ST_NO_ERROR) { ErrCode = STCC_ERROR_VBI_UNKNOWN; ErrorRecovery = STCC_RECOVERY_ERROR_VBI_ACCESS; } } if(ErrCode == ST_NO_ERROR) { /* Subscribe to UserDataEvent */ SubscribeParams.NotifyCallback = (STEVT_DeviceCallbackProc_t)stcc_UserDataCallBack; SubscribeParams.SubscriberData_p = Device_p; ErrCode = STEVT_SubscribeDeviceEvent( Device_p->DeviceData_p->EVTHandle, Device_p->DeviceData_p->InitParams.VIDName, STVID_USER_DATA_EVT, &SubscribeParams); if(ErrCode != ST_NO_ERROR) { ErrCode = STCC_ERROR_EVT_SUBSCRIBE; ErrorRecovery = STCC_RECOVERY_ERROR_VIDEO_USER_SUB; } } if(ErrCode == ST_NO_ERROR) { /* Subscribe to VSyncEvent */ SubscribeParams.NotifyCallback = (STEVT_DeviceCallbackProc_t)stcc_VSyncCallBack; ErrCode = STEVT_SubscribeDeviceEvent( Device_p->DeviceData_p->EVTHandle, Device_p->DeviceData_p->InitParams.VTGName, STVTG_VSYNC_EVT, &SubscribeParams); if(ErrCode != ST_NO_ERROR) { ErrCode = STCC_ERROR_EVT_SUBSCRIBE; ErrorRecovery = STCC_RECOVERY_ERROR_VTG_SUB; } } if(ErrCode == ST_NO_ERROR) { ErrCode = STEVT_RegisterDeviceEvent( Device_p->DeviceData_p->EVTHandle, Device_p->DeviceName, STCC_DATA_TO_BE_PRESENTED_EVT, &Device_p->DeviceData_p->Notify_id); /* Event register */ if(ErrCode != ST_NO_ERROR) { ErrCode = STCC_ERROR_EVT_REGISTER; ErrorRecovery = STCC_RECOVERY_ERROR_EVT_REGISTER; } } if(ErrCode == ST_NO_ERROR) { /* task creation */ Device_p->DeviceData_p->Task.SemProcessCC_p = semaphore_create_fifo_timeout(0); Device_p->DeviceData_p->SemAccess_p = semaphore_create_fifo(1); /* CREATE TASK */ ErrCode = STOS_TaskCreate ((void (*) (void*))stcc_ProcessCaption, (void *)Device_p, Device_p->DeviceData_p->InitParams.CPUPartition_p, STCC_TASK_STACK_SIZE, NULL, Device_p->DeviceData_p->InitParams.CPUPartition_p, &(Device_p->DeviceData_p->Task.Task_p), NULL, STCC_TASK_PRIORITY, "Closed_Caption_ProcessTask", task_flags_no_min_stack_size); if(ErrCode != ST_NO_ERROR) { return(ST_ERROR_BAD_PARAMETER); } else { /* Task created */ Device_p->DeviceData_p->Task.IsRunning = TRUE; } } switch(ErrorRecovery) { /* Break are omited volontary to undo what we already done */ /* No check to undo what succeeded */ case STCC_RECOVERY_ERROR_TASK_CREATE: semaphore_delete((Device_p->DeviceData_p->Task.SemProcessCC_p)); semaphore_delete((Device_p->DeviceData_p->SemAccess_p)); STEVT_UnregisterDeviceEvent( Device_p->DeviceData_p->EVTHandle, Device_p->DeviceName, STCC_DATA_TO_BE_PRESENTED_EVT); case STCC_RECOVERY_ERROR_EVT_REGISTER: STEVT_UnsubscribeDeviceEvent( Device_p->DeviceData_p->EVTHandle, Device_p->DeviceData_p->InitParams.VTGName, STVTG_VSYNC_EVT); case STCC_RECOVERY_ERROR_VTG_SUB: case STCC_RECOVERY_ERROR_VIDEO_FRAME_SUB: STEVT_UnsubscribeDeviceEvent( Device_p->DeviceData_p->EVTHandle, Device_p->DeviceData_p->InitParams.VIDName, STVID_USER_DATA_EVT); case STCC_RECOVERY_ERROR_VIDEO_USER_SUB: STVBI_Close(Device_p->DeviceData_p->VBIHandle); case STCC_RECOVERY_ERROR_VBI_ACCESS: STEVT_Close(Device_p->DeviceData_p->EVTHandle); case STCC_RECOVERY_ERROR_HANDLER: /* Nothing to undo */ case STCC_RECOVERY_ERROR_NONE: default: break; } } if (ErrCode != ST_NO_ERROR) { CC_Defense(ErrCode); /* De-allocate dynamic data structure */ memory_deallocate(InitParams_p->CPUPartition_p, (void *) Device_p->DeviceData_p); Device_p->DeviceData_p = NULL; } STCC_DebugStats.NbUserDataReceived = 0; STCC_DebugStats.NbUserDataParsed = 0; STCC_DebugStats.NBCaptionDataFound = 0; STCC_DebugStats.NBCaptionDataPresented = 0; return(ErrCode); }
static ULONG CreateSemaphore(int initVal) { semaphore_t *pSema = semaphore_create_fifo(initVal); return (unsigned long)pSema; }