Hallo zusammen
Ich benutze einen SAMD09D14 und habe es geschafft das SERCOM USART
Module ohne ASF zu benutzen. Beim I2C scheitert es allerdings, da ich
auf den Pins überhaupt keine Signale bekomme.
Kann mir wer hier weiterhelfen?
Hier der i2C init:
/* port mux configuration*/
PORT->Group[0].PINCFG[PIN_PA22].reg = PORT_PINCFG_PMUXEN; /* SDA */
PORT->Group[0].PINCFG[PIN_PA23].reg = PORT_PINCFG_PMUXEN; /* SCL */
/*PMUX: even = n/2, odd: (n-1)/2 */
PORT->Group[0].PMUX[PIN_PA22/2].reg = 0x02;
PORT->Group[0].PMUX[PIN_PA23/2].reg = 0x20;
/* APBCMASK */
PM->APBCMASK.reg |= PM_APBCMASK_SERCOM1;
/*gclk configuration for sercom1 module*/
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (SERCOM1_GCLK_ID_CORE) |
GCLK_CLKCTRL_GEN(0) |
GCLK_CLKCTRL_CLKEN;
/* set configuration for SERCOM1 I2C module */
SERCOM1->I2CM.CTRLB.reg = SERCOM_I2CM_CTRLB_SMEN; /* smart mode enable
*/
while (SERCOM1->I2CM.SYNCBUSY.reg);
/* Set baudrate */
uint32_t fgclk = 8000000; /* 8MHz */
uint32_t fscl = 100000; /* 100kHz SCL */
uint32_t trise = 215; /* 215 ns rising time */
int32_t numerator = fgclk - fscl*(10 + fgclk*trise/1000000000);
int32_t denominator = 2*fscl;
int32_t tmp_baud = (int32_t)(div_ceil(numerator, denominator));
SERCOM1->I2CM.BAUD.bit.BAUD = SERCOM_I2CM_BAUD_BAUD(tmp_baud);
while (SERCOM1->I2CM.SYNCBUSY.reg);
/* enable module */
SERCOM1->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_ENABLE |
SERCOM_I2CM_CTRLA_MODE_I2C_MASTER | /* i2c master mode */
SERCOM_I2CM_CTRLA_SDAHOLD(3); /* SDA hold time to 600ns */
while (SERCOM1->I2CM.SYNCBUSY.reg);
SERCOM1->I2CM.STATUS.reg |= SERCOM_I2CM_STATUS_BUSSTATE(1); /* set to
idle state */
while (SERCOM1->I2CM.SYNCBUSY.reg);
1 | /*PMUX: even = n/2, odd: (n-1)/2 */
|
2 | PORT->Group[0].PMUX[PIN_PA22/2].reg = 0x02; |
3 | PORT->Group[0].PMUX[PIN_PA23/2].reg = 0x20; |
Da wird wohl das Pinmux falsch sein. Auf Peripheral C ist korrekt.
A = 0x00 B = 0x01 C = 0x02 usw. der Pinmux sollte also stimmen Habe aber mittlerweilen diese Zeilen umgeschrieben auf: PORT->Group[0].PMUX[PIN_PA22/2].bit.PMUXO = 0x02; PORT->Group[0].PMUX[PIN_PA23/2].bit.PMUXE = 0x02;
1 | PORT->Group[0].PMUX[PIN_PA22/2].reg = 0x02; |
2 | PORT->Group[0].PMUX[PIN_PA23/2].reg = 0x20; |
22/2=11 23/2=11,5 Falls ich mich nicht täusche, setzt Du mit der zweiten Zeile den ersten Mux wieder auf 0. Es sollte also nur eine Zeile sein:
1 | PORT->Group[0].PMUX[PIN_PA22/2].reg = 0x22; |
Hab ich in meinem zweiten Post dann schon ausgebessert, das ist aber hier leider nicht das Problem.
Hast Du Pull-Up-Widerstände in den Leitungen? Hier habe ich noch eine Application-Note mit Beispielen für den SAMD21 gefunden: https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&cad=rja&http://www.atmel.com/Images/Atmel-42631-SAM-D21-SERCOM-I2C-Configuration_ApplicationNote_AT11628.pdf
Das war der falsch Link, hier der richtige: http://www.atmel.com/Images/Atmel-42631-SAM-D21-SERCOM-I2C-Configuration_ApplicationNote_AT11628.pdf
Vielen Dank für den Link. Müsste ich eigentlich nicht schon was an den Pins sehen, nachdem ich SERCOM1->I2CM.ADDR.reg = (0x29 << 1) | I2C_TRANSFER_WRITE; schreibe?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.