Commit 2c6554bc6bc4fc3e0d821fbfc76f09c39048fa82
1 parent
5cea8590
Implement multiple samplers on stellaris ADC
Signed-off-by: Paul Brook <paul@codesourcery.com>
Showing
1 changed file
with
31 additions
and
19 deletions
hw/stellaris.c
@@ -921,7 +921,7 @@ typedef struct | @@ -921,7 +921,7 @@ typedef struct | ||
921 | uint32_t ssmux[4]; | 921 | uint32_t ssmux[4]; |
922 | uint32_t ssctl[4]; | 922 | uint32_t ssctl[4]; |
923 | uint32_t noise; | 923 | uint32_t noise; |
924 | - qemu_irq irq; | 924 | + qemu_irq irq[4]; |
925 | } stellaris_adc_state; | 925 | } stellaris_adc_state; |
926 | 926 | ||
927 | static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n) | 927 | 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, | ||
945 | { | 945 | { |
946 | int head; | 946 | int head; |
947 | 947 | ||
948 | + /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry | ||
949 | + FIFO fir each sequencer. */ | ||
948 | head = (s->fifo[n].state >> 4) & 0xf; | 950 | head = (s->fifo[n].state >> 4) & 0xf; |
949 | if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) { | 951 | if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) { |
950 | s->ostat |= 1 << n; | 952 | 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, | ||
961 | static void stellaris_adc_update(stellaris_adc_state *s) | 963 | static void stellaris_adc_update(stellaris_adc_state *s) |
962 | { | 964 | { |
963 | int level; | 965 | int level; |
966 | + int n; | ||
964 | 967 | ||
965 | - level = (s->ris & s->im) != 0; | ||
966 | - qemu_set_irq(s->irq, level); | 968 | + for (n = 0; n < 4; n++) { |
969 | + level = (s->ris & s->im & (1 << n)) != 0; | ||
970 | + qemu_set_irq(s->irq[n], level); | ||
971 | + } | ||
967 | } | 972 | } |
968 | 973 | ||
969 | static void stellaris_adc_trigger(void *opaque, int irq, int level) | 974 | static void stellaris_adc_trigger(void *opaque, int irq, int level) |
970 | { | 975 | { |
971 | stellaris_adc_state *s = (stellaris_adc_state *)opaque; | 976 | stellaris_adc_state *s = (stellaris_adc_state *)opaque; |
977 | + int n; | ||
972 | 978 | ||
973 | - if ((s->actss & 1) == 0) { | ||
974 | - return; | ||
975 | - } | 979 | + for (n = 0; n < 4; n++) { |
980 | + if ((s->actss & (1 << n)) == 0) { | ||
981 | + continue; | ||
982 | + } | ||
976 | 983 | ||
977 | - /* Some applications use the ADC as a random number source, so introduce | ||
978 | - some variation into the signal. */ | ||
979 | - s->noise = s->noise * 314159 + 1; | ||
980 | - /* ??? actual inputs not implemented. Return an arbitrary value. */ | ||
981 | - stellaris_adc_fifo_write(s, 0, 0x200 + ((s->noise >> 16) & 7)); | ||
982 | - s->ris |= 1; | ||
983 | - stellaris_adc_update(s); | 984 | + if (((s->emux >> (n * 4)) & 0xff) != 5) { |
985 | + continue; | ||
986 | + } | ||
987 | + | ||
988 | + /* Some applications use the ADC as a random number source, so introduce | ||
989 | + some variation into the signal. */ | ||
990 | + s->noise = s->noise * 314159 + 1; | ||
991 | + /* ??? actual inputs not implemented. Return an arbitrary value. */ | ||
992 | + stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7)); | ||
993 | + s->ris |= (1 << n); | ||
994 | + stellaris_adc_update(s); | ||
995 | + } | ||
984 | } | 996 | } |
985 | 997 | ||
986 | static void stellaris_adc_reset(stellaris_adc_state *s) | 998 | 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, | ||
1068 | switch (offset) { | 1080 | switch (offset) { |
1069 | case 0x00: /* ACTSS */ | 1081 | case 0x00: /* ACTSS */ |
1070 | s->actss = value & 0xf; | 1082 | s->actss = value & 0xf; |
1071 | - if (value & 0xe) { | ||
1072 | - hw_error("Not implemented: ADC sequencers 1-3\n"); | ||
1073 | - } | ||
1074 | break; | 1083 | break; |
1075 | case 0x08: /* IM */ | 1084 | case 0x08: /* IM */ |
1076 | s->im = value; | 1085 | 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) | ||
1169 | return 0; | 1178 | return 0; |
1170 | } | 1179 | } |
1171 | 1180 | ||
1172 | -static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq) | 1181 | +static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq *irq) |
1173 | { | 1182 | { |
1174 | stellaris_adc_state *s; | 1183 | stellaris_adc_state *s; |
1175 | int iomemtype; | 1184 | int iomemtype; |
1176 | qemu_irq *qi; | 1185 | qemu_irq *qi; |
1186 | + int n; | ||
1177 | 1187 | ||
1178 | s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state)); | 1188 | s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state)); |
1179 | - s->irq = irq; | 1189 | + for (n = 0; n < 4; n++) { |
1190 | + s->irq[n] = irq[n]; | ||
1191 | + } | ||
1180 | 1192 | ||
1181 | iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, | 1193 | iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, |
1182 | stellaris_adc_writefn, s); | 1194 | 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, | ||
1295 | pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); | 1307 | pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); |
1296 | 1308 | ||
1297 | if (board->dc1 & (1 << 16)) { | 1309 | if (board->dc1 & (1 << 16)) { |
1298 | - adc = stellaris_adc_init(0x40038000, pic[14]); | 1310 | + adc = stellaris_adc_init(0x40038000, pic + 14); |
1299 | } else { | 1311 | } else { |
1300 | adc = NULL; | 1312 | adc = NULL; |
1301 | } | 1313 | } |