You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

117 lines
2.8 KiB

/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2018
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <samx70.h>
#include <afec.h>
#include <pio/samx70.h>
#include <ioport.h>
#include <controller/controller_block.h>
#include <log/log.h>
struct controller_block_private {
float value;
uint32_t afecnr;
uint32_t channel;
float factor;
};
static void afec_calculate(struct controller_block *afec)
{
struct controller_block_private *priv = afec->private;
int16_t data = afec_read_conversion_data(priv->afecnr, priv->channel);
float value = data * priv->factor;
priv->value = value;
}
static struct controller_block_outterm_list outterms[] = {
{ "value", CONTROLLER_BLOCK_TERM_FLOAT, offsetof(struct controller_block_private, value) },
{ NULL },
};
static struct controller_block * block_atsamx70_afec_create(char *name, int argc, va_list ap)
{
struct controller_block *afec;
int afec_nr;
afec_nr = va_arg(ap, int);
if (afec_nr < 0 || afec_nr > 1) {
log_send(LOG_T_ERROR, "%s: afec%d is not valid. (valid: 0-1)",
name, afec_nr);
return NULL;
}
if (!(afec = controller_block_alloc("atsamx70_afec", name, sizeof(struct controller_block_private))))
goto err_alloc;
if (controller_block_outterm_list_init(afec, outterms))
goto err_outterm;
afec->calculate = afec_calculate;
uint32_t pin;
switch (afec_nr) {
case 0:
afec->private->afecnr = AFEC0;
afec->private->channel = 0;
pin = PIO_PD30_IDX;
break;
case 1:
afec->private->afecnr = AFEC1;
afec->private->channel = 1;
pin = PIO_PC13_IDX;
break;
}
afec->private->factor = 1.0 / 2048.0;
ioport_init();
ioport_disable_pin(pin);
afec_init(afec->private->afecnr,
AFEC_MR_FREERUN | AFEC_MR_PRESCAL((sysclk_get_peripheral_hz()+AFEC_FMAX-1)/AFEC_FMAX),
AFEC_EMR_RES_16 | AFEC_EMR_STM_SINGLE | AFEC_EMR_SIGNMODE_SIGNED);
afec_channel_set_offset(afec->private->afecnr, 0, (AFEC_ACR_AOFF_MAX+1)/2);
afec_channel_set_gain(afec->private->afecnr, 0, 0); // set gain to 1 (value 0)
afec_channel_enable(afec->private->afecnr, afec_nr);
if (controller_block_add(afec))
goto err_add;
return afec;
err_add:
err_outterm:
controller_block_free(afec);
err_alloc:
return NULL;
}
BLOCK_CREATE(atsamx70_afec) = {
.create = block_atsamx70_afec_create,
.args = { "int", NULL },
};