AT89C5131

Hallo NG,

im Rahmen meiner Studienarbeit entwerfe ich ein USB auf CAN Interface. Als USB Controller habe ich den AT89C5131 auserkoren. Die Platine ist nun fertig und jetzt gehts an die Firmware. Ich hab mir mal das USB Keyboard Beispiel von der Atmel Webseite angeschaut und nachvollzogen.

Hat jemand weiteren (leicht nachvollziehbaren) Beispielcode parat ?

Der AT89 verfügt über ein Businterface (RD\, WR\, CS\, INT\, AD,....) über das ich den SJA1000(CAN Controller) ansteuern möchte. Das kommt im Beispiel leider gar nicht vor. Hat jemand dazu ein paar Codeschnipsel bzw. Hinweise wie ich das in Betrieb setze ?

Welche Compiler und evtl. IDEs könnt ihr empfehlen ? Gibt es Probleme mit dem SDCC ?

Vielen Danke, Sebastian Fröbisch.

Reply to
Sebastian Fröbisch
Loading thread data ...

Hi,

Wenn du das Ding implementierst würde ich dir raten es als HID (Human Interface Device) bei Windows anzumelden (= Descriptoren entsprechend zusammenbauen). Dann kannst du dir die ganze Treiberschreiberei auf PC Seite sparen und HID verwendet Interrupt-Transfers, welche du für diese Anwendung sowiso sinnigerweise benutzten solltest. In Windows kannste das Teil dann direkt über nen Devicepfad öffnen und von lesen oder drauf schreiben.

Sind denn die Leitungen des SJA und AT89 schon korrekt verbunden? Also rd, wr, int, ale, jeweils passend den Pinnamen zueinander und ad[7..0] an port0[7..0] und cs an ne Adressleitung oder auf GND? (Hab grade mal nur kurz ins AT Datenblatt geschaut, von daher für obiges keine Gewähr) Wenn ja, dann kannst du (nachdem du vermutlich vorher irgendwie noch das externe Memory Interface aktivieren musst) einfach mit IO Befehlen wie "in" und "out" (ka wie die beim 8051 heissen) auf die Register des SJA zugreifen. Wenn du beim SJA die Interruptgenerierung einschaltest (macht Sinn) brauchst du natürlich auch noch eine Interruptroutine dafür. Für den USB Teil wirst du da ja warscheinlich auch schon eine haben.

Michael

Reply to
Michael Dreschmann

Hallo,

klingt gut. Zu meiner Aufgabe gehört aber leider auch noch einen Linuxtreiber dazu zu schreiben. Rein interessehalber, wie öffnet man unter windows einen Devicepfad und schreibt / liest drauf ?

ja, die platine ist fertig und die beiden chips sind hart verbunden.

aha sehr schön, weiß jemand wie die bei dem 8051 heißen ? wenns so einfach klappt, dann ist das businterface echt praktisch :)

Vielen Dank, Sebastian.

Reply to
Sebastian Fröbisch

Hallo,

Mit normalen Dateisystemfunktionen: CreateFile, WriteFile, ReadFile, CloseHandle... Get blocking und overlapped... wie bei Dateien..

Zum finden des Devicepfades anhand Vendor und Product ID habe ich mal diesen (*) Code verwendet.

Und auch so wie ich beschrieben habe? Naja, ist von auszugehen...

Wie die Befehle heißen steht im Datenblatt bzw. Instructionset des Controllers. Für Assembler halt. Unter C musst du mal in der Doku zum Compiler lesen. Vermutlich wird es da so wie immer sein, du greifst auf die Register wie auf Variablen zu, musst nur vorher die Adresse dieser "Variablen" festlegen und oft musste dem Compiler noch erzählen, dass es keine richtige Variable sondern ein Hardware Funktionsregister ist, damit er dir keine Aufrufe darauf wegoptimiert...

Michael

(*) function Get_Enumerated_Devices: string; var HidGuid: TGUID; hDevInfo: PHDEVINFO; devInfoData: TSP_DEVICE_INTERFACE_DATA; detailData: PSP_DEVICE_INTERFACE_DETAIL_DATA; MemberIndex: byte; LengthDID: DWORD; Required: DWORD; DevicePath: string; DeviceHandle: HWND; Attributes: THIDD_ATTRIBUTES; SerialNumber: array[0..31] of char; ResultStr: string; begin ResultStr := ''; HidD_GetHidGuid(@HidGuid); hDevInfo := SetupDiGetClassDevsA(@HidGuid,PChar(''),0,DIGCF_PRESENT or DIGCF_INTERFACEDEVICE); MemberIndex := 0; devInfoData.cbSize := SizeOf(devInfoData); while SetupDiEnumDeviceInterfaces(hDevInfo,nil,@HidGuid,MemberIndex,@devInfoData) do begin SetupDiGetDeviceInterfaceDetailA(hDevInfo, @devInfoData, nil, 0, @LengthDID, nil); if (LengthDID 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin detailData := AllocMem(LengthDID); detailData^.cbSize := SizeOf(detailData^); if SetupDiGetDeviceInterfaceDetailA(hDevInfo, @devInfoData, detailData, LengthDID, @Required, nil) then begin DevicePath := PChar(@(detailData^.DevicePath)); DeviceHandle := CreateFileA(PChar(DevicePath),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0); {Generic Read & Write, File Share Read & Write, Open Existing} Attributes.Size := SizeOf(Attributes.Size); HidD_GetAttributes(DeviceHandle,@Attributes); if (Attributes.VendorID = D_VENDOR_ID) and (Attributes.ProductID = D_PRODUCT_ID) then begin HidD_GetSerialNumberString(DeviceHandle, @SerialNumber, length(SerialNumber)); ResultStr := ResultStr + DevicePath + chr($D) + chr($A) + WideCharLenToString(@SerialNumber,16) + chr($D) + chr($A); end; CloseHandle(DeviceHandle); end; FreeMem(detailData); end; inc(MemberIndex); end; SetupDiDestroyDeviceInfoList(hDevInfo); Result := Copy(ResultStr,1,length(ResultStr)-2); end;

Reply to
Michael Dreschmann

Michael Dreschmannschrieb: " [...]

Nene. Also normalerweise definiert man einen Pointer

xdata unsigned char *pucExtData; oder auch xdata u8 pExtData_u8;

Das word xdata (ist z.B. beim Keil-Compiler so) sagt dem Compiler, dass er für den Zugriff auf diese Variable In- und Out-Assm-Befehle verwenden muss.

Dann kann man pucExtData die entsp. Adresse zuweisen und mit dem Pointer arbeiten. Natürlich gehen auch andere Pointer-Typen, wie Pointer auf Arrays, Pointer auf struct, Pointer auf union usw.

Gelegendlich sieht man auch schon mal andere Deklarationen mit @ u.ä., aber da baut der Compilerhersteller wohl was Eigenes.

[....]

Dirk

Reply to
Dirk Ruth

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.