1.适配标准CONFIG命令。

This commit is contained in:
MacRsh
2023-12-10 16:21:48 +08:00
parent ebf0fbe990
commit c86764f478
6 changed files with 236 additions and 100 deletions

View File

@@ -10,6 +10,45 @@
#ifdef MR_USING_ADC
static int adc_channel_set_state(struct mr_adc *adc, int channel, int state)
{
struct mr_adc_ops *ops = (struct mr_adc_ops *)adc->dev.drv->ops;
/* Check channel is valid */
if (channel < 0 || channel >= 32)
{
return MR_EINVAL;
}
/* Configure the channel */
int ret = ops->channel_configure(adc, channel, state);
if (ret != MR_EOK)
{
return ret;
}
/* Enable or disable the channel */
if (state == MR_ADC_STATE_ENABLE)
{
mr_bits_set(adc->channel, (1 << channel));
} else
{
mr_bits_clr(adc->channel, (1 << channel));
}
return MR_EOK;
}
static int adc_channel_get_state(struct mr_adc *adc, int channel)
{
/* Check channel is valid */
if (channel < 0 || channel >= 32)
{
return MR_EINVAL;
}
return mr_bits_is_set(adc->channel, (1 << channel));
}
static int mr_adc_open(struct mr_dev *dev)
{
struct mr_adc *adc = (struct mr_adc *)dev;
@@ -66,52 +105,54 @@ static int mr_adc_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
switch (cmd)
{
case MR_CTL_ADC_SET_CONFIG:
{
if (args != MR_NULL)
{
struct mr_adc_config config = *((struct mr_adc_config *)args);
return adc_channel_set_state(adc, off, config.channel_state);
}
return MR_EINVAL;
}
case MR_CTL_ADC_SET_CHANNEL_STATE:
{
if (args != MR_NULL)
{
int state = *((int *)args);
/* Check offset is valid */
if (off < 0 || off >= 32)
{
return MR_EINVAL;
}
/* Check if the channel is enabled */
if (state != mr_bits_is_set(adc->channel, (1 << off)))
{
int ret = ops->channel_configure(adc, off, state);
if (ret == MR_EOK)
{
if (state == MR_ADC_STATE_ENABLE)
{
mr_bits_set(adc->channel, (1 << off));
} else
{
mr_bits_clr(adc->channel, (1 << off));
}
}
return ret;
}
return MR_EOK;
return adc_channel_set_state(adc, off, state);
}
return MR_EINVAL;
}
case MR_CTL_ADC_GET_CONFIG:
{
if (args != MR_NULL)
{
struct mr_adc_config *config = (struct mr_adc_config *)args;
int ret = adc_channel_get_state(adc, off);
if (ret < 0)
{
return ret;
}
config->channel_state = ret;
return MR_EOK;
}
}
case MR_CTL_ADC_GET_CHANNEL_STATE:
{
if (args != MR_NULL)
{
int *state = (int *)args;
/* Check offset is valid */
if (off < 0 || off >= 32)
int ret = adc_channel_get_state(adc, off);
if (ret < 0)
{
return MR_EINVAL;
return ret;
}
*state = mr_bits_is_set(adc->channel, (1 << off));
*state = ret;
return MR_EOK;
}
return MR_EINVAL;

View File

@@ -10,6 +10,45 @@
#ifdef MR_USING_DAC
static int dac_channel_set_state(struct mr_dac *dac, int channel, int state)
{
struct mr_dac_ops *ops = (struct mr_dac_ops *)dac->dev.drv->ops;
/* Check channel is valid */
if (channel < 0 || channel >= 32)
{
return MR_EINVAL;
}
/* Configure the channel */
int ret = ops->channel_configure(dac, channel, state);
if (ret != MR_EOK)
{
return ret;
}
/* Enable or disable the channel */
if (state == MR_DAC_STATE_ENABLE)
{
mr_bits_set(dac->channel, (1 << channel));
} else
{
mr_bits_clr(dac->channel, (1 << channel));
}
return MR_EOK;
}
static int dac_channel_get_state(struct mr_dac *dac, int channel)
{
/* Check channel is valid */
if (channel < 0 || channel >= 32)
{
return MR_EINVAL;
}
return mr_bits_is_set(dac->channel, (1 << channel));
}
static int mr_dac_open(struct mr_dev *dev)
{
struct mr_dac *dac = (struct mr_dac *)dev;
@@ -66,47 +105,54 @@ static int mr_dac_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
switch (cmd)
{
case MR_CTL_DAC_SET_CONFIG:
{
if (args != MR_NULL)
{
struct mr_dac_config config = *((struct mr_dac_config *)args);
return dac_channel_set_state(dac, off, config.channel_state);
}
return MR_EINVAL;
}
case MR_CTL_DAC_SET_CHANNEL_STATE:
{
if (args != MR_NULL)
{
int state = *((int *)args);
/* Check offset is valid */
if (off < 0 || off >= 32)
{
return MR_EINVAL;
}
int ret = ops->channel_configure(dac, off, state);
if (ret == MR_EOK)
{
if (state == MR_DAC_STATE_ENABLE)
{
mr_bits_set(dac->channel, (1 << off));
} else
{
mr_bits_clr(dac->channel, (1 << off));
}
}
return ret;
return dac_channel_set_state(dac, off, state);
}
return MR_EINVAL;
}
case MR_CTL_DAC_GET_CONFIG:
{
if (args != MR_NULL)
{
struct mr_dac_config *config = (struct mr_dac_config *)args;
int ret = dac_channel_get_state(dac, off);
if (ret < 0)
{
return ret;
}
config->channel_state = ret;
return MR_EOK;
}
}
case MR_CTL_DAC_GET_CHANNEL_STATE:
{
if (args != MR_NULL)
{
int *state = (int *)args;
/* Check offset is valid */
if (off < 0 || off >= 32)
int ret = dac_channel_get_state(dac, off);
if (ret < 0)
{
return MR_EINVAL;
return ret;
}
*state = mr_bits_is_set(dac->channel, (1 << off));
*state = ret;
return MR_EOK;
}
return MR_EINVAL;

View File

@@ -18,6 +18,61 @@ struct pin_irq
int (*call)(int desc, void *args);
};
static int pin_set_mode(struct mr_pin *pin, int number, int mode)
{
struct mr_pin_ops *ops = (struct mr_pin_ops *)pin->dev.drv->ops;
/* Check number is valid */
if (number < 0)
{
return MR_EINVAL;
}
/* Configure pin mode */
int ret = ops->configure(pin, number, mode);
if (ret != MR_EOK)
{
return ret;
}
/* If the irq exists, update it */
struct mr_list *list = MR_NULL;
for (list = pin->irq_list.next; list != &pin->irq_list; list = list->next)
{
struct pin_irq *irq = (struct pin_irq *)mr_container_of(list, struct pin_irq, list);
if (irq->number == number)
{
if (mode < MR_PIN_MODE_IRQ_RISING)
{
/* Remove irq */
mr_list_remove(list);
mr_free(irq);
} else
{
/* Update irq */
irq->desc = pin->dev.rd_call.desc;
irq->call = pin->dev.rd_call.call;
}
return MR_EOK;
}
}
/* If not exist, allocate new irq */
if (mode >= MR_PIN_MODE_IRQ_RISING)
{
struct pin_irq *irq = (struct pin_irq *)mr_malloc(sizeof(struct pin_irq));
if (irq != MR_NULL)
{
mr_list_init(&irq->list);
irq->number = number;
irq->desc = pin->dev.rd_call.desc;
irq->call = pin->dev.rd_call.call;
mr_list_insert_before(&pin->irq_list, &irq->list);
}
}
return MR_EOK;
}
static ssize_t mr_pin_read(struct mr_dev *dev, int off, void *buf, size_t size, int async)
{
struct mr_pin *pin = (struct mr_pin *)dev;
@@ -67,61 +122,23 @@ static int mr_pin_ioctl(struct mr_dev *dev, int off, int cmd, void *args)
switch (cmd)
{
case MR_CTL_PIN_SET_CONFIG:
{
if (args != MR_NULL)
{
struct mr_pin_config config = *((struct mr_pin_config *)args);
return pin_set_mode(pin, off, config.mode);
}
return MR_EINVAL;
}
case MR_CTL_PIN_SET_MODE:
{
if (args != MR_NULL)
{
int mode = *((int *)args);
/* Check offset is valid */
if (off < 0)
{
return MR_EINVAL;
}
/* Configure pin mode */
int ret = ops->configure(pin, off, mode);
if (ret != MR_EOK)
{
return ret;
}
/* If the irq exists, update it */
struct mr_list *list = MR_NULL;
for (list = pin->irq_list.next; list != &pin->irq_list; list = list->next)
{
struct pin_irq *irq = (struct pin_irq *)mr_container_of(list, struct pin_irq, list);
if (irq->number == off)
{
if (mode < MR_PIN_MODE_IRQ_RISING)
{
/* Remove irq */
mr_list_remove(list);
mr_free(irq);
} else
{
/* Update irq */
irq->desc = pin->dev.rd_call.desc;
irq->call = pin->dev.rd_call.call;
}
return MR_EOK;
}
}
/* If not exist, allocate new irq */
if (mode >= MR_PIN_MODE_IRQ_RISING)
{
struct pin_irq *irq = (struct pin_irq *)mr_malloc(sizeof(struct pin_irq));
if (irq != MR_NULL)
{
mr_list_init(&irq->list);
irq->number = off;
irq->desc = dev->rd_call.desc;
irq->call = dev->rd_call.call;
mr_list_insert_before(&pin->irq_list, &irq->list);
}
}
return MR_EOK;
return pin_set_mode(pin, off, mode);
}
return MR_EINVAL;
}