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:
parent
5d123098b8
commit
dda47dd4a9
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user