Merge remote-tracking branch 'origin/master' into ieee802154

This commit is contained in:
Gregory Nutt 2017-06-16 09:34:57 -06:00
commit c8f6475749
6 changed files with 134 additions and 38 deletions

View File

@ -151,7 +151,7 @@ struct twi_dev_s
struct i2c_msg_s *msg; /* Message list */ struct i2c_msg_s *msg; /* Message list */
uint32_t twiclk; /* TWIHS input clock frequency */ uint32_t twiclk; /* TWIHS input clock frequency */
uint32_t frequency; /* TWIHS transfer clock frequency */ uint32_t frequency; /* TWIHS transfer clock frequency */
bool initd; /* True :device has been initialized */ int refs; /* Reference count */
uint8_t msgc; /* Number of message in the message list */ uint8_t msgc; /* Number of message in the message list */
sem_t exclsem; /* Only one thread can access at a time */ sem_t exclsem; /* Only one thread can access at a time */
@ -1118,6 +1118,10 @@ static int twi_reset(FAR struct i2c_master_s *dev)
DEBUGASSERT(priv != NULL); DEBUGASSERT(priv != NULL);
/* Our caller must own a ref */
DEBUGASSERT(priv->refs > 0);
/* Get exclusive access to the TWIHS device */ /* Get exclusive access to the TWIHS device */
twi_takesem(&priv->exclsem); twi_takesem(&priv->exclsem);
@ -1342,6 +1346,7 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus)
{ {
struct twi_dev_s *priv; struct twi_dev_s *priv;
uint32_t frequency; uint32_t frequency;
const struct twi_attr_s *attr = 0;
irqstate_t flags; irqstate_t flags;
int ret; int ret;
@ -1353,7 +1358,7 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus)
/* Select up TWIHS0 and setup invariant attributes */ /* Select up TWIHS0 and setup invariant attributes */
priv = &g_twi0; priv = &g_twi0;
priv->attr = &g_twi0attr; attr = &g_twi0attr;
/* Select the (initial) TWIHS frequency */ /* Select the (initial) TWIHS frequency */
@ -1367,7 +1372,7 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus)
/* Select up TWIHS1 and setup invariant attributes */ /* Select up TWIHS1 and setup invariant attributes */
priv = &g_twi1; priv = &g_twi1;
priv->attr = &g_twi1attr; attr = &g_twi1attr;
/* Select the (initial) TWIHS frequency */ /* Select the (initial) TWIHS frequency */
@ -1381,7 +1386,7 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus)
/* Select up TWIHS2 and setup invariant attributes */ /* Select up TWIHS2 and setup invariant attributes */
priv = &g_twi2; priv = &g_twi2;
priv->attr = &g_twi2attr; attr = &g_twi2attr;
/* Select the (initial) TWIHS frequency */ /* Select the (initial) TWIHS frequency */
@ -1394,14 +1399,16 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus)
return NULL; return NULL;
} }
/* Perform one-time TWIHS initialization */
flags = enter_critical_section(); flags = enter_critical_section();
/* Has the device already been initialized? */ /* Has the device already been initialized? */
if (!priv->initd) if ((volatile int)priv->refs++ == 0)
{ {
/* Perform one-time TWIHS initialization */
priv->attr = attr;
/* Allocate a watchdog timer */ /* Allocate a watchdog timer */
priv->timeout = wd_create(); priv->timeout = wd_create();
@ -1438,10 +1445,6 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus)
/* Perform repeatable TWIHS hardware initialization */ /* Perform repeatable TWIHS hardware initialization */
twi_hw_initialize(priv, frequency); twi_hw_initialize(priv, frequency);
/* Now it has been initialized */
priv->initd = true;
} }
leave_critical_section(flags); leave_critical_section(flags);
@ -1452,6 +1455,7 @@ errout_with_wdog:
priv->timeout = NULL; priv->timeout = NULL;
errout_with_irq: errout_with_irq:
priv->refs--;
leave_critical_section(flags); leave_critical_section(flags);
return NULL; return NULL;
} }
@ -1469,11 +1473,23 @@ int sam_i2cbus_uninitialize(FAR struct i2c_master_s *dev)
struct twi_dev_s *priv = (struct twi_dev_s *) dev; struct twi_dev_s *priv = (struct twi_dev_s *) dev;
irqstate_t flags; irqstate_t flags;
i2cinfo("TWIHS%d Un-initializing\n", priv->attr->twi); DEBUGASSERT(priv);
/* Decrement reference count and check for underflow */
if (priv->refs == 0)
{
return ERROR;
}
i2cinfo("TWIHS%d Un-initializing refs:%d\n", priv->attr->twi, priv->refs);
/* Disable TWIHS interrupts */ /* Disable TWIHS interrupts */
flags = enter_critical_section(); flags = enter_critical_section();
if (--priv->refs == 0)
{
up_disable_irq(priv->attr->irq); up_disable_irq(priv->attr->irq);
/* Reset data structures */ /* Reset data structures */
@ -1489,8 +1505,8 @@ int sam_i2cbus_uninitialize(FAR struct i2c_master_s *dev)
/* Detach Interrupt Handler */ /* Detach Interrupt Handler */
(void)irq_detach(priv->attr->irq); (void)irq_detach(priv->attr->irq);
}
priv->initd = false;
leave_critical_section(flags); leave_critical_section(flags);
return OK; return OK;
} }

View File

@ -466,4 +466,8 @@
void stm32_flash_lock(void); void stm32_flash_lock(void);
void stm32_flash_unlock(void); void stm32_flash_unlock(void);
#ifdef CONFIG_STM32_STM32F40XX
int stm32_flash_writeprotect(size_t page, bool enabled);
#endif
#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_FLASH_H */ #endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_FLASH_H */

View File

@ -615,7 +615,7 @@
#endif #endif
#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4) #define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN4)
#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN7) #define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN11)
#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5) #define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTB|GPIO_PIN5)
#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12) #define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12)
#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15) #define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN15)

View File

@ -79,6 +79,8 @@
#else #else
# define FLASH_KEY1 0x45670123 # define FLASH_KEY1 0x45670123
# define FLASH_KEY2 0xCDEF89AB # define FLASH_KEY2 0xCDEF89AB
# define FLASH_OPTKEY1 0x08192A3B
# define FLASH_OPTKEY2 0x4C5D6E7F
#endif #endif
#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX)
@ -384,6 +386,87 @@ ssize_t stm32_eeprom_erase(size_t addr, size_t eraselen)
#endif /* defined(CONFIG_STM32_STM32L15XX) */ #endif /* defined(CONFIG_STM32_STM32L15XX) */
/************************************************************************************
* Name: stm32_flash_writeprotect
*
* Description:
* Enable or disable the write protection of a flash sector.
*
************************************************************************************/
#ifdef CONFIG_STM32_STM32F40XX
int stm32_flash_writeprotect(size_t page, bool enabled)
{
uint32_t reg;
uint32_t val;
#ifdef CONFIG_STM32_STM32F40XX
if (page >= STM32_FLASH_NPAGES)
{
return -EFAULT;
}
#else
# warning missing logic in stm32_flash_writeprotect
#endif
/* Select the register that contains the bit to be changed */
if (page < 12)
{
reg = STM32_FLASH_OPTCR;
}
#if defined(CONFIG_STM32_FLASH_CONFIG_I) && defined(CONFIG_STM32_STM32F40XX)
else
{
reg = STM32_FLASH_OPTCR1;
page -= 12;
}
#else
else
{
return -EFAULT;
}
#endif
/* Read the option status */
val = getreg32(reg);
/* Set or clear the protection */
if (enabled)
{
val &= ~(1 << (16+page) );
}
else
{
val |= (1 << (16+page) );
}
/* Unlock options */
putreg32(FLASH_OPTKEY1, STM32_FLASH_OPTKEYR);
putreg32(FLASH_OPTKEY2, STM32_FLASH_OPTKEYR);
/* Write options */
putreg32(val, reg);
/* Trigger programmation */
modifyreg32(STM32_FLASH_OPTCR, 0, FLASH_OPTCR_OPTSTRT);
/* Wait for completion */
while(getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste();
/* Relock options */
modifyreg32(STM32_FLASH_OPTCR, 0, FLASH_OPTCR_OPTLOCK);
return 0;
}
#endif
#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX)
size_t up_progmem_pagesize(size_t page) size_t up_progmem_pagesize(size_t page)
{ {

View File

@ -2333,7 +2333,7 @@ static int i2s_dma_allocate(struct stm32_i2s_s *priv)
{ {
/* Allocate an RX DMA channel */ /* Allocate an RX DMA channel */
priv->rx.dma = stm32_dmachannel(DMAMAP_SPI3_RX_2); priv->rx.dma = stm32_dmachannel(DMACHAN_I2S3_RX);
if (!priv->rx.dma) if (!priv->rx.dma)
{ {
i2serr("ERROR: Failed to allocate the RX DMA channel\n"); i2serr("ERROR: Failed to allocate the RX DMA channel\n");
@ -2356,7 +2356,7 @@ static int i2s_dma_allocate(struct stm32_i2s_s *priv)
{ {
/* Allocate a TX DMA channel */ /* Allocate a TX DMA channel */
priv->tx.dma = stm32_dmachannel(DMAMAP_SPI3_TX_2); priv->tx.dma = stm32_dmachannel(DMACHAN_I2S3_TX);
if (!priv->tx.dma) if (!priv->tx.dma)
{ {
i2serr("ERROR: Failed to allocate the TX DMA channel\n"); i2serr("ERROR: Failed to allocate the TX DMA channel\n");

View File

@ -310,21 +310,14 @@
#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1 #define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1
#define GPIO_SPI2_SCK GPIO_SPI2_SCK_1 #define GPIO_SPI2_SCK GPIO_SPI2_SCK_1
/* SPI3 - Onboard devices use SPI3 */ /* I2S3 - CS43L22 configuration uses I2S3 */
#define GPIO_SPI3_MISO GPIO_SPI3_MISO_2
#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_2
#define GPIO_SPI3_SCK GPIO_SPI3_SCK_2
#define GPIO_SPI3_NSS GPIO_SPI3_NSS_2
/* I2S3 - Onboard devices use I2S3 */
#define GPIO_I2S3_SD GPIO_I2S3_SD_2 #define GPIO_I2S3_SD GPIO_I2S3_SD_2
#define GPIO_I2S3_CK GPIO_I2S3_CK_2 #define GPIO_I2S3_CK GPIO_I2S3_CK_2
#define GPIO_I2S3_WS GPIO_I2S3_WS_1 #define GPIO_I2S3_WS GPIO_I2S3_WS_1
#define DMACHAN_SPI3_RX DMAMAP_SPI3_RX_2 #define DMACHAN_I2S3_RX DMAMAP_SPI3_RX_2
#define DMACHAN_SPI3_TX DMAMAP_SPI3_TX_2 #define DMACHAN_I2S3_TX DMAMAP_SPI3_TX_2
/* I2C config to use with Nunchuk PB7 (SDA) and PB8 (SCL) */ /* I2C config to use with Nunchuk PB7 (SDA) and PB8 (SCL) */