Commit 2c6554bc6bc4fc3e0d821fbfc76f09c39048fa82

Authored by Paul Brook
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 }