| Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme. |
Diskussion: SPI per PDC auf einem ARM7 im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Moin HABO, ich bin, was Mikrocontroller angeht, ziemlich ins kalte Wasser geworfen worden und bekomme deshalb immer wieder Probleme, ...
![]() |
| | #1 (permalink) |
| Registriert seit: 06.06.09 ![]() Likes: 6 | Anzeige Moin HABO, ich bin, was Mikrocontroller angeht, ziemlich ins kalte Wasser geworfen worden und bekomme deshalb immer wieder Probleme, sobald es etwas komplexer wird So auch dieses mal.Ich sitze hier vor einem Problem mit meinem AT91SAM7X512, dass ich nicht gelöst bekomme. Ich möchte über SPI pro Frame 7 mal 2 Bytes übertragen. Das ganze mit SCC/PDC. Grundsätzlich funktioniert das auch, allerdings sind die einzelnen Datenblöcke um je 2 Bytes verschoben. Das heißt wenn ich mir anschaue, was empfangen wurde, dann habe ich WERT7, WERT1, WERT2 WERT3, WERT4, WERT5, WERT6 statt WERT1, WERT2, WERT3, WERT4, WERT5, WERT6, WERT7. Ich denke ich habe da an einer Stelle noch nicht ganz durchschaut, wie das funktioniert, obwohl ich die entsprechenden Stellen im Datenblatt nun schon mehrmals gelesen habe. Hat hier vielleicht jemand einen Tipp für mich? Code: // Enable clock for SSC controller
*AT91C_PMC_PCER = (1 << AT91C_ID_SSC);
// SPI software reset
*AT91C_SSC_CR = AT91C_SSC_SWRST;
// Clock divider
*AT91C_SSC_CMR = 3;
// Configure receive clock
// TK Clock signal
// START: Detection of a low level on RF input
// Receive/Transmit Clock Inversion
// The data inputs (Data and Frame Sync signals) are sampled on
// Receive Clock rising edge. The Frame Sync signal output
// is shifted out on Receive Clock falling edge.
*AT91C_SSC_RCMR = AT91C_SSC_CKS_TK | AT91C_SSC_START_LOW_RF | AT91C_SSC_CKI;
// Configure receive frame
*AT91C_SSC_RFMR = (6 << 8) | // DATNB = 6 => 7 data words per frame
(15) | // DATLEN = 15 => half-words are transfered (16 bit)
AT91C_SSC_MSBF; // MSB first
// Enables Receive
*AT91C_SSC_CR = AT91C_SSC_RXEN; Code: if (*AT91C_SSC_RNCR == 0 && *AT91C_SSC_RCR == 0)
{
*AT91C_SSC_RPR = (unsigned int)&data;
*AT91C_SSC_RCR = sizeof(data) / 2;
*AT91C_SSC_RNCR = 0;
*AT91C_SSC_PTCR = AT91C_PDC_RXTEN;
} Code: typedef struct _data {
unsigned short value1;
unsigned short value2;
short value3;
short value4;
short value5;
short value6;
unsigned short value7;
} data, *pData;
__________________ A good programmer looks both ways before crossing a one-way street. Die Politik kann uns nur für so dumm verkaufen, wie wir sind. |
| | |
| | #2 (permalink) |
| Member of Honour ![]() Registriert seit: 28.05.10 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 210 | ich kanns hier nicht testen, aber die empfangsseite sieht auf den ersten blick richtig aus ... bist du sicher, dass die daten in der richtigen reihenfolge auf dem bus liegen, und der fehler erst intern beim empfänger auftritt?
__________________ Code: :(){ :|:& };: |
| | |
| HaBOT | - Anzeige - |
| |
| | #3 (permalink) |
| Themenstarter Registriert seit: 06.06.09 ![]() Likes: 6 | Soweit ich das beurteilen kann ja. Ich habe oben auch einen Screenshot angehängt, der die Ausgabe vom FPGA zeigt. Der erste Wert sollte eine 7000 sein und das sieht für mich soweit gut aus. In meiner Struktur landet die 7000 aber im zweiten Member.
__________________ A good programmer looks both ways before crossing a one-way street. Die Politik kann uns nur für so dumm verkaufen, wie wir sind. |
| | |
| | #4 (permalink) |
| Member of Honour ![]() Registriert seit: 28.05.10 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 210 | das erste ist: 0000 1101 1010 1100 BIN - 3500 DEZ ... also 7000 mit 1 bit rechts-shift
__________________ Code: :(){ :|:& };: |
| | |
| | #5 (permalink) |
| Themenstarter Registriert seit: 06.06.09 ![]() Likes: 6 | Oh, ja. Dazu wurde mir von dem Entwickler, von dem ich den Code übernommen habe und dem Entwickler, der sich um den FPGA kümmert erzählt, dass es schon immer so gewesen sei, dass das erste Bit ignoriert wurde. Warum und wieso konnte sich wohl keiner erklären. Ich habe das jetzt erst mal einfach so hingenommen, da ich wie gesagt nicht wirklich viel Ahnung von der Materie habe. Eine 7000 kommt ja auch an, auch die anderen Werte stimmen, sind aber eben verschoben, deswegen bin ich dem erst mal nicht weiter nachgegangen. Soweit ich das für mich aus dem Datenblatt herauslesen kann stimmt der Code und du scheinst das ja zu bestätigen. Hast du vielleicht einen Tipp, was ich probieren könnte um den Fehler einzugrenzen?
__________________ A good programmer looks both ways before crossing a one-way street. Die Politik kann uns nur für so dumm verkaufen, wie wir sind. |
| | |
| | #6 (permalink) |
| Member of Honour ![]() Registriert seit: 28.05.10 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 210 | bei näherer betrachtung von SSC_RFMR FSLEN dürfte die führende 0 als frame sync dienen ... dann fehlt mir aber irgendwie ganz hinten das letzte bit ... egal ... nehmen wir mal an dass die daten auf dem bus ok sind ... was geht also schief? offensichtlich funktioniert der SPI part einwandfrei, da die werte sauber gelesen werden und deiner aussage nach auch alle da sind ... demnach scheint auch ssc zu tun was man von dem teil verlangt ... bleibt noch pdc als mögliche fehlerquelle beim schreiben in den speicher ... diese vermutung wird dadurch begünstigt, dass der erste wert im speicher gleichzeitig der letzte ist, der über den bus kommt ... der fehler kann also erst aufgetreten sein, nachdem der letzte wert empfangen wurde ... ich würde demnach den fehler in dem teil suchen der sich mit dem PDC befasst ... ich weiß nicht in welchem context dein if steht ... Code: if (*AT91C_SSC_RNCR == 0 && *AT91C_SSC_RCR == 0)
__________________ Code: :(){ :|:& };: |
| | |
| | #7 (permalink) | |
| Themenstarter Registriert seit: 06.06.09 ![]() Likes: 6 | Zitat:
Das steht in einem Interrupt Handler, der von extern jede Millisekunde ausgelöst wird. Code: if (*AT91C_SSC_TNCR == 0 && *AT91C_SSC_TCR == 0)
{
if (*AT91C_SSC_RNCR == 0 && *AT91C_SSC_RCR == 0)
{
*AT91C_SSC_RPR = (unsigned int)&data;
*AT91C_SSC_RCR = sizeof(data) / 2;
*AT91C_SSC_RNCR = 0;
*AT91C_SSC_PTCR = AT91C_PDC_RXTEN;
}
}
__________________ A good programmer looks both ways before crossing a one-way street. Die Politik kann uns nur für so dumm verkaufen, wie wir sind. | |
| | |
| | #8 (permalink) |
| Member of Honour ![]() Registriert seit: 28.05.10 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 210 | wofür memcopy? warum stellst du keinen neuen puffer bereit?
__________________ Code: :(){ :|:& };: |
| | |
| | #9 (permalink) |
| Themenstarter Registriert seit: 06.06.09 ![]() Likes: 6 | Gute Frage, ich muss gestehen, dass ich mir darüber noch keine Gedanken gemacht habe. Das war schon so, als ich den Code übernommen habe und auf Grund meiner nicht vorhandenen Kenntnisse habe ich bisher nicht wirklich Änderungen an der Codebase vorgenommen. Du schlägst also vor in der ISR einen neuen Buffer zu allozieren wenn eine Übertragung fertig ist und diesen für die nächste zu verwenden? Dann könnte ich den alten Buffer freigeben, sobald die darin enthaltenen Daten verarbeitet sind. Ok, das probiere ich gleich morgen einmal aus.
__________________ A good programmer looks both ways before crossing a one-way street. Die Politik kann uns nur für so dumm verkaufen, wie wir sind. |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |