//============================================================================= // hal_SdioWakeUp //----------------------------------------------------------------------------- /// This function requests a resource of #HAL_SYS_FREQ_52M. /// hal_SdioSleep() must be called before any other //============================================================================= PUBLIC VOID hal_SdioWakeUp(VOID) { // Take a resource (The idea is to be able to get a 25Mhz clock) // hwp_sysCtrl->Clk_Per_Enable |= SYS_CTRL_ENABLE_PER_SDMMC2;//modify 2012-02-24 ,wuys // wifi_i2c_rf_write_data(0x3f, 0x0000,1); hal_SysRequestFreq(HAL_SYS_FREQ_SDMMC2, HAL_SYS_FREQ_104M, hal_SdioUpdateDivider); UINT32 scStatus = hal_SysEnterCriticalSection(); // Make sure the last clock is set hal_SdioUpdateDivider(hal_SysGetFreq()); hal_SysExitCriticalSection(scStatus); // hwp_configRegs->GPIO_Mode &= ~CFG_REGS_MODE_PIN_SPI1_CLK;//modify 2012-02-24 ,wuys #if 0 hwp_configRegs->GPIO_Mode &= ~0x1D000;;//modify 2012-02-24 ,wuys // hwp_configRegs->Alt_mux_select &= ~0x800;//modify 2012-02-24 ,wuys hwp_configRegs->Alt_mux_select |= 0x800;//modify 2012-02-24 ,wuys #endif //hal_SdioGpioClr(); //hwp_gpio->gpio_oen_set_out //hwp_sysCtrl->Clk_Per_Enable |= SYS_CTRL_ENABLE_PER_SDMMC2;//modify 2012-02-24 ,wuys //hal_SdioSetClk(2000000); }
// ============================================================================= // hal_IfcGetChannel // ----------------------------------------------------------------------------- /// Get an IFC channel opend in NO auto-disable mode /// /// @param requestId Describe the direction of the tranfer (rx or /// tx) and the module to or from which data are to be moved. /// @param ifcMode Mode of the transfer (Autodisable or not, 8 or 32 bits) /// @return The channel number got or HAL_UNKNOWN_CHANNEL // ============================================================================= PROTECTED UINT8 hal_IfcGetChannel(HAL_IFC_REQUEST_ID_T requestId, HAL_IFC_MODE_T ifcMode) { UINT8 channel; // This function is only relevant/available for manual transferts. HAL_ASSERT(ifcMode == HAL_IFC_SIZE_8_MODE_MANUAL || ifcMode == HAL_IFC_SIZE_32_MODE_MANUAL, "hal_IfcGetChannel called with an autodisable %d mode", ifcMode); UINT32 status = hal_SysEnterCriticalSection(); channel = SYS_IFC_CH_TO_USE(hwp_sysIfc->get_ch) ; if (channel >= SYS_IFC_STD_CHAN_NB) { hal_SysExitCriticalSection(status); return HAL_UNKNOWN_CHANNEL; } hwp_sysIfc->std_ch[channel].tc = 0; hwp_sysIfc->std_ch[channel].start_addr = 0; g_halModuleIfcChannelOwner[channel] = requestId; hwp_sysIfc->std_ch[channel].control = (SYS_IFC_REQ_SRC(requestId) | ifcMode #if (CHIP_HAS_ASYNC_TCU) | SYS_IFC_CH_RD_HW_EXCH #endif | SYS_IFC_ENABLE); hal_SysExitCriticalSection(status); return channel; }
// ============================================================================= // hal_IfcChannelRelease // ----------------------------------------------------------------------------- /// Force the release of a channel owned by a request. /// /// The channel is only released if the specified request /// owns the channel. /// /// @param requestId Describe the direction of the tranfer (rx or /// tx) and the module to or from which data are to be moved. /// @param channel Channel to release // ============================================================================= PROTECTED VOID hal_IfcChannelRelease(HAL_IFC_REQUEST_ID_T requestId, UINT8 channel) { UINT32 status; // Here, we consider the transfer as previously finished. if (channel == HAL_UNKNOWN_CHANNEL) return; // Channel number too big. IFC_ASSERT(channel < SYS_IFC_STD_CHAN_NB, channel); status = hal_SysEnterCriticalSection(); if (g_halModuleIfcChannelOwner[channel] == requestId) { // Disable this channel // CAUTION: It needs several cycles to disable IFC, but the FLUSH bit // will take effect immediately. If the FLUSH bit is cleared while // the DISABLE bit is set, IFC will still work for the next few cycles, // which might lead to data loss! hwp_sysIfc->std_ch[channel].control |= SYS_IFC_DISABLE; #if 0 // Read the status of this channel while((hwp_sysIfc->std_ch[channel].status & SYS_IFC_ENABLE) != 0); // Write the TC to 0 for next time the channel is re-enabled hwp_sysIfc->std_ch[channel].tc = 0; #endif } hal_SysExitCriticalSection(status); }
// ============================================================================= // hal_AifPlayStream // ----------------------------------------------------------------------------- /// Play a stream, copied from a buffer in memory to the AIF fifos, in infinite /// mode: when the end of the buffer is reached, playing continues from the /// beginning. /// The buffer start address must be aligned on a 32-bit address, and the size /// must be a multiple of 32 bytes. /// /// @param playedStream Pointer to the played stream. A stream pointing to /// a NULL buffer (startAddress field) only enable the audio, without /// playing data from anywhere. /// @return HAL_ERR_NO if everything is alright or HAL_ERR_RESOURCE_BUSY if /// a play is already in process. // ============================================================================= PUBLIC HAL_ERR_T hal_AifPlayStream(CONST HAL_AIF_STREAM_T* playedStream) { UINT32 status; HAL_ERR_T errStatus = HAL_ERR_NO; if (hal_SysGetRequestFreq(HAL_SYS_FREQ_AIF) == HAL_SYS_FREQ_32K) { HAL_ASSERT(FALSE, "AIF Play Stream when resource not active"); } status = hal_SysEnterCriticalSection(); if (playedStream->startAddress != NULL) { errStatus = hal_AifStream((HAL_AIF_STREAM_T*) playedStream, PLAY); } if (errStatus == HAL_ERR_NO) { g_halAifPlaying = TRUE; // Allow symbols to be sent hwp_aif->ctrl = (g_halAifControlReg | AIF_ENABLE_H_ENABLE) & ~AIF_TX_OFF; } hal_SysExitCriticalSection(status); return errStatus; }
PRIVATE MEMD_ERR_T memd_BlockLockStatus(UINT8 * phy_SectorAddr, UINT16 *Locked) { VOLATILE UINT16 * BankAddr; VOLATILE UINT16 * BlockAddr; UINT16 DeviceCode; UINT32 phy_Start; UINT32 phy_End; UINT32 status; memd_FlashGetSectorLimits((UINT32)phy_SectorAddr, &phy_Start, &phy_End); if ((UINT32)phy_SectorAddr != phy_Start) { *Locked = 0xffff; return MEMD_ERR_ALIGN; } BankAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phy_Start&FLASHBANK_MASK)); BlockAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + phy_Start); // Block Protection Read hal_EbcFlashWriteEnable(TRUE); status = hal_SysEnterCriticalSection(); *BankAddr = CMD_READ_ESD; DeviceCode = *(UINT16*)(BankAddr + 0x1); *Locked = *(UINT16*)(BlockAddr + 0x2); *BankAddr = CMD_READ_ARRAY; hal_SysExitCriticalSection(status); hal_EbcFlashWriteEnable(FALSE); // Write out Device Code for debug check return MEMD_ERR_NO; }
// ============================================================================ // hal_TimGetReminderTime // ---------------------------------------------------------------------------- /// Return the remaining time to count before the previously programmed period /// expires. /// @return Time before the previously programmed period expires. // ============================================================================ PUBLIC UINT32 hal_TimGetReminderTime(VOID) { HAL_PROFILE_FUNCTION_ENTER(hal_TimGetReminderTime); UINT32 status; UINT32 timVal; status=hal_SysEnterCriticalSection(); // // the timer counts negatively once wrapped, so ... // // overflow + wrap time = remaining time to count // if ((hwp_timer->irq_cause & TIMER_STATUS(OSTIM_IRQ))) // { // // The counter wrapped and the irq is pending or under treatment // tim_val=g_halTickOverflow; // #ifdef TIM_VERBOSE // hal_Printf((_PAL | TSTDOUT,"TickGetVal : Irq Pending")); // #endif // } // else timVal = hal_TimTickGetVal() + g_halTickOverflow; #ifdef TIM_VERBOSE HAL_TRACE(_PAL | TSTDOUT, 0, "TickGetVal: %d",timVal); #endif hal_SysExitCriticalSection(status); HAL_PROFILE_FUNCTION_EXIT(hal_TimGetReminderTime); return (timVal); }
// ============================================================================ // hal_TimSetExpirationTime // ---------------------------------------------------------------------------- /// Set the next time when the OS timer will wrap. /// @param nextPeriod The next period before the new wrap. // ============================================================================ PUBLIC VOID hal_TimSetExpirationTime(UINT32 nextPeriod) { HAL_PROFILE_FUNCTION_ENTER(hal_TimSetExpirationTime); UINT32 status; UINT32 period = nextPeriod; status=hal_SysEnterCriticalSection(); #ifdef TIM_VERBOSE HAL_TRACE(_PAL|TSTDOUT,0,"TickNotify: Next_Period %d, TickError %d",Next_Period,TickError); #endif if (period>HAL_TIM_MAX_PER) { g_halTickOverflow = period-HAL_TIM_MAX_PER; g_halTickLastPeriod = HAL_TIM_MAX_PER; } else { g_halTickOverflow = 0; g_halTickLastPeriod = period; } #ifdef TIM_VERBOSE HAL_TRACE(_PAL|TSTDOUT,0, "TickNotify: g_halTickLastPeriod %d",g_halTickLastPeriod); #endif hal_TimTickStart(g_halTickLastPeriod); hal_SysExitCriticalSection(status); HAL_PROFILE_FUNCTION_EXIT(hal_TimSetExpirationTime); }
// ============================================================================ // hal_TickIrqHandler // ---------------------------------------------------------------------------- /// IRQ handler for the OS timer, called when this timer wrap. // ============================================================================ PRIVATE VOID hal_TickIrqHandler(VOID) { UINT32 scStatus; INT32 tickError=0; UINT32 reportedPeriod; scStatus=hal_SysEnterCriticalSection(); // save error tickError = (INT32) hal_TimTickGetVal(); // disable timer hal_TimTickStop(); reportedPeriod = g_halTickLastPeriod-tickError; hal_SysExitCriticalSection(scStatus); #ifdef TIM_VERBOSE HAL_TRACE(_PAL | TSTDOUT, 0, "TickIRQ: Tampax %d, Error %d", reportedPeriod, tickError); #endif sxr_Tampax(reportedPeriod, 0); }
PUBLIC VOID hal_SdioOpen(UINT8 clk_adj, HAL_SDIO_IRQ_HANDLER_T handler) { g_halSdioRegistry = handler; // Take the module out of reset hwp_sysCtrl->REG_DBG = SYS_CTRL_PROTECT_UNLOCK; hwp_sysCtrl->BB_Rst_Clr = SYS_CTRL_CLR_RST_SDMMC2; hwp_sysCtrl->Clk_Per_Enable |= SYS_CTRL_ENABLE_PER_SDMMC2; hwp_sysCtrl->Clk_Sys_Mode |= SYS_CTRL_MODE_SYS_PCLK_DATA_MANUAL; // hwp_sysCtrl->Sys_Rst_Clr = SYS_CTRL_CLR_RST_SDMMC2; hwp_sysCtrl->REG_DBG = SYS_CTRL_PROTECT_LOCK; // We don't use interrupts. // hwp_sdmmc2->SDMMC2_INT_MASK = 0x80; hwp_sdmmc2->SDMMC2_INT_MASK = 0x00; hwp_sdmmc2->SDMMC2_MCLK_ADJUST = clk_adj; // Take a resource (The idea is to be able to get a 25Mhz clock) hal_SysRequestFreq(HAL_SYS_FREQ_SDMMC2, HAL_SYS_FREQ_104M, hal_SdioUpdateDivider); UINT32 scStatus = hal_SysEnterCriticalSection(); // Make sure the last clock is set hal_SdioUpdateDivider(hal_SysGetFreq()); hal_SysExitCriticalSection(scStatus); // pmd_EnablePower(PMD_POWER_SDMMC2, TRUE); }
// ============================================================================= // hal_AifRecordDisableIfcAtNextIrq // ----------------------------------------------------------------------------- /// During Record the IFC channel is in Fifo loop mode /// In order to stop it cleanly, you can ask to automatically disable /// the IFC channel at the next Half Fifo/End Fifo interrupt. /// @return #HAL_ERR_NO // ============================================================================= PUBLIC HAL_ERR_T hal_AifRecordDisableIfcAtNextIrq(VOID) { UINT32 status = hal_SysEnterCriticalSection(); hwp_bbIfc->ch[RECORD].control |= BB_IFC_AUTO_DISABLE; hal_SysExitCriticalSection(status); return HAL_ERR_NO; }
// ============================================================================= // hal_SdioSetClk // ----------------------------------------------------------------------------- /// Set the SDMMC2 clock frequency to something inferior but close to that, /// taking into account system frequency. // ============================================================================= PUBLIC VOID hal_SdioSetClk(UINT32 clock) { // TODO Add assert to stay on supported values ? g_halSdioFreq = clock; UINT32 scStatus = hal_SysEnterCriticalSection(); // Update the divider takes care of the registers configuration hal_SdioUpdateDivider(hal_SysGetFreq()); hal_SysExitCriticalSection(scStatus); }
// ============================================================================ // hal_EbcFlashOpen // ---------------------------------------------------------------------------- /// Enable the CS for FLASH. That chip select is named like this for its /// common use, but can in fact be plugged to a RAM. /// This function must be called before any other EBC driver function, /// as the Flash Chip is the device imposing the frequency on the memory /// bridge. This optimal frequency is set as a parameter and the corresponding /// EBC settings are also specified. /// The Chip Select used is not a parameter of the function as it is always /// #HAL_EBC_FLASH (ie. CS0) /// /// @param optimalFreq Optimal Frequency to use the chip plugged on the /// #HAL_EBC_FLASH chip select. /// @param csConfig Configuration for the chip select. The \c csEn enable bit /// of the mode configuration must be set to 1 ! /// @param cbFunc callback function for enabling the burst mode on sram /// or NULL if not needed. Note: cbFunc must not be in flash /// @return Base address of the configured space // ============================================================================ PUBLIC VOID* HAL_BOOT_FUNC hal_EbcFlashOpen(HAL_SYS_FREQ_T optimalFreq, CONST HAL_EBC_CS_CFG_T* csConfig, HAL_EBC_BURSTCALLBACK_T* cbFunc) { #ifdef CHIP_HAS_EBC_CS2_BUG // union representing the status bitfield in a 32 bits value // loadable in the register union { UINT32 reg; HAL_EBC_TIME_CFG_T bitfield; } timeCfgUnion; // union representing the status bitfield in a 32 bits value // loadable in the register union { UINT32 reg; HAL_EBC_MODE_CFG_T bitfield; } modeCfgUnion; #endif VOID* retval = NULL; //ENTER CRITICAL UINT32 status = hal_SysEnterCriticalSection(); // Wait if the lock is locked hal_EbcWaitReady(); // Set EBC frequency // FIXME The membridge clock must be set-up before the system clock, and done // only once. The flash open should (must) be done before hal_Open for // the Admux. As long as it's not, hal_EbcCsSetup is called by hal_Open. // hal_EbcCsSetup(optimalFreq); // Write the pointer into the table //g_halEbcCsConfigArray[0] = csConfig; hal_EbcCsSetupWithCallback(HAL_EBC_FLASH, csConfig, cbFunc); retval = (VOID*)hwp_cs0; #ifdef CHIP_HAS_EBC_CS2_BUG timeCfgUnion.bitfield = csConfig->time; modeCfgUnion.bitfield = csConfig->mode; g_halCs0TimeReg = timeCfgUnion.reg; g_halCs0ModeReg = modeCfgUnion.reg; #endif //EXIT CRITICAL hal_SysExitCriticalSection(status); return retval; }
// ============================================================================= // hal_IfcTransferStart // ----------------------------------------------------------------------------- /// Start an IFC transfer /// /// This is a non blocking function that starts the transfer /// and returns the hand. /// /// @param requestId Describe the direction of the tranfer (rx or /// tx) and the module to or from which data are to be moved. /// @param memStartAddr. Start address of the buffer where data /// to be sent are located or where to put the data read, according /// to the request defined by the previous parameter /// @param xferSize Number of bytes to transfer. The maximum size /// is 2^20 - 1 bytes. /// @param ifcMode Mode of the transfer (Autodisable or not, 8 or 32 bits) /// @return Channel got or HAL_UNKNOWN_CHANNEL. // ============================================================================= PROTECTED UINT8 hal_IfcTransferStart(HAL_IFC_REQUEST_ID_T requestId, UINT8* memStartAddr, UINT32 xferSize, HAL_IFC_MODE_T ifcMode) { // Check buffer alignment depending on the mode if (ifcMode != HAL_IFC_SIZE_8_MODE_MANUAL && ifcMode != HAL_IFC_SIZE_8_MODE_AUTO) { // Then ifcMode == HAL_IFC_SIZE_32, check word alignment HAL_ASSERT(((UINT32)memStartAddr%4) == 0, "HAL IFC: 32 bits transfer misaligned 0x@%08X", memStartAddr); } else { // ifcMode == HAL_IFC_SIZE_8, nothing to check } HAL_ASSERT(xferSize < (1<<SYS_IFC_TC_LEN), "HAL IFC: Transfer size too large: %d", xferSize); UINT32 status = hal_SysEnterCriticalSection(); UINT8 channel; UINT8 i; // Check the requested id is not currently already used. for (i = 0; i < SYS_IFC_STD_CHAN_NB ; i++) { if (GET_BITFIELD(hwp_sysIfc->std_ch[i].control, SYS_IFC_REQ_SRC) == requestId) { // This channel is or was used for the requestId request. // Check it is still in use. HAL_ASSERT((hwp_sysIfc->std_ch[i].status & SYS_IFC_ENABLE) == 0, "HAL: Attempt to use the IFC to deal with a %d" " request still active on channel %d", requestId, i); } } channel = SYS_IFC_CH_TO_USE(hwp_sysIfc->get_ch) ; if (channel >= SYS_IFC_STD_CHAN_NB) { hal_SysExitCriticalSection(status); return HAL_UNKNOWN_CHANNEL; } g_halModuleIfcChannelOwner[channel] = requestId; hwp_sysIfc->std_ch[channel].start_addr = (UINT32) memStartAddr; hwp_sysIfc->std_ch[channel].tc = xferSize; hwp_sysIfc->std_ch[channel].control = (SYS_IFC_REQ_SRC(requestId) | ifcMode #if (CHIP_HAS_ASYNC_TCU) | SYS_IFC_CH_RD_HW_EXCH #endif | SYS_IFC_ENABLE); hal_SysExitCriticalSection(status); return channel; }
UINT16 get_data_from_CircularBuffer(struct CircularBuf *pCirBuff, UINT8 *pBuff,UINT16 uDataSize) { UINT16 Block_Len, First_half, Second_half, real_len, real_sent_len, tmp_Get; real_sent_len = 0; UINT32 status = hal_SysEnterCriticalSection(); Block_Len = GET_DATA_BLOCK_LEN(pCirBuff->Get, pCirBuff->Put, pCirBuff->Buf_len); if ((Block_Len == 0) && (pCirBuff->NotEmpty)) Block_Len = pCirBuff->Buf_len; real_len = (Block_Len < uDataSize) ? Block_Len : uDataSize; if (real_len > 0)/*have data to send*/ { if (pCirBuff->Get < pCirBuff->Put) { memcpy(pBuff, &pCirBuff->Buf[pCirBuff->Get], real_len); tmp_Get = MOD_BUFF_LEN(pCirBuff->Get + real_len,pCirBuff->Buf_len); } else { First_half = pCirBuff->Buf_len - pCirBuff->Get; if (real_len < First_half) { memcpy(pBuff, &pCirBuff->Buf[pCirBuff->Get], real_len); tmp_Get = MOD_BUFF_LEN(pCirBuff->Get + real_len,pCirBuff->Buf_len); } else { memcpy(pBuff, &pCirBuff->Buf[pCirBuff->Get], First_half); Second_half = real_len - First_half; tmp_Get = MOD_BUFF_LEN(pCirBuff->Get + First_half,pCirBuff->Buf_len); memcpy(&pBuff[First_half], &pCirBuff->Buf[tmp_Get], Second_half); tmp_Get = MOD_BUFF_LEN(tmp_Get + Second_half,pCirBuff->Buf_len); } } pCirBuff->Get = tmp_Get; if (pCirBuff->Get == pCirBuff->Put) pCirBuff->NotEmpty = 0; } hal_SysExitCriticalSection(status); return real_len; }
// ============================================================================ // hal_EbcSramOpen // ---------------------------------------------------------------------------- /// Enable a CS for SRAM. The chip selects for /// FLASH have been set before by calling #hal_EbcFlashOpen. /// The enabling of a CS returns the base address of the configured space. /// The settings are given at the opening of the peripheral on the given /// chip select, and must support the external maximal clock as it has been /// set by the configuring of the CS0 (Flash) chipo select. /// /// @param csConfig Configuration for the chip select. The \c csEn enable bit /// of the mode configuration must be set to 1 there if the chip select /// of the opened peripheral have to be enabled ! /// @param cbFunc callback function for enabling the burst mode on sram /// or NULL if not needed. Note: cbFunc must not be in sram /// @return Base address of the configured space // ============================================================================ PUBLIC VOID* HAL_BOOT_FUNC hal_EbcSramOpen(CONST HAL_EBC_CS_CFG_T* csConfig, HAL_EBC_BURSTCALLBACK_T* cbFunc) { VOID* retval = NULL; //ENTER CRITICAL UINT32 status = hal_SysEnterCriticalSection(); hal_EbcCsSetupWithCallback(HAL_EBC_SRAM, csConfig, cbFunc); retval = (VOID*)hwp_cs1; //EXIT CRITICAL hal_SysExitCriticalSection(status); return retval; }
// ============================================================================= // hal_BootEnterMonitor // ----------------------------------------------------------------------------- /// Call this function to enter the boot monitor. // ============================================================================= PUBLIC VOID hal_BootEnterMonitor(VOID) { // We want to reboot now, and not get interrupted by any trivial stuff. UINT32 __attribute__((unused)) status = hal_SysEnterCriticalSection(); if (g_halBootBeforeMonCallback != NULL) { (*g_halBootBeforeMonCallback)(); } // To restart in the Boot Monitor, by going through // the Boot Sector. hal_BootSectorSetCommand(BOOT_SECTOR_CMD_ENTER_BOOT_MONITOR); hal_SysRestart(); }
// ============================================================================= // hal_AifStopRecord // ----------------------------------------------------------------------------- /// Stop playing a buffer // ============================================================================= PUBLIC VOID hal_AifStopRecord(VOID) { g_halAifRecording = FALSE; hwp_bbIfc->ch[RECORD].control = BB_IFC_DISABLE; hwp_bbIfc->ch[RECORD].int_mask = 0; g_halAifHandlers[RECORD].halfHandler = NULL; g_halAifHandlers[RECORD].endHandler = NULL; // Disable the AIF if not recording UINT32 status = hal_SysEnterCriticalSection(); if (!g_halAifPlaying) { hwp_aif->ctrl = AIF_PARALLEL_OUT_SET_PARA | AIF_PARALLEL_IN_SET_PARA ; } hal_SysExitCriticalSection(status); }
// ============================================================================= // hal_AifStopPlay // ----------------------------------------------------------------------------- /// Stop playing a buffer // ============================================================================= PUBLIC VOID hal_AifStopPlay(VOID) { g_halAifPlaying = FALSE; // More caution needed ? hwp_bbIfc->ch[PLAY].control = BB_IFC_DISABLE; hwp_bbIfc->ch[PLAY].int_mask = 0; g_halAifHandlers[PLAY].halfHandler = NULL; g_halAifHandlers[PLAY].endHandler = NULL; // Disable the AIF if not recording UINT32 status = hal_SysEnterCriticalSection(); if (!g_halAifRecording) { // To have the clock allowing the disabling. hwp_aif->ctrl = AIF_PARALLEL_OUT_SET_PARA | AIF_PARALLEL_IN_SET_PARA; } hal_SysExitCriticalSection(status); }
UINT16 memd_FlashRead_ID(UINT16 index) { VOLATILE UINT16 * BankAddr; VOLATILE UINT16 * ptr; UINT32 phys_add; UINT16 data =0 ; UINT32 status; phys_add = 0x0; BankAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phys_add&FLASHBANK_MASK)); ptr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phys_add&~1)); status = hal_SysEnterCriticalSection(); *(BankAddr) = 0x90; data = *(ptr+index); *BankAddr = CMD_READ_ARRAY; hal_SysExitCriticalSection(status); return data; }
// ============================================================================= // lcdd_MutexGet // ----------------------------------------------------------------------------- /// This function enter in critical section, read the value of the mutex and, /// if this is a '1', returns '1' and set the mutex to 0. If this is a '0', /// it does nothing. Then, in both cases, it exists the Critical Section. /// /// @param mutex Pointer to the integer used as a mutex. /// @return '1' if the mutex was taken, '0' otherwise. // ============================================================================= PRIVATE UINT32 lcdd_MutexGet(UINT32* mutex) { UINT32 status; UINT32 result; status = hal_SysEnterCriticalSection(); if ((*mutex) == 1) { // Take the mutex *mutex = 0; result = 1; } else { // Too bad ... result = 0; } hal_SysExitCriticalSection(status); return result; }
// ============================================================================= // hal_AifRecordStream // ----------------------------------------------------------------------------- /// Record a stream, copied from the AIF fifos to a buffer in memory, in infinite /// mode: when the end of the buffer is reached, playing continues from the /// beginning. /// The buffer start address must be aligned on a 32-bit address, and the size /// must be a multiple of 32 bytes. /// /// @param recordedStream Pointer to the recorded stream. A stream pointing to /// a NULL buffer (startAddress field) only enable /// the audio, without recording data from anywhere. /// // ============================================================================= PUBLIC HAL_ERR_T hal_AifRecordStream(CONST HAL_AIF_STREAM_T* recordedStream) { UINT32 status; HAL_ERR_T errStatus = HAL_ERR_NO; if (hal_SysGetRequestFreq(HAL_SYS_FREQ_AIF) == HAL_SYS_FREQ_32K) { HAL_ASSERT(FALSE, "AIF Record Stream when resource not active"); } status = hal_SysEnterCriticalSection(); if (recordedStream->startAddress != NULL) { errStatus = hal_AifStream(recordedStream, RECORD); } if (errStatus == HAL_ERR_NO) { g_halAifRecording = TRUE; // In Loopback mode, do not start now - the Tx will do it // This is usefull for synchronization purpose if ((!g_halAifPlaying) && ((g_halAifControlReg & AIF_LOOP_BACK)==0)) { // Need to start the clock: write 4 data not to send hwp_aif->ctrl = g_halAifControlReg | AIF_ENABLE_H_ENABLE | AIF_TX_OFF_TX_OFF; hwp_aif->data = 0; hwp_aif->data = 0; hwp_aif->data = 0; hwp_aif->data = 0; } } hal_SysExitCriticalSection(status); return errStatus; }
// ============================================================================ // hal_EbcCsClose // ---------------------------------------------------------------------------- /// Disables a CS (except FLASH and SRAM). /// The address space previously allocated for this chip select becomes /// unavailable after a call to this function /// /// @param cs The Chip Select to Disable // ============================================================================ PUBLIC VOID hal_EbcCsClose(HAL_EBC_CS_T cs) { UINT32 status = hal_SysEnterCriticalSection(); hal_EbcWaitReady(); hwp_memBridge->CS_Time_Write = 0; switch(cs) { case HAL_EBC_CS2: hwp_memBridge->CS_Config[2].CS_Mode = 0; //g_halEbcCsConfigArray[2]= NULL; break; case HAL_EBC_CS3: hwp_memBridge->CS_Config[3].CS_Mode = 0; //g_halEbcCsConfigArray[3]= NULL; break; case HAL_EBC_CS4: hwp_memBridge->CS_Config[4].CS_Mode = 0; //g_halEbcCsConfigArray[4]= NULL; break; default: break; } hal_SysExitCriticalSection(status); }
// ============================================================================= // hal_IfcChannelFlush // ----------------------------------------------------------------------------- /// Empty the FIFO a specified channel. /// /// If #requestId does not match #channel owner, does not do anything. /// /// @param requestId Describe the direction of the tranfer (rx or /// tx) and the module to or from which data are to be moved. /// @param channel Channel whose FIFO is to be clear. // ============================================================================= PROTECTED VOID hal_IfcChannelFlush(HAL_IFC_REQUEST_ID_T requestId, UINT8 channel) { UINT32 status; // Here, we consider the transfer as previously finished. if (channel == HAL_UNKNOWN_CHANNEL) return; // Channel number too big. IFC_ASSERT(channel < SYS_IFC_STD_CHAN_NB, channel); // Check that the channel is really owned by the peripheral // which is doing the request, it could have been release // automatically or by an IRQ handler. status = hal_SysEnterCriticalSection(); if (g_halModuleIfcChannelOwner[channel] == requestId) { // Always flush IFC regardless of whether FIFO is currently empty. // In case of RX, if some data is being received, it has // NOT been put in FIFO yet. hwp_sysIfc->std_ch[channel].control |= SYS_IFC_FLUSH; } hal_SysExitCriticalSection(status); }
// ============================================================================= // hal_IfcGetTc // ----------------------------------------------------------------------------- /// Returns the transfer count of the IFC. /// If #requestId does not match #channel owner, returns 0. /// /// @param requestId Describe the direction of the tranfer (rx or /// tx) and the module to or from which data are to be moved. /// @param channel Number of the channel whose transfer we are concerned for. /// @return The number of bytes remaining to be transfered. // ============================================================================= PROTECTED UINT32 hal_IfcGetTc(HAL_IFC_REQUEST_ID_T requestId, UINT8 channel) { UINT32 status; UINT32 tc = 0; // Here, we consider the transfer as previously finished. if (channel == HAL_UNKNOWN_CHANNEL) return tc; // Channel number too big. IFC_ASSERT(channel < SYS_IFC_STD_CHAN_NB, channel); // Check that the channel is really owned by the peripheral // which is doing the request, it could have been release // automatically or by an IRQ handler. status = hal_SysEnterCriticalSection(); if (g_halModuleIfcChannelOwner[channel] == requestId) { tc = hwp_sysIfc->std_ch[channel].tc; } hal_SysExitCriticalSection(status); return tc; }
// ============================================================================= // hal_IfcChannelIsFifoEmpty // ----------------------------------------------------------------------------- /// Returns \c TRUE when the FIFO is empty. /// /// If #requestId does not match #channel owner, returns TRUE. /// /// @param requestId Describe the direction of the tranfer (rx or /// tx) and the module to or from which data are to be moved. /// @param channel Channel whose FIFO is to be checked. // ============================================================================= PROTECTED BOOL hal_IfcChannelIsFifoEmpty(HAL_IFC_REQUEST_ID_T requestId, UINT8 channel) { UINT32 status; BOOL fifoIsEmpty = TRUE; // Here, we consider the transfer as previously finished. if (channel == HAL_UNKNOWN_CHANNEL) return fifoIsEmpty; // Channel number too big. IFC_ASSERT(channel < SYS_IFC_STD_CHAN_NB, channel); // Check that the channel is really owned by the peripheral // which is doing the request, it could have been release // automatically or by an IRQ handler. status = hal_SysEnterCriticalSection(); if (g_halModuleIfcChannelOwner[channel] == requestId) { fifoIsEmpty = (0 != (hwp_sysIfc->std_ch[channel].status & SYS_IFC_FIFO_EMPTY)); } hal_SysExitCriticalSection(status); return fifoIsEmpty; }
if (pkt_head_len==5) { pkt_head[1]=hci_handle_flags & 0xFF; pkt_head[2]=hci_handle_flags >> 8; pkt_head[3]=pdu->dataLen& 0xFF; pkt_head[4]=pdu->dataLen>> 8; } header[0] = type; header[1] = pdu->dataLen+pkt_head_len-1; //hal_HstSendEvent(SYS_EVENT,0x10170000 + type); //hal_HstSendEvent(SYS_EVENT,pdu->buf[0]+(pdu->buf[1]<<8)); critical = hal_SysEnterCriticalSection(); hal_ShareMem_SendData(pkt_head+1,pdu->dataLen+pkt_head_len-1); hal_ShareMem_SendHeader(header); hal_SysExitCriticalSection(critical); HCI_FreeWriteBuffer(pdu, type); page = hal_ShareMem_GetTxPage(); if(page != cmd_tx_page) { if(cmd_tx_page != cmd_rx_page &&(page+1 == cmd_rx_page || (cmd_rx_page == 0 && page == 3))) rdabt_cntx.tx_busy = 1; cmd_tx_page = page;
// ============================================================================= // memd_BlockLock // ----------------------------------------------------------------------------- /// This Locks or Unlocks a block (sector) or range of blocks. /// Flash Write Enable must already be set. /// /// @param phy_startFlshAddr Start address of the block in flash to start /// locking. This must be aligned on a block. /// @param phy_endFlshAddr End address of the block in flash to stop locking /// (inclusive). This must also be aligned on a block. If this parameter is /// NULL, then only one block (starting at phy_startFlshAddr) will be locked. /// @return MEMD_ERR_T error type (alignment errors only) // ============================================================================= PRIVATE MEMD_ERR_T memd_BlockLock(UINT8 *phy_startFlshAddr, UINT8 *phy_endFlshAddr, BOOL Lock) { UINT32 phy_Start; UINT32 phy_End; UINT32 status; VOLATILE UINT16 * CurBankAddr; VOLATILE UINT16 * PrevBankAddr; // Check that start & end addresses are aligned if (phy_endFlshAddr == NULL) { memd_FlashGetSectorLimits((UINT32)phy_startFlshAddr, &phy_Start, &phy_End); phy_endFlshAddr = (UINT8*)phy_End; } else { if ((UINT32)phy_endFlshAddr != FLASH_SIZE) { memd_FlashGetSectorLimits((UINT32)phy_endFlshAddr , &phy_Start, &phy_End); if ((UINT32)phy_endFlshAddr != phy_Start) { return MEMD_ERR_ALIGN; } } } memd_FlashGetSectorLimits((UINT32)phy_startFlshAddr, &phy_Start, &phy_End); if ((UINT32)phy_startFlshAddr != phy_Start) { return MEMD_ERR_ALIGN; } PrevBankAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phy_Start&FLASHBANK_MASK)); while (phy_Start != (UINT32)phy_endFlshAddr) { VOLATILE UINT16 * SectAddr; SectAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + phy_Start); CurBankAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phy_Start&FLASHBANK_MASK)); status = hal_SysEnterCriticalSection(); // If Bank Address is the same as previous Bank Address, continue // otherwise, need to put old Bank into Read Array mode and // open new Bank. if (CurBankAddr != PrevBankAddr) { // Close Prev Bank *PrevBankAddr = CMD_READ_ARRAY; PrevBankAddr = CurBankAddr; } // Lock Set/Clr if (Lock) { *SectAddr = CMD_BLOCK_PROT; *SectAddr = CMD_BLOCK_LOCK; } else { *SectAddr = CMD_BLOCK_PROT; *SectAddr = CMD_BLOCK_UNLOCK; } hal_SysExitCriticalSection(status); if (phy_End != FLASH_SIZE) { memd_FlashGetSectorLimits(phy_End, &phy_Start, &phy_End); } else { phy_Start = phy_End; } } // Return to Read Array mode status = hal_SysEnterCriticalSection(); *PrevBankAddr = CMD_READ_ARRAY; hal_SysExitCriticalSection(status); return MEMD_ERR_NO; }
// ============================================================================= // memd_FlashWrite // ----------------------------------------------------------------------------- /// This function writes data in the flash. It gets its data from \c buffer, copies /// \c byteSize bytes to the flash location designed by \c flashAddress. \c /// pWrittenbyteSize is filled with the actual number of written bytes (Equal /// to size, or less in case of error). /// /// @param flashAddress The byte offset within the flash chip. (Take care not /// to overwrite the code present at the beginning of the flash) /// @param byteSize Number of bytes to write in flash /// @param pWrittenbyteSize Number of bytes actually written in flash /// @param buffer Buffer where to get the data to write in the flash /// @return #MEMD_ERR_NO, #MEMD_ERR_WRITE or #MEMD_ERR_PROTECT /// whether the operation succeeded or failed. // ============================================================================= PUBLIC MEMD_ERR_T memd_FlashWrite(UINT8 *flashAddress, UINT32 byteSize, UINT32 * pWrittenbyteSize, CONST UINT8* buffer) { VOLATILE UINT16 * BankAddr; VOLATILE UINT16 * ptr; UINT16 data; UINT32 bsize=0; UINT32 wsize=0; UINT32 owsize=0; MEMD_ERR_T errorcode=MEMD_ERR_NO; UINT32 status; UINT32 phys_add; UINT32 phy_SectAddr; UINT32 phy_End; BOOL isLocked; UINT16 rdstatus; *pWrittenbyteSize=0; if (byteSize==0) { return MEMD_ERR_NO; } hal_EbcFlashWriteEnable(TRUE); phys_add = (UINT32)flashAddress; MEMD_ASSERT((phys_add & 0xe0000000) == 0, "flash_address is expected to be a byte offset within the flash chip, not an absolute address") memd_FlashGetSectorLimits((UINT32)flashAddress, &phy_SectAddr, &phy_End); BankAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phys_add&FLASHBANK_MASK)); ptr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phys_add&~1)); // Unlock block memd_FlashGetLockStatus((UINT8*)((UINT32)phy_SectAddr & MY_MASK),&isLocked); hal_EbcFlashWriteEnable(TRUE); if(isLocked == TRUE) memd_BlockLock((UINT8*)((UINT32)phy_SectAddr & MY_MASK),NULL,FALSE); if ((phys_add&1) == 1) { data = *(ptr); } else { data = (*buffer) | ~0x00ff; buffer ++; bsize ++; } if (bsize<byteSize) { data = data & (((*buffer) << 8) | 0x00ff); buffer ++; bsize ++; } if (bsize==byteSize) { // last byte data = data & *(ptr); } // first byte is prepared /* 16b data ready write it to flash*/ status = hal_SysEnterCriticalSection(); *(BankAddr) = CMD_PROG; *(ptr)=data; hal_SysExitCriticalSection(status); while(bsize<byteSize) { UINT16 tdata; VOLATILE UINT16 * tptr; // do the next data preparation before the pooling so we are ready to do a new programming just after pooling is OK. tdata = data; tptr = ptr; owsize = wsize; wsize = bsize; ptr+=1; if (bsize<byteSize) { data = (*buffer) | ~0x00ff; buffer ++; bsize ++; } if(bsize<byteSize) { data = data & (((*buffer) << 8) | 0x00ff); buffer ++; bsize ++; } // pooling // do { rdstatus = *BankAddr; } while((rdstatus & SR7) != SR7); // Should probably fix this scheme for reporting errors more cleanly. // For now, just prioritize the errors with the most significant error returned // in errorcode (order this list from least to most significant) if ((rdstatus & SR4) != 0) { // Some other programming error, should be decoded, but maybe do it later errorcode=MEMD_ERR_WRITE; } else if ((rdstatus & SR1) != 0) { errorcode=MEMD_ERR_PROTECT; } if (errorcode!=MEMD_ERR_NO) break; if(bsize==byteSize) { /* last byte */ *BankAddr = CMD_READ_ARRAY; data = data & *(ptr); } /* 16b data ready write it to flash*/ status = hal_SysEnterCriticalSection(); *(BankAddr) = CMD_PROG; *(ptr)=data; hal_SysExitCriticalSection(status); } if (errorcode!=MEMD_ERR_NO) { wsize = owsize; } else { // last data pooling do { rdstatus = *BankAddr; } while((rdstatus & SR7) != SR7); if ((rdstatus & SR4) != 0) { // Some other programming error, should be decoded, but maybe do it later errorcode=MEMD_ERR_WRITE; } else if ((rdstatus & SR1) != 0) { errorcode=MEMD_ERR_PROTECT; } wsize = bsize; } *pWrittenbyteSize = wsize; // return to Read Array mode status = hal_SysEnterCriticalSection(); *BankAddr = CMD_READ_ARRAY; hal_SysExitCriticalSection(status); if(errorcode != MEMD_ERR_NO) { status = hal_SysEnterCriticalSection(); *BankAddr = CMD_CLR_STATUS_REG; hal_SysExitCriticalSection(status); } hal_EbcFlashWriteEnable(FALSE); return errorcode; }
// ============================================================================= // memd_FlashErase // ----------------------------------------------------------------------------- /// This function erases contiguous flash sectors. /// Addresses <B> must be aligned on sectors</B>: /// - The \c startFlashAddress is the address of the first sector to erase. /// - The \c endFlashAddress is the address of the first sector NOT to erase. /// If \c endFlashAddress is \c NULL, only one sector will be erased. /// . /// Care must be taken not to erase the code present at the beginning of the flash. /// /// @param start_flashAddress The address of the first sector to erase. Must /// be a _physical_ address (byte offset from start of Flash) /// @param end_flashAddress The address of the first sector NOT to erase. /// If \c NULL, only one sector will be erased /// @return #MEMD_ERR_NO, #MEMD_ERR_ERASE, #MEMD_ERR_ALIGN or #MEMD_ERR_PROTECT /// whether the operation succeeded or failed /// // ============================================================================= PUBLIC MEMD_ERR_T memd_FlashErase(UINT8 *startFlashAddress, UINT8 *endFlashAddress) { UINT32 status; VOLATILE UINT16 * ptr; VOLATILE UINT16 *BankAddr; UINT32 phy_Start; UINT32 phy_End; UINT32 phys_end_add; UINT32 phys_start_add; MEMD_ERR_T errorcode=MEMD_ERR_NO; BOOL isLocked; UINT16 rdstatus; phys_start_add = (UINT32)startFlashAddress; MEMD_ASSERT((phys_start_add & 0xe0000000) == 0, "flash_address is expected to be a byte offset within the flash chip, not an absolute address"); // Check that start & end addresses are aligned if (endFlashAddress == NULL) { memd_FlashGetSectorLimits(phys_start_add, &phy_Start, &phy_End); phys_end_add = phy_End; } else { phys_end_add = (UINT32)endFlashAddress; MEMD_ASSERT((phys_end_add & 0xe0000000) == 0, "flash_address is expected to be a byte offset within the flash chip, not an absolute address") if (phys_end_add != FLASH_SIZE) { memd_FlashGetSectorLimits(phys_end_add , &phy_Start, &phy_End); if (phys_end_add != phy_Start) { return MEMD_ERR_ALIGN; } } } memd_FlashGetSectorLimits(phys_start_add, &phy_Start, &phy_End); if (phys_start_add != phy_Start) { return MEMD_ERR_ALIGN; } hal_EbcFlashWriteEnable(TRUE); BankAddr = NULL; while (phy_Start != phys_end_add) { BankAddr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + (phy_Start&FLASHBANK_MASK)); // phy_Start should already be aligned to sector boundary, so shouldn't need any more masking ptr = (VOLATILE UINT16 *)(g_memdFlashBaseAddress + phy_Start); memd_FlashGetLockStatus((UINT8*)((UINT32)ptr & MY_MASK),&isLocked); // Re-enable EBC write hal_EbcFlashWriteEnable(TRUE); if(isLocked == TRUE) { memd_BlockLock((UINT8*)((UINT32)ptr & MY_MASK),NULL,FALSE); } status = hal_SysEnterCriticalSection(); // Sector Erase command *(BankAddr) = CMD_BLOCK_ERASE_1; *(ptr) = CMD_BLOCK_ERASE_2; hal_SysExitCriticalSection(status); // pooling // Wait for Ready, then check status do { rdstatus = *BankAddr; } while((rdstatus & SR7) != SR7); // Any address in the bank may be used // Should probably fix this scheme for reporting errors more cleanly. // For now, just prioritize the errors with the most significant error returned // in errorcode (order this list from least to most significant) if ((rdstatus & SR3) != 0) { // Vpp Invalid Error errorcode=MEMD_ERR_ERASE; } else if (((rdstatus & SR5) != 0) && ((rdstatus & SR4) != 0)) { // Command Sequence Error errorcode=MEMD_ERR_ERASE; } else if ((rdstatus & SR5) != 0) { // Erase Error errorcode=MEMD_ERR_ERASE; } else if ((rdstatus & SR1) != 0) { errorcode=MEMD_ERR_PROTECT; } // Reset to read array mode when every block erase operation is finished. status = hal_SysEnterCriticalSection(); *BankAddr = CMD_READ_ARRAY; hal_SysExitCriticalSection(status); // Clear status register if any error if(errorcode != MEMD_ERR_NO) { status = hal_SysEnterCriticalSection(); *BankAddr = CMD_CLR_STATUS_REG; hal_SysExitCriticalSection(status); hal_EbcFlashWriteEnable(FALSE); return errorcode; } if (phy_End != FLASH_SIZE) { memd_FlashGetSectorLimits(phy_End, &phy_Start, &phy_End); } else { phy_Start = phy_End; } } if (BankAddr != NULL) { // Return to Read Array mode status = hal_SysEnterCriticalSection(); *BankAddr = CMD_READ_ARRAY; hal_SysExitCriticalSection(status); } // erase done hal_EbcFlashWriteEnable(FALSE); return errorcode; }
UINT16 put_data_to_CircularBuffer(struct CircularBuf *pCirBuff, UINT8 *pBuff,UINT16 uDataSize) { UINT16 Block_Len, Remain_Len, real_Len, First_half, Second_half; UINT32 status = hal_SysEnterCriticalSection(); // do thing with uart breakint not happen Block_Len = GET_DATA_BLOCK_LEN(pCirBuff->Get, pCirBuff->Put, pCirBuff->Buf_len); if ((Block_Len == 0) && (pCirBuff->NotEmpty)) { Block_Len = pCirBuff->Buf_len; } Remain_Len = pCirBuff->Buf_len - Block_Len; /*hal_HstSendEvent(SYS_EVENT, 0x07280100); hal_HstSendEvent(SYS_EVENT, Remain_Len); hal_HstSendEvent(SYS_EVENT, uDataSize);*/ if(Remain_Len==0) { hal_HstSendEvent(SYS_EVENT, 0x01010000); hal_DbgAssert("%s buffer overflow, Remain_Len=0!!",pCirBuff->Name); return 0; } if (uDataSize > Remain_Len) { hal_DbgAssert("%s buffer overflow!! uDataSize=%d, Remain_Len=%d",pCirBuff->Name,uDataSize,Remain_Len); return 0; } real_Len = uDataSize;// (uDataSize < Remain_Len) ? uDataSize : Remain_Len; if (real_Len > 0)/*circular buffer not full*/ { if (pCirBuff->Put < pCirBuff->Get) { memcpy(&pCirBuff->Buf[pCirBuff->Put], pBuff, real_Len); pCirBuff->Put = MOD_BUFF_LEN(pCirBuff->Put + real_Len,pCirBuff->Buf_len); } else { First_half = pCirBuff->Buf_len - pCirBuff->Put; if (real_Len < First_half) { memcpy(&pCirBuff->Buf[pCirBuff->Put], pBuff, real_Len); pCirBuff->Put = MOD_BUFF_LEN(pCirBuff->Put + real_Len, pCirBuff->Buf_len); } else { memcpy(&pCirBuff->Buf[pCirBuff->Put], pBuff , First_half); Second_half = real_Len - First_half; pCirBuff->Put = MOD_BUFF_LEN((pCirBuff->Put + First_half),pCirBuff->Buf_len); memcpy(&pCirBuff->Buf[pCirBuff->Put], &pBuff[First_half], Second_half); pCirBuff->Put = MOD_BUFF_LEN((pCirBuff->Put + Second_half),pCirBuff->Buf_len); } } pCirBuff->NotEmpty = 1; } else { SXS_TRACE(TSTDOUT,"warning put len %x",real_Len); } hal_SysExitCriticalSection(status); return Remain_Len -real_Len; }