MMA655x Beschleunigungssensoren ansprechen

  • 1
  • 2
  • Page 1 of 2
Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 526
Registered: 02 / 2007
Subject:

MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 08.12.2013 - 16:24  ·  #1
Hallo allerseits,

ich versuche seit einiger Zeit einen G-Sensor von Freescale, der Typ ist "MMA6555" anzusprechen, leider ohne Erfolg.
Beide Muster die ich hier habe reagieren nicht auf SPI-Kommandos, andere Geräte am selben Setup sprechen an, am Board oder der Software liegt es also wohl nicht.
Angeschlossen sind sie auch korrekt.

Das Datenblatt ist ziemlich karg und beschreibt die Kommunikation nicht besonders gut, ich vermute, ich muss das Teil irgendwie freischalten, nur wie?
Hat jemand zufällig schon einmal so einen Typ programmiert und kann mir einen Tipp geben?

Mich wunderts, dass da gar nichts raus kommt, MISO bleibt auf 0.

Louis
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 08.12.2013 - 20:57  ·  #2
Hallo Louis,

SPI Mode korrekt eingestellt ?

rolf
Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 526
Registered: 02 / 2007
Subject:

Re: MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 09.12.2013 - 11:40  ·  #3
Ja, ich habe alles 10x gecheckt. Alle Parameter stimmen, die Pins des Sensors haben alle Spannungen die sie haben müssen, die interna scheinen also zu arbeiten. Aber alle Versuche da überhaupt über SPI eine Reaktion zu erhalten sind gescheitert.
Dass 2 Muster beide defekt sind kann ich nicht glauben, zumal ich sie nach Vorschrift verlötet habe.
Auf dem selben Bus sitzen noch 2 Sensoren und ein A/D Wandler, die den selben SPI-Mode (0) verwenden, die arbeiten normal.
Das ist ein recht kopmplizierter Baustein, das Datenblatt beschreibt zwar die Kommandos, aber nicht ob und wie man bestimmte zum Initialisieren senden muss, ich vermute, dass es eines Kommandos bedarf der etwas frei schaltet.
Ein Resetkommando gibt es, das bewirkt aber nichts.

Ich habe auch den Hersteller angeschrieben, ob es ein Kommando gibt dass eine Reaktion erzeugt, so dass ich zumindest sehen kann ob es "lebt". Bisher kam da keine Reaktion. Ich dachte, dass hier evtl. schon jemand mit dem Sensor zu tun hatte und einen Tipp hat. Manchmal hat man ja Glück :-)

Ich habe eine Library in C für den Sensor, leider...ist C-Üblich kompliziert geschrieben, kaum lesbar für mich. Aber da geht leider auch nicht draus hervor ob man da etwas freischalten muss bevor die Kommunikation klappt.

Louis
miparo
Administrator
Avatar
Gender:
Location: Germany
Age: 59
Posts: 956
Registered: 09 / 2007
Subject:

Re: MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 09.12.2013 - 15:21  ·  #4
Hallo Louis ,
dann schick mir mal die C Lib dann kann ich Dir evtl. helfen.
Das Datenblatt von dem MAX ist doch detailiert und auch vom SPI.

Gruß
miparo
Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 526
Registered: 02 / 2007
Subject:

Re: MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 09.12.2013 - 20:09  ·  #5
Hallo,

hier ist der C-Code:

Code
  18 #include <ao.h>
  19 #include <ao_mma655x.h>
  20 
  21 #if HAS_MMA655X
  22 
  23 #if 0
  24 #define PRINTD(...) do { printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); } while(0)
  25 #else
  26 #define PRINTD(...) 
  27 #endif
  28 
  29 static uint8_t  mma655x_configured;
  30 
  31 uint8_t ao_mma655x_spi_index = AO_MMA655X_SPI_INDEX;
  32 
  33 static void
  34 ao_mma655x_start(void) {
  35         ao_spi_get_bit(AO_MMA655X_CS_PORT,
  36                        AO_MMA655X_CS_PIN,
  37                        AO_MMA655X_CS,
  38                        AO_MMA655X_SPI_INDEX,
  39                        AO_SPI_SPEED_FAST);
  40 }
  41 
  42 static void
  43 ao_mma655x_stop(void) {
  44         ao_spi_put_bit(AO_MMA655X_CS_PORT,
  45                        AO_MMA655X_CS_PIN,
  46                        AO_MMA655X_CS,
  47                        AO_MMA655X_SPI_INDEX);
  48 }
  49 
  50 static void
  51 ao_mma655x_restart(void) {
  52         uint8_t i;
  53         ao_gpio_set(AO_MMA655X_CS_PORT, AO_MMA655X_CS_PIN, AO_MMA655X_CS, 1);
  54 
  55         /* Emperical testing on STM32L151 at 32MHz for this delay amount */
  56         for (i = 0; i < 9; i++)
  57                 ao_arch_nop();
  58         ao_gpio_set(AO_MMA655X_CS_PORT, AO_MMA655X_CS_PIN, AO_MMA655X_CS, 0);
  59 }
  60 
  61 static uint8_t
  62 ao_parity(uint8_t v)
  63 {
  64         uint8_t p;
  65         /* down to four bits */
  66         p = (v ^ (v >> 4)) & 0xf;
  67 
  68         /* Cute lookup hack -- 0x6996 encodes the sixteen
  69          * even parity values in order.
  70          */
  71         p = (~0x6996 >> p) & 1;
  72         return p;
  73 }
  74 
  75 static void
  76 ao_mma655x_cmd(uint8_t d[2])
  77 {
  78         ao_mma655x_start();
  79         PRINTD("\tSEND %02x %02x\n", d[0], d[1]);
  80         ao_spi_duplex(d, d, 2, AO_MMA655X_SPI_INDEX);
  81         PRINTD("\t\tRECV %02x %02x\n", d[0], d[1]);
  82         ao_mma655x_stop();
  83 }
  84 
  85 static uint8_t
  86 ao_mma655x_reg_read(uint8_t addr)
  87 {
  88         uint8_t d[2];
  89         ao_mma655x_start();
  90         d[0] = addr | (ao_parity(addr) << 7);
  91         d[1] = 0;
  92         ao_spi_send(&d, 2, AO_MMA655X_SPI_INDEX);
  93         ao_mma655x_restart();
  94 
  95         /* Send a dummy read of 00 to clock out the SPI data */
  96         d[0] = 0x80;
  97         d[1] = 0x00;
  98         ao_spi_duplex(&d, &d, 2, AO_MMA655X_SPI_INDEX);
  99         ao_mma655x_stop();
 100         return d[1];
 101 }
 102 
 103 static void
 104 ao_mma655x_reg_write(uint8_t addr, uint8_t value)
 105 {
 106         uint8_t d[2];
 107 
 108         addr |= (1 << 6);       /* write mode */
 109         d[0] = addr | (ao_parity(addr^value) << 7);
 110         d[1] = value;
 111         ao_mma655x_start();
 112         ao_spi_send(d, 2, AO_MMA655X_SPI_INDEX);
 113         ao_mma655x_stop();
 114 
 115         addr &= ~(1 << 6);
 116         PRINTD("write %x %x = %x\n",
 117                addr, value, ao_mma655x_reg_read(addr));
 118 }
 119 
 120 static uint16_t
 121 ao_mma655x_value(void)
 122 {
 123         uint8_t         d[2];
 124         uint16_t        v;
 125 
 126         d[0] = ((0 << 6) |      /* Axis selection (X) */
 127                 (1 << 5) |      /* Acceleration operation */
 128                 (1 << 4));      /* Raw data */
 129         d[1] = ((1 << 3) |      /* must be one */
 130                 (1 << 2) |      /* Unsigned data */
 131                 (0 << 1) |      /* Arm disabled */
 132                 (1 << 0));      /* Odd parity */
 133         ao_mma655x_start();
 134         PRINTD("value SEND %02x %02x\n", d[0], d[1]);
 135         ao_spi_send(d, 2, AO_MMA655X_SPI_INDEX);
 136         ao_mma655x_restart();
 137         d[0] = 0x80;
 138         d[1] = 0x00;
 139         ao_spi_duplex(d, d, 2, AO_MMA655X_SPI_INDEX);
 140         ao_mma655x_stop();
 141         PRINTD("value RECV %02x %02x\n", d[0], d[1]);
 142 
 143         v = (uint16_t) d[1] << 2;
 144         v |= d[0] >> 6;
 145         v |= (uint16_t) (d[0] & 3) << 10;
 146         return v;
 147 }
 148 
 149 static void
 150 ao_mma655x_reset(void) {
 151         ao_mma655x_reg_write(AO_MMA655X_DEVCTL,
 152                              (0 << AO_MMA655X_DEVCTL_RES_1) |
 153                              (0 << AO_MMA655X_DEVCTL_RES_1));
 154         ao_mma655x_reg_write(AO_MMA655X_DEVCTL,
 155                              (1 << AO_MMA655X_DEVCTL_RES_1) |
 156                              (1 << AO_MMA655X_DEVCTL_RES_1));
 157         ao_mma655x_reg_write(AO_MMA655X_DEVCTL,
 158                              (0 << AO_MMA655X_DEVCTL_RES_1) |
 159                              (1 << AO_MMA655X_DEVCTL_RES_1));
 160 }
 161 
 162 #define DEVCFG_VALUE    (\
 163         (1 << AO_MMA655X_DEVCFG_OC) |           /* Disable offset cancelation */ \
 164         (1 << AO_MMA655X_DEVCFG_SD) |           /* Receive unsigned data */ \
 165         (0 << AO_MMA655X_DEVCFG_OFMON) |        /* Disable offset monitor */ \
 166         (AO_MMA655X_DEVCFG_A_CFG_DISABLE << AO_MMA655X_DEVCFG_A_CFG))
 167 
 168 #define AXISCFG_VALUE   (\
 169                 (0 << AO_MMA655X_AXISCFG_LPF))  /* 100Hz 4-pole filter */
 170 
 171 
 172 static void
 173 ao_mma655x_setup(void)
 174 {
 175         uint8_t         v;
 176         uint16_t        a, a_st;
 177         uint8_t         stdefl;
 178         uint8_t         i;
 179         uint8_t s0, s1, s2, s3;
 180         uint8_t pn;
 181         uint32_t        lot;
 182         uint16_t        serial;
 183 
 184 
 185         if (mma655x_configured)
 186                 return;
 187         mma655x_configured = 1;
 188         ao_delay(AO_MS_TO_TICKS(10));   /* Top */
 189         ao_mma655x_reset();
 190         ao_delay(AO_MS_TO_TICKS(10));   /* Top */
 191         (void) ao_mma655x_reg_read(AO_MMA655X_DEVSTAT);
 192         v = ao_mma655x_reg_read(AO_MMA655X_DEVSTAT);
 193 
 194         /* Configure R/W register values.
 195          * Most of them relate to the arming feature, which
 196          * we don't use, so the only registers we need to
 197          * write are DEVCFG and AXISCFG
 198          */
 199 
 200         ao_mma655x_reg_write(AO_MMA655X_DEVCFG,
 201                              DEVCFG_VALUE | (0 << AO_MMA655X_DEVCFG_ENDINIT));
 202 
 203         /* Test X axis
 204          */
 205         
 206         ao_mma655x_reg_write(AO_MMA655X_AXISCFG,
 207                              AXISCFG_VALUE |
 208                              (1 << AO_MMA655X_AXISCFG_ST));
 209         for (i = 0; i < 10; i++) {
 210                 a_st = ao_mma655x_value();
 211                 printf ("SELF-TEST %2d = %6d\n", i, a_st);
 212         }
 213 
 214         stdefl = ao_mma655x_reg_read(AO_MMA655X_STDEFL);
 215 
 216         ao_mma655x_reg_write(AO_MMA655X_AXISCFG,
 217                              AXISCFG_VALUE |
 218                              (0 << AO_MMA655X_AXISCFG_ST));
 219         a = ao_mma655x_value();
 220 
 221         for (i = 0; i < 10; i++) {
 222                 a = ao_mma655x_value();
 223                 printf("NORMAL   %2d = %6d\n", i, a);
 224         }
 225 
 226         ao_mma655x_reg_write(AO_MMA655X_DEVCFG,
 227                              DEVCFG_VALUE | (1 << AO_MMA655X_DEVCFG_ENDINIT));
 228         s0 = ao_mma655x_reg_read(AO_MMA655X_SN0);
 229         s1 = ao_mma655x_reg_read(AO_MMA655X_SN1);
 230         s2 = ao_mma655x_reg_read(AO_MMA655X_SN2);
 231         s3 = ao_mma655x_reg_read(AO_MMA655X_SN3);
 232         lot = ((uint32_t) s3 << 24) | ((uint32_t) s2 << 16) |
 233                 ((uint32_t) s1 << 8) | ((uint32_t) s0);
 234         serial = lot & 0x1fff;
 235         lot >>= 12;
 236         pn = ao_mma655x_reg_read(AO_MMA655X_PN);
 237         printf ("MMA655X lot %d serial %d number %d\n", lot, serial, pn);
 238 
 239 }
 240 
 241 uint16_t        ao_mma655x_current;
 242 
 243 static void
 244 ao_mma655x_dump(void)
 245 {
 246         printf ("MMA655X value %d\n", ao_mma655x_current);
 247 }
 248 
 249 __code struct ao_cmds ao_mma655x_cmds[] = {
 250         { ao_mma655x_dump,      "A\0Display MMA655X data" },
 251         { 0, NULL },
 252 };
 253 
 254 static void
 255 ao_mma655x(void)
 256 {
 257         ao_mma655x_setup();
 258         for (;;) {
 259                 ao_mma655x_current = ao_mma655x_value();
 260                 ao_arch_critical(
 261                         AO_DATA_PRESENT(AO_DATA_MMA655X);
 262                         AO_DATA_WAIT();
 263                         );
 264         }
 265 }
 266 
 267 static __xdata struct ao_task ao_mma655x_task;
 268 
 269 void
 270 ao_mma655x_init(void)
 271 {
 272         mma655x_configured = 0;
 273 
 274         ao_cmd_register(&ao_mma655x_cmds[0]);
 275         ao_spi_init_cs(AO_MMA655X_CS_PORT, (1 << AO_MMA655X_CS_PIN));
 276 
 277         ao_add_task(&ao_mma655x_task, ao_mma655x, "mma655x");
 278 }
 279 
 280 #endif


Da wird erst ein Reset (line 189)gesendet, dann 2x das DEVSTAT Register gelesen (191+192).
Das habe ich auch schon probiert, leider ohne Erfolg.
Von Freescale ist auch noch keine Antwort da, warte ich also mal ab.

Louis
miparo
Administrator
Avatar
Gender:
Location: Germany
Age: 59
Posts: 956
Registered: 09 / 2007
Subject:

Re: MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 09.12.2013 - 22:29  ·  #6
und die anderen beiden .h Files vergessen !
Am besten die drei Files mal als Anhang.
Lschreyer
Schreiberling
Avatar
Gender: n/a
Posts: 526
Registered: 02 / 2007
Subject:

Re: MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 10.12.2013 - 17:23  ·  #7
Mittlerweile hat Freescale geantwortet, und mir ein paar Tipps gegeben, leider ohne Erfolg.
Dabei habe ich noch entdeckt, dass MISO beim ersten Commando auf eine 36 MHz Sinusschwingung über geht, danach geht nichts mehr.
Da scheint also der Baustein nicht genügend entkoppelt zu sein, obwohl ich es genau nach Handbuch gemacht habe. Da werde ich jetzt ansetzen, evtl. liegt es an de Leitung zum Controller, die ist zwar nur 2cm lang, könnte es aber sein.

Louis
Harald_K
 
Avatar
 
Subject:

Re: MMA655x Beschleunigungssensoren ansprechen

 · 
Posted: 11.12.2013 - 20:30  ·  #8
da fällt mir spontan dazu ein:

1. vielleicht die beiden Datenleitungen zwischen Chip und Atmel vertauscht??

2. wenn man am ATMEL im Mastermode den SS auf Eingang läßt schaltet das SPI-Interface automatisch auf Slave-Mode um wenn von außen SS auf low gezogen wird .... (kein Pullup / falsch initialisiert)
  • 1
  • 2
  • Page 1 of 2
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   138   152 · Page-Gen-Time: 0.035447s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI