Hallo Leute,
ich habe eine kleine Schaltung mit einem ATXMega32e5 aufgebaut. Dieser
XMega hat ein SPI Flash (AT45DB161D), 3 PWM kanäle für RGB-LEDs und
einen für Sound sowie ein UART-Wlan Modul (ESP8266). Dabei nutze ich:
PWM Leds: PC0-PC2
PWM-Sound: PD5
SPI auf PORTC
UART auf PORTD
Soweit so gut.
Jetzt das Problem: Ich bekomme nichts zum Laufen auf dem XMega32e5
(meine Erfahrungen mit der A-Serie ging gut).
Ich habe folgende Phänomene:
Ich kann die PWM-Kanäle initialisieren und beschreiben (funktioniert,
siehe Quellcodeauszug).
1 | //Timer PWM Configs
|
2 | //Timer Counter 0 Type
|
3 | TCC4.CTRLE = TC45_BYTEM_NORMAL_gc; //8-Bit Timer
|
4 | TCC4.CTRLE = TC45_CCAMODE_COMP_gc|TC45_CCBMODE_COMP_gc|TC45_CCCMODE_COMP_gc; //Ausgabe bei A&B&C
|
5 | TCC4.CTRLA = TC45_CLKSEL_DIV4_gc; //4 Div, 31,25khz
|
6 | TCC4.CTRLB = TC45_WGMODE_SINGLESLOPE_gc; //SingleSlope mit PER als TOP
|
7 | TCC4.PER = PWM_Aufloesung; //TOP Zählwert
|
8 |
|
9 | //For Interrupt @ CCD for Sound and ovf for time
|
10 | TCC4.INTCTRLA = TC45_CCDINTLVL_HI_gc |TC45_OVFINTLVL_HI_gc; //Activate COMP-LVL Interrupt
|
11 | TCC4.CCD = 250; //Lichtmuster/Sound, Tastrate: 32khz ==> 250er @ div4
|
12 |
|
13 |
|
14 |
|
15 | //PWM Audio Output @ 1953,125Hz AND OVF INT for TimeCalc
|
16 | TCD5.CTRLE = TC45_BYTEM_NORMAL_gc | TC45_CCBMODE_COMP_gc; //8-Bit Timer & Ausgabe bei B
|
17 | TCD5.CTRLA = TC45_CLKSEL_DIV1_gc; //1 Div ==> 125kHz
|
18 | TCD5.CTRLB = TC45_WGMODE_SINGLESLOPE_gc; //SingleSlope mit PER als TOP
|
19 | TCD5.PER = PWM_Aufloesung; //TOP Zählwert
|
20 |
|
21 |
|
22 | //activate interrupt levels
|
23 | PMIC.CTRL |= PMIC_HILVLEN_bm | PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm; //Interrupt Level freigeben (alle)
|
24 | sei();
|
Jetzt wird es Interessant und es kommt das Problem:
Wenn ich SPI initialisiere, dann geht dieser außer MISO-Pin. Dieser
treibt weak gegen Masse (wenn ich bspw. Kurzschluss vom MISO und
SCK-Signal mache, habe ich auf MISO max. 1,5V als HIGH).
Wenn ich vom HW-PWM Initialisierung folgende Zeilen auskommentiere:
1 | TCC4.CTRLE = TC45_BYTEM_NORMAL_gc; //8-Bit Timer
|
2 | TCC4.CTRLE = TC45_CCAMODE_COMP_gc|TC45_CCBMODE_COMP_gc|TC45_CCCMODE_COMP_gc; //Ausgabe bei A&B&C
|
3 | TCC4.CTRLA = TC45_CLKSEL_DIV4_gc; //4 Div, 31,25khz
|
dann geht das SPI nicht mehr. Es geht genauso wenig wenn ich
1 | spi->port->DIRCLR = SPI_MISO_bm;
|
2 | spi->port->PIN6CTRL = PORT_OPC_PULLUP_gc;
|
3 |
|
4 | zu
|
5 |
|
6 | spi->port->DIRCLR |= SPI_MISO_bm;
|
7 | spi->port->PIN6CTRL = PORT_OPC_PULLUP_gc;
|
ändere. Dies bewirkt zwar dann, dass MISO wirklich INPUT gepullt ist,
dafür geht kein SPI mehr.
Ich habe das Gefühl, dass irgendwas da gesetzt ist, was irgendwelche
Portzugriffe überschreibt. Ich verstehe das absolut nicht. Es läuft auf
internem OSC mit 32MHz.
Hier die Initialisierung vom SPI.
1 | SPI_MasterInit(&spiMasterC, &SPIC, &PORTC, FALSE, SPI_MODE_3_gc, SPI_INTLVL_OFF_gc, FALSE, SPI_PRESCALER_DIV128_gc);
|
2 |
|
3 | Die Funktion dazu:
|
4 |
|
5 | void SPI_MasterInit(SPI_Master_t *spi, SPI_t *module, PORT_t *port, uint8_t lsbFirst, SPI_MODE_t mode, SPI_INTLVL_t intLevel, uint8_t clk2x, SPI_PRESCALER_t clockDivision)
|
6 | {
|
7 | spi->module = module;
|
8 | spi->port = port;
|
9 | spi->interrupted = 0;
|
10 |
|
11 |
|
12 | /* Interrupt level. */
|
13 | spi->module->INTCTRL = intLevel;
|
14 |
|
15 |
|
16 | /* No assigned data packet. */
|
17 | spi->dataPacket = NULL;
|
18 |
|
19 |
|
20 | /* MOSI, SCK and SS as output. */
|
21 | spi->port->DIRSET = (SPI_MOSI_bm | SPI_SCK_bm | SPI_SS_bm);
|
22 |
|
23 | /* MISO as input. and pulled */
|
24 | spi->port->DIRCLR = SPI_MISO_bm;
|
25 | spi->port->PIN6CTRL = PORT_OPC_PULLUP_gc;
|
26 |
|
27 |
|
28 | spi->module->CTRL = clockDivision | /* SPI prescaler. */
|
29 | (clk2x ? SPI_CLK2X_bm : 0) | /* SPI Clock double. */
|
30 | SPI_ENABLE_bm | /* Enable SPI module. */
|
31 | (lsbFirst ? SPI_DORD_bm : 0) | /* Data order. */
|
32 | SPI_MASTER_bm | /* SPI master. */
|
33 | mode; /* SPI mode. */
|
34 | }
|
Wenn ich das SPI Initialisiere wie folgt vor der while
1 | PORTC.DIR = (SPI_MOSI_bm | SPI_SCK_bm | SPI_SS_bm | (1<<3) | (1<<4));
|
2 | PORTC.PIN6CTRL = PORT_OPC_PULLUP_gc;
|
3 |
|
4 | SPIC.INTCTRL = SPI_INTLVL_OFF_gc;
|
5 | SPIC.DATA = 0;
|
6 | SPIC.CTRL = (SPI_PRESCALER_DIV128_gc | SPI_INTLVL_OFF_gc | SPI_MODE_0_gc | SPI_MASTER_bm | SPI_ENABLE_bm);
|
7 |
|
8 | FLASH_ON;
|
9 | AT45DB_SELECT;
|
10 |
|
11 | do
|
12 | {
|
13 | SPIC.DATA = 0xD7;
|
14 | while(!(SPIC.STATUS & SPI_IF_bm));
|
15 | }while (!SPIC.DATA);
|
16 |
|
17 | while(1)
|
18 | {
|
19 | PORTC.OUTTGL = 0xFF;
|
20 | }
|
Get das SPI an sich NUR (!) wenn ich die 3 ersten Zeilen vom TCC4
einkommentiere. Jedoch ist dabei das Signal auf MISO immer 0V. Wenn ich
ein High Signal (bspw Brücke zu SCK) herstelle, habe ich das Signal
jedoch mit einem max. Pegel von 1,5V, anstelle der 3,3V.