提交 2c6554bc 编写于 作者: P Paul Brook

Implement multiple samplers on stellaris ADC

Signed-off-by: NPaul Brook <paul@codesourcery.com>
上级 5cea8590
...@@ -921,7 +921,7 @@ typedef struct ...@@ -921,7 +921,7 @@ typedef struct
uint32_t ssmux[4]; uint32_t ssmux[4];
uint32_t ssctl[4]; uint32_t ssctl[4];
uint32_t noise; uint32_t noise;
qemu_irq irq; qemu_irq irq[4];
} stellaris_adc_state; } stellaris_adc_state;
static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n) static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
...@@ -945,6 +945,8 @@ static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n, ...@@ -945,6 +945,8 @@ static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
{ {
int head; int head;
/* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
FIFO fir each sequencer. */
head = (s->fifo[n].state >> 4) & 0xf; head = (s->fifo[n].state >> 4) & 0xf;
if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) { if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
s->ostat |= 1 << n; s->ostat |= 1 << n;
...@@ -961,26 +963,36 @@ static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n, ...@@ -961,26 +963,36 @@ static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
static void stellaris_adc_update(stellaris_adc_state *s) static void stellaris_adc_update(stellaris_adc_state *s)
{ {
int level; int level;
int n;
level = (s->ris & s->im) != 0; for (n = 0; n < 4; n++) {
qemu_set_irq(s->irq, level); level = (s->ris & s->im & (1 << n)) != 0;
qemu_set_irq(s->irq[n], level);
}
} }
static void stellaris_adc_trigger(void *opaque, int irq, int level) static void stellaris_adc_trigger(void *opaque, int irq, int level)
{ {
stellaris_adc_state *s = (stellaris_adc_state *)opaque; stellaris_adc_state *s = (stellaris_adc_state *)opaque;
int n;
if ((s->actss & 1) == 0) { for (n = 0; n < 4; n++) {
return; if ((s->actss & (1 << n)) == 0) {
} continue;
}
/* Some applications use the ADC as a random number source, so introduce if (((s->emux >> (n * 4)) & 0xff) != 5) {
some variation into the signal. */ continue;
s->noise = s->noise * 314159 + 1; }
/* ??? actual inputs not implemented. Return an arbitrary value. */
stellaris_adc_fifo_write(s, 0, 0x200 + ((s->noise >> 16) & 7)); /* Some applications use the ADC as a random number source, so introduce
s->ris |= 1; some variation into the signal. */
stellaris_adc_update(s); s->noise = s->noise * 314159 + 1;
/* ??? actual inputs not implemented. Return an arbitrary value. */
stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
s->ris |= (1 << n);
stellaris_adc_update(s);
}
} }
static void stellaris_adc_reset(stellaris_adc_state *s) static void stellaris_adc_reset(stellaris_adc_state *s)
...@@ -1068,9 +1080,6 @@ static void stellaris_adc_write(void *opaque, target_phys_addr_t offset, ...@@ -1068,9 +1080,6 @@ static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
switch (offset) { switch (offset) {
case 0x00: /* ACTSS */ case 0x00: /* ACTSS */
s->actss = value & 0xf; s->actss = value & 0xf;
if (value & 0xe) {
hw_error("Not implemented: ADC sequencers 1-3\n");
}
break; break;
case 0x08: /* IM */ case 0x08: /* IM */
s->im = value; s->im = value;
...@@ -1169,14 +1178,17 @@ static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) ...@@ -1169,14 +1178,17 @@ static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq) static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq *irq)
{ {
stellaris_adc_state *s; stellaris_adc_state *s;
int iomemtype; int iomemtype;
qemu_irq *qi; qemu_irq *qi;
int n;
s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state)); s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state));
s->irq = irq; for (n = 0; n < 4; n++) {
s->irq[n] = irq[n];
}
iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn,
stellaris_adc_writefn, s); stellaris_adc_writefn, s);
...@@ -1295,7 +1307,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, ...@@ -1295,7 +1307,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
if (board->dc1 & (1 << 16)) { if (board->dc1 & (1 << 16)) {
adc = stellaris_adc_init(0x40038000, pic[14]); adc = stellaris_adc_init(0x40038000, pic + 14);
} else { } else {
adc = NULL; adc = NULL;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册