📄 hardwareio.c
字号:
* Function: Enable3wIrq
*
* Authors: Hung van Le
* Purpose: Enable/Disable system interrupt, which is assigned to the 3-wire bus (GPIO on DATA-line)
* Input: bState: TRUE=enable interrupt
* FALSE=disable interrupt
* Output: Nothing
* Comments: This function is not required if 3W-interrupt is not necessary
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
void Enable3wIrq(BOOL bState)
{
BYTE byTmp;
byTmp = _I45CR;
byTmp &= 0x0F; // Bit 5=0: Clear any pending INT5
if (bState)
{
// Enable INT5 - don't touch INT4 settings
/*
_putbit(0, _I45CR, 5); // Bit 5=0: Clear any pending INT5
_putbit(1, _I45CR, 7); // Bit [7:6]=10b: INT5 on rising edge
_putbit(1, _I45CR, 4); // Bit 4=1: Enable INT5
*/
//_I45CR = 0x90; // Enable INT5, disable INT4
//_I45CR &= 0x0F; // Bit 5=0: Clear any pending INT5
//_I45CR |= 0x90; // Bit [7:6]=10b: INT5 on rising edge; Bit 4=1: Enable INT5
byTmp |= 0x90;
}
else
{
// Disable INT5 - don't touch INT4 settings
//_putbit(0, _I45CR, 4); // Bit 4=0: Disable INT5
//_I45CR = 0x00; // Disable INT5, disable INT4
//_I45CR &= 0x0F; // Bit 5=0: Clear any pending INT5
//byTmp &= 0x0F; // Bit 5=0: Clear any pending INT5
}
_I45CR = byTmp;
}// End Enable3wIrq
/* ************************************************************************************************
*
* Function: ClearPresetStorage
*
* Authors: Hung van Le
* Purpose: Clear the preset storage RAM (to be called before an auto scan)
* Input: Nothing
* Output: Nothing
* Comments: AM/FM has different storage buffer and storage format (See also SavePreset)
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
#ifdef USE_PRESET
void ClearPresetStorage()
{
BYTE byTmp;
#ifdef SUPPORT_AMFM
if ( (g_byStnFlag & STN_AM_MODE) == STN_AM_MODE ) // AM mode - clear AM presets
{
for (byTmp=0; byTmp < PRESET_CNT; byTmp++)
g_stEvkSetting.byaAmPreset[byTmp] = 0;
}
else // FM mode - clear FM presets
{
for (byTmp=0; byTmp < PRESET_CNT; byTmp++)
g_stEvkSetting.waFmPreset[byTmp] = 0;
}
#endif //SUPPORT_AMFM
#ifdef FM_ONLY
for (byTmp=0; byTmp < PRESET_CNT; byTmp++)
g_stEvkSetting.waFmPreset[byTmp] = 0;
#endif //FM_ONLY
} // End ClearPresetStorage
#endif //USE_PRESET
/* ************************************************************************************************
*
* Function: GetNextSavePresetLocation
*
* Authors: Hung van Le
* Purpose: Determine next available preset location for storage
* Input: Nothing
* Output: The preset location or PRESET_CNT if no more available location
* Comments: This function is an example of how preset can implemented. It just now write to RAM.
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
#ifdef USE_PRESET
BYTE GetNextSavePresetLocation(void)
{
BYTE byTmp;
#ifdef SUPPORT_AMFM
if ( (g_byStnFlag & STN_AM_MODE) == STN_AM_MODE ) // AM mode - check for available AM preset
{
for (byTmp=0; byTmp < PRESET_CNT; byTmp++)
{
if (g_stEvkSetting.byaAmPreset[byTmp] == 0)
break;
}
}
else // FM mode - check for available FM preset
{
for (byTmp=0; byTmp < PRESET_CNT; byTmp++)
{
if (g_stEvkSetting.waFmPreset[byTmp] == 0)
break;
}
}
#endif //SUPPORT_AMFM
#ifdef FM_ONLY
for (byTmp=0; byTmp < PRESET_CNT; byTmp++)
{
if (g_stEvkSetting.waFmPreset[byTmp] == 0)
break;
}
#endif //FM_ONLY
return(byTmp);
} // End GetNextSavePresetLocation
#endif //USE_PRESET
/* ************************************************************************************************
*
* Function: SavePreset
*
* Authors: Hung van Le
* Purpose: Store the specified frequency into the specified preset location, overwrite the current one
* Input: byLocation: preset number
* wFreq: FM frequency in 10 kHz-unit to be stored (FM mode)
* AM frequency in 1 kHz-unit, aligned at AM-grid to be stored (AM mode)
* Output: Status as defined in LvErr.h
* Comments: This function is an example of how preset can implemented. It just now write to RAM.
* The FM frequency is written directly without compression.
* The AM frequency is compressed as follows:
* If grid=10kHz: base frequency = 520 kHz, save_byte = 0x80|(AM_freq - base_freq)/10
* This results in range 128-247 cover frequency range 520 kHz - 1710 kHz (USA)
* If grid=9kHz: base frequency = 513 kHz, save_byte = (AM_freq - base_freq)/9
* This results in range 0-124 cover frequency range 513 kHz - 1629 kHz (Europe/Japan)
* Code 0 is meant for empty entry
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
#ifdef USE_PRESET
BYTE SavePreset(BYTE byLocation, WORD wFreq)
{
if (byLocation >= PRESET_CNT)
return(LVLS_NO_MORE_PRST_MEM); // Invalid location for storage
#ifdef SUPPORT_AMFM
if ( (g_byStnFlag & STN_AM_MODE) == STN_AM_MODE ) // AM mode
{
WORD wBaseFreq;
BYTE bySaveByte;
if (g_wFreqGrid == 10)
{
wBaseFreq = 520;
bySaveByte = 0x80;
}
else
{
wBaseFreq = 513;
bySaveByte = 0x00;
}
bySaveByte |= (BYTE)((wFreq - wBaseFreq)/g_wFreqGrid);
g_stEvkSetting.byaAmPreset[byLocation]= bySaveByte;
}
else // FM
{
g_stEvkSetting.waFmPreset[byLocation] = wFreq; // Store FM frequency
}
#endif //SUPPORT_AMFM
#ifdef FM_ONLY
g_stEvkSetting.waFmPreset[byLocation] = wFreq; // Store FM frequency
#endif //FM_ONLY
return(LVLS_NO_ERROR);
} // End SavePreset
#endif //USE_PRESET
/* ************************************************************************************************
*
* Function: RecallPreset
*
* Authors: Hung van Le
* Purpose: Retrieve the frequency stored under the specified preset number
* Input: byLocation: preset number
* Output: The frequency in 10 kHz-unit for FM
* 0 if the location is empty or invalid location
* Comments: This function is an example of how preset can implemented. It just now write to RAM.
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
#ifdef USE_PRESET
WORD RecallPreset(BYTE byLocation)
{
if (byLocation>=PRESET_CNT)
return(0); // Invalid location
#ifdef SUPPORT_AMFM
if ( (g_byStnFlag & STN_AM_MODE) == STN_AM_MODE ) // AM mode - clear AM presets
{
WORD wFreq;
BYTE byTmp;
byTmp = g_stEvkSetting.byaAmPreset[byLocation];
if (byTmp == 0) // Empty entry
return(0);
if (byTmp & 0x80) // 10 kHz grid at 520 kHz base
{
wFreq = byTmp - 0x80; // Fetch grid count
wFreq *= 10; // Convert grdi count to frequency
wFreq += 520; // Add base frequency -> we have the AM frequency
}
else // 9 kHz grid at 513kHz base
{
wFreq = byTmp; // Fetch grid count
wFreq *= 9; // Convert grdi count to frequency
wFreq += 513; // Add base frequency -> we have the AM frequency
}
return(wFreq);
}
else // FM mode - clear FM presets
{
return(g_stEvkSetting.waFmPreset[byLocation]);
}
#endif //SUPPORT_AMFM
#ifdef FM_ONLY
return(g_stEvkSetting.waFmPreset[byLocation]);
#endif //FM_ONLY
} // End RecallPreset
#endif //USE_PRESET
/* ************************************************************************************************
*
* Function: DelayUs
*
* Authors: Hung van Le
* Purpose: Delay a specified time, using timer 0 of LC87F1564
* Input: wT0Cnt: the count for timer 0 to perform the delay
* Output: Nothing
* Comments: This function is an example of delay routine. It's LC87F1564 specific.
*
* ************************************************************************************************
* Copyright (c) 2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
* ************************************************************************************************ */
void DelayUs(WORD wT0Cnt)
{
BYTE byTmp;
// Using timer 0 in mode 2
// Init the timer 0 control register (T0CNT) (Reset counter, disable interrupt...)
_T0CNT = 0x10; // Set T0LONG bit for 16 bit timer
// Program the prescaler match register (T0PRR)
_T0PRR = 0x01; // 2 Tcyc
// Program the data match register T0HR/T0LR
_T0LR = (BYTE)(wT0Cnt&0xFF); // count low
_T0HR = (BYTE)(wT0Cnt>>8); // count high
// Start timer 0 (mode 2)
_T0CNT = 0xE0; // Set T0HRUN, T0LRUN, T0LONG bits
// Wait for match flag
do
{
byTmp = _T0CNT; // Read the match flag
if (byTmp & 0x08)
break; // Stop when T0HCMP bit set
} while (1);
_T0CNT = 0x00; // Stop timer 0
} // End DelayUs
#ifdef USE_PRESET
BYTE WriteSettingsToFlash(BOOL bClear)
{
BYTE i, byFlsByte, byResult;
PBYTE pbyRamContent;
// Init the pointer to RAM content
pbyRamContent = (PBYTE)&g_stEvkSetting;
if (bClear)
{
for (i=0; i<PRESET_AREA_SIZE; i++)
pbyRamContent[i] = 0;
}
else // End clear handling
{
// Construct the image for writing
g_stEvkSetting.bySignA = PFLS_SIGN_A;
g_stEvkSetting.bySignB = PFLS_SIGN_B;
// the scan list is already stored
g_stEvkSetting.wLastFreq = GetDisplayFrequency(g_wFreqGrid); // 100 kHz grid?
// Store feature value
for (i=0; i<SETTING_CNT; i++)
g_stEvkSetting.byaSetting[i] = GetHwFeatureValue(i);
} // End Save-handling
// Now check if the flash need to be written (content changes?)
byResult=LVLS_NO_ERROR;
for (i=0; i<PRESET_AREA_SIZE && byResult==LVLS_NO_ERROR; i++)
{
// Read flash
if ( ReadLcFls((WORD)(gFlsRom + i), 1, &byFlsByte) != FLS_STS_OK )
{
byResult = LVLS_FLASH_READ_ERR;
}
else
{
if (byFlsByte != pbyRamContent[i])
byResult = LVLS_FLASH_CORRUPT_ERR;
}
}
// Write the flash when it is corrupted
if (byResult == LVLS_FLASH_CORRUPT_ERR)
{
if ( WriteLcFls((WORD)gFlsRom, PRESET_AREA_SIZE, pbyRamContent) != FLS_STS_OK )
byResult = LVLS_FLASH_WRITE_ERR;
else
byResult = LVLS_NO_ERROR;
}
return(byResult);
} // End WriteSettingsToFlash
#endif //USE_PRESET
#ifdef USE_PRESET
BYTE RetrieveSettingsFromFlash(BYTE bySettingId)
{
BYTE i;
i = LVLS_NO_ERROR;
if ( ReadLcFls((WORD)gFlsRom, PRESET_AREA_SIZE, (PBYTE)&g_stEvkSetting) != FLS_STS_OK )
i = LVLS_FLASH_READ_ERR;
else if (g_stEvkSetting.bySignA != PFLS_SIGN_A) // Check signs
i = LVLS_FLASH_CORRUPT_ERR;
else if (g_stEvkSetting.bySignB != PFLS_SIGN_B)
i = LVLS_FLASH_CORRUPT_ERR;
// If we don't have to retrieve all settings, handle the call separately
if (bySettingId != RSFF_ALL)
{
if ( (i == LVLS_NO_ERROR) && (bySettingId < SETTING_CNT) )
{
if (GetHwFeatureLimit(bySettingId) != 0) // feature supported
SetHwFeatureValue(bySettingId, g_stEvkSetting.byaSetting[bySettingId]);
}
return(i);
}
if (i == LVLS_NO_ERROR) // All check passed - restore the settings
{
// Restore feature value
for (i=0; i<SETTING_CNT; i++)
{
if (GetHwFeatureLimit(i) != 0) // feature supported
{
if (i != IHCAP_AMUTE) // Don't restore the audio mute !
SetHwFeatureValue(i, g_stEvkSetting.byaSetting[i]);
}
}
// the scan list is already retrieved
if (g_stEvkSetting.wLastFreq != 0)
g_wLastSetRF = DisplayFreqToRf(g_stEvkSetting.wLastFreq);
}
else // invalid data - clear our RAM
{
// Mark everything is invalid
PBYTE pbyRamContent;
pbyRamContent = (PBYTE)&g_stEvkSetting;
for (i=0; i<PRESET_AREA_SIZE; i++)
pbyRamContent[i] = 0;
}
return(LVLS_NO_ERROR);
} // End RetrieveSettingsFromFlash
#endif //USE_PRESET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -