Check return from nxsem_wait_uninterruptible()

This commits is for the remaining files in arch/arm/src/cxd56xx
  arch/arm/src/imxrt and arch/arm/src/stm32l4
This commit is contained in:
Ouss4 2020-04-05 19:04:58 +01:00 committed by patacongo
parent 5d123098b8
commit dda47dd4a9
5 changed files with 263 additions and 94 deletions

View File

@ -155,9 +155,9 @@ struct cxd56_emmc_state_s g_emmcdev;
* Private Functions
****************************************************************************/
static void emmc_takesem(FAR sem_t *sem)
static int emmc_takesem(FAR sem_t *sem)
{
nxsem_wait_uninterruptible(sem);
return nxsem_wait_uninterruptible(sem);
}
static void emmc_givesem(FAR sem_t *sem)
@ -377,6 +377,7 @@ static void emmc_send(int datatype, uint32_t opcode, uint32_t arg,
uint32_t mask;
uint32_t cmd;
uint32_t status;
int ret;
/* Get current interrupt mask, leave SDIO relative bits. */
@ -440,7 +441,21 @@ static void emmc_send(int datatype, uint32_t opcode, uint32_t arg,
/* Wait for command or data transfer done */
emmc_takesem(&g_waitsem);
do
{
ret = emmc_takesem(&g_waitsem);
/* The only expected error is ECANCELED which would occur if the
* calling thread were canceled.
*/
DEBUGASSERT(ret == OK || ret == -ECANCELED);
/* REVISIT: emmc_taksem error is lost. This loop needs to save
* the return from takesem and return it at the end.
*/
}
while (ret < 0);
/* Restore interrupt mask */
@ -708,7 +723,12 @@ static int cxd56_emmc_readsectors(FAR struct cxd56_emmc_state_s *priv,
return -ENOMEM;
}
emmc_takesem(&priv->excsem);
ret = emmc_takesem(&priv->excsem);
if (ret < 0)
{
kmm_free(descs);
return ret;
}
putreg32(nsectors * SECTOR_SIZE, EMMC_BYTCNT);
emmc_send(EMMC_NON_DATA, SET_BLOCK_COUNT, nsectors, EMMC_RESP_R1);
@ -765,7 +785,12 @@ static int cxd56_emmc_writesectors(FAR struct cxd56_emmc_state_s *priv,
return -ENOMEM;
}
emmc_takesem(&priv->excsem);
ret = emmc_takesem(&priv->excsem);
if (ret < 0)
{
kmm_free(descs);
return ret;
}
putreg32(nsectors * SECTOR_SIZE, EMMC_BYTCNT);
emmc_send(EMMC_NON_DATA, SET_BLOCK_COUNT, nsectors, EMMC_RESP_R1);
@ -825,13 +850,19 @@ finish:
static int cxd56_emmc_open(FAR struct inode *inode)
{
FAR struct cxd56_emmc_state_s *priv;
int ret;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cxd56_emmc_state_s *)inode->i_private;
/* Just increment the reference count on the driver */
emmc_takesem(&priv->excsem);
ret = emmc_takesem(&priv->excsem);
if (ret < 0)
{
return ret;
}
priv->crefs++;
emmc_givesem(&priv->excsem);
return OK;
@ -840,6 +871,7 @@ static int cxd56_emmc_open(FAR struct inode *inode)
static int cxd56_emmc_close(FAR struct inode *inode)
{
FAR struct cxd56_emmc_state_s *priv;
int ret;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cxd56_emmc_state_s *)inode->i_private;
@ -847,7 +879,12 @@ static int cxd56_emmc_close(FAR struct inode *inode)
/* Decrement the reference count on the block driver */
DEBUGASSERT(priv->crefs > 0);
emmc_takesem(&priv->excsem);
ret = emmc_takesem(&priv->excsem);
if (ret < 0)
{
return ret;
}
priv->crefs--;
emmc_givesem(&priv->excsem);
return OK;

View File

@ -158,9 +158,9 @@ static struct iccdev_s *g_cpumsg[NCPUS];
* Private Functions
****************************************************************************/
static void icc_semtake(sem_t *semid)
static int icc_semtake(sem_t *semid)
{
nxsem_wait_uninterruptible(semid);
return nxsem_wait_uninterruptible(semid);
}
static void icc_semgive(sem_t *semid)
@ -174,6 +174,7 @@ static FAR struct iccdev_s *icc_getprotocol(int protoid)
{
return NULL;
}
return g_protocol[protoid];
}
@ -183,6 +184,7 @@ static FAR struct iccdev_s *icc_getcpu(int cpuid)
{
return NULL;
}
return g_cpumsg[cpuid];
}
@ -288,6 +290,7 @@ static int icc_sighandler(int cpuid, int protoid, uint32_t pdata,
iccinfo("Call signal handler with No %d.\n", signo);
priv->u.sighandler(signo, sigdata, data, priv->userdata);
}
return OK;
}
@ -321,7 +324,11 @@ static int icc_recv(FAR struct iccdev_s *priv, FAR iccmsg_t *msg, int32_t ms)
wd_start(priv->rxtimeout, timo, icc_rxtimeout, 1, (uint32_t)priv);
}
icc_semtake(&priv->rxwait);
ret = icc_semtake(&priv->rxwait);
if (ret < 0)
{
return ret;
}
wd_cancel(priv->rxtimeout);
@ -356,6 +363,7 @@ static FAR struct iccdev_s *icc_devnew(void)
{
return NULL;
}
memset(priv, 0, sizeof(struct iccdev_s));
priv->rxtimeout = wd_create();
@ -405,6 +413,7 @@ int cxd56_iccregisterhandler(int protoid, cxd56_icchandler_t handler,
{
ret = -EINVAL;
}
leave_critical_section(flags);
return ret;
@ -428,6 +437,7 @@ int cxd56_iccregistersighandler(int cpuid, cxd56_iccsighandler_t handler,
{
ret = -EINVAL;
}
leave_critical_section(flags);
return ret;
@ -501,7 +511,8 @@ int cxd56_iccrecvmsg(FAR iccmsg_t *msg, int32_t ms)
return icc_recv(priv, msg, ms);
}
int cxd56_iccsignal(int8_t cpuid, int8_t signo, int16_t sigdata, uint32_t data)
int cxd56_iccsignal(int8_t cpuid, int8_t signo, int16_t sigdata,
uint32_t data)
{
struct iccreq_s req;
@ -555,6 +566,7 @@ int cxd56_iccinit(int protoid)
{
return -ENOMEM;
}
g_protocol[protoid] = priv;
return OK;
@ -579,6 +591,7 @@ int cxd56_iccinitmsg(int cpuid)
{
return -ENOMEM;
}
g_cpumsg[cpuid] = priv;
return OK;
@ -601,6 +614,7 @@ void cxd56_iccuninit(int protoid)
icc_devfree(priv);
g_protocol[protoid] = NULL;
}
leave_critical_section(flags);
}
@ -621,6 +635,7 @@ void cxd56_iccuninitmsg(int cpuid)
icc_devfree(priv);
g_cpumsg[cpuid] = NULL;
}
leave_critical_section(flags);
}

View File

@ -33,6 +33,10 @@
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/arch.h>
@ -48,13 +52,34 @@
#include "cxd56_icc.h"
#include "cxd56_sysctl.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_CXD56_SYSCTL_TIMEOUT
# define SYSCTL_TIMEOUT CONFIG_CXD56_SYSCTL_TIMEOUT
#else
# define SYSCTL_TIMEOUT 5000
#endif
static int sysctl_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static int sysctl_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
static int sysctl_semtake(sem_t *semid);
static void sysctl_semgive(sem_t *semid);
static int sysctl_rxhandler(int cpuid, int protoid,
uint32_t pdata, uint32_t data,
FAR void *userdata);
/****************************************************************************
* Private Data
****************************************************************************/
static sem_t g_exc;
static sem_t g_sync;
@ -65,6 +90,10 @@ static const struct file_operations g_sysctlfops =
.ioctl = sysctl_ioctl,
};
/****************************************************************************
* Private Functions
****************************************************************************/
static int sysctl_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
int ret = OK;
@ -85,9 +114,9 @@ static int sysctl_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
return ret;
}
static void sysctl_semtake(sem_t *semid)
static int sysctl_semtake(sem_t *semid)
{
nxsem_wait_uninterruptible(semid);
return nxsem_wait_uninterruptible(semid);
}
static void sysctl_semgive(sem_t *semid)
@ -109,6 +138,10 @@ static int sysctl_rxhandler(int cpuid, int protoid,
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
int cxd56_sysctlcmd(uint8_t id, uint32_t data)
{
iccmsg_t msg;
@ -116,7 +149,11 @@ int cxd56_sysctlcmd(uint8_t id, uint32_t data)
/* Get exclusive access */
sysctl_semtake(&g_exc);
ret = sysctl_semtake(&g_exc);
if (ret < 0)
{
return ret;
}
msg.cpuid = 0;
msg.msgid = id;
@ -127,13 +164,19 @@ int cxd56_sysctlcmd(uint8_t id, uint32_t data)
ret = cxd56_iccsend(CXD56_PROTO_SYSCTL, &msg, SYSCTL_TIMEOUT);
if (ret < 0)
{
sysctl_semgive(&g_exc);
_err("Timeout.\n");
return ret;
}
/* Wait for reply message from system CPU */
sysctl_semtake(&g_sync);
ret = sysctl_semtake(&g_sync);
if (ret < 0)
{
sysctl_semgive(&g_exc);
return ret;
}
/* Get the error code returned from system cpu */

View File

@ -56,7 +56,7 @@
#include "imxrt_enc.h"
/* This functionality is dependent on Qencoder Sensor support*/
/* This functionality is dependent on Qencoder Sensor support */
#ifndef CONFIG_SENSORS_QENCODER
# undef CONFIG_IMXRT_ENC
@ -69,9 +69,11 @@
* Pre-processor Definitions
****************************************************************************/
/* Debug ****************************************************************************/
/* Debug ********************************************************************/
/* Non-standard debug that may be used to enable the imxrt qe's built-in test features */
/* Non-standard debug that may be used to enable the imxrt qe's built-in test
* features
*/
#ifndef CONFIG_DEBUG_FEATURES
# undef CONFIG_DEBUG_SENSORS
@ -262,12 +264,15 @@ struct imxrt_qeconfig_s
uint32_t init_val; /* Value to initialize position counters to */
uint32_t modulus; /* Modulus to use when modulo counting is enabled */
uint16_t in_filt_per; /* Period for input filter sampling in # of periph
* clock cycles */
* clock cycles
*/
uint16_t in_filt_cnt; /* # of consecutive input filter samples that must
* agree */
* agree
*/
uint16_t init_flags; /* Flags to control which signals and edge transitions
* will reinitialize the position counter. Bits 4-0:
* [MOD, REV, XNE, XIP, HNE, HIP] */
* [MOD, REV, XNE, XIP, HNE, HIP]
*/
#ifdef CONFIG_DEBUG_SENSORS
bool tst_dir_adv; /* Whether to generate down/up test signals */
@ -280,8 +285,8 @@ struct imxrt_qeconfig_s
struct imxrt_enc_lowerhalf_s
{
/* The first field of this state structure must be a pointer to the lower-
* half callback structure:
*/
* half callback structure:
*/
FAR const struct qe_ops_s *ops; /* Lower half callback structure */
@ -289,7 +294,8 @@ struct imxrt_enc_lowerhalf_s
FAR const struct imxrt_qeconfig_s *config; /* static configuration */
sem_t sem_excl; /* Mutual exclusion semaphore to
* ensure atomic 32-bit reads. */
* ensure atomic 32-bit reads.
*/
};
/****************************************************************************
@ -309,8 +315,10 @@ static inline void imxrt_enc_modifyreg16
static void imxrt_enc_clock_enable (uint32_t base);
static void imxrt_enc_clock_disable (uint32_t base);
static inline void imxrt_enc_sem_wait(FAR struct imxrt_enc_lowerhalf_s *priv);
static inline void imxrt_enc_sem_post(FAR struct imxrt_enc_lowerhalf_s *priv);
static inline int imxrt_enc_sem_wait(
FAR struct imxrt_enc_lowerhalf_s *priv);
static inline void imxrt_enc_sem_post(
FAR struct imxrt_enc_lowerhalf_s *priv);
static int imxrt_enc_reconfig(FAR struct imxrt_enc_lowerhalf_s *priv,
uint16_t args);
@ -329,7 +337,8 @@ static int imxrt_enc_test_gen(FAR struct imxrt_enc_lowerhalf_s *priv,
static int imxrt_setup(FAR struct qe_lowerhalf_s *lower);
static int imxrt_shutdown(FAR struct qe_lowerhalf_s *lower);
static int imxrt_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos);
static int imxrt_position(FAR struct qe_lowerhalf_s *lower,
FAR int32_t *pos);
static int imxrt_reset(FAR struct qe_lowerhalf_s *lower);
static int imxrt_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd,
unsigned long arg);
@ -359,9 +368,12 @@ static const struct imxrt_qeconfig_s imxrt_enc1_config =
.modulus = CONFIG_ENC1_MODULUS,
.in_filt_per = CONFIG_ENC1_FILTPER,
.in_filt_cnt = CONFIG_ENC1_FILTCNT,
.init_flags = CONFIG_ENC1_HIP << HIP_SHIFT | CONFIG_ENC1_HNE << HNE_SHIFT |
CONFIG_ENC1_XIP << XIP_SHIFT | CONFIG_ENC1_XNE << XNE_SHIFT |
CONFIG_ENC1_DIR << REV_SHIFT | CONFIG_ENC1_MOD << MOD_SHIFT,
.init_flags = CONFIG_ENC1_HIP << HIP_SHIFT |
CONFIG_ENC1_HNE << HNE_SHIFT |
CONFIG_ENC1_XIP << XIP_SHIFT |
CONFIG_ENC1_XNE << XNE_SHIFT |
CONFIG_ENC1_DIR << REV_SHIFT |
CONFIG_ENC1_MOD << MOD_SHIFT,
#ifdef CONFIG_DEBUG_SENSORS
.tst_dir_adv = CONFIG_ENC1_TST_DIR,
@ -384,9 +396,12 @@ static const struct imxrt_qeconfig_s imxrt_enc2_config =
.modulus = CONFIG_ENC2_MODULUS,
.in_filt_per = CONFIG_ENC2_FILTPER,
.in_filt_cnt = CONFIG_ENC2_FILTCNT,
.init_flags = CONFIG_ENC2_HIP << HIP_SHIFT | CONFIG_ENC2_HNE << HNE_SHIFT |
CONFIG_ENC2_XIP << XIP_SHIFT | CONFIG_ENC2_XNE << XNE_SHIFT |
CONFIG_ENC2_DIR << REV_SHIFT | CONFIG_ENC2_MOD << MOD_SHIFT,
.init_flags = CONFIG_ENC2_HIP << HIP_SHIFT |
CONFIG_ENC2_HNE << HNE_SHIFT |
CONFIG_ENC2_XIP << XIP_SHIFT |
CONFIG_ENC2_XNE << XNE_SHIFT |
CONFIG_ENC2_DIR << REV_SHIFT |
CONFIG_ENC2_MOD << MOD_SHIFT,
#ifdef CONFIG_DEBUG_SENSORS
.tst_dir_adv = CONFIG_ENC2_TST_DIR,
@ -409,9 +424,12 @@ static const struct imxrt_qeconfig_s imxrt_enc3_config =
.modulus = CONFIG_ENC3_MODULUS,
.in_filt_per = CONFIG_ENC3_FILTPER,
.in_filt_cnt = CONFIG_ENC3_FILTCNT,
.init_flags = CONFIG_ENC3_HIP << HIP_SHIFT | CONFIG_ENC3_HNE << HNE_SHIFT |
CONFIG_ENC3_XIP << XIP_SHIFT | CONFIG_ENC3_XNE << XNE_SHIFT |
CONFIG_ENC3_DIR << REV_SHIFT | CONFIG_ENC3_MOD << MOD_SHIFT,
.init_flags = CONFIG_ENC3_HIP << HIP_SHIFT |
CONFIG_ENC3_HNE << HNE_SHIFT |
CONFIG_ENC3_XIP << XIP_SHIFT |
CONFIG_ENC3_XNE << XNE_SHIFT |
CONFIG_ENC3_DIR << REV_SHIFT |
CONFIG_ENC3_MOD << MOD_SHIFT,
#ifdef CONFIG_DEBUG_SENSORS
.tst_dir_adv = CONFIG_ENC3_TST_DIR,
@ -434,9 +452,12 @@ static const struct imxrt_qeconfig_s imxrt_enc4_config =
.modulus = CONFIG_ENC4_MODULUS,
.in_filt_per = CONFIG_ENC4_FILTPER,
.in_filt_cnt = CONFIG_ENC4_FILTCNT,
.init_flags = CONFIG_ENC4_HIP << HIP_SHIFT | CONFIG_ENC4_HNE << HNE_SHIFT |
CONFIG_ENC4_XIP << XIP_SHIFT | CONFIG_ENC4_XNE << XNE_SHIFT |
CONFIG_ENC4_DIR << REV_SHIFT | CONFIG_ENC4_MOD << MOD_SHIFT,
.init_flags = CONFIG_ENC4_HIP << HIP_SHIFT |
CONFIG_ENC4_HNE << HNE_SHIFT |
CONFIG_ENC4_XIP << XIP_SHIFT |
CONFIG_ENC4_XNE << XNE_SHIFT |
CONFIG_ENC4_DIR << REV_SHIFT |
CONFIG_ENC4_MOD << MOD_SHIFT,
#ifdef CONFIG_DEBUG_SENSORS
.tst_dir_adv = CONFIG_ENC4_TST_DIR,
@ -570,9 +591,9 @@ void imxrt_enc_clock_disable (uint32_t base)
*
****************************************************************************/
static inline void imxrt_enc_sem_wait(FAR struct imxrt_enc_lowerhalf_s *priv)
static inline int imxrt_enc_sem_wait(FAR struct imxrt_enc_lowerhalf_s *priv)
{
nxsem_wait_uninterruptible(&priv->sem_excl);
return nxsem_wait_uninterruptible(&priv->sem_excl);
}
/****************************************************************************
@ -755,8 +776,8 @@ static void imxrt_enc_modulo_disable(FAR struct imxrt_enc_lowerhalf_s *priv)
*
* Input Parameters:
* priv - A reference to the IMXRT enc lowerhalf structure
* value - Bit encoded variable to indicate how many pulse advances to generate
* and which direction to generate them.
* value - Bit encoded variable to indicate how many pulse advances to
* generate and which direction to generate them.
* Bits 15-9: Reserved.
* Bit 8: QDN. Generate negative/ positive advances.
* Bits 7-0: TEST_COUNT. Number of advances to generate.
@ -808,21 +829,25 @@ static int imxrt_enc_test_gen(FAR struct imxrt_enc_lowerhalf_s *priv,
static int imxrt_setup(FAR struct qe_lowerhalf_s *lower)
{
FAR struct imxrt_enc_lowerhalf_s *priv =
(FAR struct imxrt_enc_lowerhalf_s *)lower;
(FAR struct imxrt_enc_lowerhalf_s *)lower;
FAR const struct imxrt_qeconfig_s *config = priv->config;
uint32_t regval;
int ret;
ret = imxrt_enc_sem_wait(priv);
if (ret < 0)
{
return ret;
}
/* Ungate the clock */
imxrt_enc_clock_enable(config->base);
/* Initialize the registers */
imxrt_enc_sem_wait(priv);
/* Initial value registers */
imxrt_enc_putreg16(priv, IMXRT_ENC_LINIT_OFFSET, config->init_val & 0xffff);
imxrt_enc_putreg16(priv, IMXRT_ENC_LINIT_OFFSET,
config->init_val & 0xffff);
imxrt_enc_putreg16(priv, IMXRT_ENC_UINIT_OFFSET,
(config->init_val >> 16) & 0xffff);
@ -843,7 +868,8 @@ static int imxrt_setup(FAR struct qe_lowerhalf_s *lower)
#ifdef CONFIG_DEBUG_SENSORS
regval = ENC_TST_TCE | ENC_TST_TEN;
regval |= config->tst_dir_adv ? ENC_TST_QDN : 0;
regval |= (config->tst_period & ENC_TST_PERIOD_MASK) << ENC_TST_PERIOD_SHIFT;
regval |= (config->tst_period & ENC_TST_PERIOD_MASK) <<
ENC_TST_PERIOD_SHIFT;
imxrt_enc_putreg16(priv, IMXRT_ENC_TST_OFFSET, regval);
#endif
@ -876,11 +902,17 @@ static int imxrt_setup(FAR struct qe_lowerhalf_s *lower)
static int imxrt_shutdown(FAR struct qe_lowerhalf_s *lower)
{
FAR struct imxrt_enc_lowerhalf_s *priv = (FAR struct imxrt_enc_lowerhalf_s *)lower;
FAR struct imxrt_enc_lowerhalf_s *priv =
(FAR struct imxrt_enc_lowerhalf_s *)lower;
int ret;
/* Ensure any in-progress operations are done. */
imxrt_enc_sem_wait(priv);
ret = imxrt_enc_sem_wait(priv);
if (ret < 0)
{
return ret;
}
#ifdef CONFIG_DEBUG_SENSORS
imxrt_enc_putreg16(priv, IMXRT_ENC_TST_OFFSET, 0);
@ -914,26 +946,35 @@ static int imxrt_shutdown(FAR struct qe_lowerhalf_s *lower)
static int imxrt_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos)
{
FAR struct imxrt_enc_lowerhalf_s *priv = (FAR struct imxrt_enc_lowerhalf_s *)lower;
FAR struct imxrt_enc_lowerhalf_s *priv =
(FAR struct imxrt_enc_lowerhalf_s *)lower;
uint16_t lpos;
uint16_t upos;
int i;
int ret;
ret = imxrt_enc_sem_wait(priv);
if (ret < 0)
{
return ret;
}
imxrt_enc_sem_wait(priv);
lpos = imxrt_enc_getreg16(priv, IMXRT_ENC_LPOS_OFFSET);
/**********************************************************************************
* When a position register is read, it triggers a snapshot into the position hold
* registers.
/**************************************************************************
* When a position register is read, it triggers a snapshot into the
* position hold registers.
*
* If the core clock is faster than the peripheral clock, we might need to
* wait until the snapshot registers latch properly. There is no interrupt to
* signal that the snapshot is done, so we have to poll LPOSH until it equals our
* reading. We will poll for at most, 2 peripheral clock cycles. Since IPG_PODF max
* is 4, at most we'll poll 8 core clock cycles.
**********************************************************************************/
* wait until the snapshot registers latch properly. There is no interrupt
* to signal that the snapshot is done, so we have to poll LPOSH until it
* equals our reading. We will poll for at most, 2 peripheral clock cycles.
* Since IPG_PODF max is 4, at most we'll poll 8 core clock cycles.
**************************************************************************/
for (i = 8; lpos != imxrt_enc_getreg16(priv, IMXRT_ENC_LPOSH_OFFSET) && i > 0; i--)
for (i = 8;
lpos != imxrt_enc_getreg16(priv, IMXRT_ENC_LPOSH_OFFSET) && i > 0;
i--)
{
}
@ -961,11 +1002,18 @@ static int imxrt_position(FAR struct qe_lowerhalf_s *lower, FAR int32_t *pos)
static int imxrt_reset(FAR struct qe_lowerhalf_s *lower)
{
FAR struct imxrt_enc_lowerhalf_s *priv = (FAR struct imxrt_enc_lowerhalf_s *)lower;
FAR struct imxrt_enc_lowerhalf_s *priv =
(FAR struct imxrt_enc_lowerhalf_s *)lower;
int ret;
/* Write a 1 to the SWIP bit to load UINIT and LINIT into UPOS and LPOS */
imxrt_enc_sem_wait(priv);
ret = imxrt_enc_sem_wait(priv);
if (ret < 0)
{
return ret;
}
imxrt_enc_modifyreg16(priv, IMXRT_ENC_CTRL_OFFSET, 0, ENC_CTRL_SWIP);
imxrt_enc_sem_post(priv);
@ -1029,12 +1077,13 @@ static int imxrt_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd,
* Name: imxrt_qeinitialize
*
* Description:
* Initialize a quadrature encoder interface. This function must be called from
* board-specific logic..
* Initialize a quadrature encoder interface. This function must be called
* from board-specific logic..
*
* Input Parameters:
* devpath - The full path to the driver to register. E.g., "/dev/qe0"
* enc - The encoder peripheral to use. 'enc' must be an element of {1,2,3,4}
* enc - The encoder peripheral to use. 'enc' must be an element of
* {1,2,3,4}
*
* Returned Value:
* Zero on success; A negated errno value is returned on failure.

View File

@ -181,10 +181,10 @@ static void sai_dump_regs(struct stm32l4_sai_s *priv, const char *msg);
/* Semaphore helpers */
static void sai_exclsem_take(struct stm32l4_sai_s *priv);
static int sai_exclsem_take(struct stm32l4_sai_s *priv);
#define sai_exclsem_give(priv) nxsem_post(&priv->exclsem)
static void sai_bufsem_take(struct stm32l4_sai_s *priv);
static int sai_bufsem_take(struct stm32l4_sai_s *priv);
#define sai_bufsem_give(priv) nxsem_post(&priv->bufsem)
/* Buffer container helpers */
@ -380,7 +380,7 @@ static inline void sai_putreg(struct stm32l4_sai_s *priv, uint8_t offset,
putreg32(value, priv->base + offset);
}
/************************************************************************************
/****************************************************************************
* Name: sai_modifyreg
*
* Description:
@ -395,7 +395,7 @@ static inline void sai_putreg(struct stm32l4_sai_s *priv, uint8_t offset,
* Returned Value:
* None
*
************************************************************************************/
****************************************************************************/
static void sai_modifyreg(struct stm32l4_sai_s *priv, uint8_t offset,
uint32_t clrbits, uint32_t setbits)
@ -451,21 +451,21 @@ static void sai_dump_regs(struct stm32l4_sai_s *priv, const char *msg)
* priv - A reference to the SAI peripheral state
*
* Returned Value:
* None
* OK on success; a negated errno value on failure
*
****************************************************************************/
static void sai_exclsem_take(struct stm32l4_sai_s *priv)
static int sai_exclsem_take(struct stm32l4_sai_s *priv)
{
nxsem_wait_uninterruptible(&priv->exclsem);
return nxsem_wait_uninterruptible(&priv->exclsem);
}
/****************************************************************************
* Name: sai_mckdivider
*
* Description:
* Setup the master clock divider based on the currently selected data width
* and the sample rate
* Setup the master clock divider based on the currently selected data
* width and the sample rate
*
* Input Parameters:
* priv - SAI device structure (only the sample rate and frequency are
@ -979,7 +979,12 @@ static int sai_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
/* Get exclusive access to the SAI driver data */
sai_exclsem_take(priv);
ret = sai_exclsem_take(priv);
if (ret < 0)
{
sai_buf_free(priv, bfcontainer);
return ret;
}
/* Verify not already TX'ing */
@ -1011,8 +1016,8 @@ static int sai_receive(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
flags = enter_critical_section();
sq_addlast((sq_entry_t *)bfcontainer, &priv->pend);
/* Then start the next transfer. If there is already a transfer in progress,
* then this will do nothing.
/* Then start the next transfer. If there is already a transfer in
* progress, then this will do nothing.
*/
#ifdef CONFIG_STM32L4_SAI_DMA
@ -1079,7 +1084,12 @@ static int sai_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
/* Get exclusive access to the SAI driver data */
sai_exclsem_take(priv);
ret = sai_exclsem_take(priv);
if (ret < 0)
{
sai_buf_free(priv, bfcontainer);
return ret;
}
/* Verify not already RX'ing */
@ -1111,8 +1121,8 @@ static int sai_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
flags = enter_critical_section();
sq_addlast((sq_entry_t *)bfcontainer, &priv->pend);
/* Then start the next transfer. If there is already a transfer in progress,
* then this will do nothing.
/* Then start the next transfer. If there is already a transfer in
* progress, then this will do nothing.
*/
#ifdef CONFIG_STM32L4_SAI_DMA
@ -1139,13 +1149,13 @@ errout_with_exclsem:
* priv - A reference to the SAI peripheral state
*
* Returned Value:
* None
* OK on success; a negated errno value on failure
*
****************************************************************************/
static void sai_bufsem_take(struct stm32l4_sai_s *priv)
static int sai_bufsem_take(struct stm32l4_sai_s *priv)
{
nxsem_wait_uninterruptible(&priv->bufsem);
return nxsem_wait_uninterruptible(&priv->bufsem);
}
/****************************************************************************
@ -1172,12 +1182,17 @@ static struct sai_buffer_s *sai_buf_allocate(struct stm32l4_sai_s *priv)
{
struct sai_buffer_s *bfcontainer;
irqstate_t flags;
int ret;
/* Set aside a buffer container. By doing this, we guarantee that we will
* have at least one free buffer container.
*/
sai_bufsem_take(priv);
ret = sai_bufsem_take(priv);
if (ret < 0)
{
return ret;
}
/* Get the buffer from the head of the free list */
@ -1210,7 +1225,8 @@ static struct sai_buffer_s *sai_buf_allocate(struct stm32l4_sai_s *priv)
*
****************************************************************************/
static void sai_buf_free(struct stm32l4_sai_s *priv, struct sai_buffer_s *bfcontainer)
static void sai_buf_free(struct stm32l4_sai_s *priv,
struct sai_buffer_s *bfcontainer)
{
irqstate_t flags;
@ -1293,7 +1309,8 @@ static void sai_portinitialize(struct stm32l4_sai_s *priv)
/* Configure the data width */
sai_datawidth((struct i2s_dev_s *)priv, CONFIG_STM32L4_SAI_DEFAULT_DATALEN);
sai_datawidth((struct i2s_dev_s *)priv,
CONFIG_STM32L4_SAI_DEFAULT_DATALEN);
#ifdef CONFIG_STM32L4_SAI_DMA
/* Get DMA channel */
@ -1304,17 +1321,21 @@ static void sai_portinitialize(struct stm32l4_sai_s *priv)
sai_modifyreg(priv, STM32L4_SAI_CR1_OFFSET, 0, SAI_CR1_DMAEN);
#endif
sai_modifyreg(priv, STM32L4_SAI_CR1_OFFSET, SAI_CR1_SYNCEN_MASK, priv->syncen);
sai_modifyreg(priv, STM32L4_SAI_CR1_OFFSET, SAI_CR1_SYNCEN_MASK,
priv->syncen);
sai_modifyreg(priv, STM32L4_SAI_CR2_OFFSET, SAI_CR2_FTH_MASK, SAI_CR2_FTH_1QF);
sai_modifyreg(priv, STM32L4_SAI_CR2_OFFSET, SAI_CR2_FTH_MASK,
SAI_CR2_FTH_1QF);
sai_modifyreg(priv, STM32L4_SAI_FRCR_OFFSET,
SAI_FRCR_FSDEF | SAI_FRCR_FSPOL | SAI_FRCR_FSOFF,
SAI_FRCR_FSDEF_CHID | SAI_FRCR_FSPOL_LOW | SAI_FRCR_FSOFF_BFB);
SAI_FRCR_FSDEF_CHID | SAI_FRCR_FSPOL_LOW |
SAI_FRCR_FSOFF_BFB);
sai_modifyreg(priv, STM32L4_SAI_SLOTR_OFFSET,
SAI_SLOTR_NBSLOT_MASK | SAI_SLOTR_SLOTEN_MASK,
SAI_SLOTR_NBSLOT(2) | SAI_SLOTR_SLOTEN_0 | SAI_SLOTR_SLOTEN_1);
SAI_SLOTR_NBSLOT(2) | SAI_SLOTR_SLOTEN_0 |
SAI_SLOTR_SLOTEN_1);
sai_dump_regs(priv, "After initialization");
}
@ -1360,6 +1381,7 @@ struct i2s_dev_s *stm32l4_sai_initialize(int intf)
# endif
break;
}
#endif
#ifdef CONFIG_STM32L4_SAI1_B
case SAI1_BLOCK_B:
@ -1375,6 +1397,7 @@ struct i2s_dev_s *stm32l4_sai_initialize(int intf)
# endif
break;
}
#endif
#ifdef CONFIG_STM32L4_SAI2_A
case SAI2_BLOCK_A:
@ -1390,6 +1413,7 @@ struct i2s_dev_s *stm32l4_sai_initialize(int intf)
# endif
break;
}
#endif
#ifdef CONFIG_STM32L4_SAI2_B
case SAI2_BLOCK_B:
@ -1405,6 +1429,7 @@ struct i2s_dev_s *stm32l4_sai_initialize(int intf)
# endif
break;
}
#endif
default:
{