mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
SAMA5 TWI: If running from SDRAM, BOARD_MCK_FREQUENCY is not a constant and cannot be used in pre-processor conditionals
This commit is contained in:
@@ -7171,7 +7171,6 @@
|
|||||||
also reset the camera module. Noted by David Sidrane (2014-4-11).
|
also reset the camera module. Noted by David Sidrane (2014-4-11).
|
||||||
* arch/arm/src/stm32/stm32_usbhost.c/.h and stm32_otgfshost.c: USB host
|
* arch/arm/src/stm32/stm32_usbhost.c/.h and stm32_otgfshost.c: USB host
|
||||||
tracing added by Leo (2014-4-12).
|
tracing added by Leo (2014-4-12).
|
||||||
* arch/arm/src/sama5/sam_adc.c, sam_can.c, sam_emac.c, sam_gmac.c, and
|
* arch/arm/src/sama5/sam_adc.c, sam_can.c, sam_emac.c, sam_gmac.c,
|
||||||
sam_ssc.c: If running from SDRAM, then BOARD_MCK_FREQUENCY is not a
|
sam_ssc.c, and sam_twi.c: If running from SDRAM, then BOARD_MCK_FREQUENCY
|
||||||
constant and cannot be used in conditional compilation (2014-4-16).
|
is not a constant and cannot be used in conditional compilation (2014-4-16).
|
||||||
|
|
||||||
|
|||||||
@@ -99,22 +99,6 @@
|
|||||||
|
|
||||||
#define TWI_MAX_FREQUENCY 66000000 /* Maximum TWI frequency */
|
#define TWI_MAX_FREQUENCY 66000000 /* Maximum TWI frequency */
|
||||||
|
|
||||||
#if BOARD_MCK_FREQUENCY <= TWI_MAX_FREQUENCY
|
|
||||||
# define TWI_FREQUENCY BOARD_MCK_FREQUENCY
|
|
||||||
# define TWI_PCR_DIV PMC_PCR_DIV1
|
|
||||||
#elif (BOARD_MCK_FREQUENCY >> 1) <= TWI_MAX_FREQUENCY
|
|
||||||
# define TWI_FREQUENCY (BOARD_MCK_FREQUENCY >> 1)
|
|
||||||
# define TWI_PCR_DIV PMC_PCR_DIV2
|
|
||||||
#elif (BOARD_MCK_FREQUENCY >> 2) <= TWI_MAX_FREQUENCY
|
|
||||||
# define TWI_FREQUENCY (BOARD_MCK_FREQUENCY >> 2)
|
|
||||||
# define TWI_PCR_DIV PMC_PCR_DIV4
|
|
||||||
#elif (BOARD_MCK_FREQUENCY >> 3) <= TWI_MAX_FREQUENCY
|
|
||||||
# define TWI_FREQUENCY (BOARD_MCK_FREQUENCY >> 3)
|
|
||||||
# define TWI_PCR_DIV PMC_PCR_DIV8
|
|
||||||
#else
|
|
||||||
# error Cannot realize TWI frequency
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Debug ***********************************************************************/
|
/* Debug ***********************************************************************/
|
||||||
/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */
|
/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */
|
||||||
|
|
||||||
@@ -139,6 +123,7 @@ struct twi_dev_s
|
|||||||
struct i2c_dev_s dev; /* Generic I2C device */
|
struct i2c_dev_s dev; /* Generic I2C device */
|
||||||
struct i2c_msg_s *msg; /* Message list */
|
struct i2c_msg_s *msg; /* Message list */
|
||||||
uintptr_t base; /* Base address of registers */
|
uintptr_t base; /* Base address of registers */
|
||||||
|
uint32_t frequency; /* TWO clock frequency */
|
||||||
uint16_t irq; /* IRQ number for this device */
|
uint16_t irq; /* IRQ number for this device */
|
||||||
uint16_t address; /* Slave address */
|
uint16_t address; /* Slave address */
|
||||||
uint16_t flags; /* Transfer flags */
|
uint16_t flags; /* Transfer flags */
|
||||||
@@ -277,7 +262,7 @@ struct i2c_ops_s g_twiops =
|
|||||||
* Name: twi_takesem
|
* Name: twi_takesem
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Take the wait semaphore (handling false alarm wakeups due to the receipt
|
* Take the wait semaphore (handling false alarm wake-ups due to the receipt
|
||||||
* of signals).
|
* of signals).
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
@@ -314,7 +299,7 @@ static void twi_takesem(sem_t *sem)
|
|||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* true: This is the first register access of this type.
|
* true: This is the first register access of this type.
|
||||||
* flase: This is the same as the preceding register access.
|
* false: This is the same as the preceding register access.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@@ -322,9 +307,9 @@ static void twi_takesem(sem_t *sem)
|
|||||||
static bool twi_checkreg(struct twi_dev_s *priv, bool wr, uint32_t value,
|
static bool twi_checkreg(struct twi_dev_s *priv, bool wr, uint32_t value,
|
||||||
uint32_t address)
|
uint32_t address)
|
||||||
{
|
{
|
||||||
if (wr == priv->wrlast && /* Same kind of access? */
|
if (wr == priv->wrlast && /* Same kind of access? */
|
||||||
value == priv->vallast && /* Same value? */
|
value == priv->vallast && /* Same value? */
|
||||||
address == priv->addrlast) /* Same address? */
|
address == priv->addrlast) /* Same address? */
|
||||||
{
|
{
|
||||||
/* Yes, then just keep a count of the number of times we did this. */
|
/* Yes, then just keep a count of the number of times we did this. */
|
||||||
|
|
||||||
@@ -504,7 +489,6 @@ static int twi_interrupt(struct twi_dev_s *priv)
|
|||||||
uint32_t imr;
|
uint32_t imr;
|
||||||
uint32_t pending;
|
uint32_t pending;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Retrieve masked interrupt status */
|
/* Retrieve masked interrupt status */
|
||||||
|
|
||||||
@@ -580,9 +564,8 @@ static int twi_interrupt(struct twi_dev_s *priv)
|
|||||||
else if ((pending & TWI_INT_TXCOMP) != 0)
|
else if ((pending & TWI_INT_TXCOMP) != 0)
|
||||||
{
|
{
|
||||||
twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXCOMP);
|
twi_putrel(priv, SAM_TWI_IDR_OFFSET, TWI_INT_TXCOMP);
|
||||||
ret = OK;
|
|
||||||
|
|
||||||
/* Is there another messasge to send? */
|
/* Is there another message to send? */
|
||||||
|
|
||||||
if (priv->msgc > 1)
|
if (priv->msgc > 1)
|
||||||
{
|
{
|
||||||
@@ -1096,7 +1079,7 @@ static uint32_t twi_hw_setfrequency(struct twi_dev_s *priv, uint32_t frequency)
|
|||||||
{
|
{
|
||||||
/* Calulate the CLDIV value using the current CKDIV guess */
|
/* Calulate the CLDIV value using the current CKDIV guess */
|
||||||
|
|
||||||
cldiv = ((TWI_FREQUENCY / (frequency << 1)) - 4) / (1 << ckdiv);
|
cldiv = ((priv->frequency / (frequency << 1)) - 4) / (1 << ckdiv);
|
||||||
|
|
||||||
/* Is CLDIV in range? */
|
/* Is CLDIV in range? */
|
||||||
|
|
||||||
@@ -1121,7 +1104,7 @@ static uint32_t twi_hw_setfrequency(struct twi_dev_s *priv, uint32_t frequency)
|
|||||||
|
|
||||||
/* Return the actual frequency */
|
/* Return the actual frequency */
|
||||||
|
|
||||||
actual = (TWI_FREQUENCY / 2) / (((1 << ckdiv) * cldiv) + 2);
|
actual = (priv->frequency / 2) / (((1 << ckdiv) * cldiv) + 2);
|
||||||
i2cvdbg("TWI%d frequency: %d ckdiv: %d cldiv: %d actual: %d\n",
|
i2cvdbg("TWI%d frequency: %d ckdiv: %d cldiv: %d actual: %d\n",
|
||||||
priv->twi, frequency, ckdiv, cldiv, actual);
|
priv->twi, frequency, ckdiv, cldiv, actual);
|
||||||
|
|
||||||
@@ -1140,6 +1123,7 @@ static void twi_hw_initialize(struct twi_dev_s *priv, unsigned int pid,
|
|||||||
uint32_t frequency)
|
uint32_t frequency)
|
||||||
{
|
{
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
uint32_t mck;
|
||||||
|
|
||||||
i2cvdbg("TWI%d Initializing\n", priv->twi);
|
i2cvdbg("TWI%d Initializing\n", priv->twi);
|
||||||
|
|
||||||
@@ -1161,9 +1145,35 @@ static void twi_hw_initialize(struct twi_dev_s *priv, unsigned int pid,
|
|||||||
|
|
||||||
twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_MSEN);
|
twi_putrel(priv, SAM_TWI_CR_OFFSET, TWI_CR_MSEN);
|
||||||
|
|
||||||
|
/* Determine the maximum valid frequency setting */
|
||||||
|
|
||||||
|
mck = BOARD_MCK_FREQUENCY;
|
||||||
|
DEBUGASSERT((mck >> 3) <= TWI_MAX_FREQUENCY);
|
||||||
|
|
||||||
|
if (mck <= TWI_MAX_FREQUENCY)
|
||||||
|
{
|
||||||
|
priv->frequency = mck;
|
||||||
|
regval = PMC_PCR_DIV1;
|
||||||
|
}
|
||||||
|
else if ((mck >> 1) <= TWI_MAX_FREQUENCY)
|
||||||
|
{
|
||||||
|
priv->frequency = (mck >> 1);
|
||||||
|
regval = PMC_PCR_DIV2;
|
||||||
|
}
|
||||||
|
else if ((mck >> 2) <= TWI_MAX_FREQUENCY)
|
||||||
|
{
|
||||||
|
priv->frequency = (mck >> 2);
|
||||||
|
regval = PMC_PCR_DIV4;
|
||||||
|
}
|
||||||
|
else /* if ((mck >> 3) <= TWI_MAX_FREQUENCY) */
|
||||||
|
{
|
||||||
|
priv->frequency = (mck >> 3);
|
||||||
|
regval = PMC_PCR_DIV8;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the TWI peripheral input clock to the maximum, valid frequency */
|
/* Set the TWI peripheral input clock to the maximum, valid frequency */
|
||||||
|
|
||||||
regval = PMC_PCR_PID(pid) | PMC_PCR_CMD | TWI_PCR_DIV | PMC_PCR_EN;
|
regval |= PMC_PCR_PID(pid) | PMC_PCR_CMD | PMC_PCR_EN;
|
||||||
twi_putabs(priv, SAM_PMC_PCR, regval);
|
twi_putabs(priv, SAM_PMC_PCR, regval);
|
||||||
|
|
||||||
/* Set the initial TWI data transfer frequency */
|
/* Set the initial TWI data transfer frequency */
|
||||||
|
|||||||
Reference in New Issue
Block a user