Assembler RFN12b an Tiny44 und Tiny2313 via USI

Hallo Avr-Racer ich nehme an das du selbst dem Problem auf noch nicht herr geworden bist. Nun ja es sind in diesem fred nun etliche Lösungsansätze. Die letztere ist noch ungetestet. Es läuft denke ich so oder so auf Soft SPI raus, dar das ganze einfach etwas unabhängiger ist in der Handhabung. Das RFM reagiert nur sporadisch, bzw erhalte ich sporadisch den inhalt des statusregisters via RS232 auf das terminal. Dieser ist aber um 1 bit verschoben. Dar ich irgendwie in erinnerung habe in den letzten Tagen schon einmal von dir gelesen zu haben eine Frage an dich. In wie fern hast du eine Funktionierende Kommunikation zwischen Modul und AVR realisiert? Ich bin zwar im Forum unterwegs, an den Basteltisch schaffe ich die nächsten Tage aber leider auch nicht. Wenn du eventuelle Infos hast wäre ich dir Dankbar wenn du sie hier posten könntest.
Beschaltung ist wie folgt-:
SDO / SDI /SCK/Nsel an frei Ausgänge des AVR´s welche in dem Programm zu declarieren sind. FSS oder wie der Pin heisst (3 auf der rechten Seite) über 10k auf VCC.

PS: Tut mir übrigens sehr leid das der Thread so Ausufert und ich einfach nichts weiter bringe :/ schöne Feiertage noch

Kleine neuerung ich hab jetzt einfach ,mal die vorher gepostete routine verwendet. Dank neuem terminalprogramm weis ich nun. Der UART spuckt nicht 000 aus. Die rohdaten sind 0x30 0x30 0x30


hier mal ein ausschnitt: Man sieht sehr gut wie nsel auf low geht dann eine eher etwas zulang geratene pause folgt und dann das bit 0xB8 also zu deutsch 184


Beim sender sieht es so aus als würde er in einer initschleife feststecken..immer die 11 fgleichen werte, dabei sollte er ein register dec und senden..

der Code des Senders:


CodeBox Assembler
.include "tn44def.inc"
;///Ich sende dummdoof werte die Aufsteigen von 0-255
.org 0x000
rjmp main
.def temp1=r16
.def temp2=r17
.def temp3=r18
.def temp4=r19
.def counter=r20
.def status=r21
.equ spiddr= ddra
.equ spiport=porta
.equ spipin=pina
.equ sdo=0
.equ sdi=1
.equ sck=2
.equ nsel=3
.equ XTAL=1000000

main:
ldi temp1, low(ramend)
ldi temp2, high(ramend)
out spl, temp1
out sph, temp2
rcall delay1s
ldi temp4, 22
rcall RFM12init

loop:
inc temp4
mov XL, temp4
rcall RFM12sendbyte
rcall delay100ms
rjmp loop







.include "RFM12V2.txt"
;.include"stddelay.inc"

 

Anhänge

  • Empfänger.jpg
    Empfänger.jpg
    199,2 KB · Aufrufe: 2
  • sender2.jpg
    sender2.jpg
    258,9 KB · Aufrufe: 2
  • Sender1.jpg
    Sender1.jpg
    255,9 KB · Aufrufe: 1
  • RFM12V2.txt
    5,6 KB · Aufrufe: 5
Zuletzt bearbeitet:
Mein heutiger Test mit dem USI eines tiny85 zeigt erste erfolge :)
Der Status des RFM nach dem Poweron wird als 0x4000 am SDO pin des Moduls ausgegeben(siehe Bild) der SDO pin ist Kanal 07. Rest kann man sich denke ich mal denken Sck ist Sck Nsel ist Nsel.
Das RFM legt den pin SDO nach einer fallenden Flanke von Nsel ebenfalls auf low-Pegel(minimal versetzt) bei +70µs sieht man wie ich einfach einmal einen Nsel "IMpuls" in folge der programminit rausgeschmissen hab und das modul darauf reagiert hat.
Desweiteren scheint das modul frequenzen von sck jenseits von 1 Mhz nicht mehr ab zu können. Im Beispiel lief der tiny mit 1Mhz



CodeBox Assembler
.include "tn85def.inc"


.def temp1=r16
.def temp2=r17
.def temp3=r18
.def msb=r20
.def lsb=r19
.equ XTAL=1000000
.equ SS=3

.org 0x0000
main:
ldi temp1, low(ramend)
ldi temp2, high(ramend)
out spl, temp1
out sph, temp2
ldi temp1, 0xFF
out ddrb, temp1
sbi portb, SS
cbi ddrb, PB0                              ;Alles auf ausgang außer SDO vom Modul

loop:
clr msb                                       ;Befehel um status zu lesen ist 0x0000
clr lsb
;add lsb, r25                               ;Auskommentiert und unnütz(aus vorherigen test)
;adc msb, r26
rcall SPI4RFM12
rcall delay10ms

rjmp loop

SPI4RFM12:
cbi portb, SS                              ;Nsel low
mov temp1, msb                        ;msb in temp1 und senden
rcall SPITransfer
mov temp1, lsb                          ;lsb senden
rcall SPITransfer
nop nop nop
sbi portb, SS                              Nsel wider auf high
ret


SPITransfer:                                                                                       ;Aus Datenblatt des Tiny85
out    USIDR,temp1
ldi    r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
ldi    r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
out    USICR,r16 ; MSB
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16 ; LSB
out    USICR,r17
in     temp1,USIDR
ret
.include "stddelay.inc"

 

Anhänge

  • RFMstatusnachreset.jpg
    RFMstatusnachreset.jpg
    219,4 KB · Aufrufe: 4
Jetzt hätte ich aber noch eine dumme frage....Ich kann es mir selbst nicht erklären. Beide AVR´s scheinen nur zu arbeiten wenn DI mit einem hochohmigen pulldown versehen ist.....seltsam

edit:iegt offenbar an meinem billiglogicanalyzer für 20euro... Anscheinend ist wirklich die wahl eines etwas teureren gerät angesagt. Saleae hat sehr ansprechende geräte im sortiment doch ist der 8 Kanal doch schon recht teuer...Auf jeden Fall bin ihc nun gewiss. Das USI funktioniert. die Befehle kommen beim modul an und es andwortet zumindest bei der statusabfrage korrekt. Mehr konnte ich für den heutigen tag nicht erreichen. Langsam nervt mich das ganze etwas
 
Zuletzt bearbeitet:
Obacht!
In Zeile 19 machst Du den gesamten B-Port zum Ausgang. Da das Port Latch Register B da noch 0x00 (default) ist, liegen alle Beine auf Gnd.
Insbesondere also auch B.3 (NSEL). Dadurch wird das RFM selektiert, und legt SDO von tristate auf einen Ausgangspegel (das MSB vom Statusregister).
SDO hast Du aber am DI des Tiny (oder etwa nicht?), den Du erst in Zeile 21 wieder auf Eingang (und somit Tristate) schaltest.
Ok, in Zeile 20 legst Du /NSEL wieder auf High, aber im Takt von 19 zu 20 legt der Tiny Gnd auf SDO, und der RFM das MSB seines SREG...
Default sollte das ER-Bit im Power Management Command "0" sein -> MSB des RFM-SREG wäre dann RGIT - TX-Register ready for next Byte.

Ich würde DO nie auf Ausgang legen (wenn irgendein Slave aktiviert sein könnte).

Nachtrag: Du verwendest ja jetzt für die Clocks die Variante zu Fuß (ohne auslesen des 4-Bit-Counter-Überlaufs (USIOIF in USISR)).
In vielen Datenblättern findet sich dazu ein Code-Beispiel, bei dem zum prüfen von USIOIF USISR in dasselbe Rechenregister geladen wird, in dem das Byte steht (stehen sollte), welches für die Clocks nach USICR geschrieben wird. Das ist ein (bekannter) Copy&Paste-Fehler (und zwar mehrfach).

In einigen Tinies ist das USISR direct bit accessible - USIOIF kann also mit SBIS/SBIC geprüft werden OHNE USISR laden zu müssen.
Das entsprechende Codebeispiel wurde dann leider auch in Datenblättern verwendet, wo USISR nicht direct bit accessible war. Dort wurde das dann irgendwann auf die Version über die Rechenregister "korrigiert", aber dummerweise dasselbe Recheregister für USICR und USISR verwendet - nach der ersten Clock-Flanke wird nicht mehr der vorbereitete Wert (Flanke/Schieben) ins USICR geschrieben, sondern der letzte zurückgelesene Wert aus USISR.
Und diese Variante wiederum wurde in einige neuere Controller-Datenblätter übernommen, bei denen USISR direct bit accessible wäre (zB der Tiny25/45/85).

USIOIF muß dann zu Fuß wieder zurückgesetzt werden, bei den direct bit accessiblen sollte das mit SBI gehen.

Habe jetzt nicht nachgesehen, wie Du das damals in der Transfer loop hattest...
 
Zuletzt bearbeitet:
Hallo,

bisher hab ich mit dem RFM noch nicht gearbeitet aber die Kommunikation ist ähnlich als wenn man nen 74HC595 (Schieberegister) oder nen LTC1286(ADC) ansteuern willst.
Haben nen Enable/Clk/Dataeingang.

Wichtig ist bei der Init darauf zu achten das du dir die Sachen vorher schon definierst:
den SS-Pin kannst auch gleich NSEL = NOT selsct machen


CodeBox Assembler
.def temp1=r16
.def temp2=r17
.def temp3=r18
.def msb=r20
.def lsb=r19
.equ XTAL=1000000

.equ NSLCT = 3  ;SS_PIN
.equ DataOut = ?
.equ DataIn = ?
.equ SCK = ?
.equ RFM_Port = PORTB
.equ RFM_Pin = PINB
.equ RFM_DDR = DDRB

Init_RFM:

ldi    temp0,(1<<SS | 1<<DataOut | 0<<DataIn | 1<<SCK)
out  RFM_DDRB, temp0

ldi     temp0, (1<<SS | 0<<DataOut | 1<<DataIn | 0<<SCK)
out   RFM_PORTB,temp0

ret


Beim Datentransfer bist aber mutig Daten mit maximalen SPEED zu senden siehe Seite 111 im Datenblatt. Fang lieber mit nem kleinen Takt an.

Dein Problem mit dem PULL's ist das der SCK/DI OPEN DRAIN sind. Das heißt du musst ein PULLup nutzen von 10kohm, diesen gegen 5V schalten!!!! Nicht ein Hochohmigen PULLdown der sich dann auf Grund der Hochohmigkeit langsam die Spannung hoch zieht.(Antenne) DB seite 108 / 109 / 112

Auf Seite 117 siehst du wie was initialisiert sein muss und 118 wie der Clock ensteht.

Ich denke das Problem ist das du son komischen Mix nutzt von SoftUSI und HardwareUSI

Könntest du mal die INIT deiner USI einfügen ???
 
Zuletzt bearbeitet:
Beim Datentransfer bist aber mutig Daten mit maximalen SPEED zu senden siehe Seite 111 im Datenblatt. Fang lieber mit nem kleinen Takt an.
Bei einem MHz Systemtakt dauert ein Takt 1000ns. Ein Bit wird über den USI in zwei Takten geschoben (einmal SCK-Flankenwechsel ohne Byte schieben, einmal SCK-Flankenwechsel mit Byte schieben), also 2000ns Periodendauer.
Im Datenblatt des IA4420 finde ich auf Seite 11 für die minimalen Clock-low und Clock-high Zeiten je 25ns (also Periodendauer mindestens 50ns).
Dein Problem mit dem PULL's ist das der SCK/DI OPEN DRAIN sind. Das heißt du musst ein PULLup nutzen von 10kohm
???
Der Tiny ist Master, er legt SCK auf Gnd oder Vcc (Ausgang). DI ist Eingang. Abgesehen von dem einen Takt, auf den ich im letzten Post hinwies.
Der RFM wiederum hat doch bei SDO 'n Ausgangstreiber, der durch NSEL aktiviert wird.
Der LA-Mitschnitt aus #62 sieht doch ganz gut aus.
Ich denke das Problem ist das du son komischen Mix nutzt von SoftUSI und HardwareUSI
???
Das ist doch hard-USI, und zwar im Three Wire Mode (USI Wire Mode = 0b01). Die sechzehn USITC-Strobes bewirken die Flankenwechsel an SCK, bei jedem zweiten wird zusätzlich mit USICLK-Strobes das Datenregister geschoben. Das ist der schnellste USI, da ohne Schleife. Findest Du auch im Datenblatt des Tinies.
Alternativ kann man das Datenregisterschieben auch an eine(!) Flanke des eigenen SCK koppeln, und dann nur sechzehn USITC-Strobes ausführen.
Natürlich kann man die Strobes auch in eine Schleife packen, und den Überlauf des 4bit-Zählers auswerten, aber das sind eben zusätzliche Takte (die natürlich Flash sparen.
Könntest du mal die INIT deiner USI einfügen ???
In den Zeilen 18..21 werden die Beine festgelegt (war ich ja bereits drauf eingegangen),
wenn das erste mal Zeile 48 erreicht wird, wird USIWM0 gesetzt, USI übernimmt im 3WireMode Kontrolle über die Pins (mehr oder weniger, klar). dieser 3wireMode wird nie wieder aufgehoben.
 
Also das USI funktinoiert soweit ganz gut. bis auf den Punkt mit den Pullups. Ich kann ja auch das Portbit des Eingangs (DI pinSDO vom Modul) setzen. Somit ist der interne Pullup aktiviert. Das ganze ist mir aufgefallen als der logicanalyzer keine sinnvollen signale vom AVR mehr angezeigt hat sobald ich meinen Seriellen Programmer abgezogen habe welcher an MISO welcher sich mit dem DI port in die quere kommt einen pulldown gegen masse drin hat. SCK ist als ausgang geschaltet, dar der AVR Master ist und stellt somit kein problem da. Das USI wird in jedem Transferloop entsprechend dem Datenblatt konfiguriert. Das mit max speed müsstest du evtl nocheinmal näher erläutern. Der AVR läuft mit 1 Mhz das bedeutet einen USI Takt der deutlich unter den 2 Mhz welche im Datenblatt des RFms tehen liegt. Das mit ab Zeile 19 muss ich nochmal genauer ansehen, aber danke für den hinweis @LotadaC.
Nur ist es ja nun zumindest soweit das (mit kleinen koreckturen) der AVR und das RFM erfolgreich kommunizieren. Leider ist aber keine Datenübertragung möglich, dar die INIT werte welche ich hier (oben auch schon mal erwähnt) habe anscheinend nicht stimmen.

Auch wenn es jetzt bereits wieder hinfällig ist habe ich das ganze gestern noch einmal seperat "verpackt" in einer .inc. Leider liegt die auf der anderen Platte.
 
Also das USI des Senders funktioniert :D ich dödel hatte den Gnd des LA nicht angeschlossen und der hat sich seinen Pegel über das ISP und den USB durch den PC gezogen, was bei einer batteriebetriebenen geschichte etwas schlecht funktioniert :D
Jetzt muss nur noch der Empfänger fit gemacht werden....Das dumme sind die init werte -.-
Er initialisiert sich und sieht nach dem status. ist das bit 15 gesetzt ließt er den FIFO..aber leider kommen keine daten an so das er nach 100 fehlschlägen aufgibt...
 

Anhänge

  • 576.jpg
    576.jpg
    325,7 KB · Aufrufe: 5
Zuletzt bearbeitet:
Heißt das, daß das mit den Pull-Widerständen jetzt nicht mehr nötig ist? In dem von Dir verlinkten Datenblatt von HopeRF (#22) zum RFM12B sehe ich einen aktivierbaren Pullup nur an Pin6 (FSK/Data/nFFS) im Eingangszweig des Pins, Pin10 (nRES) wäre als Ausgang open collector, bei Pin16 (nINT/VDI) kann ein (recht hochohmiger) Pullup aktiviert werden, ABER bei SDO (--> DI am AVR) sehe ich nur einen (mit NSEL)aktivierbaren Ausgangstreiber, einen internen Serienwiderstand, und Schutzdioden.
Ein Pull-Widerstand im Slaves-Out---Master-In - Netz ist ja eigentlich auch sinnfrei - solange kein Slave selektiert ist, kann das ganze Netz tristate sein; wenn einer(!!) der Slaves durch den Master (AVR) selektiert wurde, ist dieser Slave auch der einzige, der den Pegel auf dem Netz bestimmt, als Ausgang. Woher stammt die Information, daß SDO angeblich Open Collector wäre? Quelle?

Anmerkung: die USI-Pins sind gleichzeitig (zusammen mit /Reset) auch die ISP-Pins des AVR. Wenn Du den also ISP-Flashen willst, während der RFM drannhängt, solltest Du den NSEL-Pin mit einem externen (!! - der verwendete Pin ist ja im Reset tristate) Pullup hochziehen, da sonst der RFM während des Programmierens dazwischenquatscht.

P.S.: wo bekommt man denn eigentlich diese Module? Ich finde die nur bei Pollins Resterampe, und da auch nur die 12er mit 868MHz. Da müßte man sich dann aber mMn auch an irgendwelche Regeln im Sendebetrieb halten - bei 433MHz wäre das wohl egal...
Dafür gäbe es dann noch RFM24, RFM26, RFM64 und RFM69. Nutzen die dann auch denselben IC?
 
Di RFM24,26,64,69 sind meines wissens andere IC´s was ich gelesen habe und sollen nicht so der hit sein. 868mhz ist ja im allgemeinen auch kein problem. Der Dutycycle von glaube 10% welcher erlaubt ist kann ja notfals durch eine etwas höhere datenrate kompensiert werden, oder (ich hab auch die 868mhz von pollin) einfach ohne antenne, dann is die reichweite nicht so enorm, und wo kein kläger ist da ist kein richter. Das mit den pullups hat sich soweit erledigt. Woher die info mit open collector stammt weis ich nicht. auf jeden fall funktioniert die kommunikation soweit laut LA einwandfrei das Modul nimmt daten entgegen und antwortet auch. Auch der SDo wird wie im Datenblatt geschrieben kurz nach Nsel=low ebenfalls auf low gezogen und nachdem Nsel high dauert es noch etwas und der sdo wird ebenfalls wieder high. Daraus widerrum entnehm ich aber für mich die info das 1 ms delay nach einer übertragung an das modul nicht schaden kann dar, SDO immer noch low ist nach dem nsel wieder auf high geht und die routine verlassen wurde. Springt man jetzt sofort wieder in eine routine ein so ist SDO noch low obwohl das Modul nicht bereit ist.
Routine von mir folgt in 10 min


so hier ist die routine die ich für die Screenshtos vom LA oben genutzt habe. Das USI funktioniert. Man bräuchte noch unterroutinen in denen einmal RXENABLE, TXENABLE, und eine welche zu energiesparzwecken sender uind empfänger auschaltet..Wobei meine idee dabei lag VCC und Gnd des moduls einfach über jeweils einen Transistor am gleichen portpin zu schalten. somit wäre das modul wenn es nicht gebraucht wird stromlos. Macht natürlich beim empfänger keinen sinn aber beim Sender(welcher mal mit einer CR24(schlagmichtod) batterie betrieben werden soll


CodeBox Assembler
;*******************************ACHTUNG*********ACHTUNG!!!!!!!**********
;Die routine SPI4RFM12 verändert das msb und lsb
;Beim senden von mehreren Datenbytes muss das MSB stehts neu geladen werden!
;
;

RFMinit:

ldi msb, 0x82
ldi lsb, 0x39
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0x82
ldi lsb, 0x39
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xA6
ldi lsb ,0x40
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xC6
ldi lsb, 0x47
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0x94
ldi lsb, 0xA0
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xC2
ldi lsb, 0xAC
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xCA
ldi lsb, 0x81
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xC4
ldi lsb ,0x83
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0x98
ldi lsb, 0x50
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xE0
ldi lsb, 0x00
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xC8
ldi lsb ,0x00
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0xC4
ldi lsb, 0x00
rcall delay1ms
rcall SPI4RFM12

ldi msb, 0x82
ldi lsb, 0x39
rcall delay1ms
rcall SPI4RFM12

ret

;*******************************readFIFO*******************************
;Daten sollten anschließend in lsb stehen
;Daten sind im FIFO vorhanden wen der Status 0x8000 entspricht also das bit 15 gesetzt ist

readFIFO:
ldi counter, 100
schleife:               ;sind daten vorhanden?
dec counter
breq nix               ;100 mal keine Daten?? dann wieder ins Hauptprogramm
rcall readstatus
sbrs msb, 7               ;wenn daten vorhanden weiter machen
rjmp schleife

ldi msb, 0xB0               ;Befehl für das lesen des FIFOS
ldi lsb, 0x00
rcall SPI4RFM12               ;datenbyte in lsb
ret

nix:
ret

;***************************************readstatus************************
;Status muss in msb/lsb stehen


readstatus:               ;Muss ebenfalls funktionieren
ldi msb, 0x00
ldi lsb, 0x00
rcall SPI4RFM12
ret

;************************************sendbyte********************************
;SENDET BYTE AUS LSB
;Verändert:Counter, LSB, MSB

sendbyte:
push lsb
ldi msb, 0xB0               ;Msb mit sendebefehl füllen

ldi counter, 3
bla:                   ;3 mal preambel senden 0xAA
ldi msb, 0xB0               ;Msb mit sendebefehl füllen
ldi lsb, 0xAA
rcall SPI4RFM12
rcall delay1ms
dec counter
brne bla

ldi msb, 0xB0               ;Msb mit sendebefehl füllen
ldi lsb, 0x2D               ;Synclow
rcall SPI4RFM12
rcall delay1ms

ldi msb, 0xB0               ;Msb mit sendebefehl füllen
ldi lsb, 0xD4               ;Synchigh
rcall SPI4RFM12
rcall delay1ms

ldi msb, 0xB0               ;Msb mit sendebefehl füllen
pop lsb
rcall SPI4RFM12               ;Datenbyte

ret                   ;BYTE müsste übertragen sein



;****************************UNTERROUTINEN*********************************

SPI4RFM12:               ;Getestet mit logic. Funktioniert
cbi rfmport, SS               ;Sendet msb+lsb.Antwort in msb/lsb
wait:                   ;warten AUF SDO=LOW
sbic rfmpin, sdo
rjmp wait

mov temp1, msb               ;MSB
rcall SPITransfer
mov msb, temp1

mov temp1, lsb               ;LSB
rcall SPITransfer
mov lsb, temp1

nop nop nop
sbi rfmport, SS
ret


SPITransfer:
out    USIDR,temp1
ldi    r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
ldi    r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
out    USICR,r16 ; MSB
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16
out    USICR,r17
out    USICR,r16 ; LSB
out    USICR,r17
in     temp1,USIDR
ret
.include "stddelay.inc"

 
Zuletzt bearbeitet:
Bei einem MHz Systemtakt dauert ein Takt 1000ns. Ein Bit wird über den USI in zwei Takten geschoben (einmal SCK-Flankenwechsel ohne Byte schieben, einmal SCK-Flankenwechsel mit Byte schieben), also 2000ns Periodendauer.
Im Datenblatt des IA4420 finde ich auf Seite 11 für die minimalen Clock-low und Clock-high Zeiten je 25ns (also Periodendauer mindestens 50ns).

50ns sind 20MHz. Und ist ja auch richtig nur hat man keinen Einblick in den Aufbau Freiluft oder auf eine sauber gelayouteten Platine. Gut dann ist man eben bei 500Khz ist zwar nicht so schnell aber bezogen auf den unbekannten Aufbau setze ich für mich einen geringen Takt an

???
Der Tiny ist Master, er legt SCK auf Gnd oder Vcc (Ausgang). DI ist Eingang. Abgesehen von dem einen Takt, auf den ich im letzten Post hinwies.
Der RFM wiederum hat doch bei SDO 'n Ausgangstreiber, der durch NSEL aktiviert wird.
Der LA-Mitschnitt aus #62 sieht doch ganz gut aus.

Ja der SDO des RFM hat einen Treiber und der geht auf den DI das AVR. Aber der SDO des AVR's zum DI des RFM hat keinen Treiber bzw PullUp.

???
Das ist doch hard-USI, und zwar im Three Wire Mode (USI Wire Mode = 0b01). Die sechzehn USITC-Strobes bewirken die Flankenwechsel an SCK, bei jedem zweiten wird zusätzlich mit USICLK-Strobes das Datenregister geschoben. Das ist der schnellste USI, da ohne Schleife. Findest Du auch im Datenblatt des Tinies.
Alternativ kann man das Datenregisterschieben auch an eine(!) Flanke des eigenen SCK koppeln, und dann nur sechzehn USITC-Strobes ausführen.
Natürlich kann man die Strobes auch in eine Schleife packen, und den Überlauf des 4bit-Zählers auswerten, aber das sind eben zusätzliche Takte (die natürlich Flash sparen.

Ist halt nicht eindeutig ersichtlich gewesen aber wenn ihr sagt das im 3WireMode gearbeitet wird dann ist alles gut. Die Hardware brauchst mir nicht erklären wie diese funktioniert, denn die wird funktionieren. Aber sie funktioniert nur so gut wie sie der Programmierer umsetzt!!!! Das ist ja unser eigentliches Problem.

In den Zeilen 18..21 werden die Beine festgelegt (war ich ja bereits drauf eingegangen),
wenn das erste mal Zeile 48 erreicht wird, wird USIWM0 gesetzt, USI übernimmt im 3WireMode Kontrolle über die Pins (mehr oder weniger, klar). dieser 3wireMode wird nie wieder aufgehoben.

Hier war mein Punkt eher der Übersichtlichkeit für Aussenstehende gedacht. Es ist ein Unterschied ob alles in einer Zeile gepackt ist oder ob man alles in mehreren Zeilen packt die man vom Verständniss her erstmal durchgehen muss.



Also das USI funktinoiert soweit ganz gut. bis auf den Punkt mit den Pullups. Ich kann ja auch das Portbit des Eingangs (DI pinSDO vom Modul) setzen. Somit ist der interne Pullup aktiviert.

Es ist nicht der PULLUP des RFM_SDO--->> AVR_SDI gemeint sondern der PULLUP des AVR-SDO-->>> RFM_SDI. Hat der RFM_SDI ein PULL ist ja alles i.O. wenn nicht würde ich einen spendieren und probieren ob es mit oder auch ohne geht.

Das ganze ist mir aufgefallen als der logicanalyzer keine sinnvollen signale vom AVR mehr angezeigt hat sobald ich meinen Seriellen Programmer abgezogen habe welcher an MISO welcher sich mit dem DI port in die quere kommt einen pulldown gegen masse drin hat.

uuuhhhhhhhiiii böses Faul :D kommt vor

SCK ist als ausgang geschaltet, dar der AVR Master ist und stellt somit kein problem da. Das USI wird in jedem Transferloop entsprechend dem Datenblatt konfiguriert.

Das mit max speed müsstest du evtl nocheinmal näher erläutern. Der AVR läuft mit 1 Mhz das bedeutet einen USI Takt der deutlich unter den 2 Mhz welche im Datenblatt des RFms tehen liegt. Das mit ab Zeile 19 muss ich nochmal genauer ansehen, aber danke für den hinweis @LotadaC.

1Mhz / 2Takte = 500Khz aber da Anmerkung von oben. MAX des RFM sind 20Mhz(1/50ns = 1 / 0,000 000 050) aber man reitzt es niemals bis zum Anschlag aus auch wenn der RFM es kann aber kannst du garantieren das man, ich sag mal als Hobbybastler gewisse Spezifikationen einhalten kannst? Wenn du es in SoftUSI machen könntest bestehe zumindest in der Theorie die Möglichkeit bis auf 2 Hz den SCK zu drosseln. Somit könnte man debuggen mit nur paar Leds


Nur ist es ja nun zumindest soweit das (mit kleinen koreckturen) der AVR und das RFM erfolgreich kommunizieren. Leider ist aber keine Datenübertragung möglich, dar die INIT werte welche ich hier (oben auch schon mal erwähnt) habe anscheinend nicht stimmen.

Auch wenn es jetzt bereits wieder hinfällig ist habe ich das ganze gestern noch einmal seperat "verpackt" in einer .inc. Leider liegt die auf der anderen Platte.

sicher das es an der Init liegt und du nicht einfach nur dem RFM ein cmd senden müsstest das die folgenden Daten gesendet werden sollen ?
 

Anhänge

  • Unbenannt.PNG
    Unbenannt.PNG
    93 KB · Aufrufe: 3
Hab mich zwischenzeitlich mal hingesetzt um die USI zu verstehn gerade mit dem FAST-Transfer das ist ja nichts weiter als BIT-geeiere 0.o aber das nur so...
@LotadaC mit den Pullups das kam von mir da es eine UNIVERSELLE sache ist und man TWI sowie i²c drüberlaufen lassen kann und diese benötigen diese Pulls. Im Vorpost ist auch das Bild dazu

Zum RFM habs mal als include geschrieben mit den Defines. Dannyboy du musst aufpassen, manche Kommandos sind länger als 1byte. Aber der RFM hat 16bit Empfangsbuffer somit musst du nur rechtzeitig das 2te byte hinterherschicken da man nur über temp0/R16 zugreift

MAIN


CodeBox Assembler
;###########################################
;# Projekt:                                #
;#                                            #
;#                                           #
;# Taktfrequenz des AVR: X MHz               #
;#                                            #
;# CS-SOFT                                    #
;###########################################

.include "tn85def.inc"   ;Atmega8


.def math1h    = r8
.def math1l    = r9
.def math2h    = R10
.def math2l    = r11
.def matherghh   = r12
.def mathergh   = r13
.def mathergl   = r14
.def mathergll   = r15

.def temp0 = r16    ;
.def temp1 = r17    ;
.def temp2 = r18
.def temp3 = r19    ;
.def temp4 = r20
.def cnt   = r21

.equ cpu   = 4000000
.equ Baud   = 9600
.equ UBRRx   = cpu/(16*Baud)-1

;*******USI
.equ NSLCT        = 3  ;SS_PIN
.equ SCK        = 2
.equ DataIn    = 1
.equ DataOut   = 0

.equ RFM_Port    = PORTB
.equ RFM_Pin    = PINB
.equ RFM_DDR    = DDRB


.org $0000
   rjmp    start
.org $0001
   reti; INT0
.org $0002
   reti;PCINT0
.org $0003
   reti;TIMER1_COMPA
.org $0004
   reti;TIMER1_OVF
.org $0005
   reti;TIMER0_OVF
.org $0006
   reti;EE_RDY
.org $0007
   reti;ANA_COMP
.org $0008
   reti;ADC
.org $0009
   reti;TIMER1_COMPB
.org $000A
   reti;TIMER0_COMPA
.org 0x000B
   reti;TIMER0_COMPB
.org $000C
   reti;WDT
.org $000D
   reti;USI_START
.org $000E
   reti;USI_OVF


start:   ldi        temp1,high(ramend)  ;Stackpointer festlegen
       out        sph, temp1
       ldi        temp1,low(ramend)   ;Stackpointer festlegen
        out        spl, temp1

       rcall       SPI4RFM12
       rcall       Init_RFM

Hauptprogramm:
       rjmp       Hauptprogramm

;*************************weitere*includedata***********************
.include "RFM_12B_defines.inc"
.include "RFM_12B.asm"
.include "USI.asm"



RFM_defines


CodeBox Assembler
;**********RFM_12B
.equ conf_set_cmd    = $80
.equ el               = 7
.equ ef               = 6
.equ b1                 = 5
.equ b0                 = 4
.equ x3               = 3
.equ x2               = 2
.equ x1               = 1
.equ x0               = 0

.equ pwr_mgmnt       = $82
.equ er               = 7
.equ ebb           = 6
.equ et                 = 5
.equ es                 = 4
.equ ex               = 3
.equ eb               = 2
.equ ew               = 1
.equ dc               = 0

.equ frequenzy_mgmnt   = $A0
.equ f_11               = 3
.equ f_10               = 2
.equ f_9               = 1
.equ f_8               = 0
.equ f_7               = 7
.equ f_6               = 6
.equ f_5                 = 5
.equ f_4                 = 4
.equ f_3               = 3
.equ f_2               = 2
.equ f_1               = 1
.equ f_0               = 0

.equ data_rate_mgmnt   = $C6
.equ CS                   = 7
.equ r_6               = 6
.equ r_5                 = 5
.equ r_4                 = 4
.equ r_3               = 3
.equ r_2               = 2
.equ r_1               = 1
.equ r_0               = 0

.equ pwr_set_cmd    = $90
.equ p16           = 2
.equ d__1           = 1
.equ d__0           = 0
.equ i2               = 7
.equ i1               = 6
.equ i0                 = 5
.equ g1                 = 4
.equ g0               = 3
;.equ r_2               = 2
;.equ r_1               = 1
;.equ r_0               = 0

.equ data_filter_cmd= $C2
.equ al               = 7
.equ ml               = 6
;.equ  1                 = 5
.equ s                 = 4
;.equ  1               = 3
;.equ f_2           = 2
;.equ f_1           = 1
;.equ f_0           = 0

.equ fifo_rst_mode_cmd= $CA
.equ f__3           = 7
.equ f__2           = 6
.equ f__1             = 5
.equ f__0             = 4
;.equ 0               = 3
.equ al_               = 2
.equ ff               = 1
.equ dr               = 0

.equ rx_fifo_read_cmd= $B0

.equ AFC_cmd       = $C4
.equ a1               = 7
.equ a0               = 6
.equ rl1             = 5
.equ rl0             = 4
.equ st0           = 3
.equ fi               = 2
.equ oe               = 1
.equ en_AFC           = 0

.equ TX_Co_Co_cmd   = $98
.equ mp               = 0
.equ m_3           = 7
.equ m_2            = 6
.equ m_1             = 5
.equ m_0             = 4
;.equ 0           = 3
.equ p2               = 2
.equ p1               = 1
.equ p0               = 0

.equ TM_Reg_write_cmd= $B8
.equ t7               = 7
.equ t6               = 6
.equ t5                 = 5
.equ t4                 = 4
.equ t3               = 3
.equ t2               = 2
.equ t1               = 1
.equ t0               = 0

.equ wake_up_cmd    = $e0
;.equ r_4               = 4
;.equ r_3               = 3
;.equ r_2               = 2
;.equ r_1               = 1
;.equ r_0               = 0
.equ m7               = 7
.equ m6               = 6
.equ m5                 = 5
.equ m4                 = 4
.equ m3               = 3
.equ m2               = 2
.equ m1               = 1
.equ m0               = 0

.equ low_duty_cycle_cmd= $C8
.equ d6               = 7
.equ d5               = 6
.equ d4                 = 5
.equ d3                 = 4
.equ d2               = 3
.equ d1               = 2
.equ d0               = 1
.equ en_duty       = 0 ;ENABLE = 1 / 0 = disable

.equ low_bat_clock_devide_cmd= $C0
.equ d_2           = 7
.equ d_1           = 6
.equ d_0             = 5
.equ v4                 = 4
.equ v3               = 3
.equ v2               = 2
.equ v1               = 1
.equ v0               = 0 ;ENABLE = 1 / 0 = disable


RFM_init und commands. Ist die Frage in welche Grundzustand der RFM ist sonst kannst du auch nicht benötigte Kommandos weg lassen.


CodeBox Assembler
Init_RFM:
     rcall       load_config_set_cmd
   rcall       load_pwr_mgmnt
   rcall       load_frequenzy_set_cmd
   rcall       load_data_rate_cmd
   rcall       load_pwr_set_cmd
     rcall       load_data_filter_cmd
   rcall       load_fifo_rst_mode_cmd
   rcall       load_rx_fifo_read_cmd
   rcall       load_AFC_cmd
   rcall       load_TX_Co_Co_cmd
   rcall       load_TM_Reg_write_cmd
   rcall       load_wake_up_cmd
   rcall       load_low_duty_cycle_cmd
   rcall       load_low_bat_clock_devide_cmd
   ret

load_config_set_cmd: ;433Mhz bei 16pF CrystalLoadCapacitance
   ldi         temp0,conf_set_cmd
   ldi           temp1,(0<<el | 0<<ef | 0<<b1 | 1<<b0 | 1 << x3 | 1 << x2 | 1 << x1 | 1 << x0)
   rcall       SPITransfer_Fast
   ret

load_pwr_mgmnt:
   ldi         temp0,pwr_mgmnt
   ldi           temp1,(0<<er | 0<<ebb | 0 << et | 0 << es | 1 << ex | 0 << eb | 0 << ew | 0 << dc)
   rcall       SPITransfer_Fast
   ret

load_frequenzy_set_cmd: ;gucken im DB und berechnen was man braucht min 96dez = 60Hex
   ldi         temp0,frequenzy_mgmnt
   ori           temp0,(0<<f_11 | 0<<f_10 | 0 << f_9 | 0 << f_8 )
   ldi           temp1,(0<<f_7 | 1<<f_6 | 1 << f_5 | 0 << f_4 | 0 << f_3 | 0 << f_2 | 0 << f_1 | 0 << f_0)
   rcall       SPITransfer_Fast
   ret

load_data_rate_cmd: ;gucken im DB und berechnen was man braucht
   ldi         temp0,data_rate_mgmnt
   ldi           temp1,(0<<CS | 0<<r_6 | 0 << r_5 | 0 << r_4 | 0 << r_3 | 0 << r_2 | 0 << r_1 | 0 << r_0)
   rcall       SPITransfer_Fast
   ret

load_pwr_set_cmd: ;gucken im DB und berechnen was man braucht
   ldi         temp0,pwr_set_cmd
   ori           temp0,(0<<p16 | 0<<d__1 | 0<<d__0)
   ldi           temp1,(0<<i2 | 0<<i1 | 0 << i0 | 0 << g1 | 0 << g0 | 0 << r_2 | 0 << r_1 | 0 << r_0)
   rcall       SPITransfer_Fast
   ret

load_data_filter_cmd: ;gucken im DB und berechnen was man braucht
   ldi         temp0,data_filter_cmd
   ldi           temp1,( 0<<al | 0 << ml /* 1*/ | 0 << s /*1*/| 0<<f_2 | 0 << f_1 | 0 << f_0)
   rcall       SPITransfer_Fast
   ret

load_fifo_rst_mode_cmd: ;gucken im DB und berechnen was man braucht
   ldi         temp0,fifo_rst_mode_cmd
   ldi           temp1,( 0<<f__3 | 0 << f__2 | 0 << f__1 |  0 << f__0  /*0*/ | 0 << al | 0 << ff | 0 << dr)
   rcall       SPITransfer_Fast
   ret

load_rx_fifo_read_cmd: ;ReadCMD senden zum RFM, Master sollte jetzt was empfangen
   ldi         temp0,rx_fifo_read_cmd
   clr           temp1
   rcall       SPITransfer_Fast
   /* ab hier kann jetzt deine SPI-Empfangsroutine stehen*/
   ret

load_AFC_cmd: ;gucken im DB und berechnen was man braucht, ST0 deshalb weil st ein AVR-Befehl ist
   ldi         temp0,AFC_cmd
   ldi           temp1,( 0<<a1 | 0 << a0 | 0 << rl1 |  0 << rl0 | 0 << st0 | 0 << fi | 0 << oe | 0 << en_AFC)
   rcall       SPITransfer_Fast
   ret

load_TX_Co_Co_cmd: ;gucken im DB und berechnen was man braucht, ST0 deshalb weil st ein AVR-Befehl ist
   ldi         temp0,TX_Co_Co_cmd
   ori           temp0,(0 << mp)
   ldi           temp1,( 0<<m3 | 0 << m2 | 0 << m1 |  0 << m0  /*0*/ | 0 << p2 | 0 << p1 | 0 << p0)
   rcall       SPITransfer_Fast
   ret

load_TM_Reg_write_cmd: ;gucken im DB und berechnen was man braucht, ST0 deshalb weil st ein AVR-Befehl ist
   ldi         temp0,TM_Reg_write_cmd
   ldi           temp1,( 0<<t7 | 0 << t6 | 0 << t5 |  0 << t4 | 0 << t3 | 0 << t2 | 0 << t1 | 0 << t0)
   rcall       SPITransfer_Fast
   /* hier kann deine Datensenderoutine stehen*/
   ret

load_wake_up_cmd: ;gucken im DB und berechnen was man braucht
   ldi         temp0,wake_up_cmd
   ori           temp0,(0<<r_4 | 0<<r_3 | 0<<r_2 | 0<<r_1 | 0<<r_0)
   ldi           temp1,(0<<m7 | 0<<m6 | 0 << m5 | 0 << m4 | 0 << m3 | 0 << m2 | 0 << m1 | 0 << m0)
   rcall       SPITransfer_Fast
   ret

load_low_duty_cycle_cmd: ;PWR_Management beachten
   ldi         temp0,low_duty_cycle_cmd
   ldi           temp1,( 0 << d6 | 0 << d5 | 0 << d4 | 0 << d3 | 0 << d2 | 0 << d1 | 0 << d0 | 0 << en_duty)
   rcall       SPITransfer_Fast
   ret

load_low_bat_clock_devide_cmd: ;PWR_Management beachten
   ldi         temp0,low_bat_clock_devide_cmd
   ldi           temp1,( 0 << d2 | 0 << d1 | 0 << d0 | 0 << v4 | 0 << v3 | 0 << v2 | 0 << v1 | 0 << v0)
   rcall       SPITransfer_Fast
   ret



SPI_init


CodeBox Assembler
SPI4RFM12:
   ldi           temp0,(1<<DataOut | 0<<DataIn | 1<<SCK | 1<<NSLCT )
   out          RFM_DDR, temp0
   ldi         temp0, (0<<DataOut | 1<<DataIn | 0<<SCK | 1<<NSLCT )
   out           RFM_PORT,temp0

   ret

SPITransfer_Fast:
   push       temp1
   out           USIDR,r16
   ldi           r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
   ldi           r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
   out           USICR,r16 ; MSB
   out           USICR,r17
   out           USICR,r16
   out           USICR,r17
   out           USICR,r16
   out           USICR,r17
   out           USICR,r16
   out           USICR,r17

   pop           temp1
   out           USIDR,r17
   ldi           r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
   ldi           r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
   out           USICR,r16
   out          USICR,r17
   out           USICR,r16
   out           USICR,r17
   out           USICR,r16
   out           USICR,r17
   out           USICR,r16 ; LSB
   out           USICR,r17
   in             r16,USIDR
   ret
 
Hey @avr_racer Ja das war ein böses faul mit dem Gnd :D Den Takt weiter zu verringern halte ich für keine gute idee da das RFM Fehler über Fehler ausspuckt wenn die Datenn nicht schnell genug gelsen oder geschrieben werden.
Das mit der RFM define datei und der Init welche auf diese aufbaut finde ich sehr ansprechend. Sauber und aufgeräumt wenn es auch auf den ersten blick etwas wuchtig aussieht.

Nur vom überfligen her hast du meine SPI4RFM12: nicht ganz verstanden. Sie war nur das mittel zum zweck um 16 bit per spi zu senden Nsel zu begin auf low zu ziehen und anschließend nach 16 bit wieder auf high. Wo berücksichtigst du Nsel? oder wartest auf SDO vom Modul?
Auch habe ich herrausgefunden das wenn eine unterbrechung zwischen high und lowbyte von nsel misst herrauskommt.
 
Nicht deine sondern wie Atmel es in Hardware umgesetzt hat mit dem r16/r17 das es nur umgeschaltet wird und so der Takt ensteht beim Transfer. Würde trotzdem lieber auf den Timer als Taktgeber ausweichen da der auch auf dem selben Pin einen Takt rausgeben kann. Somit kannst du recht gut den Takt bestimmen während die Daten gesendet werden und schon die nächsten Daten laden und ins USIDR geben wenn der 7 Takt vorbei ist.

guckst hier vllt hilft es dir weiter die kleinen Fehler zu finden https://www2.htw-dresden.de/~wiki_sn/index.php/RFM12

Ja wuchtig das stimmt aber glaub mir als Programmierer kotzt es dich nachher irgendwann an wenn du was suchst im Spagetticode so brauchst du nur gezielt 0 oder 1 ändern, proggen Thema gegessen und kannst an wichtigen Kernpunkten arbeiten.

Nur vom überfligen her hast du meine SPI4RFM12: nicht ganz verstanden. Sie war nur das mittel zum zweck um 16 bit per spi zu senden Nsel zu begin auf low zu ziehen und anschließend nach 16 bit wieder auf high. Wo berücksichtigst du Nsel? oder wartest auf SDO vom Modul?
Auch habe ich herrausgefunden das wenn eine unterbrechung zwischen high und lowbyte von nsel misst herrauskommt.

Doch im groben schon nur man hat ja andere Erfahrungen und das ist ja eine Übertragung in der Übertragung. RS232 wird nur einmal geinitet als BSP und ins UDRE schreibst die Daten, mehr muss ich da nicht machen. Die Umsetzung wie die Bits aus dem UDRE auf die Leitung kommt macht dort die HArdware und gibt mir nur Rückmeldung usw. Und da du ein USIDR dachte ich es währe ähnlich aber dem war nicht so ;)
NSELCT heißt er bei mir und der wird nur beim arbeiten auf 0 gezogen und wenn ich mir ganz sicher bin das ich nichts mehr mit dem RFM12 machen will wird NSELCT auf 1 gesetzt. Der darf während du kommunizierst nicht unterbrochen werden!!!!!
Hab es nur überflogen alles nur wenn es der Hersteller explizit erwähnt das man nach xyxz den CHIPSELECT deaktivieren soll dann macht man es.

Achso den RFM mit ner Transe zu deaktivieren, ok wenn Funkstille sein muss/soll. Nur denk dran nach jedem Neustart musst der initalisiert werden könnte bei gewissen Sachen kritisch werden.

In Software RX/TX abschalten und wenn er wirklich nicht gebraucht wird dann Spannung weg.
 
Zuletzt bearbeitet:
Also bei genauerer Betrachtung könnte man nun jedes Commando einfach in dieser Form anlegen. Bei der init gehöhrt soetwas wie FIFO lesen und Statuslesen nicht mit rein(kann man ja auskommentieren)
Dann müsste man die "SPI4RFM12" nur noch so umstricken das sie msb und lsb jeweils in einem register(bei mir heißen sie auch so) erwartet, via SPI ausgibt, das ergebniss natürlich wieder in die entsprechenden register schreibt und 'ret'.
Bei
load_TM_Reg_write_cmd

muss ich dir allerdings widersprechen. hier macht es keinen sinn das LSB zu verändern :D den das sind ja die daten die gesendet werden sollen. Hier ist wieder LSB sichern angesagt 3x 0xAA senden
dann 0x2D dann 0xD4 als syncword und dann das LSB pop'n und senden.
Auch muss ich mich erst einmal durch deinen bezeichnugen kämpfen. Aber die grundsätzliche Struktur des ganzen finde ich gerade wirklich faszinierend.



CodeBox Assembler
load_TM_Reg_write_cmd: ;gucken im DB und berechnen was man braucht, ST0 deshalb weil st ein AVR-Befehl ist ====>Sendet datenbyte
   ldi         msb,TM_Reg_write_cmd
;   ldi         lsb,( 0<<t7 | 0 << t6 | 0 << t5 |  0 << t4 | 0 << t3 | 0 << t2 | 0 << t1 | 0 << t0)       ;Macht keinen sinn
   push lsb
   ldi lsb, preambel
   rcall       SPI4RFM12
   ldi         msb,TM_Reg_write_cmd               ;3mal preambel
   ldi lsb, preambel
   rcall       SPI4RFM12
   ldi         msb,TM_Reg_write_cmd
   ldi lsb, preambel                       
   rcall       SPI4RFM12

   ldi         msb,TM_Reg_write_cmd
   ldi lsb, syncword_highbyte
   rcall       SPI4RFM12                   ;Syncword
   ldi         msb,TM_Reg_write_cmd
   ldi lsb, syncword_lowbyte
   rcall       SPI4RFM12

   pop lsb
   ldi         msb,TM_Reg_write_cmd               ;Datenbyte
   rcall       SPI4RFM12

   ret
 
Zuletzt bearbeitet:
Aber der SDO des AVR's zum DI des RFM hat keinen Treiber bzw PullUp.
So einen SDO gibt es gar nicht. Du meinst DO, der mit SDI des RFM verbunden ist. DO wurde hier (im 3wire mode) als Ausgang (=Ausgangstreiber aktiviert) festgelegt, liefert feste Pegel.
DI ist mit SDO des RFM verbunden, und dieser liefert feste Pegel, wenn er selektiert ist (/nSEL).
Die von Dir genannten Pullups sind nur im 2wire-mode relevant, AFAIK schaltet der Tiny seine internen Pullups da sogar via Override (PUOE) sicher ab.
Wenn nun beide Seiten wegen fehlender Gnd-Verbindung schweben....
1Mhz / 2Takte = 500Khz aber da Anmerkung von oben. MAX des RFM sind 20Mhz(1/50ns = 1 / 0,000 000 050) aber man reitzt es niemals bis zum Anschlag aus auch wenn der RFM es kann
Bei möglichen 20MHz würde ich die verwendeten 500kHz nicht gerade auls ausgereizt bezeichnen.
USI zu verstehn gerade mit dem FAST-Transfer das ist ja nichts weiter als BIT-geeiere 0.o aber das nur so...
Du kannst, statt der sechzehn abwechselnden USICLK und USICLK+USITC Strobes auch einfach den Zähler/das Schieberegister auf den eigenen USCK koppeln, und den so Takten, als wenn es extern wäre.
also sechzehnmal
Code:
(1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC)
nach USICR schreiben.
Wenn Du die sechzehn Zeilen (im Flash) nicht haben willst, kannst Du das auch in eine Schleife packen, und den Überlauf des Counters auswerten -> Transfer-loop aus dem Datenblatt (nur eben mit dem Doppelt benutzten Register, welches man hier wegen direct bit accessibility gar nicht bräuchte.


CodeBox Assembler
IN R16, USISR
SBRS R16, USIOIF
wird durch

CodeBox Assembler
SBIS R16, USIOIF
ersetzt, das Flag wird mit

CodeBox Assembler
SBI USISR, USIOIF
gelöscht.

Das USICR ist auch direct bit accessible, Du kanns also auch einmal
Code:
(1<<USIWM0)|(1<<USICS1)|(1<<USICLK)
nach USICR schreiben (als einmaliges Init), und für den eigentlichen Transfer dann nur noch sechzehn USITC-Strobes erzeugen (
Code:
SBI USISR, USITC
)
Ob nun in einer schleife mit dem Flag, oder zu Fuß, ist Dir überlassen.
 
RS232 wird nur einmal geinitet als BSP und ins UDRE schreibst die Daten, mehr muss ich da nicht machen. Die Umsetzung wie die Bits aus dem UDRE auf die Leitung kommt macht dort die HArdware und gibt mir nur Rückmeldung usw. Und da du ein USIDR dachte ich es währe ähnlich aber dem war nicht so ;)
Jain...
beim USI hast Du quasi 'ne Halbautomatik. Wiremode usw stellst Du eigentlich nur einmal ein, das Schieben mit den Beinen übernimmt die Hardware (beim 2wire auch die Start Condition Detection usw), aber USI besitzt keinerlei Anbindung an den Systemtakt. Darum mußt Du Dich selbst kümmern. Entweder durch entsprechende Strobes, oder durch ein Timer Compare Match (wobei der Timer dann rechtzeitig gestoppt werden muß).
und schon die nächsten Daten laden und ins USIDR geben wenn der 7 Takt vorbei ist.
Da wird doch aber erst noch das achte Bit vom RFM her reingeschoben, und auslesen willst Du es vielleicht auch noch...
Wenn der Timer als Taktgeber verwendet werden soll, muß er nach jedem Byte irgendwie angehalten werden (unter zuhilfenahme des Flags) - unklar ist hier, auf welches "Timer/Counter0 Compare Match" sich hier bezogen wird - Timer0 hat ja zwei OC-Units.

Bei Tinies mit gepuffertem USIDR (betrifft nur den Empfang), kanns Du nach einem komplett(!) übertragenem Byte das nächste übertragen lassen, und währenddessen das empfangene Byte aus dem Bufferregister laden (bevor das nächste komplett durch ist, klar).
 
Der Pin hat zwei mögliche Funktionen.
  • ist das p16-Bit (Bit10) des Power Setting Command gesetzt, ist das Bein VDI-Ausgang. Die Bits d1..d0 desselben Registers bestimmen dann die "Response time" des Beines. Im von mir mal verlinkten Datenblatt des IA4420 findet sich ein entsprechendes Schaltungsschema auf Seite 15.
  • ist p16 gelöscht, dient nINT als Interrupteingang, bei einer fallenden Flanke wird das EXT-Bit (Bit 11) im Statusregister gesetzt. Gedacht ist das dazu, den am Controller wegen nIRQ (Pin5) verbrauchten Interrupteingang zu ersetzen - der Externe IRQ wird dann einfach durchgeleitet; warum nIRQ auslöst (RGIT, FFIT, POR, FFOV, RGUR, WKUP, EXT, LBD (BOD)), mußt Du aus dem SREG auslesen.
 
So nun hab ich die init werte noch mal überarbeitet. Der empfänger ließt als status die ganze zeit der fifopuffer ist übergelaufen....der sender kackt auf einmal mitten drin ab oO Gibt es die möglichkeit per interrupt zu erkennen ob daten im fifo vorhanden sind?
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)