Sida 1 av 1

PIC32, Fler Mystiska saker, nu SPI.

Postat: 8 januari 2013, 12:36:42
av TomasL
Helt plötsligt har vi stött på ett SPI-problem vi inte haft tidigare (vi har aldrig använt minnen på SPI-bussen, så det kanske är förklaringen).
Använder ett 25AA1024 spi-minne samt PIC32MX695F512L
Använder SPI1
Problemet är att vi får två extra byte i början, vid mottagning.
Läskoden ser ut så här:

Kod: Markera allt

short SPI_mem_Read_bytes(uint8 *p, int a, int n)	{		
	uint8 temp, i; //KTL20130107 DEBUG 
	// start reading
	SpiChnClose(SPI_MEM_PORT);
	//ckp=0 cke=1 SPI_MODE_00
	SpiChnOpen(SPI_MEM_PORT, SPI_MODE_00 | SPI_OPEN_MSTEN | SPI_OPEN_MODE8 | SPI_OPEN_ON | SPI_OPEN_ENHBUF, SPI_MEM_PORT_DIV);
	
	SPI_mem_CS_clr();
	SpiChnPutC(SPI_MEM_PORT, SPI_MEM_READ);
		
	// send adress
	SpiChnPutC(SPI_MEM_PORT, 255&(a>>16));
	SpiChnPutC(SPI_MEM_PORT, 255&(a>>8));
	SpiChnPutC(SPI_MEM_PORT, 255&(a));
	SPI_mem_buf_empty();
	// get data
	while(n) {
		SpiChnPutC(SPI_MEM_PORT, 0);
		while( SpiChnIsBusy (SPI_MEM_PORT));
		temp = SpiChnReadC(SPI_MEM_PORT);  //KTL20130107 DEBUG                               
		*p = temp; //SpiChnReadC(SPI_MEM_PORT); KTL20130107 DEBUG
		p++;
		n--;
	}
	while( SpiChnIsBusy (SPI_MEM_PORT));
	SPI_mem_CS_set();
	
	SpiChnClose(SPI_MEM_PORT);
}
Samt

Kod: Markera allt

void SPI_mem_buf_empty()
{
	uint8 temp;
	while( SpiChnIsBusy (SPI_MEM_PORT));
	while(!SpiChnRxBuffEmpty(SPI_MEM_PORT))
	{
		
		SpiChnReadC(SPI_MEM_PORT);
		temp=SpiChnRxBuffCount(SPI_MEM_PORT);
	}
}
Har har bara hittat en referens, utan lösning på detta.

Re: PIC32, Fler Mystiska saker, nu SPI.

Postat: 8 januari 2013, 13:11:21
av Micke_s
Inte så att SPI flash:et har wait-states beroende på hastighet( olika kommandon för olika hastighet)

Re: PIC32, Fler Mystiska saker, nu SPI.

Postat: 8 januari 2013, 13:28:53
av TomasL
Inte enligt databladet, minnet är specat till 20MHz, och vi kör på 200k.

Fel i första inlägget, det skall vara en extra byte i stället för två.

Re: PIC32, Fler Mystiska saker, nu SPI.

Postat: 8 januari 2013, 13:47:49
av Andax
Varför har du SPI_mem_buf_empty(); och SpiChnPutC(SPI_MEM_PORT, 0); med?
Tycker inte det stämmer överens med databladet för SPI-EEPROMet... ...eller är det SpiChnPutC(SPI_MEM_PORT, 0); som genererar klockan under läsfasen?

Re: PIC32, Fler Mystiska saker, nu SPI.

Postat: 8 januari 2013, 14:34:00
av TomasL
"SpiChnPutC(SPI_MEM_PORT, 0)" genererar klockan.
"SPI_mem_buf_empty();" tömmer RX bufferten, eftersom jag har tre skrivningar (adressen) efter det att jag satt Minnet i Läsmode, och då får jag tillbaka adressen på RX-linan från minnet.
RX bufferten är 16 Byte djup.

Re: PIC32, Fler Mystiska saker, nu SPI.

Postat: 8 januari 2013, 14:43:24
av TomasL
Hittade i erratan hittade jag en konstighet:
6. Module: SPI
The SPIBUSY and SRMT bits assert 1 bit time
before the end of the transaction.
Verkar som att det är det som orsakar problemet.
Satt in en FOR-loop före efter varje SPIBUSY-kontroll, verkar lösa problemet tillfälligt.
Dock är det i mitt tycke, en dålig lösning.

Edit, for-loopen skall ligga efter varje SPIBUSY kontroll.
For-loopens längd beror på processorhastighet och frekvensen på SPI-Klockan.
EN annan sak att tänka på när det gäller PIC32 är att ha fördröjningar efter det man gjort något med SS-Pinnen, fördröjningens längd får man läsa ut i slav-kretsens datablad.
Om man till exempel skall sätta SS hög, och sedan skall sätta den låg, utan fördröjning, så är det inte säkert att slaven ser den, då det går riktigt fort, speciellt om man kör P-bussen fort.
I min applikation där P-Bussen snurrar i 40 MHz så blir det bara 25 ns eller så som pinnen är hög, vilket ofta inte är tillräckligt.

Re: PIC32, Fler Mystiska saker, nu SPI.

Postat: 12 januari 2013, 13:14:52
av Swech
:humm:
Jag pysslar inte med C men är inte koden mycket skum då den inte är direkt
säker utifrån dess uppförande?

Variablerna är definierade som 32 bits? INT
// send adress
SpiChnPutC(SPI_MEM_PORT, 255&(a>>16));
SpiChnPutC(SPI_MEM_PORT, 255&(a>>8));
SpiChnPutC(SPI_MEM_PORT, 255&(a));
kan väl sätta adresser som är utanför SPI minnets totala adress rymd?

variabel n kontrolleras aldrig om den är större än minnesrymden.
Skulle den anropas med 0 så blir väl while loopen oerhört stor?

uint8 *p - betyder detta att pekaren endast kan peka på de första 256 bytes av ram?
Som sagt C är inte min grej.....

För övrigt, om något händer med uteblivna synkroniseringar så hänger sig väl koden
eftersom den står och väntar i en massa while loopar...

Swech

Re: PIC32, Fler Mystiska saker, nu SPI.

Postat: 12 januari 2013, 15:52:18
av baron3d
Adressen kan bli för stor, men blir inte det.
While-loopen går noll varv om n=0.
"uint8 *p" betyder en pekare som pekar på en uint8. Pekaren är på 32 bitar.