/*---------------------------------------------------------------------------* Project: TwlSDK - demos.TWL - spi - spiMonkey3 File: main.c Copyright 2007-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2009-09-24#$ $Rev: 11063 $ $Author: okubata_ryoma $ *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* A sample which controls microphone input, touch panel input, and sound output in parallel. Since TWL has a hardware to control SPI inputs, Software is not imposed limitation to use SPI devices in parallel. USAGE: UP, DOWN: Switch microphone sampling span. LEFT, RIGHT: Switch microphone sampling bit range. SEL , STA : Switch microphone sampling loop enable or disable. HOWTO: 1. Initialize MIC library and SNDEX library. 2. Start automatic sampling of microphone by default configuration. 3. Initialize TP library with getting calibration parameters. 4. Start automatic sampling of touch panel by fixed configuration. 5. Initialize SND library. 6. Start emitting sound. 7. When you switch parameters for automatic sampling of microphone, first, stop automatic sampling. Then, if necessary, stop emitting sound and switch I2S frequency. After that, edit parameters and start automatic sampling of microphone again. *---------------------------------------------------------------------------*/ #include #include "snd_data.h" #include "DEMO.h" /*---------------------------------------------------------------------------* Constant definitions *---------------------------------------------------------------------------*/ #define BUFFER_SIZE_MIC (256 * 1024) // 256 KB #define RETRY_MAX_COUNT 8 #define START_VCOUNT_TP 0 #define FREQUENCE_TP 4 #define BUFFER_SIZE_TP (FREQUENCE_TP + 1) /* Microphone sampling type string */ static const char* bitRangeString[MIC_SAMPLING_TYPE_MAX] = { "unsigned 8", "unsigned 12", "signed 8", "signed 12", "unsigned 12 (filter off)", "signed 12 (filter off)" }; /* Font data */ static const u32 fontChar[8 * 4]; static const u32 fontPltt[8 * 4]; /*---------------------------------------------------------------------------* Internal Function Definitions *---------------------------------------------------------------------------*/ static void StartMicSampling(const MICAutoParam* param); static void StopMicSampling(void); static void AdjustMicSampling(u32 rate); static SNDEXFrequency GetI2SFrequency(void); static void SetI2SFrequency(SNDEXFrequency freq); static void SwitchI2SFrequency(void); static void StepUpSamplingRate(void); static void StepDownSamplingRate(void); static void VBlankIntr(void); static void InitDrawMicData(void); static void SetDrawMicData(void *address, MICSamplingType type); static void DrawMicData(void); static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color); static void PrintMicSamplingParam(void); static void InitDrawTpData(void); static void SetDrawTpData(void); static void DrawTpData(void); /*---------------------------------------------------------------------------* Internal Variable Definitions *---------------------------------------------------------------------------*/ static u16 fontScr[32 * 32] ATTRIBUTE_ALIGN(HW_CACHE_LINE_SIZE); static MICAutoParam gMicAutoParam; static u8 gMicData[BUFFER_SIZE_MIC] ATTRIBUTE_ALIGN(HW_CACHE_LINE_SIZE); static u8 gDrawMicData[192]; static TPData gTpData[BUFFER_SIZE_TP]; static TPData gDrawTpData[FREQUENCE_TP]; static volatile BOOL g_sample_busy = FALSE; static u32 g_snd_async_tag; /*---------------------------------------------------------------------------* Name: TwlMain Description: Initialization and main loop. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void TwlMain(void) { /* Various types of initialization */ OS_Init(); FX_Init(); GX_Init(); GX_DispOff(); GXS_DispOff(); // When in NITRO mode, stopped by Panic DEMOCheckRunOnTWL(); /* Initializes display settings */ GX_SetBankForLCDC(GX_VRAM_LCDC_ALL); MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE); (void)GX_DisableBankForLCDC(); /* Display-related initialization */ InitDrawMicData(); InitDrawTpData(); /* Interrupt settings */ OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr); (void)OS_EnableIrqMask(OS_IE_V_BLANK); (void)OS_EnableIrq(); (void)OS_EnableInterrupts(); (void)GX_VBlankIntr(TRUE); /* Initialize microphone-related libraries */ { (void)PM_SetAmp(PM_AMP_ON); SNDEX_Init(); MIC_Init(); gMicAutoParam.type = MIC_SAMPLING_TYPE_8BIT; gMicAutoParam.buffer = (void *)gMicData; gMicAutoParam.size = BUFFER_SIZE_MIC; if ((OS_IsRunOnTwl() == TRUE) && (GetI2SFrequency() == SNDEX_FREQUENCY_47610)) { gMicAutoParam.rate = MIC_SAMPLING_RATE_23810; } else { gMicAutoParam.rate = MIC_SAMPLING_RATE_16360; } gMicAutoParam.loop_enable = TRUE; gMicAutoParam.full_callback = NULL; StartMicSampling((const MICAutoParam*)&gMicAutoParam); } /* Touch screen initialization */ { TPCalibrateParam calibrate; TP_Init(); if (TRUE == TP_GetUserInfo(&calibrate)) { TP_SetCalibrateParam(&calibrate); if (0 != TP_RequestAutoSamplingStart(START_VCOUNT_TP, FREQUENCE_TP, gTpData, BUFFER_SIZE_TP)) { OS_Panic("Could not start auto sampling of touch panel.\n"); } } else { OS_Panic("Could not get userInfo about touch panel calibration.\n"); } } /* Initialize sound */ SND_Init(); SND_AssignWaveArc((SNDBankData*)sound_bank_data, 0, (SNDWaveArc*)sound_wave_data); SND_StartSeq(0, sound_seq_data, 0, (SNDBankData*)sound_bank_data); /* Initialize internal variables */ MI_CpuFill8(gDrawMicData, 0x80, 192); /* LCD display start */ GX_DispOn(); GXS_DispOn(); /* Debug string output */ OS_Printf("spiMonkey3 demo started.\n"); OS_Printf(" up/down -> switch microphone sampling rate\n"); OS_Printf(" left/right -> switch microphone sampling bit range\n"); OS_Printf(" select -> switch microphone sampling loop state\n"); OS_Printf("\n"); PrintMicSamplingParam(); /* Empty call for getting key input data (strategy for pressing A Button in the IPL) */ (void)PAD_Read(); { u16 keyOld = 0; u16 keyTrg; u16 keyNow; /* Main loop */ while (TRUE) { /* Get key input data */ keyNow = PAD_Read(); keyTrg = (u16)((keyOld ^ keyNow) & keyNow); keyOld = keyNow; if (g_sample_busy == FALSE) { /* Change sampling type (bit width) */ if (keyTrg & PAD_KEY_LEFT) { StopMicSampling(); gMicAutoParam.type = (MICSamplingType)((gMicAutoParam.type + MIC_SAMPLING_TYPE_MAX - 1) % MIC_SAMPLING_TYPE_MAX); StartMicSampling((const MICAutoParam*)&gMicAutoParam); PrintMicSamplingParam(); } if (keyTrg & PAD_KEY_RIGHT) { StopMicSampling(); gMicAutoParam.type = (MICSamplingType)((gMicAutoParam.type + 1) % MIC_SAMPLING_TYPE_MAX); StartMicSampling((const MICAutoParam*)&gMicAutoParam); PrintMicSamplingParam(); } /* Change sampling rate */ if (keyTrg & PAD_KEY_UP) { StepUpSamplingRate(); PrintMicSamplingParam(); if (OS_IsRunOnTwl() == TRUE) { g_sample_busy = TRUE; SND_PauseSeq(0, TRUE); g_snd_async_tag = SND_GetCurrentCommandTag(); } } if (keyTrg & PAD_KEY_DOWN) { StepDownSamplingRate(); PrintMicSamplingParam(); if (OS_IsRunOnTwl() == TRUE) { g_sample_busy = TRUE; SND_PauseSeq(0, TRUE); g_snd_async_tag = SND_GetCurrentCommandTag(); } } /* Change loop availability when buffer is full */ if (keyTrg & (PAD_BUTTON_SELECT | PAD_BUTTON_START)) { StopMicSampling(); gMicAutoParam.loop_enable = (gMicAutoParam.loop_enable + 1) % 2; StartMicSampling((const MICAutoParam*)&gMicAutoParam); PrintMicSamplingParam(); } } else { if (OS_IsRunOnTwl() == TRUE) { if (SND_IsFinishedCommandTag(g_snd_async_tag) == TRUE) { StopMicSampling(); SwitchI2SFrequency(); StartMicSampling((const MICAutoParam*)&gMicAutoParam); SND_PauseSeq(0, FALSE); g_sample_busy = FALSE; } } else { g_sample_busy = FALSE; } } /* Edit sampling results in display buffer */ SetDrawMicData(MIC_GetLastSamplingAddress(), gMicAutoParam.type); SetDrawTpData(); /* Render microphone sampling waveform */ DrawMicData(); /* Main sound processing */ while (SND_RecvCommandReply(SND_COMMAND_NOBLOCK) != NULL) { } (void)SND_FlushCommand(SND_COMMAND_NOBLOCK); /* Waiting for the V-Blank */ OS_WaitVBlankIntr(); } } } /*---------------------------------------------------------------------------* Name: StartMicSampling Description: Calls the MIC_StartLimitedSampling function and performs error processing. Arguments: param: Parameters passed to the microphone functions Returns: None. *---------------------------------------------------------------------------*/ static void StartMicSampling(const MICAutoParam* param) { MICResult result; s32 retry = 0; while (TRUE) { result = MIC_StartLimitedSampling(param); switch (result) { case MIC_RESULT_SUCCESS: // Success return; case MIC_RESULT_BUSY: // Another thread is using the microphone case MIC_RESULT_SEND_ERROR: // PXI queue is full if (++ retry <= RETRY_MAX_COUNT) { OS_Sleep(1); continue; } OS_TWarning("Retry count overflow.\n"); return; case MIC_RESULT_ILLEGAL_STATUS: // Not in an autosampling stopped state OS_TWarning("Already started sampling.\n"); return; case MIC_RESULT_ILLEGAL_PARAMETER: // The specified parameter is not supported OS_TWarning("Illegal parameter to start automatic sampling.\n"); return; default: // Other fatal error OS_Panic("Fatal error (%d).\n", result); /* Never return */ } } } /*---------------------------------------------------------------------------* Name: StopMicSampling Description: Calls the MIC_StopLimitedSampling function and performs error processing. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void StopMicSampling(void) { MICResult result; s32 retry = 0; while (TRUE) { result = MIC_StopLimitedSampling(); switch (result) { case MIC_RESULT_SUCCESS: // Success case MIC_RESULT_ILLEGAL_STATUS: // Not in an autosampling state return; case MIC_RESULT_BUSY: // Microphone in use by other thread case MIC_RESULT_SEND_ERROR: // PXI queue is full if (++ retry <= RETRY_MAX_COUNT) { OS_Sleep(1); continue; } OS_TWarning("Retry count overflow.\n"); return; default: // Other fatal error OS_Panic("Fatal error (%d).\n", result); /* Never return */ } } } /*---------------------------------------------------------------------------* Name: AdjustMicSampling Description: Calls the MIC_AdjustLimitedSampling function and performs error processing. Arguments: rate: Specifies the sampling period. Returns: None. *---------------------------------------------------------------------------*/ static void AdjustMicSampling(u32 rate) { MICResult result; s32 retry = 0; while (TRUE) { result = MIC_AdjustLimitedSampling(rate); switch (result) { case MIC_RESULT_SUCCESS: // Success case MIC_RESULT_ILLEGAL_STATUS: // Not in an autosampling state return; case MIC_RESULT_BUSY: // Microphone in use by other thread case MIC_RESULT_SEND_ERROR: // PXI queue is full if (++ retry <= RETRY_MAX_COUNT) { OS_Sleep(1); continue; } OS_TWarning("Retry count overflow.\n"); return; case MIC_RESULT_ILLEGAL_PARAMETER: // The specified parameter is not supported OS_TWarning("Illegal parameter to adjust automatic sampling rate.\n"); return; default: // Other fatal error OS_Panic("Fatal error (%d).\n", result); /* Never return */ } } } #include /*---------------------------------------------------------------------------* Name: GetI2SFrequency Description: Gets the I2S operating frequency. Arguments: None. Returns: SNDEXFrequency: Returns the I2S operating frequency. *---------------------------------------------------------------------------*/ static SNDEXFrequency GetI2SFrequency(void) { SNDEXResult result; SNDEXFrequency freq; s32 retry = 0; while (TRUE) { result = SNDEX_GetI2SFrequency(&freq); switch (result) { case SNDEX_RESULT_SUCCESS: // Success return freq; case SNDEX_RESULT_EXCLUSIVE: // Exclusion error case SNDEX_RESULT_PXI_SEND_ERROR: // PXI queue is full if (++ retry <= RETRY_MAX_COUNT) { OS_Sleep(1); continue; } OS_TWarning("Retry count overflow.\n"); break; case SNDEX_RESULT_BEFORE_INIT: // Pre-initialization case SNDEX_RESULT_ILLEGAL_STATE: // Abnormal state OS_TWarning("Illegal state to get I2S frequency.\n"); break; case SNDEX_RESULT_FATAL_ERROR: // Fatal error default: OS_Panic("Fatal error (%d).\n", result); /* Never return */ } } return SNDEX_FREQUENCY_32730; } /*---------------------------------------------------------------------------* Name: SetI2SFrequency Description: Changes the I2S operating frequency. Arguments: freq: I2S operating frequency. Returns: None. *---------------------------------------------------------------------------*/ static void SetI2SFrequency(SNDEXFrequency freq) { SNDEXResult result; s32 retry = 0; while (TRUE) { result = SNDEX_SetI2SFrequency(freq); switch (result) { case SNDEX_RESULT_SUCCESS: // Success return; case SNDEX_RESULT_EXCLUSIVE: // Exclusion error case SNDEX_RESULT_PXI_SEND_ERROR: // PXI queue is full if (++ retry <= RETRY_MAX_COUNT) { OS_Sleep(1); continue; } OS_TWarning("Retry count overflow.\n"); return; case SNDEX_RESULT_BEFORE_INIT: // Pre-initialization case SNDEX_RESULT_ILLEGAL_STATE: // Abnormal state OS_TWarning("Illegal state to set I2S frequency.\n"); return; case SNDEX_RESULT_INVALID_PARAM: // Abnormal argument OS_TWarning("Could not set I2S frequency into %d.\n", freq); return; case SNDEX_RESULT_FATAL_ERROR: // Fatal error default: OS_Panic("Fatal error (%d)\n", result); /* Never return */ } } } /*---------------------------------------------------------------------------* Name: SwitchI2SFrequency Description: Changes the I2S operating frequency in conjunction with the microphone sampling frequency. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void SwitchI2SFrequency(void) { SNDEXFrequency freq; freq = GetI2SFrequency(); switch (gMicAutoParam.rate) { case MIC_SAMPLING_RATE_8180: case MIC_SAMPLING_RATE_10910: case MIC_SAMPLING_RATE_16360: case MIC_SAMPLING_RATE_32730: if (freq != SNDEX_FREQUENCY_32730) { SetI2SFrequency(SNDEX_FREQUENCY_32730); } break; case MIC_SAMPLING_RATE_11900: case MIC_SAMPLING_RATE_15870: case MIC_SAMPLING_RATE_23810: case MIC_SAMPLING_RATE_47610: if (freq != SNDEX_FREQUENCY_47610) { SetI2SFrequency(SNDEX_FREQUENCY_47610); } break; } } #include /*---------------------------------------------------------------------------* Name: StepUpSamplingRate Description: Increases the microphone sampling frequency by one level. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void StepUpSamplingRate(void) { if (OS_IsRunOnTwl() == TRUE) { switch (gMicAutoParam.rate) { case MIC_SAMPLING_RATE_8180: // 32.73k / 4 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910; break; case MIC_SAMPLING_RATE_10910: // 32.73k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900; break; case MIC_SAMPLING_RATE_11900: // 47.61k / 4 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870; break; case MIC_SAMPLING_RATE_15870: // 47.61k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360; break; case MIC_SAMPLING_RATE_16360: // 32.73k / 2 gMicAutoParam.rate = MIC_SAMPLING_RATE_23810; break; case MIC_SAMPLING_RATE_23810: // 47.61k / 2 gMicAutoParam.rate = MIC_SAMPLING_RATE_32730; break; case MIC_SAMPLING_RATE_32730: // 32.73k / 1 gMicAutoParam.rate = MIC_SAMPLING_RATE_47610; break; case MIC_SAMPLING_RATE_47610: // 47.61k / 1 default: /* Do nothing */ return; } } else { switch (gMicAutoParam.rate) { case MIC_SAMPLING_RATE_8180: // 32.73k / 4 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910; break; case MIC_SAMPLING_RATE_10910: // 32.73k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900; break; case MIC_SAMPLING_RATE_11900: // 47.61k / 4 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870; break; case MIC_SAMPLING_RATE_15870: // 47.61k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360; break; case MIC_SAMPLING_RATE_16360: // 32.73k / 2 gMicAutoParam.rate = MIC_SAMPLING_RATE_23810; break; case MIC_SAMPLING_RATE_23810: // 47.61k / 2 default: /* Do nothing */ return; } AdjustMicSampling(gMicAutoParam.rate); } } /*---------------------------------------------------------------------------* Name: StepUpSamplingRate Description: Decreases the microphone sampling frequency by one level. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void StepDownSamplingRate(void) { if (OS_IsRunOnTwl() == TRUE) { switch (gMicAutoParam.rate) { case MIC_SAMPLING_RATE_47610: // 47.61k / 1 gMicAutoParam.rate = MIC_SAMPLING_RATE_32730; break; case MIC_SAMPLING_RATE_32730: // 32.73k / 1 gMicAutoParam.rate = MIC_SAMPLING_RATE_23810; break; case MIC_SAMPLING_RATE_23810: // 47.61k / 2 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360; break; case MIC_SAMPLING_RATE_16360: // 32.73k / 2 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870; break; case MIC_SAMPLING_RATE_15870: // 47.61k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900; break; case MIC_SAMPLING_RATE_11900: // 47.61k / 4 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910; break; case MIC_SAMPLING_RATE_10910: // 32.73k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_8180; break; case MIC_SAMPLING_RATE_8180: // 32.73k / 4 default: /* Do nothing */ return; } } else { switch (gMicAutoParam.rate) { case MIC_SAMPLING_RATE_23810: // 47.61k / 2 gMicAutoParam.rate = MIC_SAMPLING_RATE_16360; break; case MIC_SAMPLING_RATE_16360: // 32.73k / 2 gMicAutoParam.rate = MIC_SAMPLING_RATE_15870; break; case MIC_SAMPLING_RATE_15870: // 47.61k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_11900; break; case MIC_SAMPLING_RATE_11900: // 47.61k / 4 gMicAutoParam.rate = MIC_SAMPLING_RATE_10910; break; case MIC_SAMPLING_RATE_10910: // 32.73k / 3 gMicAutoParam.rate = MIC_SAMPLING_RATE_8180; break; case MIC_SAMPLING_RATE_8180: // 32.73k / 4 default: /* Do nothing */ return; } AdjustMicSampling(gMicAutoParam.rate); } } /*---------------------------------------------------------------------------* Name: VBlankIntr Description: V-Blank interrupt vector. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void VBlankIntr(void) { /* Sets the IRQ check flag */ OS_SetIrqCheckFlag(OS_IE_V_BLANK); /* Display the position of touch screen contact */ DrawTpData(); } /*---------------------------------------------------------------------------* Name: InitDrawMicData Description: Performs initialization for 3D display of microphone sampling waveform. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void InitDrawMicData(void) { /* Main display 3D display settings */ G3X_Init(); G3X_InitMtxStack(); G3X_AlphaTest(FALSE, 0); G3X_AntiAlias(TRUE); G3X_EdgeMarking(FALSE); G3X_SetFog(FALSE, (GXFogBlend)0, (GXFogSlope)0, 0); G3X_SetClearColor(GX_RGB(0, 0, 0), 0, 0x7fff, 63, FALSE); G3_ViewPort(0, 0, 255, 191); G3_MtxMode(GX_MTXMODE_POSITION_VECTOR); MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_3D); GX_SetVisiblePlane(GX_PLANEMASK_BG0); G2_SetBG0Priority(0); } /*---------------------------------------------------------------------------* Name: SetDrawMicData Description: Edits the most recent microphone sampled data in the display buffer. Arguments: address: Location in main memory where the most recent sampling data was stored by the component type: Sampling type (bit width). Returns: None. *---------------------------------------------------------------------------*/ static void SetDrawMicData(void *address, MICSamplingType type) { s32 i; /* If sampling has never been performed, do nothing and stop. (Because it would delete memory cache(s) unrelated to the microphone) */ if ((address < gMicData) || (address >= (gMicData + BUFFER_SIZE_MIC))) { return; } switch (type) { case MIC_SAMPLING_TYPE_8BIT: case MIC_SAMPLING_TYPE_SIGNED_8BIT: /* In the case of 8-bit sampling */ { u8 *p; p = (u8 *)((u32)address - 191); if (p < gMicData) { p = (u8 *)((u32)p + BUFFER_SIZE_MIC); } DC_InvalidateRange((void *)((u32)p & ~(HW_CACHE_LINE_SIZE - 1)), HW_CACHE_LINE_SIZE); for (i = 0; i < 192; i++) { gDrawMicData[i] = *p; p++; if ((u32)p >= (u32)(gMicData + BUFFER_SIZE_MIC)) { p -= BUFFER_SIZE_MIC; } if (((u32)p % HW_CACHE_LINE_SIZE) == 0) { DC_InvalidateRange(p, HW_CACHE_LINE_SIZE); } } } break; case MIC_SAMPLING_TYPE_12BIT: case MIC_SAMPLING_TYPE_SIGNED_12BIT: case MIC_SAMPLING_TYPE_12BIT_FILTER_OFF: case MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF: /* For 12-bit sampling */ { u16 *p; p = (u16 *)((u32)address - 382); if ((u32)p < (u32)gMicData) { p = (u16 *)((u32)p + BUFFER_SIZE_MIC); } DC_InvalidateRange((void *)((u32)p & ~(HW_CACHE_LINE_SIZE - 1)), HW_CACHE_LINE_SIZE); for (i = 0; i < 192; i++) { gDrawMicData[i] = (u8)((*p >> 8) & 0x00ff); p++; if ((u32)p >= (u32)(gMicData + BUFFER_SIZE_MIC)) { p = (u16 *)((u32)p - BUFFER_SIZE_MIC); } if (((u32)p % HW_CACHE_LINE_SIZE) == 0) { DC_InvalidateRange(p, HW_CACHE_LINE_SIZE); } } } break; } } /*---------------------------------------------------------------------------* Name: DrawMicData Description: Performs 3D display of microphone sampling waveform. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void DrawMicData(void) { s32 i; G3X_Reset(); G3_Identity(); G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, 0, 31, 0); if ((gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_8BIT) || (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT) || (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF)) { for (i = 0; i < 191; i++) { DrawLine((s16)((s8)gDrawMicData[i]), (s16)i, (s16)((s8)gDrawMicData[i + 1]), (s16)(i + 1), GX_RGB(31, 31, 31)); } } else { for (i = 0; i < 191; i++) { DrawLine((s16)(gDrawMicData[i]), (s16)i, (s16)(gDrawMicData[i + 1]), (s16)(i + 1), GX_RGB(31, 31, 31)); } } G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W); } /*---------------------------------------------------------------------------* Name: DrawLine Description: Renders a line with a triangular polygon. Arguments: sx: X-coordinate of starting point of line to render sy: Y-coordinate of starting point of line to render ex: X-coordinate of endpoint of line to render ey: Y-coordinate of endpoint of line to render color: Color of line to render Returns: None. *---------------------------------------------------------------------------*/ static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color) { fx16 fsx = (fx16)(((sx - 128) * 0x1000) / 128); fx16 fsy = (fx16)(((96 - sy) * 0x1000) / 96); fx16 fex = (fx16)(((ex - 128) * 0x1000) / 128); fx16 fey = (fx16)(((96 - ey) * 0x1000) / 96); G3_Begin(GX_BEGIN_TRIANGLES); { G3_Color(color); G3_Vtx(fsx, fsy, 0); G3_Color(color); G3_Vtx(fex, fey, 0); G3_Color(color); G3_Vtx(fsx, fsy, 1); } G3_End(); } /*---------------------------------------------------------------------------* Name: PrintMicSamplingParam Description: Print-outputs the microphone's sampling settings. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void PrintMicSamplingParam(void) { s32 range = 0; OS_Printf(" sampling-rate: "); switch (gMicAutoParam.rate) { case MIC_SAMPLING_RATE_32730: OS_Printf("32.73kHz"); break; case MIC_SAMPLING_RATE_16360: OS_Printf("16.36kHz"); break; case MIC_SAMPLING_RATE_10910: OS_Printf("10.91kHz"); break; case MIC_SAMPLING_RATE_8180: OS_Printf(" 8.18kHz"); break; case MIC_SAMPLING_RATE_47610: OS_Printf("47.61kHz"); break; case MIC_SAMPLING_RATE_23810: OS_Printf("23.81kHz"); break; case MIC_SAMPLING_RATE_15870: OS_Printf("15.87kHz"); break; case MIC_SAMPLING_RATE_11900: OS_Printf("11.90kHz"); break; } OS_Printf(" , loop: %s", (gMicAutoParam.loop_enable ? " on" : "off")); OS_Printf(" , bit-range: %s\n", bitRangeString[gMicAutoParam.type % MIC_SAMPLING_TYPE_MAX]); } /*---------------------------------------------------------------------------* Name: Prepare2DScreen Description: Initializes the 2D screen to display touch screen contact positions. Arguments: scr: Specifies the start address of screen data to be edited. pltt: Specifies the palette number used for the line indicating the contact position. Returns: None. *---------------------------------------------------------------------------*/ static void Prepare2DScreen(u16* scr, u16 pltt) { s32 i; s32 j; scr[0] = (u16)(0x0003 | ((pltt & 0x000f) << 12)); for (j = 1; j < 32; j ++) { scr[j] = (u16)(0x0001 | ((pltt & 0x000f) << 12)); } for (i = 1; i < 32; i ++) { scr[i * 32] = (u16)(0x0002 | ((pltt & 0x000f) << 12)); for (j = 1; j < 32; j ++) { scr[(i * 32) + j] = (u16)((pltt & 0x000f) << 12); } } DC_StoreRange(scr, (32 * 32 * sizeof(u16))); } /*---------------------------------------------------------------------------* Name: InitDrawTpData Description: Performs initialization for 2D display of touch screen contact positions. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void InitDrawTpData(void) { /* Sub-display 2D display settings */ GX_SetBankForSubBG(GX_VRAM_SUB_BG_32_H); GXS_SetGraphicsMode(GX_BGMODE_0); G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0x6000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01); G2S_SetBG1Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0x6800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01); G2S_SetBG2ControlText(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0x7000, GX_BG_CHARBASE_0x00000); G2S_SetBG3ControlText(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0x7800, GX_BG_CHARBASE_0x00000); Prepare2DScreen(fontScr, 0); GXS_LoadBG0Scr(fontScr, 0, sizeof(fontScr)); Prepare2DScreen(fontScr, 1); GXS_LoadBG1Scr(fontScr, 0, sizeof(fontScr)); Prepare2DScreen(fontScr, 2); GXS_LoadBG2Scr(fontScr, 0, sizeof(fontScr)); Prepare2DScreen(fontScr, 3); GXS_LoadBG3Scr(fontScr, 0, sizeof(fontScr)); G2S_SetBG0Priority(0); G2S_SetBG1Priority(1); G2S_SetBG2Priority(2); G2S_SetBG3Priority(3); GXS_LoadBGPltt(fontPltt, 0, sizeof(fontPltt)); GXS_LoadBG0Char(fontChar, 0, sizeof(fontChar)); GXS_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_BG1 | GX_PLANEMASK_BG2 | GX_PLANEMASK_BG3); } /*---------------------------------------------------------------------------* Name: SetDrawTpData Description: Edits the buffer for converting the most recent touch screen sampled data to display screen coordinates and displaying it. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void SetDrawTpData(void) { s32 i; s32 index; s32 lastIndex; lastIndex = TP_GetLatestIndexInAuto(); for (i = 0; i < FREQUENCE_TP; i ++) { index = (lastIndex + BUFFER_SIZE_TP - i) % BUFFER_SIZE_TP; if ((gTpData[index].touch == TP_TOUCH_ON) && (gTpData[index].validity == TP_VALIDITY_VALID)) { gDrawTpData[i].touch = TP_TOUCH_ON; TP_GetCalibratedPoint(&gDrawTpData[i], &gTpData[index]); } else { gDrawTpData[i].touch = TP_TOUCH_OFF; } } } /*---------------------------------------------------------------------------* Name: DrawTpData Description: Performs 2D display of the touch screen contact position. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void DrawTpData(void) { int plane = GX_PLANEMASK_NONE; if (gDrawTpData[0].touch == TP_TOUCH_ON) { G2S_SetBG0Offset((256 - gDrawTpData[0].x), (256 - gDrawTpData[0].y)); plane |= GX_PLANEMASK_BG0; } if (gDrawTpData[1].touch == TP_TOUCH_ON) { G2S_SetBG1Offset((256 - gDrawTpData[1].x), (256 - gDrawTpData[1].y)); plane |= GX_PLANEMASK_BG1; } if (gDrawTpData[2].touch == TP_TOUCH_ON) { G2S_SetBG2Offset((256 - gDrawTpData[2].x), (256 - gDrawTpData[2].y)); plane |= GX_PLANEMASK_BG2; } if (gDrawTpData[3].touch == TP_TOUCH_ON) { G2S_SetBG3Offset((256 - gDrawTpData[3].x), (256 - gDrawTpData[3].y)); plane |= GX_PLANEMASK_BG3; } GXS_SetVisiblePlane(plane); } /*---------------------------------------------------------------------------* Font data *---------------------------------------------------------------------------*/ static const u32 fontChar[8 * 4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x11111111, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x11111111, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 }; static const u32 fontPltt[8 * 4] = { 0x7fff0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x5ef70000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3def0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1ce70000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };