diff --git a/Documentation/README.html b/Documentation/README.html index 2f9ba9066b2..4430ef211f7 100644 --- a/Documentation/README.html +++ b/Documentation/README.html @@ -8,7 +8,7 @@

NuttX README Files

-

Last Updated: February 19, 2017

+

Last Updated: March 21, 2017

@@ -297,6 +297,8 @@ nuttx/ | | `- README.txt | |- viewtool-stm32f107/ | | `- README.txt + | |- xmc4500-relax/ + | | `- README.txt | |- xtrs/ | | `- README.txt | |- z16f2800100zcog/ diff --git a/README.txt b/README.txt index ed3d41c30f8..4bab1306ff7 100644 --- a/README.txt +++ b/README.txt @@ -1681,6 +1681,8 @@ nuttx/ | | `- README.txt | |- viewtool-stm32f107/ | | `- README.txt + | |- xmc5400-relax/ + | | `- README.txt | |- xtrs/ | | `- README.txt | |- z16f2800100zcog/ diff --git a/arch/arm/include/xmc4/chip.h b/arch/arm/include/xmc4/chip.h index 5c3fcdabfa2..6507917fe6b 100644 --- a/arch/arm/include/xmc4/chip.h +++ b/arch/arm/include/xmc4/chip.h @@ -51,23 +51,23 @@ #if defined(CONFIG_ARCH_CHIP_XMC4500) # define XMC4_NUSIC 3 /* Three USIC modules: USCI0-2 */ # undef XMC4_SCU_GATING /* No clock gating registers */ -# define XMC4_NECATN 0 /* No EtherCAT support */ +# define XMC4_NECAT 0 /* No EtherCAT support */ #elif defined(CONFIG_ARCH_CHIP_XMC4700) # define XMC4_NUSIC 3 /* Three USIC modules: USCI0-2 */ # define XMC4_SCU_GATING 1 /* Has clock gating registers */ -# define XMC4_NECATN 0 /* No EtherCAT support */ +# define XMC4_NECAT 0 /* No EtherCAT support */ #elif defined(CONFIG_ARCH_CHIP_XMC4700) # define XMC4_NUSIC 3 /* Three USIC modules: USCI0-2 */ # define XMC4_SCU_GATING 1 /* Has clock gating registers */ -# define XMC4_NECATN 1 /* One EtherCAT module */ +# define XMC4_NECAT 1 /* One EtherCAT module */ #else # error "Unsupported XMC4xxx chip" #endif /* NVIC priority levels *************************************************************/ -/* Each priority field holds a priority value, 0-15. The lower the value, the greater - * the priority of the corresponding interrupt. The XMC4500 implements only - * bits[7:2] of this field, bits[1:0] read as zero and ignore writes. +/* Each priority field holds a priority value. The lower the value, the greater the + * priority of the corresponding interrupt. The XMC4500 implements only bits[7:2] + * of this field, bits[1:0] read as zero and ignore writes. */ #define NVIC_SYSH_PRIORITY_MIN 0xfc /* All bits[7:2] set is minimum priority */ diff --git a/arch/arm/include/xmc4/xmc4500_irq.h b/arch/arm/include/xmc4/xmc4500_irq.h index dfd21d6c21d..b35a1b3f8a2 100644 --- a/arch/arm/include/xmc4/xmc4500_irq.h +++ b/arch/arm/include/xmc4/xmc4500_irq.h @@ -184,7 +184,7 @@ #define XMC4_IRQ_SDMMC_SR0 (XMC4_IRQ_FIRST+106) /* 106: SDMMC, SR0 */ #define XMC4_IRQ_USB0_SR0 (XMC4_IRQ_FIRST+107) /* 107: USB, SR0 */ #define XMC4_IRQ_ETH0_SR0 (XMC4_IRQ_FIRST+108) /* 108: Ethernet, module 0, SR0 */ -#define XMC4_IRQ_RESVD109 (XMC4_IRQ_FIRST+109) /* 109: Reserved */ +#define XMC4_IRQ_ECAT0_SR0 (XMC4_IRQ_FIRST+109) /* 109: EtherCAT, module 0, SR0 */ #define XMC4_IRQ_GPCMA1_SR0 (XMC4_IRQ_FIRST+110) /* 110: GPDMA1, SR0 */ #define XMC4_IRQ_RESVD111 (XMC4_IRQ_FIRST+111) /* 111: Reserved */ diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 8dea045fda5..de2c8fe23be 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -6190,6 +6190,16 @@ config STM32_I2C_DUTY16_9 default n depends on STM32_I2C +config STM32_I2C_DMA + bool "I2C DMA Support" + default n + depends on STM32_I2C && STM32_STM32F40XX && STM32_DMA1 + ---help--- + This option enables the DMA for I2C transfers. + Note: The user can define CONFIG_I2C_DMAPRIO: a custom priority value for the + I2C dma streams, else the default priority level is set to medium. + Note: This option is compatible with CONFIG_I2C_POLLED. + endmenu menu "SDIO Configuration" diff --git a/arch/arm/src/stm32/stm32f40xxx_i2c.c b/arch/arm/src/stm32/stm32f40xxx_i2c.c index c0d1a2d6fd0..3d7d5567f89 100644 --- a/arch/arm/src/stm32/stm32f40xxx_i2c.c +++ b/arch/arm/src/stm32/stm32f40xxx_i2c.c @@ -63,7 +63,6 @@ * - 1 x 10 bit addresses + 1 x 7 bit address (?) * - plus the broadcast address (general call) * - Multi-master support - * - DMA (to get rid of too many CPU wake-ups and interventions) * - Be ready for IPMI */ @@ -95,6 +94,7 @@ #include "stm32_rcc.h" #include "stm32_i2c.h" #include "stm32_waste.h" +#include "stm32_dma.h" /* At least one I2C peripheral must be enabled */ @@ -162,6 +162,21 @@ #define MKI2C_OUTPUT(p) (((p) & (GPIO_PORT_MASK | GPIO_PIN_MASK)) | I2C_OUTPUT) +/* I2C DMA priority */ + +#ifdef CONFIG_STM32_I2C_DMA + +# if defined(CONFIG_I2C_DMAPRIO) +# if (CONFIG_I2C_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_I2C_DMAPRIO" +# endif +# define I2C_DMA_PRIO CONFIG_I2C_DMAPRIO +# else +# define I2C_DMA_PRIO DMA_SCR_PRIMED +# endif + +#endif + /* Debug ****************************************************************************/ /* I2C event trace logic. NOTE: trace uses the internal, non-standard, low-level @@ -253,7 +268,7 @@ struct stm32_i2c_priv_s struct i2c_msg_s *msgv; /* Message list */ uint8_t *ptr; /* Current message buffer */ uint32_t frequency; /* Current I2C frequency */ - int dcnt; /* Current message length */ + volatile int dcnt; /* Current message length */ uint16_t flags; /* Current message flags */ bool check_addr_ACK; /* Flag to signal if on next interrupt address has ACKed */ uint8_t total_msg_len; /* Flag to signal a short read sequence */ @@ -270,6 +285,15 @@ struct stm32_i2c_priv_s #endif uint32_t status; /* End of transfer SR2|SR1 status */ + + /* I2C DMA support */ + +#ifdef CONFIG_STM32_I2C_DMA + DMA_HANDLE txdma; /* TX DMA handle */ + DMA_HANDLE rxdma; /* RX DMA handle */ + uint8_t txch; /* TX DMA channel */ + uint8_t rxch; /* RX DMA channel */ +#endif }; /************************************************************************************ @@ -337,6 +361,13 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s static int stm32_i2c_reset(FAR struct i2c_master_s *dev); #endif +/* DMA support */ + +#ifdef CONFIG_STM32_I2C_DMA +static void stm32_i2c_dmarxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +static void stm32_i2c_dmatxcallback(DMA_HANDLE handle, uint8_t isr, void *arg); +#endif + /************************************************************************************ * Private Data ************************************************************************************/ @@ -398,7 +429,16 @@ static struct stm32_i2c_priv_s stm32_i2c1_priv = .ptr = NULL, .dcnt = 0, .flags = 0, - .status = 0 + .status = 0, +#ifdef CONFIG_STM32_I2C_DMA +# ifndef CONFIG_STM32_DMA1 +# error "I2C1 enabled with DMA but corresponding DMA controller 1 is not enabled!" +# endif + /* TODO: ch for i2c 1 and 2 could be *X_2 based on stream priority */ + + .rxch = DMAMAP_I2C1_RX, + .txch = DMAMAP_I2C1_TX, +#endif }; #endif @@ -428,7 +468,14 @@ static struct stm32_i2c_priv_s stm32_i2c2_priv = .ptr = NULL, .dcnt = 0, .flags = 0, - .status = 0 + .status = 0, +#ifdef CONFIG_STM32_I2C_DMA +# ifndef CONFIG_STM32_DMA1 +# error "I2C2 enabled with DMA but corresponding DMA controller 1 is not enabled!" +# endif + .rxch = DMAMAP_I2C2_RX, + .txch = DMAMAP_I2C2_TX, +#endif }; #endif @@ -458,7 +505,14 @@ static struct stm32_i2c_priv_s stm32_i2c3_priv = .ptr = NULL, .dcnt = 0, .flags = 0, - .status = 0 + .status = 0, +#ifdef CONFIG_STM32_I2C_DMA +# ifndef CONFIG_STM32_DMA1 +# error "I2C3 enabled with DMA but corresponding DMA controller 1 is not enabled!" +# endif + .rxch = DMAMAP_I2C3_RX, + .txch = DMAMAP_I2C3_TX, +#endif }; #endif @@ -521,7 +575,7 @@ static inline void stm32_i2c_sem_wait(FAR struct stm32_i2c_priv_s *priv) { while (sem_wait(&priv->sem_excl) != 0) { - ASSERT(errno == EINTR); + DEBUGASSERT(errno == EINTR); } } @@ -1185,6 +1239,12 @@ static inline void stm32_i2c_enablefsmc(uint32_t ahbenr) static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) { uint32_t status; +#ifndef CONFIG_I2C_POLLED + uint32_t regval; +#endif +#ifdef CONFIG_STM32_I2C_DMA + uint16_t cr2; +#endif i2cinfo("I2C ISR called\n"); @@ -1228,6 +1288,23 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) * stm32_i2c_sem_waitdone() waiting process. */ +#ifdef CONFIG_STM32_I2C_DMA + /* If ISR gets called (ex. polling mode) while DMA is still in + * progress, we should just return and let the DMA finish. + */ + + cr2 = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + if ((cr2 & I2C_CR2_DMAEN) != 0) + { +#ifdef CONFIG_DEBUG_I2C_INFO + size_t left = stm32_dmaresidual(priv->rxdma); + + i2cinfo("DMA in progress: %ld [bytes] remainining. Returning.\n", left); +#endif + return OK; + } +#endif + if (priv->dcnt == -1 && priv->msgc > 0) { i2cinfo("Switch to new message\n"); @@ -1484,6 +1561,46 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) /* Trace */ stm32_i2c_traceevent(priv, I2CEVENT_ADDRESS_ACKED, 0); + +#ifdef CONFIG_STM32_I2C_DMA + /* DMA only when not doing a short read */ + + i2cinfo("Starting dma transfer and disabling interrupts\n"); + + /* The DMA must be initialized and enabled before the I2C data transfer. + * The DMAEN bit must be set in the I2C_CR2 register before the ADDR event. + */ + + stm32_dmasetup(priv->rxdma, priv->config->base+STM32_I2C_DR_OFFSET, + (uint32_t) priv->ptr, priv->dcnt, + DMA_SCR_DIR_P2M | + DMA_SCR_MSIZE_8BITS | + DMA_SCR_PSIZE_8BITS | + DMA_SCR_MINC | + I2C_DMA_PRIO); + + /* Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is + * used. + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_ITBUFEN, 0); + +#ifndef CONFIG_I2C_POLLED + /* Now let DMA do all the work, disable i2c interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval &= ~I2C_CR2_ALLINTS; + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); +#endif + + /* The user can generate a Stop condition in the DMA Transfer Complete + * interrupt routine if enabled. This will be done in the dma rx callback + * Start DMA. + */ + + stm32_dmastart(priv->rxdma, stm32_i2c_dmarxcallback, priv, false); + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_DMAEN); +#endif } } @@ -1520,19 +1637,67 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) if (priv->dcnt >= 1) { - /* Transmitting message. Send byte == write data into write register */ +#ifdef CONFIG_STM32_I2C_DMA + /* if DMA is enabled, only makes sense to make use of it for longer + than 1 B transfers.. */ - stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, *priv->ptr++); + if (priv->dcnt > 1) + { + i2cinfo("Starting dma transfer and disabling interrupts\n"); - /* Decrease current message length */ + /* The DMA must be initialized and enabled before the I2C data transfer. + * The DMAEN bit must be set in the I2C_CR2 register before the ADDR event. + */ - stm32_i2c_traceevent(priv, I2CEVENT_WRITE_TO_DR, priv->dcnt); - priv->dcnt--; + stm32_dmasetup(priv->txdma, priv->config->base+STM32_I2C_DR_OFFSET, + (uint32_t) priv->ptr, priv->dcnt, + DMA_SCR_DIR_M2P | + DMA_SCR_MSIZE_8BITS | + DMA_SCR_PSIZE_8BITS | + DMA_SCR_MINC | + I2C_DMA_PRIO ); + /* Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is + * used. + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_ITBUFEN, 0); + +#ifndef CONFIG_I2C_POLLED + /* Now let DMA do all the work, disable i2c interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval &= ~I2C_CR2_ALLINTS; + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); +#endif + + /* In the interrupt routine after the EOT interrupt, disable DMA + * requests then wait for a BTF event before programming the Stop + * condition. To do this, we'll just call the ISR again in + * dma tx callback, in which point we fall into the msgc==0 case + * which ultimately sends the stop..TODO: but we don't explicitly + * wait for BTF bit being set... + * Start DMA. + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, 0, I2C_CR2_DMAEN); + stm32_dmastart(priv->txdma, stm32_i2c_dmatxcallback, priv, false); + } + else +#endif /* CONFIG_STM32_I2C_DMA */ + { + /* Transmitting message. Send byte == write data into write register */ + + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, *priv->ptr++); + + /* Decrease current message length */ + + stm32_i2c_traceevent(priv, I2CEVENT_WRITE_TO_DR, priv->dcnt); + priv->dcnt--; + } } else if (priv->dcnt == 0) { - /* After last byte, check what to do based on next message flags */ if (priv->msgc == 0) @@ -1678,6 +1843,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) stm32_i2c_traceevent(priv, I2CEVENT_READ_2, 0); } +#ifndef CONFIG_STM32_I2C_DMA /* Case total message length >= 3 */ else if (priv->dcnt >= 4 && priv->total_msg_len >= 3) @@ -1757,6 +1923,7 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) priv->dcnt = -1; } +#endif /* CONFIG_STM32_I2C_DMA */ /* Error handling for read mode */ @@ -1765,7 +1932,8 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) i2cinfo("I2C read mode no correct state detected\n"); i2cinfo(" state %i, dcnt=%i\n", status, priv->dcnt); - /* set condition to terminate ISR and wake waiting thread */ + /* Set condition to terminate ISR and wake waiting thread */ + priv->dcnt = -1; priv->msgc = 0; stm32_i2c_traceevent(priv, I2CEVENT_READ_ERROR, 0); @@ -1804,9 +1972,9 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) else { - #ifdef CONFIG_I2C_POLLED +#ifdef CONFIG_I2C_POLLED stm32_i2c_traceevent(priv, I2CEVENT_POLL_DEV_NOT_RDY, 0); - #else +#else /* Read rest of the state */ status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); @@ -1814,12 +1982,12 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) i2cinfo(" No correct state detected(start bit, read or write) \n"); i2cinfo(" state %i\n", status); - /* set condition to terminate ISR and wake waiting thread */ + /* Set condition to terminate ISR and wake waiting thread */ priv->dcnt = -1; priv->msgc = 0; stm32_i2c_traceevent(priv, I2CEVENT_STATE_ERROR, 0); - #endif +#endif } /* Messages handling(2/2) @@ -1842,9 +2010,9 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) priv->msgv = NULL; - #ifdef CONFIG_I2C_POLLED +#ifdef CONFIG_I2C_POLLED priv->intstate = INTSTATE_DONE; - #else +#else /* Clear all interrupts */ uint32_t regval; @@ -1863,12 +2031,98 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) sem_post(&priv->sem_isr); priv->intstate = INTSTATE_DONE; } - #endif +#endif } return OK; } +/***************************************************************************** + * Name: stm32_i2c_dmarxcallback + * + * Description: + * Called when the RX DMA completes + * + *****************************************************************************/ + +#ifdef CONFIG_STM32_I2C_DMA +static void stm32_i2c_dmarxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ +#ifndef CONFIG_I2C_POLLED + uint32_t regval; +#endif + + i2cinfo("DMA rx callback, status = %d \n", status); + + FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)arg; + + priv->dcnt = -1; + + /* The user can generate a Stop condition in the DMA Transfer Complete + * interrupt routine if enabled. + */ + + stm32_i2c_sendstop(priv); + + /* Let the I2C periph know to stop DMA transfers, also is used by ISR to check + * if DMA is done. + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_DMAEN, 0); + +#ifndef CONFIG_I2C_POLLED + /* Re-enable interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval |= (I2C_CR2_ITERREN | I2C_CR2_ITEVFEN); + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); +#endif + + /* let the ISR routine take care of shutting down or switching to next msg */ + + stm32_i2c_isr(priv); +} +#endif /* ifdef CONFIG_STM32_I2C_DMA */ + +/***************************************************************************** + * Name: stm32_i2c_dmarxcallback + * + * Description: + * Called when the RX DMA completes + * + *****************************************************************************/ + +#ifdef CONFIG_STM32_I2C_DMA +static void stm32_i2c_dmatxcallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ +#ifndef CONFIG_I2C_POLLED + uint32_t regval; +#endif + + i2cinfo("DMA tx callback, status = %d \n", status); + + FAR struct stm32_i2c_priv_s *priv = (FAR struct stm32_i2c_priv_s *)arg; + + priv->dcnt = 0; + + /* In the interrupt routine after the EOT interrupt, disable DMA requests */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_DMAEN, 0); + +#ifndef CONFIG_I2C_POLLED + /* re-enable interrupts */ + + regval = stm32_i2c_getreg(priv, STM32_I2C_CR2_OFFSET); + regval |= (I2C_CR2_ITERREN | I2C_CR2_ITEVFEN); + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); +#endif + + /* let the ISR routine take care of shutting down or switching to next msg */ + + stm32_i2c_isr(priv); +} +#endif /* ifdef CONFIG_STM32_I2C_DMA */ + /************************************************************************************ * Name: stm32_i2c1_isr * @@ -1914,7 +2168,7 @@ static int stm32_i2c3_isr(int irq, void *context, FAR void *arg) return stm32_i2c_isr(&stm32_i2c3_priv); } #endif -#endif +#endif /* CONFIG_I2C_POLLED */ /************************************************************************************ * Private Initialization and Deinitialization @@ -1972,6 +2226,15 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv) stm32_i2c_setclock(priv, 100000); +#ifdef CONFIG_STM32_I2C_DMA + /* If, in the I2C_CR2 register, the LAST bit is set, I2C automatically + * sends a NACK after the next byte following EOT_1. + * Clear DMA en just in case. + */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_DMAEN, I2C_CR2_LAST); +#endif + /* Enable I2C */ stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_PE); @@ -1991,6 +2254,7 @@ static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv) /* Disable I2C */ stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, 0); + stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, 0); /* Unconfigure GPIO pins */ @@ -2006,6 +2270,13 @@ static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv) irq_detach(priv->config->er_irq); #endif +#ifdef CONFIG_STM32_I2C_DMA + /* Disable DMA */ + + stm32_dmastop(priv->txdma); + stm32_dmastop(priv->rxdma); +#endif + /* Disable clocking */ modifyreg32(STM32_RCC_APB1ENR, priv->config->clk_bit, 0); @@ -2035,7 +2306,15 @@ static int stm32_i2c_transfer(FAR struct i2c_master_s *dev, FAR struct i2c_msg_s #endif int ret = 0; - ASSERT(count); + DEBUGASSERT(count); + +#ifdef CONFIG_STM32_I2C_DMA + /* stop DMA just in case */ + + stm32_i2c_modifyreg(priv, STM32_I2C_CR2_OFFSET, I2C_CR2_DMAEN, 0); + stm32_dmastop(priv->rxdma); + stm32_dmastop(priv->txdma); +#endif #ifdef I2C1_FSMC_CONFLICT /* Disable FSMC that shares a pin with I2C1 (LBAR) */ @@ -2246,11 +2525,11 @@ static int stm32_i2c_reset(FAR struct i2c_master_s *dev) uint32_t frequency; int ret = ERROR; - ASSERT(dev); + DEBUGASSERT(dev); /* Our caller must own a ref */ - ASSERT(priv->refs > 0); + DEBUGASSERT(priv->refs > 0); /* Lock out other clients */ @@ -2412,6 +2691,19 @@ FAR struct i2c_master_s *stm32_i2cbus_initialize(int port) { stm32_i2c_sem_init(priv); stm32_i2c_init(priv); + +#ifdef CONFIG_STM32_I2C_DMA + /* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA channel. + * if the channel is not available, then stm32_dmachannel() will block and wait + * until the channel becomes available. WARNING: If you have another device sharing + * a DMA channel with SPI and the code never releases that channel, then the call + * to stm32_dmachannel() will hang forever in this function! Don't let your + * design do that! + */ + priv->rxdma = stm32_dmachannel(priv->rxch); + priv->txdma = stm32_dmachannel(priv->txch); + DEBUGASSERT(priv->rxdma && priv->txdma); +#endif /* #ifdef CONFIG_STM32_I2C_DMA */ } leave_critical_section(flags); @@ -2431,7 +2723,7 @@ int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev) FAR struct stm32_i2c_priv_s *priv = (struct stm32_i2c_priv_s *)dev; irqstate_t flags; - ASSERT(dev); + DEBUGASSERT(dev); /* Decrement reference count and check for underflow */ @@ -2454,6 +2746,11 @@ int stm32_i2cbus_uninitialize(FAR struct i2c_master_s *dev) stm32_i2c_deinit(priv); +#ifdef CONFIG_STM32_I2C_DMA + stm32_dmafree(priv->rxdma); + stm32_dmafree(priv->txdma); +#endif + /* Release unused resources */ stm32_i2c_sem_destroy(priv); diff --git a/arch/arm/src/xmc4/chip/xmc4_memorymap.h b/arch/arm/src/xmc4/chip/xmc4_memorymap.h index a2df7e405ce..a326460cc7b 100644 --- a/arch/arm/src/xmc4/chip/xmc4_memorymap.h +++ b/arch/arm/src/xmc4/chip/xmc4_memorymap.h @@ -221,7 +221,7 @@ #define XMC4_USB0_EP4_BASE 0x50040980 #define XMC4_USB0_EP5_BASE 0x500409a0 #define XMC4_USB0_EP6_BASE 0x500409c0 -#define XMC4_USB0_EP6_BASE 0x50100000 /* ECAT0 */ +#define XMC4_ECAT0_BASE 0x50100000 /* ECAT0 */ #define XMC4_PMU0_BASE 0x58000000 /* PMU0 registers */ #define XMC4_FLASH0_BASE 0x58001000 diff --git a/arch/arm/src/xmc4/chip/xmc4_ports.h b/arch/arm/src/xmc4/chip/xmc4_ports.h index bdd90c2902b..a769ddf73c9 100644 --- a/arch/arm/src/xmc4/chip/xmc4_ports.h +++ b/arch/arm/src/xmc4/chip/xmc4_ports.h @@ -71,7 +71,7 @@ #define XMC4_PORT_OUT_OFFSET 0x0000 /* Port Output Register */ #define XMC4_PORT_OMR_OFFSET 0x0004 /* Port Output Modification Register */ -#define XMC4_PORT_IOCR_OFFSET(n) (0x0010 + ((n) & 3)) +#define XMC4_PORT_IOCR_OFFSET(n) (0x0010 + ((n) & ~3)) #define XMC4_PORT_IOCR0_OFFSET 0x0010 /* Port Input/Output Control Register 0 */ #define XMC4_PORT_IOCR4_OFFSET 0x0014 /* Port Input/Output Control Register 4 */ #define XMC4_PORT_IOCR8_OFFSET 0x0018 /* Port Input/Output Control Register 8 */ @@ -79,7 +79,7 @@ #define XMC4_PORT_IN_OFFSET 0x0024 /* Port Input Register */ -#define XMC4_PORT_PDR_OFFSET(n) (0x0010 + (((n) >> 1) & 3)) +#define XMC4_PORT_PDR_OFFSET(n) (0x0040 + (((n) >> 1) & ~3)) #define XMC4_PORT_PDR0_OFFSET 0x0040 /* Port Pad Driver Mode 0 Register */ #define XMC4_PORT_PDR1_OFFSET 0x0044 /* Port Pad Driver Mode 1 Register */ @@ -399,19 +399,19 @@ #define PORT_PDR0_PD2_SHIFT (8) /* Bit 8-10: Pad Driver Mode for Port n Pin 2 */ #define PORT_PDR0_PD2_MASK (7 << PORT_PDR0_PD2_SHIFT) # define PORT_PDR0_PD2(n) ((uint32_t)(n) << PORT_PDR0_PD2_SHIFT) -#define PORT_PDR0_PD3_SHIFT (12) /* Bit 12-14: Pad Driver Mode for Port 0 Pin 3 */ +#define PORT_PDR0_PD3_SHIFT (12) /* Bit 12-14: Pad Driver Mode for Port n Pin 3 */ #define PORT_PDR0_PD3_MASK (7 << PORT_PDR0_PD3_SHIFT) # define PORT_PDR0_PD3(n) ((uint32_t)(n) << PORT_PDR0_PD3_SHIFT) -#define PORT_PDR0_PD4_SHIFT (16) /* Bit 16-18: Pad Driver Mode for Port 0 Pin 4 */ +#define PORT_PDR0_PD4_SHIFT (16) /* Bit 16-18: Pad Driver Mode for Port n Pin 4 */ #define PORT_PDR0_PD4_MASK (7 << PORT_PDR0_PD4_SHIFT) # define PORT_PDR0_PD4(n) ((uint32_t)(n) << PORT_PDR0_PD4_SHIFT) -#define PORT_PDR0_PD5_SHIFT (20) /* Bit 20-22: Pad Driver Mode for Port 0 Pin 5 */ +#define PORT_PDR0_PD5_SHIFT (20) /* Bit 20-22: Pad Driver Mode for Port n Pin 5 */ #define PORT_PDR0_PD5_MASK (7 << PORT_PDR0_PD5_SHIFT) # define PORT_PDR0_PD5(n) ((uint32_t)(n) << PORT_PDR0_PD5_SHIFT) -#define PORT_PDR0_PD6_SHIFT (24) /* Bit 24-26: Pad Driver Mode for Port 0 Pin 6 */ +#define PORT_PDR0_PD6_SHIFT (24) /* Bit 24-26: Pad Driver Mode for Port n Pin 6 */ #define PORT_PDR0_PD6_MASK (7 << PORT_PDR0_PD6_SHIFT) # define PORT_PDR0_PD6(n) ((uint32_t)(n) << PORT_PDR0_PD6_SHIFT) -#define PORT_PDR0_PD7_SHIFT (28) /* Bit 28-30: Pad Driver Mode for Port 0 Pin 7 */ +#define PORT_PDR0_PD7_SHIFT (28) /* Bit 28-30: Pad Driver Mode for Port n Pin 7 */ #define PORT_PDR0_PD7_MASK (7 << PORT_PDR0_PD7_SHIFT) # define PORT_PDR0_PD7(n) ((uint32_t)(n) << PORT_PDR0_PD7_SHIFT) @@ -429,19 +429,19 @@ #define PORT_PDR1_PD10_SHIFT (8) /* Bit 8-10: Pad Driver Mode for Port n Pin 10 */ #define PORT_PDR1_PD10_MASK (7 << PORT_PDR1_PD10_SHIFT) # define PORT_PDR1_PD10(n) ((uint32_t)(n) << PORT_PDR1_PD10_SHIFT) -#define PORT_PDR1_PD11_SHIFT (12) /* Bit 12-14: Pad Driver Mode for Port 0 Pin 11 */ +#define PORT_PDR1_PD11_SHIFT (12) /* Bit 12-14: Pad Driver Mode for Port n Pin 11 */ #define PORT_PDR1_PD11_MASK (7 << PORT_PDR1_PD11_SHIFT) # define PORT_PDR1_PD11(n) ((uint32_t)(n) << PORT_PDR1_PD11_SHIFT) -#define PORT_PDR1_PD12_SHIFT (16) /* Bit 16-18: Pad Driver Mode for Port 0 Pin 12 */ +#define PORT_PDR1_PD12_SHIFT (16) /* Bit 16-18: Pad Driver Mode for Port n Pin 12 */ #define PORT_PDR1_PD12_MASK (7 << PORT_PDR1_PD12_SHIFT) # define PORT_PDR1_PD12(n) ((uint32_t)(n) << PORT_PDR1_PD12_SHIFT) -#define PORT_PDR1_PD13_SHIFT (20) /* Bit 20-22: Pad Driver Mode for Port 0 Pin 13 */ +#define PORT_PDR1_PD13_SHIFT (20) /* Bit 20-22: Pad Driver Mode for Port n Pin 13 */ #define PORT_PDR1_PD13_MASK (7 << PORT_PDR1_PD13_SHIFT) # define PORT_PDR1_PD13(n) ((uint32_t)(n) << PORT_PDR1_PD13_SHIFT) -#define PORT_PDR1_PD14_SHIFT (24) /* Bit 24-26: Pad Driver Mode for Port 0 Pin 14 */ +#define PORT_PDR1_PD14_SHIFT (24) /* Bit 24-26: Pad Driver Mode for Port n Pin 14 */ #define PORT_PDR1_PD14_MASK (7 << PORT_PDR1_PD14_SHIFT) # define PORT_PDR1_PD14(n) ((uint32_t)(n) << PORT_PDR1_PD14_SHIFT) -#define PORT_PDR1_PD15_SHIFT (28) /* Bit 28-30: Pad Driver Mode for Port 0 Pin 15 */ +#define PORT_PDR1_PD15_SHIFT (28) /* Bit 28-30: Pad Driver Mode for Port n Pin 15 */ #define PORT_PDR1_PD15_MASK (7 << PORT_PDR1_PD15_SHIFT) # define PORT_PDR1_PD15(n) ((uint32_t)(n) << PORT_PDR1_PD15_SHIFT) diff --git a/arch/arm/src/xmc4/chip/xmc4_scu.h b/arch/arm/src/xmc4/chip/xmc4_scu.h index 38d26051b77..2d22084252d 100644 --- a/arch/arm/src/xmc4/chip/xmc4_scu.h +++ b/arch/arm/src/xmc4/chip/xmc4_scu.h @@ -889,7 +889,7 @@ #define SCU_PBCLKCR_PBDIV (1 << 0) /* Bit 0: PB Clock Divider Enable */ # define SCU_PBCLKCR_PBDIV_FCPU (0) /* 0=fCPU */ -# define SCU_PBCLKCR_PBDIV_DIV2 ((1 << 0) /* 1=fCPU/2 */ +# define SCU_PBCLKCR_PBDIV_DIV2 (1 << 0) /* 1=fCPU/2 */ /* USB Clock Control */ diff --git a/arch/arm/src/xmc4/chip/xmc4_usic.h b/arch/arm/src/xmc4/chip/xmc4_usic.h index 462ac44c955..274d0fae53b 100644 --- a/arch/arm/src/xmc4/chip/xmc4_usic.h +++ b/arch/arm/src/xmc4/chip/xmc4_usic.h @@ -563,7 +563,7 @@ # define USIC_SCTR_TRM_ACTIVE (3 << USIC_SCTR_TRM_SHIFT) /* Active without regard to signal level */ #define USIC_SCTR_FLE_SHIFT (16) /* Bits 16-21: Frame Length */ #define USIC_SCTR_FLE_MASK (0x3f << USIC_SCTR_FLE_SHIFT) -# define USIC_SCTR_FLE(n) ((uint32_t)(n) << USIC_SCTR_FLE_SHIFT) +# define USIC_SCTR_FLE(n) ((uint32_t)((n)-1) << USIC_SCTR_FLE_SHIFT) #define USIC_SCTR_WLE_SHIFT (24) /* Bits 24-27: Word Length */ #define USIC_SCTR_WLE_MASK (15 << USIC_SCTR_WLE_SHIFT) # define USIC_SCTR_WLE(n) ((uint32_t)((n)-1) << USIC_SCTR_WLE_SHIFT) diff --git a/arch/arm/src/xmc4/xmc4_clockconfig.c b/arch/arm/src/xmc4/xmc4_clockconfig.c index db72a3cdf9c..519276f2cdc 100644 --- a/arch/arm/src/xmc4/xmc4_clockconfig.c +++ b/arch/arm/src/xmc4/xmc4_clockconfig.c @@ -105,13 +105,18 @@ #define CLKSET_VALUE (0x00000000) #define SYSCLKCR_VALUE (0x00010001) #define CPUCLKCR_VALUE (0x00000000) -#define PBCLKCR_VALUE (0x00000000) #define CCUCLKCR_VALUE (0x00000000) #define WDTCLKCR_VALUE (0x00000000) #define EBUCLKCR_VALUE (0x00000003) #define USBCLKCR_VALUE (0x00010000) #define EXTCLKCR_VALUE (0x01200003) +#if BOARD_PBDIV == 1 +# define PBCLKCR_VALUE SCU_PBCLKCR_PBDIV_FCPU +#else /* BOARD_PBDIV == 2 */ +# define PBCLKCR_VALUE SCU_PBCLKCR_PBDIV_DIV2 +#endif + #if ((USBCLKCR_VALUE & SCU_USBCLKCR_USBSEL) == SCU_USBCLKCR_USBSEL_USBPLL) # define USB_DIV 3 #else @@ -182,9 +187,9 @@ void xmc4_clock_configure(void) regval = getreg32(XMC4_SCU_PWRSTAT); if ((regval & SCU_PWR_HIBEN) == 0) { - regval = getreg32(XMC4_SCU_PWRSET); - regval |= SCU_PWR_HIBEN; - putreg32(regval, XMC4_SCU_PWRSTAT); + /* Enable the HIB domain */ + + putreg32(SCU_PWR_HIBEN, XMC4_SCU_PWRSET); /* Wait until HIB domain is enabled */ @@ -193,7 +198,7 @@ void xmc4_clock_configure(void) } } - /* Remove the reset only if HIB domain were in a state of reset */ + /* Remove the reset only if HIB domain was in a state of reset */ regval = getreg32(XMC4_SCU_RSTSTAT); if ((regval & SCU_RSTSTAT_HIBRS) != 0) @@ -387,7 +392,7 @@ void xmc4_clock_configure(void) /* Before scaling to final frequency we need to setup the clock dividers */ putreg32(SYSCLKCR_VALUE, XMC4_SCU_SYSCLKCR); - putreg32(PBCLKCR_VALUE, XMC4_SCU_PBCLKCR); + putreg32(PBCLKCR_VALUE, XMC4_SCU_PBCLKCR); putreg32(CPUCLKCR_VALUE, XMC4_SCU_CPUCLKCR); putreg32(CCUCLKCR_VALUE, XMC4_SCU_CCUCLKCR); putreg32(WDTCLKCR_VALUE, XMC4_SCU_WDTCLKCR); diff --git a/arch/arm/src/xmc4/xmc4_clockutils.c b/arch/arm/src/xmc4/xmc4_clockutils.c index 4d334eaef53..2a391ca3861 100644 --- a/arch/arm/src/xmc4/xmc4_clockutils.c +++ b/arch/arm/src/xmc4/xmc4_clockutils.c @@ -161,6 +161,7 @@ uint32_t xmc4_get_coreclock(void) uint32_t xmc4_get_periphclock(void) { uint32_t periphclock; + uint32_t regval; /* Get the CPU clock frequency. Unless it is divided down, this also the * peripheral clock frequency. @@ -170,12 +171,12 @@ uint32_t xmc4_get_periphclock(void) /* Get the peripheral clock divider */ - periphclock = getreg32(XMC4_SCU_PBCLKCR); - if ((periphclock & SCU_PBCLKCR_PBDIV) != 0) + regval = getreg32(XMC4_SCU_PBCLKCR); + if ((regval & SCU_PBCLKCR_PBDIV) != 0) { /* The peripheral clock is fCPU/2 */ - periphclock <<= 1; + periphclock >>= 1; } return periphclock; diff --git a/arch/arm/src/xmc4/xmc4_gpio.c b/arch/arm/src/xmc4/xmc4_gpio.c index e26967f06f3..d88e73c7adc 100644 --- a/arch/arm/src/xmc4/xmc4_gpio.c +++ b/arch/arm/src/xmc4/xmc4_gpio.c @@ -234,7 +234,7 @@ static inline void xmc4_gpio_hwsel(uintptr_t portbase, unsigned int pin, ****************************************************************************/ static inline void xmc4_gpio_pdisc(uintptr_t portbase, unsigned int pin, - bool value) + bool enable) { uint32_t regval; uint32_t mask; @@ -243,16 +243,21 @@ static inline void xmc4_gpio_pdisc(uintptr_t portbase, unsigned int pin, regval = xmc4_gpio_getreg(portbase, XMC4_PORT_PDISC_OFFSET); - /* Set/clear the enable/disable (or analg) value for this field */ + /* Set or clear the pin field in the PDISC register. + * + * Disable = set + * Analog = set + * Enable = clear + */ mask = PORT_PIN(pin); - if (value) + if (enable) { - regval |= mask; + regval &= ~mask; } else { - regval &= ~mask; + regval |= mask; } xmc4_gpio_putreg(portbase, XMC4_PORT_PDISC_OFFSET, regval); @@ -267,7 +272,7 @@ static inline void xmc4_gpio_pdisc(uintptr_t portbase, unsigned int pin, ****************************************************************************/ static inline void xmc4_gpio_pps(uintptr_t portbase, unsigned int pin, - bool value) + bool powersave) { uint32_t regval; uint32_t mask; @@ -276,10 +281,10 @@ static inline void xmc4_gpio_pps(uintptr_t portbase, unsigned int pin, regval = xmc4_gpio_getreg(portbase, XMC4_PORT_PPS_OFFSET); - /* Set/clear the enable/disable (or analg) value for this field */ + /* Set/clear the enable/disable power save value for this field */ mask = PORT_PIN(pin); - if (value) + if (powersave) { regval |= mask; } @@ -307,7 +312,7 @@ static void xmc4_gpio_pdr(uintptr_t portbase, unsigned int pin, unsigned int offset; unsigned int shift; - /* Read the PDRregister */ + /* Read the PDR register */ offset = XMC4_PORT_PDR_OFFSET(pin); regval = xmc4_gpio_getreg(portbase, offset); @@ -412,18 +417,18 @@ int xmc4_gpio_config(gpioconfig_t pinconfig) value = xmc4_gpio_pinctrl(pinconfig); xmc4_gpio_hwsel(portbase, pin, value); - /* Select drive strength */ + /* Select drive strength (PDR) */ value = xmc4_gpio_padtype(pinconfig); xmc4_gpio_pdr(portbase, pin, value); /* Enable/enable pad or Analog only (PDISC) */ - xmc4_gpio_pdisc(portbase, pin, ((pinconfig & GPIO_PAD_DISABLE) != 0)); + xmc4_gpio_pdisc(portbase, pin, ((pinconfig & GPIO_PAD_DISABLE) == 0)); - /* Make sure pin is not in power save mode (PDR) */ + /* Make sure pin is not in power save mode (PPS) */ - xmc4_gpio_pdisc(portbase, pin, false); + xmc4_gpio_pps(portbase, pin, false); leave_critical_section(flags); return OK; diff --git a/arch/arm/src/xmc4/xmc4_gpio.h b/arch/arm/src/xmc4/xmc4_gpio.h index 4595fe6a795..0dce7af73cd 100644 --- a/arch/arm/src/xmc4/xmc4_gpio.h +++ b/arch/arm/src/xmc4/xmc4_gpio.h @@ -79,8 +79,8 @@ # define GPIO_OUTPUT_ALT4 (IOCR_OUTPUT_ALT4 << GPIO_PINTYPE_SHIFT) # define _GPIO_OUTPUT_BIT (16 << GPIO_PINTYPE_SHIFT) -# define GPIO_ISINPUT(p) (((p) & _GPIO_OUTPUT_BIT) != 0) -# define GPIO_ISOUTPUT(p) (((p) & _GPIO_OUTPUT_BIT) == 0) +# define GPIO_ISINPUT(p) (((p) & _GPIO_OUTPUT_BIT) == 0) +# define GPIO_ISOUTPUT(p) (((p) & _GPIO_OUTPUT_BIT) != 0) /* Pin type modifier: * @@ -160,7 +160,7 @@ */ #define GPIO_PORT_SHIFT (4) /* Bit 4-7: Port number */ -#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) # define GPIO_PORT0 (0 << GPIO_PORT_SHIFT) # define GPIO_PORT1 (1 << GPIO_PORT_SHIFT) # define GPIO_PORT2 (2 << GPIO_PORT_SHIFT) @@ -180,7 +180,7 @@ */ #define GPIO_PIN_SHIFT (0) /* Bits 0-3: GPIO pin: 0-15 */ -#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) #define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) #define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) #define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) diff --git a/arch/arm/src/xmc4/xmc4_lowputc.c b/arch/arm/src/xmc4/xmc4_lowputc.c index fcb930d1b90..c1416194fc3 100644 --- a/arch/arm/src/xmc4/xmc4_lowputc.c +++ b/arch/arm/src/xmc4/xmc4_lowputc.c @@ -275,7 +275,7 @@ int xmc4_uart_configure(enum usic_channel_e channel, * the config structure. */ - ret = xmc4_uisc_baudrate(channel, config->baud, UART_OVERSAMPLING); + ret = xmc4_usic_baudrate(channel, config->baud, UART_OVERSAMPLING); /* Configure frame format. * diff --git a/arch/arm/src/xmc4/xmc4_usic.c b/arch/arm/src/xmc4/xmc4_usic.c index dd69cf318dd..925c9c0f411 100644 --- a/arch/arm/src/xmc4/xmc4_usic.c +++ b/arch/arm/src/xmc4/xmc4_usic.c @@ -121,12 +121,12 @@ int xmc4_enable_usic(enum usic_e usic) putreg32(SCU_CGAT0_USIC0, XMC4_SCU_CGATCLR0); - /* De-assert peripheral reset USIC0 */ + /* Set bit in PRCLR0 to de-assert USIC0 peripheral reset */ putreg32(SCU_PR0_USIC0RS, XMC4_SCU_PRCLR0); } #else - /* De-assert peripheral reset USIC0 */ + /* Set bit in PRCLR0 to de-assert USIC0 peripheral reset */ putreg32(SCU_PR0_USIC0RS, XMC4_SCU_PRCLR0); #endif @@ -143,12 +143,12 @@ int xmc4_enable_usic(enum usic_e usic) putreg32(SCU_CGAT1_USIC1, XMC4_SCU_CGATCLR1); - /* De-assert peripheral reset USIC1 */ + /* Set bit in PRCLR1 to de-assert USIC1 peripheral reset */ putreg32(SCU_PR1_USIC1RS, XMC4_SCU_PRCLR1); } #else - /* De-assert peripheral reset USIC1 */ + /* Set bit in PRCLR1 to de-assert USIC1 peripheral reset */ putreg32(SCU_PR1_USIC1RS, XMC4_SCU_PRCLR1); #endif @@ -165,12 +165,12 @@ int xmc4_enable_usic(enum usic_e usic) putreg32(SCU_CGAT1_USIC2, XMC4_SCU_CGATCLR1); - /* De-assert peripheral reset USIC2 */ + /* Set bit in PRCLR1 to de-assert USIC2 peripheral reset */ putreg32(SCU_PR1_USIC2RS, XMC4_SCU_PRCLR1); } #else - /* De-assert peripheral reset USIC2 */ + /* Set bit in PRCLR1 to de-assert USIC2 peripheral reset */ putreg32(SCU_PR1_USIC2RS, XMC4_SCU_PRCLR1); #endif @@ -203,7 +203,7 @@ int xmc4_disable_usic(enum usic_e usic) switch (usic) { case USIC0: - /* Assert peripheral reset USIC0 */ + /* Set bit in PRSET0 to assert USIC0 peripheral reset */ putreg32(SCU_PR0_USIC0RS, XMC4_SCU_PRSET0); @@ -216,7 +216,7 @@ int xmc4_disable_usic(enum usic_e usic) #if XMC4_NUSIC > 1 case USIC1: - /* Assert peripheral reset USIC0 */ + /* Set bit in PRSET1 to assert USIC1 peripheral reset */ putreg32(SCU_PR1_USIC1RS, XMC4_SCU_PRSET1); @@ -229,7 +229,7 @@ int xmc4_disable_usic(enum usic_e usic) #if XMC4_NUSIC > 2 case USIC2: - /* Assert peripheral reset USIC0 */ + /* Set bit in PRSET1 to assert USIC2 peripheral reset */ putreg32(SCU_PR1_USIC2RS, XMC4_SCU_PRSET1); @@ -385,7 +385,7 @@ int xmc4_disable_usic_channel(enum usic_channel_e channel) } /**************************************************************************** - * Name: xmc4_uisc_baudrate + * Name: xmc4_usic_baudrate * * Description: * Set the USIC baudrate for the USIC channel @@ -396,7 +396,7 @@ int xmc4_disable_usic_channel(enum usic_channel_e channel) * ****************************************************************************/ -int xmc4_uisc_baudrate(enum usic_channel_e channel, uint32_t baud, +int xmc4_usic_baudrate(enum usic_channel_e channel, uint32_t baud, uint32_t oversampling) { uintptr_t base; @@ -448,14 +448,14 @@ int xmc4_uisc_baudrate(enum usic_channel_e channel, uint32_t baud, /* Select and setup the fractional divider */ - regval = USIC_FDR_DM_FRACTIONAL | (clkdiv_min << USIC_FDR_STEP_SHIFT); + regval = USIC_FDR_DM_FRACTIONAL | USIC_FDR_STEP(clkdiv_min); putreg32(regval, base + XMC4_USIC_FDR_OFFSET); /* Setup and enable the baud rate generator */ regval = getreg32(base + XMC4_USIC_BRG_OFFSET); regval &= ~(USIC_BRG_DCTQ_MASK | USIC_BRG_PDIV_MASK | USIC_BRG_PCTQ_MASK | USIC_BRG_PPPEN); - regval |= (USIC_BRG_DCTQ(oversampling - 1) | USIC_BRG_PDIV(pdiv_int_min - 1)); + regval |= (USIC_BRG_DCTQ(oversampling - 1) | USIC_BRG_PDIV(pdiv_int_min - 1)); putreg32(regval, base + XMC4_USIC_BRG_OFFSET); ret = OK; diff --git a/arch/arm/src/xmc4/xmc4_usic.h b/arch/arm/src/xmc4/xmc4_usic.h index 910846bc85e..291fb81fb01 100644 --- a/arch/arm/src/xmc4/xmc4_usic.h +++ b/arch/arm/src/xmc4/xmc4_usic.h @@ -177,7 +177,7 @@ int xmc4_enable_usic_channel(enum usic_channel_e channel); int xmc4_disable_usic_channel(enum usic_channel_e channel); /**************************************************************************** - * Name: xmc4_uisc_baudrate + * Name: xmc4_usic_baudrate * * Description: * Set the USIC baudrate for the USIC channel @@ -188,7 +188,7 @@ int xmc4_disable_usic_channel(enum usic_channel_e channel); * ****************************************************************************/ -int xmc4_uisc_baudrate(enum usic_channel_e channel, uint32_t baud, +int xmc4_usic_baudrate(enum usic_channel_e channel, uint32_t baud, uint32_t oversampling); #endif /* __ARCH_ARM_SRC_XMC4_XMC4_USIC_H */ diff --git a/configs/xmc4500-relax/README.txt b/configs/xmc4500-relax/README.txt new file mode 100644 index 00000000000..e1fd46fa839 --- /dev/null +++ b/configs/xmc4500-relax/README.txt @@ -0,0 +1,168 @@ +README for the XMC4500 Relax +============================ + + The directory provides board support for the Infinion XMC4500 Relax v1 + boards. There are to variants of this board: There is a Lite version + that has fewer features, for example, no 32.768KHz crystal. + + The current configurations support only the Lite version of the board. + +Status +====== + + 2017-03-21: The XMC4500 Relax boots into NSH, provides the NSH prompt, + and the LEDs are working. But there is a problem with the USIC baud + (probably); I get garbage on the serial console. This probably means + that either the peripheral clocking is wrong or the baud configuration + is wrong. + +Serial Console +============== + + Be default, UART0 (aka, USIC0, channel 0) is used as the serial console. + The RX and TX pins is available: + + RX - P1.4, Connector X2, pin 17 + TX - P1.5, Connector X2, pin 16 + GND - Available on pins 1-4 of either connector X1 or X2 + VDD3.3 - Available on pins 37-38 of either connector X1 or X2 + VDD5 - Available on pins 39-40 of either connector X1 or X2 + + A TTL to RS-232 convertor or a USB TTL-to-USB serial adaptor is required. + The notion of what is TX and what is RX depends on your point of view. + With the TTL to RS-232 converter, I connect pin 17 to the pin labeled + TX on the converter and pin 16 to the RX pin on the converter. + +LEDs +==== + + The XMC4500 Relax Lite v1 board has two LEDs: + + LED1 P1.1 High output illuminates + LED2 P1.0 High output illuminates + + If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in + any way. The definitions provided in the board.h header file can be used + to access individual LEDs. + + These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is + defined. In that case, the usage by the board port is defined in + include/board.h and src/sam_autoleds.c. The LEDs are used to encode + OS-related events as follows: + + SYMBOL Meaning LED state + LED1 LED2 + ------------------ ------------------------ ------ ------ + LED_STARTED NuttX has been started OFF OFF + LED_HEAPALLOCATE Heap has been allocated OFF OFF + LED_IRQSENABLED Interrupts enabled OFF OFF + LED_STACKCREATED Idle stack created ON OFF + LED_INIRQ In an interrupt No change + LED_SIGNAL In a signal handler No change + LED_ASSERTION An assertion failed No change + LED_PANIC The system has crashed N/C Blinking + LED_IDLE MCU is is sleep mode Not used + + Thus if LED1 is statically on, NuttX has successfully booted and is, + apparently, running normally. If LED2 is flashing at approximately + 2Hz, then a fatal error has been detected and the system has halted. + +Buttons +======= + + The XMC4500 Relax Lite v1 board has two buttons: + + BUTTON1 P1.14 Low input sensed when button pressed + BUTTON2 P1.15 Low input sensed when button pressed + +Configurations +============== + + Information Common to All Configurations + ---------------------------------------- + Each XMC4500 Relax configuration is maintained in a sub-directory and + can be selected as follow: + + cd tools + ./configure.sh xmc5400-relax/ + cd - + . ./setenv.sh + + Before sourcing the setenv.sh file above, you should examine it and + perform edits as necessary so that TOOLCHAIN_BIN is the correct path + to the directory than holds your toolchain binaries. + + And then build NuttX by simply typing the following. At the conclusion of + the make, the nuttx binary will reside in an ELF file called, simply, nuttx. + + make oldconfig + make + + The that is provided above as an argument to the tools/configure.sh + must be is one of the following. + + NOTES: + + 1. These configurations use the mconf-based configuration tool. To + change any of these configurations using that tool, you should: + + a. Build and install the kconfig-mconf tool. See nuttx/README.txt + see additional README.txt files in the NuttX tools repository. + + b. Execute 'make menuconfig' in nuttx/ in order to start the + reconfiguration process. + + 2. Unless stated otherwise, all configurations generate console + output on UART0 (aka USIC0, channel 0) as described above under + "Serial Console". The relevant configuration settings are listed + below: + + CONFIG_XMC4_USIC0=y + CONFIG_XMC4_USIC0_CHAN0_ISUART=y + CONFIG_XMC4_USIC0_CHAN1_NONE=y + + CONFIG_UART0_SERIALDRIVER=y + CONFIG_UART0_SERIAL_CONSOLE=y + + CONFIG_UART0_RXBUFSIZE=256 + CONFIG_UART0_TXBUFSIZE=256 + CONFIG_UART0_BAUD=115200 + CONFIG_UART0_BITS=8 + CONFIG_UART0_PARITY=0 + CONFIG_UART0_2STOP=0 + + + 3. All of these configurations are set up to build under Windows using the + "GNU Tools for ARM Embedded Processors" that is maintained by ARM + (unless stated otherwise in the description of the configuration). + + https://launchpad.net/gcc-arm-embedded + + That toolchain selection can easily be reconfigured using + 'make menuconfig'. Here are the relevant current settings: + + Build Setup: + CONFIG_HOST_WINDOWS=y : Window environment + CONFIG_WINDOWS_CYGWIN=y : Cywin under Windows + + System Type -> Toolchain: + CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y : GNU ARM EABI toolchain + + Configuration sub-directories + ----------------------------- + + nsh: + + Configures the NuttShell (nsh) located at examples/nsh. This + configuration is focused on low level, command-line driver testing. It + has no network. + + NOTES: + + 1. NSH built-in applications are supported. + + Binary Formats: + CONFIG_BUILTIN=y : Enable support for built-in programs + + Application Configuration: + CONFIG_NSH_BUILTIN_APPS=y : Enable starting apps from NSH command line diff --git a/configs/xmc4500-relax/include/board.h b/configs/xmc4500-relax/include/board.h index 6be8e787f23..751e8031703 100644 --- a/configs/xmc4500-relax/include/board.h +++ b/configs/xmc4500-relax/include/board.h @@ -53,16 +53,21 @@ /* Clocking *************************************************************************/ /* Default clock initialization - * fPLL = 288MHz => fSYS = 288MHz => fCPU = 144MHz - * => fPB = 144MHz - * => fCCU = 144MHz - * => fETH = 72MHz - * => fUSB = 48MHz - * => fEBU = 72MHz + * + * fXTAL = 12Mhz + * -> fPLL = (fXTAL / (2 * 1) * 48) = 288MHz + * -> fSYS = (fPLL / 1) = 288MHz + * -> fCPU = (fSYS / 2) = 144MHz + * -> fPERIPH = (fCPU / 1) = 144MHz + * -> fCCU = (fSYS / 2) = 144MHz + * -> fETH = 72MHz (REVISIT) + * -> fUSB = 48MHz (REVISIT) + * -> fEBU = 72MHz (REVISIT) * * fUSBPLL Disabled, only enabled if SCU_CLK_USBCLKCR_USBSEL_USBPLL is selected * - * fOFI = 24MHz => fWDT = 24MHz + * fOFI = 24MHz + * -> fWDT = 24MHz (REVISIT) */ #undef BOARD_FOFI_CALIBRATION /* Enable factory calibration */ @@ -79,7 +84,7 @@ /* Select the external crystal as the PLL clock source */ #define BOARD_PLL_CLOCKSRC_XTAL 1 /* PLL Clock source == extnernal crystal */ -#undef BOARD_PLL_CLOCKSRC_OFI /* PLL Clock source != internal fast oscillator */ +#undef BOARD_PLL_CLOCKSRC_OFI /* PLL Clock source != internal fast oscillator */ /* PLL Configuration: * @@ -95,16 +100,21 @@ #define BOARD_PLL_K2DIV 1 #define BOARD_PLL_FREQUENCY 288000000 -/* System frequency is divided down from PLL output */ +/* System frequency, fSYS, is divided down from PLL output */ #define BOARD_SYSDIV 1 /* PLL Output divider to get fSYS */ #define BOARD_SYS_FREQUENCY 288000000 -/* CPU frequency may be divided down from system frequency */ +/* CPU frequency, fCPU, may be divided down from system frequency */ #define BOARD_CPUDIV_ENABLE 1 /* Enable PLL dive by 2 for fCPU */ #define BOARD_CPU_FREQUENCY 144000000 +/* The peripheral clock, fPERIPH, derives from fCPU with no division */ + +#define BOARD_PBDIV 1 /* No division */ +#define BOARD_PERIPH_FREQUENCY 144000000 + /* Standby clock source selection * * BOARD_STDBY_CLOCKSRC_OSI - Internal 32.768KHz slow oscillator @@ -112,7 +122,7 @@ */ #define BOARD_STDBY_CLOCKSRC_OSI 1 -#undef BOARD_STDBY_CLOCKSRC_OSCULP +#undef BOARD_STDBY_CLOCKSRC_OSCULP #define BOARD_STDBY_FREQUENCY 32768 /* USB PLL settings. @@ -171,12 +181,9 @@ #define LED_PANIC 3 /* The system has crashed N/C Blinking */ #undef LED_IDLE /* MCU is is sleep mode Not used */ -/* Thus if LED0 is statically on, NuttX has successfully booted and is, - * apparently, running normally. If LED1 is flashing at approximately +/* Thus if LED1 is statically on, NuttX has successfully booted and is, + * apparently, running normally. If LED2 is flashing at approximately * 2Hz, then a fatal error has been detected and the system has halted. - * - * NOTE: That LED0 is not used after completion of booting and may - * be used by other board-specific logic. */ /* Button definitions ***************************************************************/ diff --git a/configs/xmc4500-relax/src/xmc4_autoleds.c b/configs/xmc4500-relax/src/xmc4_autoleds.c index 694007c5e5e..69eda6dee93 100644 --- a/configs/xmc4500-relax/src/xmc4_autoleds.c +++ b/configs/xmc4500-relax/src/xmc4_autoleds.c @@ -43,19 +43,19 @@ * include/board.h and src/sam_autoleds.c. The LEDs are used to encode * OS-related events as follows: * - * SYMBOL Meaning LED state - * LED2 LED1 - * --------------------- -------------------------- ------ ------ */ - -#define LED_STARTED 0 /* NuttX has been started OFF OFF */ -#define LED_HEAPALLOCATE 0 /* Heap has been allocated OFF OFF */ -#define LED_IRQSENABLED 0 /* Interrupts enabled OFF OFF */ -#define LED_STACKCREATED 1 /* Idle stack created ON OFF */ -#define LED_INIRQ 2 /* In an interrupt No change */ -#define LED_SIGNAL 2 /* In a signal handler No change */ -#define LED_ASSERTION 2 /* An assertion failed No change */ -#define LED_PANIC 3 /* The system has crashed N/C Blinking */ -#undef LED_IDLE /* MCU is is sleep mode Not used */ + * SYMBOL Meaning LED state + * LED1 LED2 + * ------------------ ------------------------ ------ ------ + * LED_STARTED NuttX has been started OFF OFF + * LED_HEAPALLOCATE Heap has been allocated OFF OFF + * LED_IRQSENABLED Interrupts enabled OFF OFF + * LED_STACKCREATED Idle stack created ON OFF + * LED_INIRQ In an interrupt No change + * LED_SIGNAL In a signal handler No change + * LED_ASSERTION An assertion failed No change + * LED_PANIC The system has crashed N/C Blinking + * LED_IDLE MCU is is sleep mode Not used + */ /**************************************************************************** * Included Files diff --git a/drivers/audio/wm8904.c b/drivers/audio/wm8904.c index 4489ae0f221..23da3ce9a9d 100644 --- a/drivers/audio/wm8904.c +++ b/drivers/audio/wm8904.c @@ -3,7 +3,7 @@ * * Audio device driver for Wolfson Microelectronics WM8904 Audio codec. * - * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: @@ -73,6 +73,14 @@ #include "wm8904.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Maximum number of retries */ + +#define MAX_RETRIES 3 + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -251,7 +259,7 @@ uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr) /* Try up to three times to read the register */ - for (retries = 1; retries <= 3; retries++) + for (retries = 1; retries <= MAX_RETRIES; retries++) { struct i2c_msg_s msg[2]; uint8_t data[2]; @@ -281,15 +289,20 @@ uint16_t wm8904_readreg(FAR struct wm8904_dev_s *priv, uint8_t regaddr) if (ret < 0) { #ifdef CONFIG_I2C_RESET - /* Perhaps the I2C bus is locked up? Try to shake the bus free */ + /* Perhaps the I2C bus is locked up? Try to shake the bus free. + * Don't bother with the reset if this was the last attempt. + */ - audwarn("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); - - ret = I2C_RESET(priv->i2c); - if (ret < 0) + if (retries < MAX_RETRIES) { - auderr("ERROR: I2C_RESET failed: %d\n", ret); - break; + audwarn("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); + + ret = I2C_RESET(priv->i2c); + if (ret < 0) + { + auderr("ERROR: I2C_RESET failed: %d\n", ret); + break; + } } #else auderr("ERROR: I2C_TRANSFER failed: %d\n", ret); @@ -338,7 +351,7 @@ static void wm8904_writereg(FAR struct wm8904_dev_s *priv, uint8_t regaddr, /* Try up to three times to read the register */ - for (retries = 1; retries <= 3; retries++) + for (retries = 1; retries <= MAX_RETRIES; retries++) { uint8_t data[3]; int ret; @@ -357,15 +370,20 @@ static void wm8904_writereg(FAR struct wm8904_dev_s *priv, uint8_t regaddr, if (ret < 0) { #ifdef CONFIG_I2C_RESET - /* Perhaps the I2C bus is locked up? Try to shake the bus free */ + /* Perhaps the I2C bus is locked up? Try to shake the bus free. + * Don't bother with the reset if this was the last attempt. + */ - audwarn("WARNING: i2c_write failed: %d ... Resetting\n", ret); - - ret = I2C_RESET(priv->i2c); - if (ret < 0) + if (retries < MAX_RETRIES) { - auderr("ERROR: I2C_RESET failed: %d\n", ret); - break; + audwarn("WARNING: i2c_write failed: %d ... Resetting\n", ret); + + ret = I2C_RESET(priv->i2c); + if (ret < 0) + { + auderr("ERROR: I2C_RESET failed: %d\n", ret); + break; + } } #else auderr("ERROR: I2C_TRANSFER failed: %d\n", ret); diff --git a/drivers/input/mxt.c b/drivers/input/mxt.c index f19c2bb0be5..e1152851719 100644 --- a/drivers/input/mxt.c +++ b/drivers/input/mxt.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/input/mxt.c * - * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -88,6 +88,10 @@ #define INVALID_POSITION 0x1000 +/* Maximum number of retries */ + +#define MAX_RETRIES 3 + /* Get a 16-bit value in little endian order (not necessarily aligned). The * source data is in little endian order. The host byte order does not * matter in this case. @@ -311,7 +315,7 @@ static int mxt_getreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, /* Try up to three times to read the register */ - for (retries = 1; retries <= 3; retries++) + for (retries = 1; retries <= MAX_RETRIES; retries++) { iinfo("retries=%d regaddr=%04x buflen=%d\n", retries, regaddr, buflen); @@ -342,15 +346,20 @@ static int mxt_getreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, if (ret < 0) { #ifdef CONFIG_I2C_RESET - /* Perhaps the I2C bus is locked up? Try to shake the bus free */ + /* Perhaps the I2C bus is locked up? Try to shake the bus free. + * Don't bother with the reset if this was the last attempt. + */ - iwarn("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); - - ret = I2C_RESET(priv->i2c); - if (ret < 0) + if (retries < MAX_RETRIES) { - ierr("ERROR: I2C_RESET failed: %d\n", ret); - break; + iwarn("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); + + ret = I2C_RESET(priv->i2c); + if (ret < 0) + { + ierr("ERROR: I2C_RESET failed: %d\n", ret); + break; + } } #else ierr("ERROR: I2C_TRANSFER failed: %d\n", ret); @@ -385,7 +394,7 @@ static int mxt_putreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, /* Try up to three times to read the register */ - for (retries = 1; retries <= 3; retries++) + for (retries = 1; retries <= MAX_RETRIES; retries++) { iinfo("retries=%d regaddr=%04x buflen=%d\n", retries, regaddr, buflen); @@ -416,14 +425,19 @@ static int mxt_putreg(FAR struct mxt_dev_s *priv, uint16_t regaddr, if (ret < 0) { #ifdef CONFIG_I2C_RESET - /* Perhaps the I2C bus is locked up? Try to shake the bus free */ + /* Perhaps the I2C bus is locked up? Try to shake the bus free. + * Don't bother with the reset if this was the last attempt. + */ - iwarn("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); - - ret = I2C_RESET(priv->i2c); - if (ret < 0) + if (retries < MAX_RETRIES) { - ierr("ERROR: I2C_RESET failed: %d\n", ret); + iwarn("WARNING: I2C_TRANSFER failed: %d ... Resetting\n", ret); + + ret = I2C_RESET(priv->i2c); + if (ret < 0) + { + ierr("ERROR: I2C_RESET failed: %d\n", ret); + } } #else ierr("ERROR: I2C_TRANSFER failed: %d\n", ret); diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index b3abcaeabd8..565ab07301b 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -48,6 +48,7 @@ config LCD_NOGETRUN config LCD_MAXCONTRAST int "LCD maximum contrast" + default 31 if AQM_1248A default 63 if NOKIA6100_S1D15G10 || LCD_SHARP_MEMLCD default 127 if NOKIA6100_PCF8833 default 255 if LCD_P14201 || LCD_LCD1602 @@ -596,6 +597,9 @@ config NHD_C12864KGZ config ERC_12864_3 bool "like ERC12864-3" +config AQM_1248A + bool "like AQM1248A" + endchoice config ST7565_NINTERFACES @@ -613,6 +617,7 @@ config ST7565_XRES config ST7565_YRES int "ST7565 Y Resolution" + default 48 if AQM_1248A default 64 ---help--- Specifies the Y resolution of the LCD. @@ -625,6 +630,7 @@ config ST7565_MIRROR_X config ST7565_MIRROR_Y bool "ST7565 apply mirror on Y" + default y if AQM_1248A default n ---help--- Mirror Y on LCD. diff --git a/drivers/lcd/st7565.c b/drivers/lcd/st7565.c index 0e52b58a3ec..d25583a7452 100644 --- a/drivers/lcd/st7565.c +++ b/drivers/lcd/st7565.c @@ -1030,6 +1030,27 @@ FAR struct lcd_dev_s *st7565_initialize(FAR struct st7565_lcd_s *lcd, (void)st7565_send_one_data(priv, ST7565_SETEVREG(0x24)); (void)st7565_send_one_data(priv, ST7565_SETSTARTLINE); +#elif defined(CONFIG_AQM_1248A) + + (void)st7565_send_one_data(priv, ST7565_DISPOFF); + (void)st7565_send_one_data(priv, ST7565_ADCNORMAL); + (void)st7565_send_one_data(priv, ST7565_SETCOMREVERSE); + (void)st7565_send_one_data(priv, ST7565_BIAS_1_7); + + (void)st7565_send_one_data(priv, ST7565_POWERCTRL_B); + up_mdelay(2); + (void)st7565_send_one_data(priv, ST7565_POWERCTRL_BR); + up_mdelay(2); + (void)st7565_send_one_data(priv, ST7565_POWERCTRL_INT); + + (void)st7565_send_one_data(priv, ST7565_REG_RES_4_5); + (void)st7565_send_one_data(priv, ST7565_SETEVMODE); + (void)st7565_send_one_data(priv, ST7565_SETEVREG(0x1c)); + (void)st7565_send_one_data(priv, ST7565_DISPRAM); + (void)st7565_send_one_data(priv, ST7565_SETSTARTLINE); + (void)st7565_send_one_data(priv, ST7565_DISPNORMAL); + (void)st7565_send_one_data(priv, ST7565_DISPON); + #else # error "No initialization sequence selected" #endif diff --git a/drivers/lcd/st7565.h b/drivers/lcd/st7565.h index 0855f5e8ecc..cc9d17dd0f4 100644 --- a/drivers/lcd/st7565.h +++ b/drivers/lcd/st7565.h @@ -100,6 +100,8 @@ #define ST7565_POWERCTRL_VR 0x2b /* 0x2b: Only the voltage regulator circuit and the * voltage follower circuit are used */ +#define ST7565_POWERCTRL_B 0x2c /* 0x2c: Booster=ON */ +#define ST7565_POWERCTRL_BR 0x2e /* 0x2e: Booster=ON V/R=ON */ #define ST7565_POWERCTRL_INT 0x2f /* 0x2f: Only the internal power supply is used */ /* Regulation Resistior ratio V0 = (1+Rb/Ra)*Vev */ diff --git a/net/udp/udp_psock_send.c b/net/udp/udp_psock_send.c index e3e2eb0c881..c701fe064d7 100644 --- a/net/udp/udp_psock_send.c +++ b/net/udp/udp_psock_send.c @@ -78,7 +78,7 @@ ssize_t psock_udp_send(FAR struct socket *psock, FAR const void *buf, socklen_t tolen; DEBUGASSERT(psock != NULL && psock->s_crefs > 0); - DEBUGASSERT(psock->s_type != SOCK_DGRAM); + DEBUGASSERT(psock->s_type == SOCK_DGRAM); conn = (FAR struct udp_conn_s *)psock->s_conn; DEBUGASSERT(conn); diff --git a/sched/semaphore/sem_holder.c b/sched/semaphore/sem_holder.c index bc5c186e6bf..a46cf3a8be4 100644 --- a/sched/semaphore/sem_holder.c +++ b/sched/semaphore/sem_holder.c @@ -156,7 +156,7 @@ static FAR struct semholder_s *sem_findholder(sem_t *sem, int i; pholder = NULL; - /* We have two hard-allocated holder structuse in sem_t */ + /* We have two hard-allocated holder structures in sem_t */ for (i = 0; i < 2; i++) { @@ -338,7 +338,7 @@ static int sem_boostholderprio(FAR struct semholder_s *pholder, if (!sched_verifytcb(htcb)) { serr("ERROR: TCB 0x%08x is a stale handle, counts lost\n", htcb); - DEBUGASSERT(!sched_verifytcb(htcb)); + DEBUGPANIC(); sem_freeholder(sem, pholder); } @@ -498,7 +498,7 @@ static int sem_restoreholderprio(FAR struct tcb_s *htcb, if (!sched_verifytcb(htcb)) { serr("ERROR: TCB 0x%08x is a stale handle, counts lost\n", htcb); - DEBUGASSERT(!sched_verifytcb(htcb)); + DEBUGPANIC(); pholder = sem_findholder(sem, htcb); if (pholder != NULL) { @@ -787,7 +787,6 @@ static inline void sem_restorebaseprio_task(FAR struct tcb_s *stcb, FAR sem_t *sem) { FAR struct tcb_s *rtcb = this_task(); - FAR struct semholder_s *pholder; /* Perform the following actions only if a new thread was given a count. * The thread that received the count should be the highest priority @@ -831,7 +830,6 @@ static inline void sem_restorebaseprio_task(FAR struct tcb_s *stcb, */ sem_findandfreeholder(sem, rtcb); - } /**************************************************************************** @@ -905,14 +903,15 @@ void sem_destroyholder(FAR sem_t *sem) if (sem->hhead != NULL) { serr("ERROR: Semaphore destroyed with holders\n"); - DEBUGASSERT(sem->hhead != NULL); + DEBUGPANIC(); (void)sem_foreachholder(sem, sem_recoverholders, NULL); } + #else - if (sem->holder[0].htcb != NULL || sem->holder[0].htcb != NULL) + if (sem->holder[0].htcb != NULL || sem->holder[1].htcb != NULL) { - DEBUGASSERT(sem->holder[0].htcb != NULL || sem->holder[0].htcb != NULL); serr("ERROR: Semaphore destroyed with holder\n"); + DEBUGPANIC(); } sem->holder[0].htcb = NULL;