SAMV7: Extend programmable clock support for queries about the PCK configuration
This commit is contained in:
parent
8c4302f75d
commit
9d769f6056
@ -146,7 +146,7 @@ int sam_freerun_initialize(struct sam_freerun_s *freerun, int chan,
|
||||
|
||||
/* Allocate the timer/counter and select its mode of operation
|
||||
*
|
||||
* CMR_TCCLKS - Returned by sam_tc_divisor
|
||||
* TC_CMR_TCCLKS - Returned by sam_tc_divisor
|
||||
* TC_CMR_CLKI=0 - Not inverted
|
||||
* TC_CMR_BURST_NONE - Not gated by an external signal
|
||||
* TC_CMR_CPCSTOP=0 - Don't stop the clock on an RC compare event
|
||||
|
@ -218,6 +218,70 @@ uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc,
|
||||
return actual;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_pck_frequency
|
||||
*
|
||||
* Description:
|
||||
* Return the frequency if the programmable clock
|
||||
*
|
||||
* Input Parameters:
|
||||
* pckid - Identifies the programmable clock output (0, 1, .., 6)
|
||||
*
|
||||
* Returned Value:
|
||||
* The frequency of the programmable clock (which may or may not be
|
||||
* enabled).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t sam_pck_frequency(enum pckid_e pckid)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint32_t regval;
|
||||
uint32_t clkin;
|
||||
uint32_t presc;
|
||||
|
||||
/* Get the programmable clock configuration */
|
||||
|
||||
regaddr = SAM_PMC_PCK((int)pckid);
|
||||
regval = getreg32(regaddr);
|
||||
|
||||
/* Get the frequency of the clock source */
|
||||
|
||||
switch (regval & PMC_PCK_CSS_MASK)
|
||||
{
|
||||
case PMC_PCK_CSS_SLOW: /* Slow Clock */
|
||||
clkin = BOARD_SLOWCLK_FREQUENCY;
|
||||
break;
|
||||
|
||||
case PMC_PCK_CSS_MAIN: /* Main Clock */
|
||||
clkin = BOARD_MAINOSC_FREQUENCY;
|
||||
break;
|
||||
|
||||
case PMC_PCK_CSS_PLLA: /* PLLA Clock */
|
||||
clkin = BOARD_PLLA_FREQUENCY;
|
||||
break;
|
||||
|
||||
#ifdef BOARD_UPLL_FREQUENCY
|
||||
case PMC_PCK_CSS_UPLL: /* Divided UPLL Clock */
|
||||
clkin = BOARD_UPLL_FREQUENCY;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PMC_PCK_CSS_MCK: /* Master Clock */
|
||||
clkin = BOARD_MCK_FREQUENCY;
|
||||
break;
|
||||
|
||||
default:
|
||||
dbg("ERROR: Unknown clock source\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the prescaler value */
|
||||
|
||||
presc = (regval & PMC_PCK_PRES_MASK) >> PMC_PCK_PRES_SHIFT;
|
||||
return clkin / (presc + 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_pck_enable
|
||||
*
|
||||
@ -225,7 +289,7 @@ uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc,
|
||||
* Enable or disable a programmable clock output.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pckid - Identifies the programmable clock output (0, 1, or 2)
|
||||
* pckid - Identifies the programmable clock output (0, 1, .., 6)
|
||||
* enable - True: enable the clock output, False: disable the clock output
|
||||
*
|
||||
* Returned Value:
|
||||
@ -248,7 +312,34 @@ void sam_pck_enable(enum pckid_e pckid, bool enable)
|
||||
|
||||
regaddr = enable ? SAM_PMC_SCER : SAM_PMC_SCDR;
|
||||
|
||||
/* And do the deead */
|
||||
/* And do the deed */
|
||||
|
||||
putreg32(regval, regaddr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_pck_isenabled
|
||||
*
|
||||
* Description:
|
||||
* Return true if the programmable clock is enabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pckid - Identifies the programmable clock output (0, 1, .., 6)
|
||||
*
|
||||
* Returned Value:
|
||||
* True if the specified programmable clock is enabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool sam_pck_isenabled(enum pckid_e pckid)
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
/* Select the bit in the PMC_SCSR corresponding to the programmable clock. */
|
||||
|
||||
mask = PMC_PCK(pckid);
|
||||
|
||||
/* Return true if the bit is set */
|
||||
|
||||
return (getreg32(SAM_PMC_SCSR) & mask) != 0;
|
||||
}
|
||||
|
@ -58,7 +58,11 @@ enum pckid_e
|
||||
{
|
||||
PCK0 = 0,
|
||||
PCK1,
|
||||
PCK2
|
||||
PCK2,
|
||||
PCK3,
|
||||
PCK4,
|
||||
PCK5,
|
||||
PCK6,
|
||||
};
|
||||
|
||||
enum pckid_clksrc_e
|
||||
@ -109,6 +113,23 @@ extern "C"
|
||||
uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc,
|
||||
uint32_t frequency);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_pck_frequency
|
||||
*
|
||||
* Description:
|
||||
* Return the frequency if the programmable clock
|
||||
*
|
||||
* Input Parameters:
|
||||
* pckid - Identifies the programmable clock output (0, 1, .., 6)
|
||||
*
|
||||
* Returned Value:
|
||||
* The frequency of the programmable clock (which may or may not be
|
||||
* enabled).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t sam_pck_frequency(enum pckid_e pckid);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_pck_enable
|
||||
*
|
||||
@ -116,7 +137,7 @@ uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc,
|
||||
* Enable or disable a programmable clock output.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pckid - Identifies the programmable clock output (0, 1, or 2)
|
||||
* pckid - Identifies the programmable clock output (0, 1, .., 6)
|
||||
* enable - True: enable the clock output, False: disable the clock output
|
||||
*
|
||||
* Returned Value:
|
||||
@ -126,6 +147,22 @@ uint32_t sam_pck_configure(enum pckid_e pckid, enum pckid_clksrc_e clksrc,
|
||||
|
||||
void sam_pck_enable(enum pckid_e pckid, bool enable);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_pck_isenabled
|
||||
*
|
||||
* Description:
|
||||
* Return true if the programmable clock is enabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pckid - Identifies the programmable clock output (0, 1, .., 6)
|
||||
*
|
||||
* Returned Value:
|
||||
* True if the specified programmable clock is enabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool sam_pck_isenabled(enum pckid_e pckid);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
@ -133,4 +170,3 @@ void sam_pck_enable(enum pckid_e pckid, bool enable);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARCH_ARM_SRC_SAMV7_SAM_PCK_H */
|
||||
|
||||
|
@ -553,10 +553,10 @@ static struct sam_tc_s g_tc901;
|
||||
|
||||
static const uint8_t g_log2divider[TC_NDIVIDERS] =
|
||||
{
|
||||
1, /* TIMER_CLOCK1 -> div2 */
|
||||
3, /* TIMER_CLOCK2 -> div8 */
|
||||
5, /* TIMER_CLOCK3 -> div32 */
|
||||
7 /* TIMER_CLOCK4 -> div128 */
|
||||
1, /* TIMER_CLOCK1 -> PCK6 REVISIT! Was MCK/2 */
|
||||
3, /* TIMER_CLOCK2 -> MCK/8 */
|
||||
5, /* TIMER_CLOCK3 -> MCK/32 */
|
||||
7 /* TIMER_CLOCK4 -> MCK/128 */
|
||||
};
|
||||
|
||||
/* TC register lookup used by sam_tc_setregister */
|
||||
@ -1548,7 +1548,7 @@ uint32_t sam_tc_divfreq(TC_HANDLE handle)
|
||||
* Finds the best MCK divisor given the timer frequency and MCK. The
|
||||
* result is guaranteed to satisfy the following equation:
|
||||
*
|
||||
* (Ftcin / (div * 65536)) <= freq <= (Ftcin / dev)
|
||||
* (Ftcin / (div * 65536)) <= freq <= (Ftcin / div)
|
||||
*
|
||||
* where:
|
||||
* freq - the desired frequency
|
||||
@ -1572,6 +1572,13 @@ int sam_tc_divisor(uint32_t frequency, uint32_t *div, uint32_t *tcclks)
|
||||
|
||||
tcvdbg("frequency=%d\n", frequency);
|
||||
|
||||
/* On other chips, TCCLCKS==0 corresponded to MCK/2. But for the SAMV7,
|
||||
* this is PCK6. That will need to be handled differently.
|
||||
*/
|
||||
|
||||
#warning REVISIT: PCK6 clock source not yet supported
|
||||
ndx++;
|
||||
|
||||
/* Satisfy lower bound. That is, the value of the divider such that:
|
||||
*
|
||||
* frequency >= (tc_input_frequency * 65536) / divider.
|
||||
|
Loading…
x
Reference in New Issue
Block a user