1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894 |
- From dd4bc9ff49b9a7075e579fdd62fd930d27a9a7df Mon Sep 17 00:00:00 2001
- From: Jason Self <j@jxself.org>
- Date: Thu, 4 Jul 2019 15:55:48 -0700
- Subject: [PATCH 2/8] Add firmware for the ATUSB IEEE 802.15.4 USB Adapter
- http://shop.sysmocom.de/products/atusb/
- ---
- INSTALL | 20 +-
- Makefile | 6 +-
- WHENCE | 12 ++
- atusb/Makefile | 236 +++++++++++++++++++++
- atusb/README | 94 +++++++++
- atusb/an/README | 25 +++
- atusb/an/dec.py | 127 ++++++++++++
- atusb/an/get.py | 31 +++
- atusb/an/plot | 12 ++
- atusb/atusb.c | 63 ++++++
- atusb/board.c | 120 +++++++++++
- atusb/board.h | 95 +++++++++
- atusb/board_app.c | 173 ++++++++++++++++
- atusb/board_atusb.c | 162 +++++++++++++++
- atusb/board_atusb.h | 48 +++++
- atusb/board_hulusb.c | 179 ++++++++++++++++
- atusb/board_hulusb.h | 66 ++++++
- atusb/board_rzusb.c | 169 +++++++++++++++
- atusb/board_rzusb.h | 48 +++++
- atusb/boot.c | 77 +++++++
- atusb/descr.c | 104 ++++++++++
- atusb/ep0.c | 338 ++++++++++++++++++++++++++++++
- atusb/flash.c | 97 +++++++++
- atusb/include/at86rf230.h | 402 ++++++++++++++++++++++++++++++++++++
- atusb/include/atusb/atusb.h | 97 +++++++++
- atusb/include/atusb/ep0.h | 64 ++++++
- atusb/mac.c | 250 ++++++++++++++++++++++
- atusb/mac.h | 26 +++
- atusb/sernum.c | 47 +++++
- atusb/sernum.h | 37 ++++
- atusb/spi.c | 51 +++++
- atusb/spi.h | 30 +++
- atusb/uart.c | 64 ++++++
- atusb/uart.h | 25 +++
- atusb/usb/atu2.c | 247 ++++++++++++++++++++++
- atusb/usb/dfu.c | 260 +++++++++++++++++++++++
- atusb/usb/dfu.h | 119 +++++++++++
- atusb/usb/dfu_common.c | 101 +++++++++
- atusb/usb/usb.c | 181 ++++++++++++++++
- atusb/usb/usb.h | 189 +++++++++++++++++
- atusb/version.h | 23 +++
- 42 files changed, 4512 insertions(+), 3 deletions(-)
- create mode 100644 atusb/Makefile
- create mode 100644 atusb/README
- create mode 100644 atusb/an/README
- create mode 100755 atusb/an/dec.py
- create mode 100755 atusb/an/get.py
- create mode 100755 atusb/an/plot
- create mode 100644 atusb/atusb.c
- create mode 100644 atusb/board.c
- create mode 100644 atusb/board.h
- create mode 100644 atusb/board_app.c
- create mode 100644 atusb/board_atusb.c
- create mode 100644 atusb/board_atusb.h
- create mode 100644 atusb/board_hulusb.c
- create mode 100644 atusb/board_hulusb.h
- create mode 100644 atusb/board_rzusb.c
- create mode 100644 atusb/board_rzusb.h
- create mode 100644 atusb/boot.c
- create mode 100644 atusb/descr.c
- create mode 100644 atusb/ep0.c
- create mode 100644 atusb/flash.c
- create mode 100644 atusb/include/at86rf230.h
- create mode 100644 atusb/include/atusb/atusb.h
- create mode 100644 atusb/include/atusb/ep0.h
- create mode 100644 atusb/mac.c
- create mode 100644 atusb/mac.h
- create mode 100644 atusb/sernum.c
- create mode 100644 atusb/sernum.h
- create mode 100644 atusb/spi.c
- create mode 100644 atusb/spi.h
- create mode 100644 atusb/uart.c
- create mode 100644 atusb/uart.h
- create mode 100644 atusb/usb/atu2.c
- create mode 100644 atusb/usb/dfu.c
- create mode 100644 atusb/usb/dfu.h
- create mode 100644 atusb/usb/dfu_common.c
- create mode 100644 atusb/usb/usb.c
- create mode 100644 atusb/usb/usb.h
- create mode 100644 atusb/version.h
- diff --git a/INSTALL b/INSTALL
- index 74c5cfd..7fb1116 100644
- --- a/INSTALL
- +++ b/INSTALL
- @@ -16,6 +16,8 @@ In order to build everything you will need the following on the host
- system:
-
- * A C/C++ compiler, like GCC
- + * AVR-GCC
- + * Standard C library for AVR-GCC
- * Cmake
- * GNU Bison/YACC
- * GNU Flex
- @@ -32,13 +34,27 @@ system:
-
- On GNU/Linux distros that use apt you can install these with:
-
- - apt install binutils-arm-linux-gnueabi binutils-arm-none-eabi bison \
- - cmake flex g++ gcc gcc-arm-linux-gnueabi gcc-arm-none-eabi gperf make wget
- + apt install avr-gcc avr-libc binutils-arm-linux-gnueabi \
- + binutils-arm-none-eabi bison cmake flex g++ gcc \
- + gcc-arm-linux-gnueabi gcc-arm-none-eabi gperf make wget
-
- CARL9170 Firmware Configuration
- +-------------------------------
- When building the carl9170 firmware you will be prompted with
- configuration questions.
-
- +atusb: Firmware for the ATUSB IEEE 802.15.4 USB Adapter
- +-------------------------------------------------------
- +
- +To flash the firmware you need dfu-util on the host. Issue
- +
- + make dfu
- +
- +right after plugging the device into the USB port while the red led is
- +still on.
- +
- +Refer to the included README file for more information.
- +
- Licensing
- ---------
-
- diff --git a/Makefile b/Makefile
- index 21d16fb..8474b30 100644
- --- a/Makefile
- +++ b/Makefile
- @@ -17,7 +17,7 @@ shell=/bin/sh
- prefix=/lib/firmware
- install_program=install
-
- -.PHONY: all test clean install a56 as31 aica ath9k_htc_toolchain ath9k_htc av7110 b43-tools carl9170fw-toolchain carl9170fw cis-tools cis dsp56k ihex2fw isci keyspan_pda openfwwf usbdux
- +.PHONY: all test clean install a56 as31 aica ath9k_htc_toolchain ath9k_htc atusb av7110 b43-tools carl9170fw-toolchain carl9170fw cis-tools cis dsp56k ihex2fw isci keyspan_pda openfwwf usbdux
-
- all: aica ath9k_htc av7110 carl9170fw cis dsp56k isci keyspan_pda openfwwf usbdux
-
- @@ -36,6 +36,9 @@ ath9k_htc_toolchain:
- ath9k_htc: ath9k_htc_toolchain
- cd ath9k_htc && $(MAKE) -C target_firmware
-
- +atusb:
- + cd atusb && $(MAKE)
- +
- av7110:
- cd av7110 && $(MAKE)
-
- @@ -81,6 +84,7 @@ clean:
- if [ -a as31/Makefile ]; then cd as31 && $(MAKE) clean; fi;
- cd ath9k_htc && $(MAKE) toolchain-clean
- cd ath9k_htc && $(MAKE) -C target_firmware clean
- + cd atusb && $(MAKE) clean
- cd av7110 && $(MAKE) clean
- cd carl9170fw/toolchain && $(MAKE) clean
- if [ -a carl9170fw/Makefile ]; then cd carl9170fw && $(MAKE) clean; fi;
- diff --git a/WHENCE b/WHENCE
- index 2932155..756de43 100644
- --- a/WHENCE
- +++ b/WHENCE
- @@ -112,6 +112,18 @@ From https://github.com/qca/open-ath9k-htc-firmware
-
- --------------------------------------------------------------------------
-
- +atusb: Firmware for the ATUSB IEEE 802.15.4 USB Adapter
- +http://shop.sysmocom.de/products/atusb/
- +
- +From http://projects.qi-hardware.com/index.php/p/ben-wpan/source/tree/master/atusb/fw
- +
- +License: GPL-2.0-or-later
- +
- +Version: Based on commit 805db6ebf5d80692158acadf88e239da9d3e67af
- +dated September 13 2017
- +
- +--------------------------------------------------------------------------
- +
- Driver: b43 - OpenFWWF -- Free firmware for some Broadcom 43xx series WLAN chips
-
- License: GPLv2
- diff --git a/atusb/Makefile b/atusb/Makefile
- new file mode 100644
- index 0000000..c79cb26
- --- /dev/null
- +++ b/atusb/Makefile
- @@ -0,0 +1,236 @@
- +#
- +# Makefile - Makefile of the ATUSB firmware
- +#
- +# Written 2010-2011, 2013 by Werner Almesberger
- +# Copyright 2010-2011, 2013 by Werner Almesberger
- +#
- +# This program is free software; you can redistribute it and/or modify
- +# it under the terms of the GNU General Public License as published by
- +# the Free Software Foundation; either version 2 of the License, or
- +# (at your option) any later version.
- +#
- +
- +SHELL = /bin/bash
- +
- +NAME = atusb
- +DEBUG = false
- +
- +CFLAGS = -g -mmcu=$(CHIP) -DBOOT_ADDR=$(BOOT_ADDR) \
- + -Wall -Wextra -Wshadow -Werror -Wno-unused-parameter \
- + -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes
- +
- +ifeq ($(DEBUG),true)
- +CFLAGS += -DDEBUG
- +endif
- +
- +ifeq ($(NAME),rzusb)
- +CHIP=at90usb1287
- +CFLAGS += -DRZUSB -DAT86RF230
- +else ifeq ($(NAME),hulusb)
- +CHIP=at90usb1287
- +CFLAGS += -DHULUSB -DAT86RF212
- +else
- +CHIP=atmega32u2
- +CFLAGS += -DATUSB -DAT86RF231
- +endif
- +HOST=jlime
- +BOOT_ADDR=0x7000
- +
- +AVR_PREFIX = $(BIN_PATH) avr-
- +CC = $(AVR_PREFIX)gcc
- +OBJCOPY = $(AVR_PREFIX)objcopy
- +#OBJDUMP = $(AVR_PREFIX)objdump
- +SIZE = $(AVR_PREFIX)size
- +
- +# BCD notion is 0xJJMM with JJ being major and MM being minor. Thus 0x0020 is
- +# version 0.2 */
- +USB_BCD_VERSION = 0030
- +USB_VENDOR_ID = 20b7
- +USB_PRODUCT_ID = 1540
- +USB_ID = $(USB_VENDOR_ID):$(USB_PRODUCT_ID)
- +
- +OBJS = atusb.o board.o board_app.o sernum.o spi.o descr.o ep0.o \
- + dfu_common.o usb.o app-atu2.o mac.o
- +BOOT_OBJS = boot.o board.o sernum.o spi.o flash.o dfu.o \
- + dfu_common.o usb.o boot-atu2.o
- +
- +ifeq ($(DEBUG),true)
- +OBJS += uart.o
- +endif
- +
- +ifeq ($(NAME),rzusb)
- +OBJS += board_rzusb.o
- +BOOT_OBJS += board_rzusb.o
- +else ifeq ($(NAME),hulusb)
- +OBJS += board_hulusb.o
- +BOOT_OBJS += board_hulusb.o
- +else
- +OBJS += board_atusb.o
- +BOOT_OBJS += board_atusb.o
- +endif
- +
- +
- +vpath %.c usb/
- +
- +CFLAGS += -Iinclude -Iusb -I.
- +
- +# ----- Verbosity control -----------------------------------------------------
- +
- +CC_normal := $(CC)
- +BUILD_normal :=
- +DEPEND_normal := $(CPP) $(CFLAGS) -MM -MG
- +
- +CC_quiet = @echo " CC " $@ && $(CC_normal)
- +BUILD_quiet = @echo " BUILD " $@ && $(BUILD_normal)
- +DEPEND_quiet = @$(DEPEND_normal)
- +
- +ifeq ($(V),1)
- + CC = $(CC_normal)
- + BUILD = $(BUILD_normal)
- + DEPEND = $(DEPEND_normal)
- +else
- + CC = $(CC_quiet)
- + BUILD = $(BUILD_quiet)
- + DEPEND = $(DEPEND_quiet)
- +endif
- +
- +# ----- Rules -----------------------------------------------------------------
- +
- +.PHONY: all clean upload prog dfu update version.c bindist
- +.PHONY: prog-app prog-read on off reset
- +
- +all: $(NAME).bin boot.hex
- +
- +$(NAME).elf: $(OBJS)
- + $(MAKE) version.o
- + $(CC) $(CFLAGS) -o $@ $(OBJS) version.o
- + $(SIZE) $@
- +
- +boot.elf: $(BOOT_OBJS)
- + $(CC) $(CFLAGS) -o $@ $(BOOT_OBJS) \
- + -Wl,--section-start=.text=$(BOOT_ADDR)
- + $(SIZE) $@
- +
- +%.bin: %.elf
- + $(BUILD) $(OBJCOPY) -j .text -j .data -O binary $< $@
- + @echo "build #`cat .version`, `ls -l $@`"
- +
- +%.dfu: %.bin
- + cp $(NAME).bin $(NAME).dfu
- + dfu-suffix -a $(NAME).dfu -d 0x$(USB_BCD_VERSION) \
- + -p 0x$(USB_PRODUCT_ID) -v 0x$(USB_VENDOR_ID)
- +
- +%.hex: %.elf
- + $(BUILD) $(OBJCOPY) -j .text -j .data -O ihex $< $@
- + @echo "Size: `$(SIZE) -A boot.hex | sed '/Total */s///p;d'` B"
- +
- +# ----- Cleanup ---------------------------------------------------------------
- +
- +clean:
- + rm -f $(NAME).bin $(NAME).elf $(NAME).dfu
- + rm -f $(OBJS) $(OBJS:.o=.d)
- + rm -f boot.hex boot.elf
- + rm -f $(BOOT_OBJS) $(BOOT_OBJS:.o=.d)
- + rm -f version.c version.d version.o
- +
- +# ----- Build version ---------------------------------------------------------
- +
- +version.c:
- + @if [ -f .version ]; then \
- + v=`cat .version`; \
- + expr $$v + 1 >.version; \
- + else \
- + echo 0 >.version; \
- + fi
- + @[ -s .version ] || echo 0 >.version
- + @echo '/* MACHINE-GENERATED. DO NOT EDIT ! */' >version.c
- + @echo '#include "version.h"' >>version.c
- + @echo "const char *build_date = \"`date`\";" >>version.c
- + @echo "const uint16_t build_number = `cat .version`;" \
- + >>version.c
- +
- +# ----- Dependencies ----------------------------------------------------------
- +
- +MKDEP = \
- + $(DEPEND) $< | \
- + sed \
- + -e 's|^$(basename $(notdir $<)).o:|$@:|' \
- + -e '/^\(.*:\)\? */{p;s///;s/ *\\\?$$/ /;s/ */:\n/g;H;}' \
- + -e '$${g;p;}' \
- + -e d >$(basename $@).d; \
- + [ "$${PIPESTATUS[*]}" = "0 0" ] || \
- + { rm -f $(basename $@).d; exit 1; }
- +
- +%.o: %.c
- + $(CC) $(CFLAGS) -Os -c $<
- + $(MKDEP)
- +
- +-include $(OBJS:.o=.d)
- +
- +# ----- Object file variants --------------------------------------------------
- +
- +app-%.o: usb/%.c
- + $(CC) $(CFLAGS) -Os -o $@ -c $<
- + $(MKDEP)
- +
- +boot-%.o: usb/%.c
- + $(CC) $(CFLAGS) -DBOOT_LOADER -Os -o $@ -c $<
- + $(MKDEP)
- +
- +# ----- Distribution ----------------------------------------------------------
- +
- +BINDIST_BASE=http://downloads.qi-hardware.com/people/werner/wpan/bindist
- +ATUSB_BIN_NAME=atusb-`git rev-parse HEAD | cut -c 1-7`.bin
- +
- +bindist:
- + qippl atusb.bin wpan/bindist/$(ATUSB_BIN_NAME)
- + @echo $(BINDIST_BASE)/$(ATUSB_BIN_NAME)
- + @echo md5sum: `md5sum atusb.bin | sed 's/ .*//'`
- + @echo atrf-id: \
- + `sed '/.*number = \(.*\);/s//#\1/p;d' version.c` \
- + `sed '/.*date = "\(.*\)";/s//\1/p;d' version.c`
- +
- +# ----- Programming and device control ----------------------------------------
- +
- +upload: $(NAME).bin boot.hex
- + scp $(NAME).bin boot.hex $(HOST):
- +
- +# lfuse: external clock, slow start-up
- +# hfuse: 4 kB boot loader, reset into boot loader
- +# lock: allow everything but SPM to the boot loader
- +# Note: when trying to program 0xef, we get back 0x2f, failing
- +# verification. So we just program 0x2f.
- +
- +prog-app:
- + ssh $(HOST) avrdude -F -p $(CHIP) -c nanonote_atusb -e \
- + -U flash:w:atusb.bin:r \
- + -U lfuse:w:0x60:m
- +
- +prog:
- + ssh $(HOST) avrdude -F -p $(CHIP) -c nanonote_atusb -e \
- + -U flash:w:boot.hex:i \
- + -U lfuse:w:0x60:m \
- + -U hfuse:w:0xd8:m \
- + -U lock:w:0x2f:m
- +
- +prog-read:
- + ssh $(HOST) avrdude -F -p $(CHIP) -c nanonote_atusb \
- + -U flash:r:mcu.bin:r
- +
- +dfu: $(NAME).dfu
- + dfu-util -d $(USB_ID) -D $(NAME).dfu
- +
- +update: $(NAME).bin
- + -atrf-reset -a
- + usbwait -r -i 0.01 -t 5 $(USB_ID)
- + $(MAKE) dfu
- +
- +on:
- + ssh $(HOST) poke 0x10010318 4
- +
- +off:
- + ssh $(HOST) poke 0x10010314 4
- +
- +reset:
- + ssh $(HOST) poke 0x10010318 2048
- + ssh $(HOST) poke 0x10010314 2048
- diff --git a/atusb/README b/atusb/README
- new file mode 100644
- index 0000000..99ceb22
- --- /dev/null
- +++ b/atusb/README
- @@ -0,0 +1,94 @@
- +Requires a very recent toolchain, because ATmega32U2 is relatively new.
- +
- +- Building:
- +
- + make
- +
- +- Uploading the firmware to a Ben (for flashing with the atusb-pgm cable):
- +
- + make HOST=<hostname> upload
- +
- + Example:
- +
- + make HOST=ben upload
- +
- + HOST defaults to "jlime".
- +
- +- Flashing the boot loader:
- +
- + Prerequisite: avrdude on the Ben.
- +
- + Disconnect the atusb board from USB. Insert the atusb-pgm connector into
- + the Ben. Place the atusb-pgm adapter on the exposed contact pads of the
- + atusb board and push it down. Then run
- +
- + make prog
- +
- + This takes about 30 seconds. If the programming fails with an error
- + message like "Yikes! Invalid device signature.", verify that the
- + atusb-pgm board is properly connected and placed, then try again.
- +
- +- Uploading the application:
- +
- + Prerequisite: dfu-util installed on the PC.
- +
- + Insert atusb into the PC, then run
- +
- + make dfu
- +
- + Note: since the boot loader resets the USB bus after timing out,
- + this operation can fail with a message like "No DFU capable USB device
- + found". Just retry, and it will eventually get through.
- +
- +
- +HULUSB notes:
- +-------------
- +To prepare and flash the firmware on a HULUSB device some additional steps are
- +needed;
- +
- +avr-objcopy -O ihex -R .signature -R .fuse -R .eeprom hulusb.elf hulusb.hex
- +dfu-programmer at90usb1287 flash hulusb.hex
- +dfu-programmer at90usb1287 reset
- +
- +--------------------------
- +
- +Making the toolchain:
- +
- +# patches according to
- +# http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=789527
- +
- +# some gcc prerequisites
- +
- +apt-get remove avr-libc gcc-avr binutils-avr
- +apt-get install libmpfr-dev libmpc-dev
- +
- +# binutils
- +
- +wget http://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.bz2
- +tar xfj binutils-2.21.tar.bz2
- +cd binutils-2.21
- +./configure --target=avr --disable-nls
- +make
- +make install
- +
- +# gcc
- +
- +wget http://ftpmirror.gnu.org/gcc/gcc-4.5.2/gcc-4.5.2.tar.bz2
- +wget -O gcc_452_avr.patch http://gcc.gnu.org/bugzilla/attachment.cgi?id=23050
- +tar xfj gcc-4.5.2.tar.bz2
- +cd gcc-4.5.2
- +patch -p1 -s <../gcc_452_avr.patch
- +mkdir obj-avr
- +cd obj-avr
- +../configure --target=avr --enable-languages=c \
- + --disable-nls --disable-libssp --with-dwarf2
- +make
- +make install
- +
- +wget http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.7.1.tar.bz2
- +tar xfj avr-libc-1.7.1.tar.bz2
- +cd avr-libc-1.7.1
- +./bootstrap # the automake at the end takes a while
- +./configure --build=`./config.guess` --host=avr
- +make
- +make install
- diff --git a/atusb/an/README b/atusb/an/README
- new file mode 100644
- index 0000000..8e0d2fc
- --- /dev/null
- +++ b/atusb/an/README
- @@ -0,0 +1,25 @@
- +workflow:
- +
- +- connect zprobe (note: it currently inverts because it didn't have any
- + other chips around. this may change later.)
- +
- +- capture the USB signals at an interesting moment with a sample rate of
- + 50 MSa/s
- +
- +- zoom into the frame(s) of interest
- +
- +- download the data with
- + ./get.py
- +
- +- decode with
- + ./dec.py
- +
- + For manual decoding, set the coders to D+ and D- (we need D- for SE0
- + and SE1 detection), then click on a rising clock edge left of the
- + packet and move the cursor to the right.
- +
- +- if there are problems with the clock, the analog signal and digital
- + signals derived from it can be examined after running dec.py with
- + ./plot
- +
- + (Note that the digital zprobe hides any analog anomalies.)
- diff --git a/atusb/an/dec.py b/atusb/an/dec.py
- new file mode 100755
- index 0000000..8534857
- --- /dev/null
- +++ b/atusb/an/dec.py
- @@ -0,0 +1,127 @@
- +#!/usr/bin/python
- +
- +from tmc.wave import *
- +from tmc.dxplore import dxplore
- +from tmc.decode import d_usb_stream
- +
- +
- +#
- +# Clock recovery: we assume that each change in the wave is triggered by a
- +# clock edge. We know the clock's nominal period and resynchronize on each
- +# edge. Additionally, we can obtain a list of times when a timing violation
- +# has occurred.
- +#
- +# Note that the timing violations logic doesn't make much sense in its present
- +# form, since it mainly measures noise (particularly if we're digitizing slow
- +# edges) and not clock drift.
- +#
- +# A more useful metric would be accumulated error from some point of reference
- +# or at least the timing of same edges, to eliminate (generally harmless) time
- +# offsets introduced by digitizing.
- +#
- +# So it would probably make more sense for "recover" not to check for timing
- +# violations at all, and leave this to more specialized functions.
- +#
- +def recover(self, period, min = None, max = None, t0 = None):
- + if t0 is None:
- + t0 = self.data[0]
- + v = not self.initial
- + res = []
- + violations = []
- + for t in self.data:
- + v = not v
- + if t <= t0:
- + continue
- + n = 0
- + while t0 < t-period/2:
- + res.append(t0)
- + t0 += period
- + n += 1
- + if min is not None:
- + if t0-t > n*min:
- + violations.append(t)
- + if max is not None:
- + if t-t0 > n*max:
- + violations.append(t)
- + t0 = t
- + return res, violations
- +
- +
- +#
- +# Load the analog waves saved by get.py
- +#
- +wv = waves()
- +wv.load("_wv")
- +
- +#
- +# Digitize the waves and save the result.
- +#
- +dp = wv[0].digitize(1.5, 1.8)
- +dm = wv[1].digitize(1.5, 1.8)
- +wv = waves(dp, dm, dp-dm)
- +wv.save("_dig")
- +
- +#
- +# Also record the differential signal.
- +#
- +wd = wv[1]-wv[0]
- +dd = wd.digitize(-0.5, 0.5)
- +wd.save("_diff")
- +
- +#
- +# Run clock recovery on D+/D-. We only need one, but check both to be sure.
- +#
- +#p = 1/1.5e6
- +p = 1/12e6
- +dp_t, viol = recover(dp, p, p*0.9, p*1.1)
- +print viol
- +dm_t, viol = recover(dm, p, p*.9, p*1.1, t0 = dp.data[0])
- +print viol
- +
- +#
- +# Shift the clock by half a period, add a few periods to get steady state and
- +# SE0s (if any), and then sample the data lines.
- +#
- +clk = map(lambda t: t+p/2, dp_t)
- +clk.extend((clk[-1]+p, clk[-1]+2*p, clk[-1]+3*p))
- +dp_bv = dp.get(clk)
- +dm_bv = dm.get(clk)
- +
- +#
- +# Save a wave with the recovered clock to make it easier to find the bits in
- +# analog graphs.
- +#
- +dd.data = dp_t;
- +dd.save("_clk")
- +
- +#
- +# For decoding, we need a fake bit clock. We generate it by doubling each data
- +# bit and generating a L->H transition during this bit.
- +#
- +dpd = []
- +dmd = []
- +dck = []
- +
- +# err, silly, seems that we've mixed up D+ and D- all over the place :-)
- +print d_usb_stream(dm_bv[:], dp_bv[:])
- +
- +for v in dp_bv:
- + dpd.append(v)
- + dpd.append(v)
- + dck.append(0)
- + dck.append(1)
- +
- +for v in dm_bv:
- + dmd.append(v)
- + dmd.append(v)
- +
- +#
- +# Display the reconstructed digital signal. Note that the absolute time is only
- +# correct at the beginning and that relative time is only accurate over
- +# intervals in which no significant clock resynchronization has occurred.
- +#
- +# In fact, dxplore should probably have an option to either turn off time
- +# entirely or to display a user-provided time axis. The latter may be a bit
- +# tricky to implement.
- +#
- +dxplore((dmd, dpd, dck), 0, p/2, labels = ("D+", "D-", "CLK"))
- diff --git a/atusb/an/get.py b/atusb/an/get.py
- new file mode 100755
- index 0000000..685e00f
- --- /dev/null
- +++ b/atusb/an/get.py
- @@ -0,0 +1,31 @@
- +#!/usr/bin/python
- +
- +from tmc.scope import rigol_ds1000c
- +
- +#-800, +1600
- +s = rigol_ds1000c()
- +#s.debug = False
- +
- +pos = s.hor.pos
- +scale = s.hor.scale
- +t0 = pos-scale*s.div_hor/2
- +t1 = pos+scale*s.div_hor/2
- +print t0, t1
- +
- +#zoom = 10
- +#step = scale/s.samples_per_div/zoom
- +#print step
- +step = 4e-9
- +step = 2e-9
- +
- +w = s.wave((s.ch[0], s.ch[1]), start = t0, end = t1, step = step)
- +w[0] = 3.3-w[0]
- +w[1] = 3.3-w[1]
- +
- +s.hor.pos = pos
- +s.hor.scale = scale
- +
- +w[0].label = "D+";
- +w[1].label = "D-";
- +
- +w.save("_wv")
- diff --git a/atusb/an/plot b/atusb/an/plot
- new file mode 100755
- index 0000000..1dea789
- --- /dev/null
- +++ b/atusb/an/plot
- @@ -0,0 +1,12 @@
- +#!/bin/sh
- +#
- +# Plot output of "dec"
- +#
- +gnuplot -persist <<EOF
- +set style data lines
- +plot "_wv" using 1:(\$2-4), \
- + "_dig" using 1:(\$2*3.3-4) lw 2, \
- + "_wv" using 1:3, \
- + "_dig" using 1:(\$3*3.3) lw 2, \
- + "_clk" using 1:(\$2+1) lt 7
- +EOF
- diff --git a/atusb/atusb.c b/atusb/atusb.c
- new file mode 100644
- index 0000000..28faf40
- --- /dev/null
- +++ b/atusb/atusb.c
- @@ -0,0 +1,63 @@
- +/*
- + * fw/atusb.c - ATUSB initialization and main loop
- + *
- + * Written 2008-2011 by Werner Almesberger
- + * Copyright 2008-2011 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +#include <avr/sleep.h>
- +#include <avr/interrupt.h>
- +
- +#include "usb.h"
- +
- +#include "board.h"
- +#include "sernum.h"
- +#include "spi.h"
- +#include "atusb/ep0.h"
- +
- +#ifdef DEBUG
- +#include "uart.h"
- +#endif
- +
- +
- +int main(void)
- +{
- + board_init();
- + board_app_init();
- + reset_rf();
- +
- + user_get_descriptor = sernum_get_descr;
- +
- + /* now we should be at 8 MHz */
- +
- +#ifdef DEBUG
- + uart_init();
- + static FILE atben_stdout = FDEV_SETUP_STREAM(uart_write_char, NULL,
- + _FDEV_SETUP_WRITE);
- + stdout = &atben_stdout;
- +#endif
- +
- + usb_init();
- + ep0_init();
- +#ifdef ATUSB
- + timer_init();
- +
- + /* move interrupt vectors to 0 */
- + MCUCR = 1 << IVCE;
- + MCUCR = 0;
- +#endif
- +
- + sei();
- +
- + while (1)
- + sleep_mode();
- +}
- diff --git a/atusb/board.c b/atusb/board.c
- new file mode 100644
- index 0000000..c3b8d26
- --- /dev/null
- +++ b/atusb/board.c
- @@ -0,0 +1,120 @@
- +/*
- + * fw/board.c - Board-specific functions (for boot loader and application)
- + *
- + * Written 2011, 2013 by Werner Almesberger
- + * Copyright 2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +#include <avr/interrupt.h>
- +#include <avr/boot.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#include "usb.h"
- +#include "at86rf230.h"
- +#include "board.h"
- +#include "spi.h"
- +
- +
- +uint8_t board_sernum[42] = { 42, USB_DT_STRING };
- +
- +/* ----- Register access --------------------------------------------------- */
- +
- +void change_state(uint8_t new)
- +{
- + while ((reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK) ==
- + TRX_STATUS_TRANSITION);
- + reg_write(REG_TRX_STATE, new);
- +}
- +
- +
- +uint8_t reg_read(uint8_t reg)
- +{
- + uint8_t value;
- +
- + spi_begin();
- + spi_send(AT86RF230_REG_READ | reg);
- + value = spi_recv();
- + spi_end();
- +
- + return value;
- +}
- +
- +
- +uint8_t subreg_read(uint8_t address, uint8_t mask, uint8_t position)
- +{
- + /* Read current register value and mask out subregister. */
- + uint8_t register_value = reg_read(address);
- + register_value &= mask;
- + register_value >>= position; /* Align subregister value. */
- +
- + return register_value;
- +}
- +
- +
- +void reg_write(uint8_t reg, uint8_t value)
- +{
- + spi_begin();
- + spi_send(AT86RF230_REG_WRITE | reg);
- + spi_send(value);
- + spi_end();
- +}
- +
- +
- +void subreg_write(uint8_t address, uint8_t mask, uint8_t position, uint8_t value)
- +{
- + /* Read current register value and mask area outside the subregister. */
- + uint8_t register_value = reg_read(address);
- + register_value &= ~mask;
- +
- + /* Start preparing the new subregister value. shift in place and mask. */
- + value <<= position;
- + value &= mask;
- +
- + value |= register_value; /* Set the new subregister value. */
- +
- + /* Write the modified register value. */
- + reg_write(address, value);
- +}
- +
- +
- +void panic(void)
- +{
- + cli();
- + while (1) {
- + SET(LED);
- + _delay_ms(100);
- + CLR(LED);
- + _delay_ms(100);
- + }
- +}
- +
- +
- +static char hex(uint8_t nibble)
- +{
- + return nibble < 10 ? '0'+nibble : 'a'+nibble-10;
- +}
- +
- +
- +void get_sernum(void)
- +{
- + uint8_t sig;
- + uint8_t i;
- +
- + for (i = 0; i != 10; i++) {
- + sig = boot_signature_byte_get(i+0xe);
- + board_sernum[(i << 2)+2] = hex(sig >> 4);
- + board_sernum[(i << 2)+4] = hex(sig & 0xf);
- + }
- +}
- diff --git a/atusb/board.h b/atusb/board.h
- new file mode 100644
- index 0000000..dbcd410
- --- /dev/null
- +++ b/atusb/board.h
- @@ -0,0 +1,95 @@
- +/*
- + * fw/board.h - Board-specific functions and definitions
- + *
- + * Written 2008-2011, 2013, 2013 by Werner Almesberger
- + * Copyright 2008-2011, 2013, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef BOARD_H
- +#define BOARD_H
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <atusb/atusb.h>
- +
- +#ifdef ATUSB
- +#include "board_atusb.h"
- +#endif
- +#ifdef RZUSB
- +#include "board_rzusb.h"
- +#endif
- +#ifdef HULUSB
- +#include "board_hulusb.h"
- +#endif
- +
- +#define SET_2(p, b) PORT##p |= 1 << (b)
- +#define CLR_2(p, b) PORT##p &= ~(1 << (b))
- +#define IN_2(p, b) DDR##p &= ~(1 << (b))
- +#define OUT_2(p, b) DDR##p |= 1 << (b)
- +#define PIN_2(p, b) ((PIN##p >> (b)) & 1)
- +
- +#define SET_1(p, b) SET_2(p, b)
- +#define CLR_1(p, b) CLR_2(p, b)
- +#define IN_1(p, b) IN_2(p, b)
- +#define OUT_1(p, b) OUT_2(p, b)
- +#define PIN_1(p, b) PIN_2(p, b)
- +
- +#define SET(n) SET_1(n##_PORT, n##_BIT)
- +#define CLR(n) CLR_1(n##_PORT, n##_BIT)
- +#define IN(n) IN_1(n##_PORT, n##_BIT)
- +#define OUT(n) OUT_1(n##_PORT, n##_BIT)
- +#define PIN(n) PIN_1(n##_PORT, n##_BIT)
- +
- +
- +#define USB_VENDOR ATUSB_VENDOR_ID
- +#define USB_PRODUCT ATUSB_PRODUCT_ID
- +
- +#define DFU_USB_VENDOR USB_VENDOR
- +#define DFU_USB_PRODUCT USB_PRODUCT
- +
- +
- +#define BOARD_MAX_mA 40
- +
- +#ifdef BOOT_LOADER
- +#define NUM_EPS 1
- +#else
- +#define NUM_EPS 2
- +#endif
- +
- +#define HAS_BOARD_SERNUM
- +
- +extern uint8_t board_sernum[42];
- +extern uint8_t irq_serial;
- +
- +
- +void reset_rf(void);
- +void reset_cpu(void);
- +uint8_t read_irq(void);
- +void slp_tr(void);
- +
- +void led(bool on);
- +void panic(void);
- +
- +uint64_t timer_read(void);
- +void timer_init(void);
- +
- +bool gpio(uint8_t port, uint8_t data, uint8_t dir, uint8_t mask, uint8_t *res);
- +void gpio_cleanup(void);
- +
- +void get_sernum(void);
- +
- +void board_app_init(void);
- +
- +uint8_t reg_read(uint8_t reg);
- +uint8_t subreg_read(uint8_t address, uint8_t mask, uint8_t position);
- +void reg_write(uint8_t reg, uint8_t value);
- +void subreg_write(uint8_t address, uint8_t mask, uint8_t position, uint8_t value);
- +void change_state(uint8_t new);
- +
- +#endif /* !BOARD_H */
- diff --git a/atusb/board_app.c b/atusb/board_app.c
- new file mode 100644
- index 0000000..1fa9bf4
- --- /dev/null
- +++ b/atusb/board_app.c
- @@ -0,0 +1,173 @@
- +/*
- + * fw/board_app.c - Board-specific functions (for the application)
- + *
- + * Written 2011, 2013 by Werner Almesberger
- + * Copyright 2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stddef.h>
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +#include <avr/interrupt.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#include "usb.h"
- +#include "at86rf230.h"
- +#include "spi.h"
- +#include "mac.h"
- +#include "board.h"
- +
- +
- +static volatile uint32_t timer_h = 0; /* 2^(16+32) / 8 MHz = ~1.1 years */
- +
- +
- +void reset_cpu(void)
- +{
- + WDTCSR = 1 << WDE;
- +}
- +
- +
- +uint8_t read_irq(void)
- +{
- + return PIN(IRQ_RF);
- +}
- +
- +
- +void slp_tr(void)
- +{
- + SET(SLP_TR);
- + CLR(SLP_TR);
- +}
- +
- +
- +ISR(TIMER1_OVF_vect)
- +{
- + timer_h++;
- +}
- +
- +
- +uint64_t timer_read(void)
- +{
- + uint32_t high;
- + uint8_t low, mid;
- +
- + do {
- + if (TIFR1 & (1 << TOV1)) {
- + TIFR1 = 1 << TOV1;
- + timer_h++;
- + }
- + high = timer_h;
- + low = TCNT1L;
- + mid = TCNT1H;
- + }
- + while (TIFR1 & (1 << TOV1));
- +
- + /*
- + * We need all these casts because the intermediate results are handled
- + * as if they were signed and thus get sign-expanded. Sounds wrong-ish.
- + */
- + return (uint64_t) high << 16 | (uint64_t) mid << 8 | (uint64_t) low;
- +}
- +
- +
- +void timer_init(void)
- +{
- + /* configure timer 1 as a free-running CLK counter */
- +
- + TCCR1A = 0;
- + TCCR1B = 1 << CS10;
- +
- + /* enable timer overflow interrupt */
- +
- + TIMSK1 = 1 << TOIE1;
- +}
- +
- +
- +bool gpio(uint8_t port, uint8_t data, uint8_t dir, uint8_t mask, uint8_t *res)
- +{
- + EIMSK = 0; /* recover INT_RF to ATUSB_GPIO_CLEANUP or an MCU reset */
- +
- + switch (port) {
- + case 1:
- + DDRB = (DDRB & ~mask) | dir;
- + PORTB = (PORTB & ~mask) | data;
- + break;
- + case 2:
- + DDRC = (DDRC & ~mask) | dir;
- + PORTC = (PORTC & ~mask) | data;
- + break;
- + case 3:
- + DDRD = (DDRD & ~mask) | dir;
- + PORTD = (PORTD & ~mask) | data;
- + break;
- + default:
- + return 0;
- + }
- +
- + /* disable the UART so that we can meddle with these pins as well. */
- + spi_off();
- + _delay_ms(1);
- +
- + switch (port) {
- + case 1:
- + res[0] = PINB;
- + res[1] = PORTB;
- + res[2] = DDRB;
- + break;
- + case 2:
- + res[0] = PINC;
- + res[1] = PORTC;
- + res[2] = DDRC;
- + break;
- + case 3:
- + res[0] = PIND;
- + res[1] = PORTD;
- + res[2] = DDRD;
- + break;
- + }
- +
- + return 1;
- +}
- +
- +
- +void gpio_cleanup(void)
- +{
- + EIMSK = 1 << 0;
- +}
- +
- +
- +static void done(void *user)
- +{
- + led(0);
- +}
- +
- +
- +uint8_t irq_serial;
- +
- +#if defined(ATUSB) || defined(HULUSB)
- +ISR(INT0_vect)
- +#endif
- +#ifdef RZUSB
- +ISR(TIMER1_CAPT_vect)
- +#endif
- +{
- + if (mac_irq) {
- + if (mac_irq())
- + return;
- + }
- + if (eps[1].state == EP_IDLE) {
- + led(1);
- + irq_serial = (irq_serial+1) | 0x80;
- + usb_send(&eps[1], &irq_serial, 1, done, NULL);
- + }
- +}
- diff --git a/atusb/board_atusb.c b/atusb/board_atusb.c
- new file mode 100644
- index 0000000..a02fb7f
- --- /dev/null
- +++ b/atusb/board_atusb.c
- @@ -0,0 +1,162 @@
- +/*
- + * fw/board_atusb.c - ATUSB Board-specific functions (for boot loader and application)
- + *
- + * Written 2016 by Stefan Schmidt
- + * Copyright 2016 Stefan Schmidt
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +#include <avr/interrupt.h>
- +#include <avr/boot.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#include "usb.h"
- +#include "at86rf230.h"
- +#include "board.h"
- +#include "spi.h"
- +#include "usb/usb.h"
- +
- +static bool spi_initialized = 0;
- +
- +void reset_rf(void)
- +{
- + /* set up all the outputs; default port value is 0 */
- +
- + DDRB = 0;
- + DDRC = 0;
- + DDRD = 0;
- + PORTB = 0;
- + PORTC = 0;
- + PORTD = 0;
- +
- + OUT(LED);
- + OUT(nRST_RF); /* this also resets the transceiver */
- + OUT(SLP_TR);
- +
- + spi_init();
- +
- + /* AT86RF231 data sheet, 12.4.13, reset pulse width: 625 ns (min) */
- +
- + CLR(nRST_RF);
- + _delay_us(2);
- + SET(nRST_RF);
- +
- + /* 12.4.14: SPI access latency after reset: 625 ns (min) */
- +
- + _delay_us(2);
- +
- + /* we must restore TRX_CTRL_0 after each reset (9.6.4) */
- +
- + set_clkm();
- +}
- +
- +void led(bool on)
- +{
- + if (on)
- + SET(LED);
- + else
- + CLR(LED);
- +}
- +
- +void set_clkm(void)
- +{
- + /* switch CLKM to 8 MHz */
- +
- + /*
- + * @@@ Note: Atmel advise against changing the external clock in
- + * mid-flight. We should therefore switch to the RC clock first, then
- + * crank up the external clock, and finally switch back to the external
- + * clock. The clock switching procedure is described in the ATmega32U2
- + * data sheet in secton 8.2.2.
- + */
- + spi_begin();
- + spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0);
- + spi_send(CLKM_CTRL_8MHz);
- + spi_end();
- +}
- +
- +void board_init(void)
- +{
- + /* Disable the watchdog timer */
- +
- + MCUSR = 0; /* Remove override */
- + WDTCSR |= 1 << WDCE; /* Enable change */
- + WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
- + change */
- +
- + CLKPR = 1 << CLKPCE;
- + /* We start with a 1 MHz/8 clock. Disable the prescaler. */
- + CLKPR = 0;
- +
- + get_sernum();
- +}
- +
- +void spi_begin(void)
- +{
- + if (!spi_initialized)
- + spi_init();
- + CLR(nSS);
- +}
- +
- +void spi_off(void)
- +{
- + spi_initialized = 0;
- + UCSR1B = 0;
- +}
- +
- +void spi_init(void)
- +{
- + SET(nSS);
- + OUT(SCLK);
- + OUT(MOSI);
- + OUT(nSS);
- + IN(MISO);
- +
- + UBRR1 = 0; /* set bit rate to zero to begin */
- + UCSR1C = 1 << UMSEL11 | 1 << UMSEL10;
- + /* set MSPI, MSB first, SPI data mode 0 */
- + UCSR1B = 1 << RXEN1 | 1 << TXEN1;
- + /* enable receiver and transmitter */
- + UBRR1 = 0; /* reconfirm the bit rate */
- +
- + spi_initialized = 1;
- +}
- +
- +void usb_init(void)
- +{
- + USBCON |= 1 << FRZCLK; /* freeze the clock */
- +
- + /* enable the PLL and wait for it to lock */
- + PLLCSR &= ~(1 << PLLP2 | 1 << PLLP1 | 1 << PLLP0);
- + PLLCSR |= 1 << PLLE;
- + while (!(PLLCSR & (1 << PLOCK)));
- +
- + USBCON &= ~(1 << USBE); /* reset the controller */
- + USBCON |= 1 << USBE;
- +
- + USBCON &= ~(1 << FRZCLK); /* thaw the clock */
- +
- + UDCON &= ~(1 << DETACH); /* attach the pull-up */
- + UDIEN = 1 << EORSTE; /* enable device interrupts */
- +// UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
- +
- + ep_init();
- +}
- +
- +void board_app_init(void)
- +{
- + /* enable INT0, trigger on rising edge */
- + EICRA = 1 << ISC01 | 1 << ISC00;
- + EIMSK = 1 << 0;
- +}
- diff --git a/atusb/board_atusb.h b/atusb/board_atusb.h
- new file mode 100644
- index 0000000..e5974c7
- --- /dev/null
- +++ b/atusb/board_atusb.h
- @@ -0,0 +1,48 @@
- +/*
- + * fw/board_atusb.h - ATUSB Board-specific functions and definitions
- + *
- + * Written 2016 by Stefan Schmidt
- + * Copyright 2016 Stefan Schmidt
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef BOARD_ATUSB_H
- +#define BOARD_ATUSB_H
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#define LED_PORT B
- +#define LED_BIT 6
- +#define nRST_RF_PORT C
- +#define nRST_RF_BIT 7
- +#define SLP_TR_PORT B
- +#define SLP_TR_BIT 4
- +
- +#define SCLK_PORT D
- +#define SCLK_BIT 5
- +#define MOSI_PORT D
- +#define MOSI_BIT 3
- +
- +#define MISO_PORT D
- +#define MISO_BIT 2
- +#define nSS_PORT D
- +#define nSS_BIT 1
- +#define IRQ_RF_PORT D
- +#define IRQ_RF_BIT 0
- +
- +#define SPI_WAIT_DONE() while (!(UCSR1A & 1 << RXC1))
- +#define SPI_DATA UDR1
- +
- +void set_clkm(void);
- +void board_init(void);
- +
- +void spi_begin(void);
- +void spi_off(void);
- +void spi_init(void);
- +
- +#endif /* !BOARD_H */
- diff --git a/atusb/board_hulusb.c b/atusb/board_hulusb.c
- new file mode 100644
- index 0000000..084714e
- --- /dev/null
- +++ b/atusb/board_hulusb.c
- @@ -0,0 +1,179 @@
- +/*
- + * fw/board_hulusb.c - Busware HUL Board-specific functions (for boot loader and application)
- + *
- + * Written 2017 by Filzmaier Josef
- + * Based on fw/board_rzusb written and Copyright 2016 Stefan Schmidt
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +#include <avr/interrupt.h>
- +#include <avr/boot.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#include "usb.h"
- +#include "at86rf230.h"
- +#include "board.h"
- +#include "spi.h"
- +#include "usb/usb.h"
- +
- +static bool spi_initialized = 0;
- +
- +void reset_rf(void)
- +{
- + /* set up all the outputs; default port value is 0 */
- +
- + DDRB = 0;
- + DDRC = 0;
- + DDRD = 0;
- + PORTB = 0;
- + PORTC = 0;
- + PORTD = 0;
- +
- + OUT(LED_RED);
- + OUT(LED_GREEN);
- + SET(LED_RED); /* Leds are active low on HULUSB board */
- + CLR(LED_GREEN); /* Green Led indicates the dongle is running */
- + OUT(nRST_RF); /* this also resets the transceiver */
- + OUT(SLP_TR);
- +
- + spi_init();
- +
- + /* AT86RF212 data sheet, Appendix B, p166 Power-On Reset procedure */
- + /*-----------------------------------------------------------------*/
- + CLR(SLP_TR);
- + SET(nRST_RF);
- + SET(nSS);
- + _delay_us(400);
- +
- + CLR(nRST_RF);
- + _delay_us(2);
- + SET(nRST_RF);
- +
- + /* 5.1.4.5: Wait t10: 625 ns (min) */
- +
- + _delay_us(2);
- +
- + reg_write(REG_TRX_CTRL_0, 0x19);
- +
- + change_state(TRX_CMD_FORCE_TRX_OFF);
- + /*-----------------------------------------------------------------*/
- +
- + /* we must restore TRX_CTRL_0 after each reset (7.7.4) */
- +
- + set_clkm();
- +}
- +
- +void led_red(bool on) {
- + if (on)
- + CLR(LED_RED);
- + else
- + SET(LED_RED);
- +}
- +
- +void led_green(bool on) {
- + if (on)
- + CLR(LED_GREEN);
- + else
- + SET(LED_GREEN);
- +}
- +
- +void led(bool on)
- +{
- + led_red(on);
- +}
- +
- +void set_clkm(void)
- +{
- + /* CLKM is not connected on BUSWARE HUL and therefore it is running in
- + * async mode. */
- + reg_write(REG_TRX_CTRL_0, 0x00);
- +
- + /* TX_AUTO_CRC_ON, default disabled */
- + subreg_write(SR_TX_AUTO_CRC_ON, 1);
- +}
- +
- +void board_init(void)
- +{
- + /* Disable the watchdog timer */
- +
- + MCUSR = 0; /* Remove override */
- + WDTCSR |= 1 << WDCE; /* Enable change */
- + WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
- + change */
- +
- + CLKPR = 1 << CLKPCE;
- + /* We start with a 16 MHz/8 clock. Put the prescaler to 2. */
- + CLKPR = 1 << CLKPS0;
- +
- + get_sernum();
- +}
- +
- +void spi_begin(void)
- +{
- + if (!spi_initialized)
- + spi_init();
- + CLR(nSS);
- +}
- +
- +void spi_off(void)
- +{
- + spi_initialized = 0;
- + SPCR &= ~(1 << SPE);
- +}
- +
- +void spi_init(void)
- +{
- + SET(nSS);
- + OUT(SCLK);
- + OUT(MOSI);
- + OUT(nSS);
- + IN(MISO);
- +
- + SPCR = (1 << SPE) | (1 << MSTR);
- + SPSR = (1 << SPI2X);
- +
- + spi_initialized = 1;
- +}
- +
- +void usb_init(void)
- +{
- + USBCON |= 1 << FRZCLK; /* freeze the clock */
- +
- + /* enable the PLL and wait for it to lock */
- + /* TODO sheet page 50 For Atmel AT90USB128x only. Do not use with Atmel AT90USB64x. */
- + /* FOR 8 XTAL Mhz only!!! */
- + PLLCSR = ((1 << PLLP1) | (1 << PLLP0));
- + PLLCSR |= 1 << PLLE;
- + while (!(PLLCSR & (1 << PLOCK)));
- +
- + UHWCON |= (1 << UVREGE);
- +
- + USBCON &= ~((1 << USBE) | (1 << OTGPADE)); /* reset the controller */
- + USBCON |= ((1 << USBE) | (1 << OTGPADE));
- +
- + USBCON &= ~(1 << FRZCLK); /* thaw the clock */
- +
- + UDCON &= ~(1 << DETACH); /* attach the pull-up */
- + UDIEN = 1 << EORSTE; /* enable device interrupts */
- + // UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
- +
- + ep_init();
- +}
- +
- +void board_app_init(void)
- +{
- + /* enable INT0, trigger on rising edge */
- + EICRA = 1 << ISC01 | 1 << ISC00;
- + EIMSK = 1 << INT0;
- +}
- diff --git a/atusb/board_hulusb.h b/atusb/board_hulusb.h
- new file mode 100644
- index 0000000..a1dadf0
- --- /dev/null
- +++ b/atusb/board_hulusb.h
- @@ -0,0 +1,66 @@
- +/*
- + * fw/board_hulusb.h - Busware HUL Board-specific functions (for boot loader and application)
- + *
- + * Written 2017 by Filzmaier Josef
- + * Based on fw/board_rzusb written and Copyright 2016 Stefan Schmidt
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef BOARD_HULUSB_H
- +#define BOARD_HULUSB_H
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#define LED_RED_PORT A
- +#define LED_GREEN_PORT A
- +#define LED_RED_BIT 3
- +#define LED_GREEN_BIT 4
- +#define LED_PORT LED_RED_PORT
- +#define LED_BIT LED_RED_BIT
- +
- +#define nRST_RF_PORT B
- +#define nRST_RF_BIT 5
- +#define SLP_TR_PORT B
- +#define SLP_TR_BIT 4
- +
- +#define SCLK_PORT B
- +#define SCLK_BIT 1
- +#define MOSI_PORT B
- +#define MOSI_BIT 2
- +
- +#define MISO_PORT B
- +#define MISO_BIT 3
- +#define nSS_PORT B
- +#define nSS_BIT 0
- +#define IRQ_RF_PORT D
- +#define IRQ_RF_BIT 4
- +
- +#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5
- +#define SR_CHANNEL 0x08, 0x1f, 0
- +
- +#define RG_CC_CTRL_1 (0x14)
- +
- +#define SPI_WAIT_DONE() while ((SPSR & (1 << SPIF)) == 0)
- +#define SPI_DATA SPDR
- +
- +void set_clkm(void);
- +void board_init(void);
- +
- +void led_red(bool on);
- +void led_green(bool on);
- +
- +void spi_begin(void);
- +void spi_off(void);
- +void spi_init(void);
- +
- +#ifdef DEBUG
- +void printStatus(void);
- +#define PRINT_STATUS() printStatus()
- +#endif
- +
- +#endif /* !BOARD_HULUSB_H */
- diff --git a/atusb/board_rzusb.c b/atusb/board_rzusb.c
- new file mode 100644
- index 0000000..e83d6fa
- --- /dev/null
- +++ b/atusb/board_rzusb.c
- @@ -0,0 +1,169 @@
- +/*
- + * fw/board_rzusb.c - RZUSB Board-specific functions (for boot loader and application)
- + *
- + * Written 2016 by Stefan Schmidt
- + * Copyright 2016 Stefan Schmidt
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +#include <avr/interrupt.h>
- +#include <avr/boot.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#include "usb.h"
- +#include "at86rf230.h"
- +#include "board.h"
- +#include "spi.h"
- +#include "usb/usb.h"
- +
- +static bool spi_initialized = 0;
- +
- +void reset_rf(void)
- +{
- + /* set up all the outputs; default port value is 0 */
- +
- + DDRB = 0;
- + DDRC = 0;
- + DDRD = 0;
- + PORTB = 0;
- + PORTC = 0;
- + PORTD = 0;
- +
- + OUT(LED);
- + OUT(nRST_RF); /* this also resets the transceiver */
- + OUT(SLP_TR);
- +
- + spi_init();
- +
- + /* AT86RF231 data sheet, 12.4.13, reset pulse width: 625 ns (min) */
- +
- + CLR(nRST_RF);
- + _delay_us(2);
- + SET(nRST_RF);
- +
- + /* 12.4.14: SPI access latency after reset: 625 ns (min) */
- +
- + _delay_us(2);
- +
- + /* we must restore TRX_CTRL_0 after each reset (9.6.4) */
- +
- + set_clkm();
- +}
- +
- +void led(bool on)
- +{
- + if (on)
- + SET(LED);
- + else
- + CLR(LED);
- +}
- +
- +void set_clkm(void)
- +{
- + /* switch CLKM to 8 MHz */
- +
- + /*
- + * @@@ Note: Atmel advise against changing the external clock in
- + * mid-flight. We should therefore switch to the RC clock first, then
- + * crank up the external clock, and finally switch back to the external
- + * clock. The clock switching procedure is described in the ATmega32U2
- + * data sheet in secton 8.2.2.
- + */
- + spi_begin();
- + spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0);
- + spi_send(0x10);
- + spi_end();
- +
- + /* TX_AUTO_CRC_ON, default disabled */
- + spi_begin();
- + spi_send(AT86RF230_REG_WRITE | 0x05);
- + spi_send(0x80);
- + spi_end();
- +}
- +
- +void board_init(void)
- +{
- + /* Disable the watchdog timer */
- +
- + MCUSR = 0; /* Remove override */
- + WDTCSR |= 1 << WDCE; /* Enable change */
- + WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
- + change */
- +
- + CLKPR = 1 << CLKPCE;
- + /* We start with a 16 MHz/8 clock. Put the prescaler to 2. */
- + CLKPR = 1 << CLKPS0;
- +
- + get_sernum();
- +}
- +
- +void spi_begin(void)
- +{
- + if (!spi_initialized)
- + spi_init();
- + CLR(nSS);
- +}
- +
- +void spi_off(void)
- +{
- + spi_initialized = 0;
- + SPCR &= ~(1 << SPE);
- +}
- +
- +void spi_init(void)
- +{
- + SET(nSS);
- + OUT(SCLK);
- + OUT(MOSI);
- + OUT(nSS);
- + IN(MISO);
- +
- + SPCR = (1 << SPE) | (1 << MSTR);
- + SPSR = (1 << SPI2X);
- +
- + spi_initialized = 1;
- +}
- +
- +void usb_init(void)
- +{
- + USBCON |= 1 << FRZCLK; /* freeze the clock */
- +
- + /* enable the PLL and wait for it to lock */
- + /* TODO sheet page 50 For Atmel AT90USB128x only. Do not use with Atmel AT90USB64x. */
- + /* FOR 8 XTAL Mhz only!!! */
- + PLLCSR = ((1 << PLLP1) | (1 << PLLP0));
- + PLLCSR |= 1 << PLLE;
- + while (!(PLLCSR & (1 << PLOCK)));
- +
- + UHWCON |= (1 << UVREGE);
- +
- + USBCON &= ~((1 << USBE) | (1 << OTGPADE)); /* reset the controller */
- + USBCON |= ((1 << USBE) | (1 << OTGPADE));
- +
- + USBCON &= ~(1 << FRZCLK); /* thaw the clock */
- +
- + UDCON &= ~(1 << DETACH); /* attach the pull-up */
- + UDIEN = 1 << EORSTE; /* enable device interrupts */
- +// UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
- +
- + ep_init();
- +}
- +
- +void board_app_init(void)
- +{
- + /* enable timer input capture 1, trigger on rising edge */
- + TCCR1B = (1 << ICES1);
- + TIFR1 = (1 << ICF1);
- + TIMSK1 = (1 << ICIE1);
- +}
- diff --git a/atusb/board_rzusb.h b/atusb/board_rzusb.h
- new file mode 100644
- index 0000000..c2e518f
- --- /dev/null
- +++ b/atusb/board_rzusb.h
- @@ -0,0 +1,48 @@
- +/*
- + * fw/board_rzusb.h - RZUSB Board-specific functions and definitions
- + *
- + * Written 2016 by Stefan Schmidt
- + * Copyright 2016 Stefan Schmidt
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef BOARD_RZUSB_H
- +#define BOARD_RZUSB_H
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#define LED_PORT D
- +#define LED_BIT 7
- +#define nRST_RF_PORT B
- +#define nRST_RF_BIT 5
- +#define SLP_TR_PORT B
- +#define SLP_TR_BIT 4
- +
- +#define SCLK_PORT B
- +#define SCLK_BIT 1
- +#define MOSI_PORT B
- +#define MOSI_BIT 2
- +
- +#define MISO_PORT B
- +#define MISO_BIT 3
- +#define nSS_PORT B
- +#define nSS_BIT 0
- +#define IRQ_RF_PORT D
- +#define IRQ_RF_BIT 4
- +
- +#define SPI_WAIT_DONE() while ((SPSR & (1 << SPIF)) == 0)
- +#define SPI_DATA SPDR
- +
- +void set_clkm(void);
- +void board_init(void);
- +
- +void spi_begin(void);
- +void spi_off(void);
- +void spi_init(void);
- +
- +#endif /* !BOARD_H */
- diff --git a/atusb/boot.c b/atusb/boot.c
- new file mode 100644
- index 0000000..6826ac6
- --- /dev/null
- +++ b/atusb/boot.c
- @@ -0,0 +1,77 @@
- +/*
- + * fw/boot.c - DFU boot loader for ATUSB
- + *
- + * Written 2008-2011 by Werner Almesberger
- + * Copyright 2008-2011 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +#include <avr/interrupt.h>
- +#include <avr/pgmspace.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#include "usb.h"
- +#include "dfu.h"
- +
- +#include "board.h"
- +#include "spi.h"
- +#include "atusb/ep0.h"
- +
- +
- +#define MS_TO_LOOPS(ms) ((uint32_t) (ms)*335)
- +
- +
- +static void (*run_payload)(void) = 0;
- +
- +
- +int main(void)
- +{
- + /*
- + * pgm_read_byte gets cached and there doesn't seem to be any other
- + * way to dissuade gcc from doing this.
- + */
- + volatile int zero = 0;
- + uint32_t loop = 0;
- +
- + board_init();
- + reset_rf();
- +
- + /* now we should be at 8 MHz */
- +
- + usb_init();
- + dfu_init();
- +
- + /* move interrupt vectors to the boot loader */
- + MCUCR = 1 << IVCE;
- + MCUCR = 1 << IVSEL;
- +
- + sei();
- +
- + led(1);
- +
- + while (loop != MS_TO_LOOPS(2500)) {
- + if (dfu.state == dfuIDLE && pgm_read_byte(zero) != 0xff)
- + loop++;
- + else
- + loop = 0;
- + }
- +
- + led(0);
- +
- + cli();
- +
- + usb_reset();
- + run_payload();
- +
- + while (1); /* not reached */
- +}
- diff --git a/atusb/descr.c b/atusb/descr.c
- new file mode 100644
- index 0000000..f96b0ee
- --- /dev/null
- +++ b/atusb/descr.c
- @@ -0,0 +1,104 @@
- +/*
- + * fw/descr.c - USB descriptors
- + *
- + * Written 2008-2011, 2014 by Werner Almesberger
- + * Copyright 2008-2011, 2014 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include "usb.h"
- +#include "dfu.h"
- +#include "board.h"
- +
- +
- +#define LE(x) ((uint16_t) (x) & 0xff), ((uint16_t) (x) >> 8)
- +
- +/*
- + * Device descriptor
- + */
- +
- +const uint8_t device_descriptor[18] = {
- + 18, /* bLength */
- + USB_DT_DEVICE, /* bDescriptorType */
- + LE(0x200), /* bcdUSB */
- + USB_CLASS_VENDOR_SPEC, /* bDeviceClass */
- + 0x00, /* bDeviceSubClass */
- + 0x00, /* bDeviceProtocol */
- + EP0_SIZE, /* bMaxPacketSize */
- + LE(USB_VENDOR), /* idVendor */
- + LE(USB_PRODUCT), /* idProduct */
- + LE(0x0001), /* bcdDevice */
- + 0, /* iManufacturer */
- + 0, /* iProduct */
- +#ifdef HAS_BOARD_SERNUM
- + 1, /* iSerialNumber */
- +#else
- + 0, /* iSerialNumber */
- +#endif
- + 1 /* bNumConfigurations */
- +};
- +
- +
- +/*
- + * Our configuration
- + *
- + * We're always bus-powered.
- + */
- +
- +const uint8_t config_descriptor[] = {
- + 9, /* bLength */
- + USB_DT_CONFIG, /* bDescriptorType */
- +#if 0
- + LE(9+9+7+7), /* wTotalLength */
- +#else
- + LE(9+9+7+9), /* wTotalLength */
- +#endif
- + 2, /* bNumInterfaces */
- + 1, /* bConfigurationValue (> 0 !) */
- + 0, /* iConfiguration */
- + USB_ATTR_BUS_POWERED, /* bmAttributes */
- + ((BOARD_MAX_mA)+1)/2, /* bMaxPower */
- +
- + /* Interface #0 */
- +
- + 9, /* bLength */
- + USB_DT_INTERFACE, /* bDescriptorType */
- + 0, /* bInterfaceNumber */
- + 0, /* bAlternateSetting */
- + 1, /* bNumEndpoints */
- + USB_CLASS_VENDOR_SPEC, /* bInterfaceClass */
- + 0, /* bInterfaceSubClass */
- + 0, /* bInterfaceProtocol */
- + 0, /* iInterface */
- +
- +#if 0
- + /* EP OUT */
- +
- + 7, /* bLength */
- + USB_DT_ENDPOINT, /* bDescriptorType */
- + 0x01, /* bEndPointAddress */
- + 0x02, /* bmAttributes (bulk) */
- + LE(EP1_SIZE), /* wMaxPacketSize */
- + 0, /* bInterval */
- +#endif
- +
- +#if 1
- + /* EP IN */
- +
- + 7, /* bLength */
- + USB_DT_ENDPOINT, /* bDescriptorType */
- + 0x81, /* bEndPointAddress */
- + 0x02, /* bmAttributes (bulk) */
- + LE(EP1_SIZE), /* wMaxPacketSize */
- + 0, /* bInterval */
- +#endif
- +
- + /* Interface #1 */
- +
- + DFU_ITF_DESCR(1, 0, dfu_proto_runtime, 0)
- +};
- diff --git a/atusb/ep0.c b/atusb/ep0.c
- new file mode 100644
- index 0000000..fa43f3b
- --- /dev/null
- +++ b/atusb/ep0.c
- @@ -0,0 +1,338 @@
- +/*
- + * fw/ep0.c - EP0 extension protocol
- + *
- + * Written 2008-2011, 2013 by Werner Almesberger
- + * Copyright 2008-2011, 2013 Werner Almesberger
- + * Copyright 2015-2016 Stefan Schmidt
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +#include <string.h>
- +
- +#include <avr/io.h>
- +#include <avr/eeprom.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#ifndef NULL
- +#define NULL 0
- +#endif
- +
- +#include "usb.h"
- +#include "dfu.h"
- +
- +#include "at86rf230.h"
- +#include "atusb/ep0.h"
- +#include "version.h"
- +#include "board.h"
- +#include "sernum.h"
- +#include "spi.h"
- +#include "mac.h"
- +
- +#ifdef ATUSB
- +#define HW_TYPE ATUSB_HW_TYPE_110131
- +#endif
- +
- +#ifdef RZUSB
- +#define HW_TYPE ATUSB_HW_TYPE_RZUSB
- +#endif
- +
- +#ifdef HULUSB
- +#define HW_TYPE ATUSB_HW_TYPE_HULUSB
- +#endif
- +
- +#ifdef DEBUG
- +#include "uart.h"
- +#include <stdio.h>
- +#define debug(FORMAT,args...) printf(FORMAT,##args)
- +#define error(FORMAT,args...) printf(FORMAT,##args)
- +#else
- +#define debug(...)
- +#define error(...)
- +#endif
- +
- +
- +static const uint8_t id[] = { EP0ATUSB_MAJOR, EP0ATUSB_MINOR, HW_TYPE };
- +static uint8_t buf[MAX_PSDU+3]; /* command, PHDR, and LQI */
- +static uint8_t size;
- +
- +
- +static void do_eeprom_write(void *user)
- +{
- + int i;
- +
- + for (i = 0; i < size; i++)
- + eeprom_update_byte((uint8_t*)i, buf[i]);
- +}
- +
- +static void do_buf_write(void *user)
- +{
- + uint8_t i;
- +
- + spi_begin();
- + for (i = 0; i != size; i++)
- + spi_send(buf[i]);
- + spi_end();
- +}
- +
- +
- +#define BUILD_OFFSET 7 /* '#' plus "65535" plus ' ' */
- +
- +
- +static bool my_setup(const struct setup_request *setup)
- +{
- + uint16_t req = setup->bmRequestType | setup->bRequest << 8;
- + unsigned tmp;
- + uint8_t i;
- + uint64_t tmp64;
- +
- + switch (req) {
- + case ATUSB_FROM_DEV(ATUSB_ID):
- + debug("ATUSB_ID\n");
- + if (setup->wLength > 3)
- + return 0;
- + usb_send(&eps[0], id, setup->wLength, NULL, NULL);
- + return 1;
- + case ATUSB_FROM_DEV(ATUSB_BUILD):
- + debug("ATUSB_BUILD\n");
- + tmp = build_number;
- + for (i = BUILD_OFFSET-2; tmp; i--) {
- + buf[i] = (tmp % 10)+'0';
- + tmp /= 10;
- + }
- + buf[i] = '#';
- + buf[BUILD_OFFSET-1] = ' ';
- + for (size = 0; build_date[size]; size++)
- + buf[BUILD_OFFSET+size] = build_date[size];
- + size += BUILD_OFFSET-i;
- + if (size > setup->wLength)
- + return 0;
- + usb_send(&eps[0], buf+i, size, NULL, NULL);
- + return 1;
- +
- + case ATUSB_TO_DEV(ATUSB_RESET):
- + debug("ATUSB_RESET\n");
- + reset_cpu();
- + while (1);
- +
- + case ATUSB_TO_DEV(ATUSB_RF_RESET):
- + debug("ATUSB_RF_RESET\n");
- + reset_rf();
- + mac_reset();
- + //ep_send_zlp(EP_CTRL);
- + return 1;
- +
- + case ATUSB_FROM_DEV(ATUSB_POLL_INT):
- + debug("ATUSB_POLL_INT\n");
- + if (setup->wLength < 1)
- + return 0;
- + *buf = read_irq();
- + usb_send(&eps[0], buf, 1, NULL, NULL);
- + return 1;
- +
- + case ATUSB_FROM_DEV(ATUSB_TIMER):
- + debug("ATUSB_TIMER\n");
- + size = setup->wLength;
- + if (size > sizeof(tmp64))
- + size = sizeof(tmp64);
- + tmp64 = timer_read();
- + memcpy(buf, &tmp64, sizeof(tmp64));
- + usb_send(&eps[0], buf, size, NULL, NULL);
- + return 1;
- +
- + case ATUSB_FROM_DEV(ATUSB_GPIO):
- + debug("ATUSB_GPIO\n");
- + if (setup->wLength < 3)
- + return 0;
- + if (!gpio(setup->wIndex, setup->wValue, setup->wValue >> 8,
- + setup->wIndex >> 8, buf))
- + return 0;
- + usb_send(&eps[0], buf, 3, NULL, NULL);
- + return 1;
- + case ATUSB_TO_DEV(ATUSB_GPIO_CLEANUP):
- + gpio_cleanup();
- + return 1;
- +
- + case ATUSB_TO_DEV(ATUSB_SLP_TR):
- + debug("ATUSB_SLP_TR\n");
- + slp_tr();
- + return 1;
- +
- + case ATUSB_TO_DEV(ATUSB_REG_WRITE):
- + debug("ATUSB_REG_WRITE\n");
- + spi_begin();
- + spi_send(AT86RF230_REG_WRITE | setup->wIndex);
- + spi_send(setup->wValue);
- + spi_end();
- + //ep_send_zlp(EP_CTRL);
- + return 1;
- + case ATUSB_FROM_DEV(ATUSB_REG_READ):
- + debug("ATUSB_REG_READ\n");
- + spi_begin();
- + spi_send(AT86RF230_REG_READ | setup->wIndex);
- + *buf = spi_recv();
- + spi_end();
- + usb_send(&eps[0], buf, 1, NULL, NULL);
- + return 1;
- +
- + case ATUSB_TO_DEV(ATUSB_BUF_WRITE):
- + debug("ATUSB_BUF_WRITE\n");
- + if (setup->wLength < 1)
- + return 0;
- + if (setup->wLength > MAX_PSDU)
- + return 0;
- + buf[0] = AT86RF230_BUF_WRITE;
- + buf[1] = setup->wLength;
- + size = setup->wLength+2;
- + usb_recv(&eps[0], buf+2, setup->wLength, do_buf_write, NULL);
- + return 1;
- + case ATUSB_FROM_DEV(ATUSB_BUF_READ):
- + debug("ATUSB_BUF_READ\n");
- + if (setup->wLength < 2) /* PHR+LQI */
- + return 0;
- + if (setup->wLength > MAX_PSDU+2) /* PHR+PSDU+LQI */
- + return 0;
- + spi_begin();
- + spi_send(AT86RF230_BUF_READ);
- + size = spi_recv();
- + if (size >= setup->wLength)
- + size = setup->wLength-1;
- + for (i = 0; i != size+1; i++)
- + buf[i] = spi_recv();
- + spi_end();
- + usb_send(&eps[0], buf, size+1, NULL, NULL);
- + return 1;
- +
- + case ATUSB_TO_DEV(ATUSB_SRAM_WRITE):
- + debug("ATUSB_SRAM_WRITE\n");
- + if (setup->wIndex > SRAM_SIZE)
- + return 0;
- + if (setup->wIndex+setup->wLength > SRAM_SIZE)
- + return 0;
- + buf[0] = AT86RF230_SRAM_WRITE;
- + buf[1] = setup->wIndex;
- + size = setup->wLength+2;
- + usb_recv(&eps[0], buf+2, setup->wLength, do_buf_write, NULL);
- + return 1;
- + case ATUSB_FROM_DEV(ATUSB_SRAM_READ):
- + debug("ATUSB_SRAM_READ\n");
- + if (setup->wIndex > SRAM_SIZE)
- + return 0;
- + if (setup->wIndex+setup->wLength > SRAM_SIZE)
- + return 0;
- + spi_begin();
- + spi_send(AT86RF230_SRAM_READ);
- + spi_send(setup->wIndex);
- + for (i = 0; i != setup->wLength; i++)
- + buf[i] = spi_recv();
- + spi_end();
- + usb_send(&eps[0], buf, setup->wLength, NULL, NULL);
- + return 1;
- +
- + case ATUSB_TO_DEV(ATUSB_SPI_WRITE):
- + size = setup->wLength+2;
- + if (size > sizeof(buf))
- + return 0;
- + buf[0] = setup->wValue;
- + buf[1] = setup->wIndex;
- + if (setup->wLength)
- + usb_recv(&eps[0], buf+2, setup->wLength,
- + do_buf_write, NULL);
- + else
- + do_buf_write(NULL);
- + return 1;
- + case ATUSB_FROM_DEV(ATUSB_SPI_WRITE2_SYNC):
- + spi_begin();
- + spi_send(setup->wValue);
- + spi_send(setup->wIndex);
- + spi_end();
- + buf[0] = irq_serial;
- + if (setup->wLength)
- + usb_send(&eps[0], buf, 1, NULL, NULL);
- + return 1;
- +
- + case ATUSB_FROM_DEV(ATUSB_SPI_READ1):
- + case ATUSB_FROM_DEV(ATUSB_SPI_READ2):
- + spi_begin();
- + spi_send(setup->wValue);
- + if (req == ATUSB_FROM_DEV(ATUSB_SPI_READ2))
- + spi_send(setup->wIndex);
- + for (i = 0; i != setup->wLength; i++)
- + buf[i] = spi_recv();
- + spi_end();
- + usb_send(&eps[0], buf, setup->wLength, NULL, NULL);
- + return 1;
- +
- + case ATUSB_TO_DEV(ATUSB_RX_MODE):
- + return mac_rx(setup->wValue);
- + case ATUSB_TO_DEV(ATUSB_TX):
- + return mac_tx(setup->wValue, setup->wIndex, setup->wLength);
- + case ATUSB_TO_DEV(ATUSB_EUI64_WRITE):
- + debug("ATUSB_EUI64_WRITE\n");
- + usb_recv(&eps[0], buf, setup->wLength, do_eeprom_write, NULL);
- + _delay_ms(100);
- + reset_cpu();
- + return 1;
- +
- + case ATUSB_FROM_DEV(ATUSB_EUI64_READ):
- + debug("ATUSB_EUI64_READ\n");
- + eeprom_read_block(buf, (const void*)0, 8);
- + usb_send(&eps[0], buf, 8, NULL, NULL);
- + return 1;
- +
- + default:
- + error("Unrecognized SETUP: 0x%02x 0x%02x ...\n",
- + setup->bmRequestType, setup->bRequest);
- + return 0;
- + }
- +}
- +
- +
- +static bool my_dfu_setup(const struct setup_request *setup)
- +{
- + switch (setup->bmRequestType | setup->bRequest << 8) {
- + case DFU_TO_DEV(DFU_DETACH):
- + /* @@@ should use wTimeout */
- + dfu.state = appDETACH;
- + return 1;
- + default:
- + return dfu_setup_common(setup);
- + }
- +}
- +
- +
- +static void my_set_interface(int nth)
- +{
- + if (nth) {
- + user_setup = my_dfu_setup;
- + user_get_descriptor = dfu_my_descr;
- + dfu.state = appIDLE;
- + } else {
- + user_setup = my_setup;
- + user_get_descriptor = sernum_get_descr;
- + }
- +}
- +
- +
- +static void my_reset(void)
- +{
- + if (dfu.state == appDETACH)
- + reset_cpu();
- +}
- +
- +
- +void ep0_init(void)
- +{
- + user_setup = my_setup;
- + user_set_interface = my_set_interface;
- + my_set_interface(0);
- + user_reset = my_reset;
- +}
- diff --git a/atusb/flash.c b/atusb/flash.c
- new file mode 100644
- index 0000000..1f8e59d
- --- /dev/null
- +++ b/atusb/flash.c
- @@ -0,0 +1,97 @@
- +/*
- + * fw/flash.c - Board-specific flash functions
- + *
- + * Written 2011, 2013-2015 by Werner Almesberger
- + * Copyright 2011, 2013-2015 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <avr/boot.h>
- +#include <avr/pgmspace.h>
- +
- +#include "dfu.h"
- +#include "board.h"
- +
- +
- +static uint32_t payload;
- +
- +
- +static void flash_start(void)
- +{
- + payload = 0;
- +}
- +
- +
- +static bool flash_can_write(uint16_t size)
- +{
- + return payload+size <= BOOT_ADDR;
- +}
- +
- +
- +static void flash_write(const uint8_t *buf, uint16_t size)
- +{
- + static uint8_t last;
- + const uint8_t *p;
- +
- + for (p = buf; p != buf+size; p++) {
- + if (!(payload & (SPM_PAGESIZE-1))) {
- + boot_page_erase(payload);
- + boot_spm_busy_wait();
- + }
- +
- + if (payload & 1)
- + boot_page_fill(payload, last | (*p << 8));
- + else
- + last = *p;
- + payload++;
- +
- + if (!(payload & (SPM_PAGESIZE-1))) {
- + boot_page_write(payload-SPM_PAGESIZE);
- + boot_spm_busy_wait();
- + }
- + }
- +}
- +
- +
- +static void flash_end_write(void)
- +{
- + if (payload & (SPM_PAGESIZE-1)) {
- + boot_page_write(payload & ~(SPM_PAGESIZE-1));
- + boot_spm_busy_wait();
- + }
- + boot_rww_enable();
- +}
- +
- +
- +static uint16_t flash_read(uint8_t *buf, uint16_t size)
- +{
- + uint16_t got = 0;
- +
- + while (size && payload != (uint32_t) FLASHEND+1) {
- + *buf++ = pgm_read_byte(payload);
- + payload++;
- + size--;
- + got++;
- + }
- + return got;
- +}
- +
- +
- +static const struct dfu_flash_ops flash_ops = {
- + .start = flash_start,
- + .can_write = flash_can_write,
- + .write = flash_write,
- + .end_write = flash_end_write,
- + .read = flash_read,
- +};
- +
- +
- +const struct dfu_flash_ops *dfu_flash_ops = &flash_ops;
- diff --git a/atusb/include/at86rf230.h b/atusb/include/at86rf230.h
- new file mode 100644
- index 0000000..4c3ae22
- --- /dev/null
- +++ b/atusb/include/at86rf230.h
- @@ -0,0 +1,402 @@
- +/*
- + * include/at86rf230.h - AT86RF230/AT86RF231 protocol and register definitions
- + *
- + * Written 2008-2011 by Werner Almesberger
- + * Copyright 2008-2011 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#ifndef AT86RF230_H
- +#define AT86RF230_H
- +
- +enum {
- + AT86RF230_REG_WRITE = 0xc0, /* 11... */
- + AT86RF230_REG_READ = 0x80, /* 10... */
- + AT86RF230_BUF_WRITE = 0x60, /* 011... */
- + AT86RF230_BUF_READ = 0x20, /* 001... */
- + AT86RF230_SRAM_WRITE = 0x40, /* 010... */
- + AT86RF230_SRAM_READ = 0x00 /* 000... */
- +};
- +
- +#define MAX_PSDU 127 /* octets, see AT86RF230 manual section 8.1 */
- +#define SRAM_SIZE 128
- +
- +
- +/* --- Registers ----------------------------------------------------------- */
- +
- +enum {
- + REG_TRX_STATUS = 0x01,
- + REG_TRX_STATE = 0x02,
- + REG_TRX_CTRL_0 = 0x03,
- +
- + REG_TRX_CTRL_1 = 0x04, /* 231 only */
- +
- + REG_PHY_TX_PWR = 0x05,
- + REG_PHY_RSSI = 0x06,
- + REG_PHY_ED_LEVEL = 0x07,
- + REG_PHY_CC_CCA = 0x08,
- + REG_CCA_THRES = 0x09,
- +
- + REG_RX_CTRL = 0x0a, /* 231 only */
- + REG_SFD_VALUE = 0x0b, /* 231 only */
- + REG_TRX_CTRL_2 = 0x0c, /* 231 only */
- + REG_ANT_DIV = 0x0d, /* 231 only */
- +
- + REG_IRQ_MASK = 0x0e,
- + REG_IRQ_STATUS = 0x0f,
- + REG_VREG_CTRL = 0x10,
- + REG_BATMON = 0x11,
- + REG_XOSC_CTRL = 0x12,
- +
- + REG_RX_SYN = 0x15, /* 231 only */
- + REG_XAH_CTRL_1 = 0x17, /* 231 only */
- + REG_FTN_CTRL = 0x18, /* 231 only */
- +
- + REG_PLL_CF = 0x1a,
- + REL_PLL_DCU = 0x1b,
- + REG_PART_NUM = 0x1c,
- + REG_VERSION_NUM = 0x1d,
- + REG_MAN_ID_0 = 0x1e,
- + REG_MAN_ID_1 = 0x1f,
- + REG_SHORT_ADDR_0 = 0x20,
- + REG_SHORT_ADDR_1 = 0x21,
- + REG_PAN_ID_0 = 0x22,
- + REG_PAN_ID_1 = 0x23,
- + REG_IEEE_ADDR_0 = 0x24,
- + REG_IEEE_ADDR_1 = 0x25,
- + REG_IEEE_ADDR_2 = 0x26,
- + REG_IEEE_ADDR_3 = 0x27,
- + REG_IEEE_ADDR_4 = 0x28,
- + REG_IEEE_ADDR_5 = 0x29,
- + REG_IEEE_ADDR_6 = 0x2a,
- + REG_IEEE_ADDR_7 = 0x2b,
- +
- + REG_XAH_CTRL_0 = 0x2c, /* XAH_CTRL in 230 */
- + REG_CSMA_SEED_0 = 0x2d,
- + REG_CSMA_SEED_1 = 0x2e,
- + REG_CSMA_BE = 0x2f, /* 231 only */
- +
- + REG_CONT_TX_0 = 0x36,
- + REG_CONT_TX_1 = 0x3d, /* 230 only */
- +};
- +
- +/* --- TRX_STATUS --- ------------------------------------------------------ */
- +
- +#define CCA_DONE (1 << 7)
- +#define CCA_STATUS (1 << 6)
- +
- +#define TRX_STATUS_SHIFT 0
- +#define TRX_STATUS_MASK 0x1f
- +
- +enum {
- + TRX_STATUS_P_ON = 0x00, /* reset default */
- + TRX_STATUS_BUSY_RX = 0x01,
- + TRX_STATUS_BUSY_TX = 0x02,
- + TRX_STATUS_RX_ON = 0x06,
- + TRX_STATUS_TRX_OFF = 0x08,
- + TRX_STATUS_PLL_ON = 0x09,
- + TRX_STATUS_SLEEP = 0x0f,
- + TRX_STATUS_BUSY_RX_AACK = 0x11,
- + TRX_STATUS_BUSY_TX_ARET = 0x12,
- + TRX_STATUS_RX_AACK_ON = 0x16,
- + TRX_STATUS_TX_ARET_ON = 0x19,
- + TRX_STATUS_RX_ON_NOCLK = 0x1c,
- + TRX_STATUS_RX_AACK_ON_NOCLK = 0x1d,
- + TRX_STATUS_BUSY_RX_AACK_NOCLK = 0x1e,
- + TRX_STATUS_TRANSITION = 0x1f /* ..._IN_PROGRESS */
- +};
- +
- +/* --- TRX_STATE ----------------------------------------------------------- */
- +
- +#define TRAC_STATUS_SHIFT 5
- +#define TRAC_STATUS_MASK 7
- +
- +enum {
- + TRAC_STATUS_SUCCESS = 0, /* reset default */
- + TRAC_STATUS_SUCCESS_DATA_PENDING = 1,
- + TRAC_STATUS_SUCCESS_WAIT_FOR_ACK = 2, /* 231 only */
- + TRAC_STATUS_CHANNEL_ACCESS_FAILURE = 3,
- + TRAC_STATUS_NO_ACK = 5,
- + TRAC_STATUS_INVALID = 7
- +};
- +
- +#define TRX_CMD_SHIFT 0
- +#define TRX_CMD_MASK 0x1f
- +
- +enum {
- + TRX_CMD_NOP = 0x00, /* reset default */
- + TRX_CMD_TX_START = 0x02,
- + TRX_CMD_FORCE_TRX_OFF = 0x03,
- + TRX_CMD_FORCE_PLL_ON = 0x04, /* 231 only */
- + TRX_CMD_RX_ON = 0x06,
- + TRX_CMD_TRX_OFF = 0x08,
- + TRX_CMD_PLL_ON = 0x09,
- + TRX_CMD_RX_AACK_ON = 0x16,
- + TRX_CMD_TX_ARET_ON = 0x19,
- +};
- +
- +/* --- TRX_CTRL_0 ---------------------------------------------------------- */
- +
- +#define PAD_IO_SHIFT 6
- +#define PAD_IO_MASK 3
- +
- +enum {
- + PAD_IO_2mA, /* reset default */
- + PAD_IO_4mA,
- + PAD_IO_6mA,
- + PAD_IO_8mA
- +};
- +
- +#define PAD_IO_CLKM_SHIFT 4
- +#define PAD_IO_CLKM_MASK 3
- +
- +enum {
- + PAD_IO_CLKM_2mA,
- + PAD_IO_CLKM_4mA, /* reset default */
- + PAD_IO_CLKM_5mA,
- + PAD_IO_CLKM_8mA,
- +};
- +
- +#define CLKM_SHA_SEL (1 << 3)
- +
- +#define CLKM_CTRL_SHIFT 0
- +#define CLKM_CTRL_MASK 7
- +
- +enum {
- + CLKM_CTRL_OFF = 0,
- + CLKM_CTRL_1MHz = 1, /* reset default */
- + CLKM_CTRL_2MHz = 2,
- + CLKM_CTRL_4MHz = 3,
- + CLKM_CTRL_8MHz = 4,
- + CLKM_CTRL_16MHz = 5
- +};
- +
- +/* --- TRX_CTRL_1 (231 only) ----------------------------------------------- */
- +
- +#define PA_EXT_EN (1 << 7)
- +#define IRQ_2_EXT_EN (1 << 6)
- +#define TX_AUTO_CRC_ON (1 << 5) /* 231 location */
- +#define RX_BL_CTRL (1 << 4)
- +
- +#define SPI_CMD_MODE_SHIFT 2
- +#define SPI_CMD_MODE_MASK 3
- +
- +enum {
- + SPI_CMD_MODE_EMPTY = 0, /* reset default */
- + SPI_CMD_MODE_TRX_STATUS = 1,
- + SPI_CMD_MODE_PHY_RSSI = 2,
- + SPI_CMD_MODE_IRQ_STATUS = 3,
- +};
- +
- +#define IRQ_MASK_MODE (1 << 1)
- +#define IRQ_POLARITY (1 << 0)
- +
- +/* --- PHY_TX_PWR ---------------------------------------------------------- */
- +
- +#define TX_AUTO_CRC_ON_230 (1 << 7) /* 230 location */
- +
- +#define PA_BUF_LT_SHIFT 6
- +#define PA_BUF_LT_MASK 3
- +
- +#define PA_LT_SHIFT 4
- +#define PA_LT_MASK 3
- +
- +#define TX_PWR_SHIFT 0
- +#define TX_PWR_MASK 0x0f
- +
- +/* --- PHY_RSSI ------------------------------------------------------------ */
- +
- +#define RX_CRC_VALID (1 << 7)
- +
- +#define RND_VALUE_SHIFT 5 /* 231 only */
- +#define RND_VALUE_MASK 3
- +
- +#define RSSI_SHIFT 0
- +#define RSSI_MASK 0x1f
- +
- +/* --- PHY_CC_CCA ---------------------------------------------------------- */
- +
- +#define CCA_REQUEST (1 << 7)
- +
- +#define CCA_MODE_SHIFT 5
- +#define CCA_MODE_MASK 3
- +
- +enum {
- + CCA_MODE_CARRIER_OR_ENERGY = 0, /* 231 only */
- + CCA_MODE_ENERGY = 1, /* reset default */
- + CCA_MODE_CARRIER = 2,
- + CCA_MODE_CARRIER_AND_ENERGY = 3
- +};
- +
- +#define CHANNEL_SHIFT 0
- +#define CHANNEL_MASK 0x1f
- +
- +/* --- CCA_THRES ----------------------------------------------------------- */
- +
- +#define CCA_ED_THRES_SHIFT 0
- +#define CCA_ED_THRES_MASK 0x0f
- +
- +/* --- RX_CTRL (231 only) -------------------------------------------------- */
- +
- +#define PDT_THRES_SHIFT 0
- +#define PDT_THRES_MASK 0x0f
- +
- +enum {
- + PDT_THRES_DEFAULT = 0x07, /* reset default */
- + PDT_THRES_DIVERSITY = 0x03,
- +};
- +
- +/* --- TRX_CTRL_2 (231 only) ----------------------------------------------- */
- +
- +#define RX_SAFE_MODE (1 << 7)
- +
- +#define OQPSK_DATA_RATE_SHIFT 0
- +#define OQPSK_DATA_RATE_MASK 3
- +
- +enum {
- + OQPSK_DATA_RATE_250 = 0, /* reset default */
- + OQPSK_DATA_RATE_500 = 1,
- + OQPSK_DATA_RATE_1000 = 2,
- + OQPSK_DATA_RATE_2000 = 3
- +};
- +
- +/* --- ANT_DIV (231 only) -------------------------------------------------- */
- +
- +#define ANT_SEL (1 << 7)
- +#define ANT_DIV_EN (1 << 3)
- +#define ANT_EXT_SW_EN (1 << 2)
- +
- +#define ANT_CTRL_SHIFT 0
- +#define ANT_CTRL_MASK 3
- +
- +enum {
- + ANT_CTRL_ANT_0 = 1,
- + ANT_CTRL_ANT_1 = 2,
- + ANT_CTRL_NODIV = 3, /* reset default */
- +};
- +
- +/* --- IRQ_MASK/IRQ_STATUS ------------------------------------------------- */
- +
- +enum {
- + IRQ_PLL_LOCK = 1 << 0,
- + IRQ_PLL_UNLOCK = 1 << 1,
- + IRQ_RX_START = 1 << 2,
- + IRQ_TRX_END = 1 << 3,
- + IRQ_CCA_ED_DONE = 1 << 4, /* 231 only */
- + IRQ_AMI = 1 << 5, /* 231 only */
- + IRQ_TRX_UR = 1 << 6,
- + IRQ_BAT_LOW = 1 << 7
- +};
- +
- +/* --- VREG_CTRL ----------------------------------------------------------- */
- +
- +#define AVREG_EXT (1 << 7)
- +#define AVDD_OK (1 << 6)
- +#define DVREG_EXT (1 << 3)
- +#define DVDD_OK (1 << 2)
- +
- +/* --- BATMON -------------------------------------------------------------- */
- +
- +#define BATMON_OK (1 << 5)
- +#define BATMON_HR (1 << 4)
- +
- +#define BATMON_VTH_SHIFT 0
- +#define BATMON_VTH_MASK 0x0f
- +
- +/* --- XOSC_CTRL ----------------------------------------------------------- */
- +
- +#define XTAL_MODE_SHIFT 4
- +#define XTAL_MODE_MASK 0x0f
- +
- +enum {
- + XTAL_MODE_OFF = 0x0, /* 230 only */
- + XTAL_MODE_EXT = 0x4,
- + XTAL_MODE_INT = 0xf /* reset default */
- +};
- +
- +#define XTAL_TRIM_SHIFT 4
- +#define XTAL_TRIM_MASK 0x0f
- +
- +/* --- RX_SYN (231 only) --------------------------------------------------- */
- +
- +#define RX_PDT_DIS (1 << 7)
- +
- +#define RX_PDT_LEVEL_SHIFT 0
- +#define RX_PDT_LEVEL_MASK 0xf
- +
- +/* --- XAH_CTRL_1 (231 only) ----------------------------------------------- */
- +
- +#define AACK_FLTR_RES_FT (1 << 5)
- +#define AACK_UPLD_RES_FT (1 << 4)
- +#define AACK_ACK_TIME (1 << 2)
- +#define AACK_PROM_MODE (1 << 1)
- +
- +/* --- FTN_CTRL (231 only) ------------------------------------------------- */
- +
- +#define FTN_START (1 << 7)
- +
- +/* --- PLL_CF -------------------------------------------------------------- */
- +
- +#define PLL_CF_START (1 << 7)
- +
- +/* --- PLL_DCU ------------------------------------------------------------- */
- +
- +#define PLL_DCU_START (1 << 7)
- +
- +/* --- XAH_CTRL_0 (XAH_CTRL in 230) ---------------------------------------- */
- +
- +#define MAX_FRAME_RETRIES_SHIFT 4
- +#define MAX_FRAME_RETRIES_MASK 0x0f
- +
- +#define MAX_CSMA_RETRIES_SHIFT 1
- +#define MAX_CSMA_RETRIES_MASK 0x07
- +
- +#define SLOTTED_OPERATION (1 << 0) /* 231 only */
- +
- +/* --- CSMA_SEED_1 --------------------------------------------------------- */
- +
- +#define MIN_BE_SHIFT_230 6 /* 230 location */
- +#define MIN_BE_MASK_230 3
- +
- +#define AACK_FVN_MODE_SHIFT 6 /* 231 only */
- +#define AACK_FVN_MODE_MASK 3
- +
- +enum {
- + AACK_FVN_MODE_0 = 0,
- + AACK_FVN_MODE_01 = 1, /* reset default */
- + AACK_FVN_MODE_012 = 2,
- + AACK_FVN_MODE_ANY = 3
- +};
- +
- +#define AACK_SET_PD (1 << 5)
- +#define AACK_DIS_ACK (1 << 4) /* 231 only */
- +#define I_AM_COORD (1 << 3)
- +
- +#define CSMA_SEED_1_SHIFT 0
- +#define CSMA_SEED_1_MASK 7
- +
- +/* --- CSMA_BE ------------------------------------------------------------- */
- +
- +#define MAX_BE_SHIFT 4
- +#define MAX_BE_MASK 0x0f
- +
- +#define MIN_BE_SHIFT 0 /* 231 location */
- +#define MIN_BE_MASK 0x0f
- +
- +/* --- REG_CONT_TX_0 ------------------------------------------------------- */
- +
- +#define CONT_TX_MAGIC 0x0f
- +
- +/* --- REG_CONT_TX_1 (230 only) -------------------------------------------- */
- +
- +#define CONT_TX_MOD 0x00 /* modulated */
- +#define CONT_TX_M2M 0x10 /* f_CH-2 MHz */
- +#define CONT_TX_M500K 0x80 /* f_CH-0.5 MHz */
- +#define CONT_TX_P500K 0xc0 /* f_CH+0.5 MHz */
- +
- +#endif /* !AT86RF230_H */
- diff --git a/atusb/include/atusb/atusb.h b/atusb/include/atusb/atusb.h
- new file mode 100644
- index 0000000..555d14b
- --- /dev/null
- +++ b/atusb/include/atusb/atusb.h
- @@ -0,0 +1,97 @@
- +/*
- + * atusb.h - Definitions shared between kernel and ATUSB firmware
- + *
- + * Written 2013 by Werner Almesberger <werner@almesberger.net>
- + *
- + * This program is free software; you can redistribute it and/or
- + * modify it under the terms of the GNU General Public License as
- + * published by the Free Software Foundation, version 2, or
- + * (at your option) any later version.
- + *
- + * This file should be identical for kernel and firmware.
- + * Kernel: drivers/net/ieee802154/atusb.h
- + * Firmware: ben-wpan/atusb/fw/include/atusb/atusb.h
- + */
- +
- +#ifndef _ATUSB_H
- +#define _ATUSB_H
- +
- +#define ATUSB_VENDOR_ID 0x20b7 /* Qi Hardware*/
- +#define ATUSB_PRODUCT_ID 0x1540 /* 802.15.4, device 0 */
- + /* -- - - */
- +
- +#define ATUSB_BUILD_SIZE 256 /* maximum build version/date message length */
- +
- +/* Commands to our device. Make sure this is synced with the firmware */
- +enum atusb_requests {
- + ATUSB_ID = 0x00, /* system status/control grp */
- + ATUSB_BUILD,
- + ATUSB_RESET,
- + ATUSB_RF_RESET = 0x10, /* debug/test group */
- + ATUSB_POLL_INT,
- + ATUSB_TEST, /* atusb-sil only */
- + ATUSB_TIMER,
- + ATUSB_GPIO,
- + ATUSB_SLP_TR,
- + ATUSB_GPIO_CLEANUP,
- + ATUSB_REG_WRITE = 0x20, /* transceiver group */
- + ATUSB_REG_READ,
- + ATUSB_BUF_WRITE,
- + ATUSB_BUF_READ,
- + ATUSB_SRAM_WRITE,
- + ATUSB_SRAM_READ,
- + ATUSB_SPI_WRITE = 0x30, /* SPI group */
- + ATUSB_SPI_READ1,
- + ATUSB_SPI_READ2,
- + ATUSB_SPI_WRITE2_SYNC,
- + ATUSB_RX_MODE = 0x40, /* HardMAC group */
- + ATUSB_TX,
- + ATUSB_EUI64_WRITE = 0x50, /* Parameter in EEPROM grp */
- + ATUSB_EUI64_READ,
- +};
- +
- +enum {
- + ATUSB_HW_TYPE_100813, /* 2010-08-13 */
- + ATUSB_HW_TYPE_101216, /* 2010-12-16 */
- + ATUSB_HW_TYPE_110131, /* 2011-01-31, ATmega32U2-based */
- + ATUSB_HW_TYPE_RZUSB, /* Atmel Raven USB dongle with at86rf230 */
- + ATUSB_HW_TYPE_HULUSB, /* Busware HUL USB dongle with at86rf212 */
- +};
- +
- +/*
- + * Direction bRequest wValue wIndex wLength
- + *
- + * ->host ATUSB_ID - - 3
- + * ->host ATUSB_BUILD - - #bytes
- + * host-> ATUSB_RESET - - 0
- + *
- + * host-> ATUSB_RF_RESET - - 0
- + * ->host ATUSB_POLL_INT - - 1
- + * host-> ATUSB_TEST - - 0
- + * ->host ATUSB_TIMER - - #bytes (6)
- + * ->host ATUSB_GPIO dir+data mask+p# 3
- + * host-> ATUSB_SLP_TR - - 0
- + * host-> ATUSB_GPIO_CLEANUP - - 0
- + *
- + * host-> ATUSB_REG_WRITE value addr 0
- + * ->host ATUSB_REG_READ - addr 1
- + * host-> ATUSB_BUF_WRITE - - #bytes
- + * ->host ATUSB_BUF_READ - - #bytes
- + * host-> ATUSB_SRAM_WRITE - addr #bytes
- + * ->host ATUSB_SRAM_READ - addr #bytes
- + *
- + * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
- + * ->host ATUSB_SPI_READ1 byte0 - #bytes
- + * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes
- + * ->host ATUSB_SPI_WRITE2_SYNC byte0 byte1 0/1
- + *
- + * host-> ATUSB_RX_MODE on - 0
- + * host-> ATUSB_TX flags ack_seq #bytes
- + * host-> ATUSB_EUI64_WRITE - - #bytes (8)
- + * ->host ATUSB_EUI64_READ - - #bytes (8)
- + */
- +
- +#define ATUSB_REQ_FROM_DEV (USB_TYPE_VENDOR | USB_DIR_IN)
- +#define ATUSB_REQ_TO_DEV (USB_TYPE_VENDOR | USB_DIR_OUT)
- +
- +#endif /* !_ATUSB_H */
- diff --git a/atusb/include/atusb/ep0.h b/atusb/include/atusb/ep0.h
- new file mode 100644
- index 0000000..7777345
- --- /dev/null
- +++ b/atusb/include/atusb/ep0.h
- @@ -0,0 +1,64 @@
- +/*
- + * include/atusb/ep0.h - EP0 extension protocol
- + *
- + * Written 2008-2011, 2013 by Werner Almesberger
- + * Copyright 2008-2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#ifndef EP0_H
- +#define EP0_H
- +
- +#include <atusb/atusb.h>
- +
- +
- +/*
- + * EP0 protocol:
- + *
- + * 0.0 initial release
- + * 0.1 addition of ATUSB_TEST
- + * 0.2 First public release
- + * 0.3 ATUSB_EUI64_READ/WRITE for permanent EUI64 handling
- + * Support to run the firmware on Atmel Raven USB dongles
- + * Remove FCS frame check from firmware and leave it to the driver
- + * Use extended operation mode for TX for automatic ACK handling
- + */
- +
- +#define EP0ATUSB_MAJOR 0 /* EP0 protocol, major revision */
- +#define EP0ATUSB_MINOR 3 /* EP0 protocol, minor revision */
- +
- +
- +/*
- + * bmRequestType:
- + *
- + * D7 D6..5 D4...0
- + * | | |
- + * direction (0 = host->dev)
- + * type (2 = vendor)
- + * recipient (0 = device)
- + */
- +
- +#ifndef USB_TYPE_VENDOR
- +#define USB_TYPE_VENDOR 0x40
- +#endif
- +
- +#ifndef USB_DIR_IN
- +#define USB_DIR_IN 0x80
- +#endif
- +
- +#ifndef USB_DIR_OUT
- +#define USB_DIR_OUT 0x00
- +#endif
- +
- +#define ATUSB_FROM_DEV(req) (ATUSB_REQ_FROM_DEV | (req) << 8)
- +#define ATUSB_TO_DEV(req) (ATUSB_REQ_TO_DEV | (req) << 8)
- +
- +
- +void ep0_init(void);
- +
- +#endif /* !EP0_H */
- diff --git a/atusb/mac.c b/atusb/mac.c
- new file mode 100644
- index 0000000..835002c
- --- /dev/null
- +++ b/atusb/mac.c
- @@ -0,0 +1,250 @@
- +/*
- + * fw/mac.c - HardMAC functions
- + *
- + * Written 2011, 2013 by Werner Almesberger
- + * Copyright 2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#include <stddef.h>
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include "usb.h"
- +
- +#include "at86rf230.h"
- +#include "spi.h"
- +#include "board.h"
- +#include "mac.h"
- +
- +#define RX_BUFS 3
- +
- +
- +bool (*mac_irq)(void) = NULL;
- +
- +
- +static uint8_t rx_buf[RX_BUFS][MAX_PSDU+2]; /* PHDR+payload+LQ */
- +static uint8_t tx_buf[MAX_PSDU];
- +static uint8_t tx_size = 0;
- +static bool txing = 0;
- +static bool queued_tx_ack = 0;
- +static uint8_t next_seq, this_seq, queued_seq;
- +
- +
- +/* ----- Receive buffer management ----------------------------------------- */
- +
- +
- +static uint8_t rx_in = 0, rx_out = 0;
- +
- +
- +static inline void next_buf(uint8_t *index)
- +{
- + *index = (*index+1) % RX_BUFS;
- +}
- +
- +
- +/* ----- Interrupt handling ------------------------------------------------ */
- +
- +
- +static void rx_done(void *user);
- +static void tx_ack_done(void *user);
- +
- +
- +static void usb_next(void)
- +{
- + const uint8_t *buf;
- +
- + if (rx_in != rx_out) {
- + buf = rx_buf[rx_out];
- + led(1);
- + usb_send(&eps[1], buf, buf[0]+2, rx_done, NULL);
- + }
- +
- + if (queued_tx_ack) {
- + usb_send(&eps[1], &queued_seq, 1, tx_ack_done, NULL);
- + queued_tx_ack = 0;
- + }
- +}
- +
- +
- +static void tx_ack_done(void *user)
- +{
- + usb_next();
- +}
- +
- +static void rx_done(void *user)
- +{
- + led(0);
- + next_buf(&rx_out);
- + usb_next();
- +#ifdef AT86RF230
- + /* slap at86rf230 - reduce fragmentation issue */
- + change_state(TRX_STATUS_RX_AACK_ON);
- +#endif
- +}
- +
- +
- +static void receive_frame(void)
- +{
- + uint8_t size;
- + uint8_t *buf;
- +
- + spi_begin();
- + spi_io(AT86RF230_BUF_READ);
- +
- + size = spi_recv();
- + if (!size || (size & 0x80)) {
- + spi_end();
- + return;
- + }
- +
- + buf = rx_buf[rx_in];
- + spi_recv_block(buf+1, size+1);
- + spi_end();
- +
- + buf[0] = size;
- + next_buf(&rx_in);
- +
- + if (eps[1].state == EP_IDLE)
- + usb_next();
- +}
- +
- +
- +static bool handle_irq(void)
- +{
- + uint8_t irq;
- +
- + irq = reg_read(REG_IRQ_STATUS);
- + if (!(irq & IRQ_TRX_END))
- + return 1;
- +
- + if (txing) {
- + if (eps[1].state == EP_IDLE) {
- + usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
- + } else {
- + queued_tx_ack = 1;
- + queued_seq = this_seq;
- + }
- + txing = 0;
- + return 1;
- + }
- +
- + /* likely */
- + if (eps[1].state == EP_IDLE || rx_in != rx_out)
- + receive_frame();
- +
- + return 1;
- +}
- +
- +
- +/* ----- TX/RX ------------------------------------------------------------- */
- +
- +
- +bool mac_rx(int on)
- +{
- + if (on) {
- + mac_irq = handle_irq;
- + reg_read(REG_IRQ_STATUS);
- + change_state(TRX_CMD_RX_AACK_ON);
- + } else {
- + mac_irq = NULL;
- + change_state(TRX_CMD_FORCE_TRX_OFF);
- + txing = 0;
- + }
- + return 1;
- +}
- +
- +
- +static void do_tx(void *user)
- +{
- + uint16_t timeout = 0xffff;
- + uint8_t status;
- + uint8_t i;
- +
- + /*
- + * If we time out here, the host driver will time out waiting for the
- + * TRX_END acknowledgement.
- + */
- + do {
- + if (!--timeout)
- + return;
- + status = reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK;
- + }
- + while (status != TRX_STATUS_RX_ON && status != TRX_STATUS_RX_AACK_ON);
- +
- +#ifdef AT86RF231
- + /*
- + * We use TRX_CMD_FORCE_PLL_ON instead of TRX_CMD_PLL_ON because a new
- + * reception may have begun while we were still working on the previous
- + * one.
- + */
- + reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
- +#endif
- +#ifdef AT86RF230
- + /*
- + * at86rf230 doesn't support force change, nevetherless this works
- + * somehow
- + */
- + reg_write(REG_TRX_STATE, TRX_CMD_PLL_ON);
- +#endif
- +#ifdef AT86RF212
- + /*
- + * We use TRX_CMD_FORCE_PLL_ON instead of TRX_CMD_PLL_ON because a new
- + * reception may have begun while we were still working on the previous
- + * one.
- + */
- + reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
- +#endif
- +
- + handle_irq();
- +
- + spi_begin();
- + spi_send(AT86RF230_BUF_WRITE);
- + spi_send(tx_size+2); /* CRC */
- + for (i = 0; i != tx_size; i++)
- + spi_send(tx_buf[i]);
- + spi_end();
- +
- + change_state(TRX_STATUS_TX_ARET_ON);
- +
- + slp_tr();
- +
- + txing = 1;
- + this_seq = next_seq;
- +
- + /*
- + * Wait until we reach BUSY_TX_ARET, so that we command the transition to
- + * RX_AACK_ON which will be executed upon TX completion.
- + */
- + change_state(TRX_CMD_PLL_ON);
- + change_state(TRX_CMD_RX_AACK_ON);
- +}
- +
- +
- +bool mac_tx(uint16_t flags, uint8_t seq, uint16_t len)
- +{
- + if (len > MAX_PSDU)
- + return 0;
- + tx_size = len;
- + next_seq = seq;
- + usb_recv(&eps[0], tx_buf, len, do_tx, NULL);
- + return 1;
- +}
- +
- +
- +void mac_reset(void)
- +{
- + mac_irq = NULL;
- + txing = 0;
- + queued_tx_ack = 0;
- + rx_in = rx_out = 0;
- + next_seq = this_seq = queued_seq = 0;
- +
- + /* enable CRC and PHY_RSSI (with RX_CRC_VALID) in SPI status return */
- + reg_write(REG_TRX_CTRL_1,
- + TX_AUTO_CRC_ON | SPI_CMD_MODE_PHY_RSSI << SPI_CMD_MODE_SHIFT);
- +}
- diff --git a/atusb/mac.h b/atusb/mac.h
- new file mode 100644
- index 0000000..f3c92fb
- --- /dev/null
- +++ b/atusb/mac.h
- @@ -0,0 +1,26 @@
- +/*
- + * fw/mac.h - HardMAC functions
- + *
- + * Written 2011, 2013 by Werner Almesberger
- + * Copyright 2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef MAC_H
- +#define MAC_H
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +
- +extern bool (*mac_irq)(void);
- +
- +bool mac_rx(int on);
- +bool mac_tx(uint16_t flags, uint8_t seq, uint16_t len);
- +void mac_reset(void);
- +
- +#endif /* !MAC_H */
- diff --git a/atusb/sernum.c b/atusb/sernum.c
- new file mode 100644
- index 0000000..41e434c
- --- /dev/null
- +++ b/atusb/sernum.c
- @@ -0,0 +1,47 @@
- +/*
- + * fw/sernum.c - ATUSB serial number
- + *
- + * Written 2008-2011, 2013 by Werner Almesberger
- + * Copyright 2008-2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include "usb.h"
- +
- +#include "board.h"
- +#include "sernum.h"
- +
- +
- +static const uint8_t string_descriptor_0[] = {
- + 4, /* blength */
- + USB_DT_STRING, /* bDescriptorType */
- + LE(USB_LANGID_ENGLISH_US) /* wLANGID[0] */
- +};
- +
- +
- +bool sernum_get_descr(uint8_t type, uint8_t index, const uint8_t **reply,
- + uint8_t *size)
- +{
- + if (type != USB_DT_STRING)
- + return 0;
- + switch (index) {
- + case 0:
- + *reply = string_descriptor_0;
- + *size = sizeof(string_descriptor_0);
- + return 1;
- + case 1:
- + *reply = board_sernum;
- + *size = sizeof(board_sernum);
- + return 1;
- + default:
- + return 0;
- + }
- +}
- diff --git a/atusb/sernum.h b/atusb/sernum.h
- new file mode 100644
- index 0000000..31a8e27
- --- /dev/null
- +++ b/atusb/sernum.h
- @@ -0,0 +1,37 @@
- +/*
- + * fw/sernum.h - ATUSB serial number
- + *
- + * Written 2011, 2013 by Werner Almesberger
- + * Copyright 2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef SERNUM_H
- +#define SERNUM_H
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include "board.h"
- +
- +
- +#ifdef HAS_BOARD_SERNUM
- +
- +bool sernum_get_descr(uint8_t type, uint8_t index, const uint8_t **reply,
- + uint8_t *size);
- +
- +#else /* HAS_BOARD_SERNUM */
- +
- +static inline bool sernum_get_descr(uint8_t type, uint8_t index,
- + const uint8_t **reply, uint8_t *size)
- +{
- + return 0;
- +}
- +
- +#endif /* !HAS_BOARD_SERNUM */
- +
- +#endif /* !SERNUM_H */
- diff --git a/atusb/spi.c b/atusb/spi.c
- new file mode 100644
- index 0000000..3fa5715
- --- /dev/null
- +++ b/atusb/spi.c
- @@ -0,0 +1,51 @@
- +/*
- + * fw/spi.c - ATmega8 family SPI I/O
- + *
- + * Written 2011, 2013 by Werner Almesberger
- + * Copyright 2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include <avr/io.h>
- +
- +#include "board.h"
- +#include "spi.h"
- +
- +
- +uint8_t spi_io(uint8_t v)
- +{
- +// while (!(UCSR1A & 1 << UDRE1));
- + SPI_DATA = v;
- + SPI_WAIT_DONE();
- + return SPI_DATA;
- +}
- +
- +
- +void spi_end(void)
- +{
- +// while (!(UCSR1A & 1 << TXC1));
- + SET(nSS);
- +}
- +
- +
- +void spi_recv_block(uint8_t *buf, uint8_t n)
- +{
- + if (!n)
- + return;
- + SPI_DATA = 0;
- + while (--n) {
- + SPI_WAIT_DONE();
- + *buf++ = SPI_DATA;
- + SPI_DATA = 0;
- + }
- + SPI_WAIT_DONE();
- + *buf++ = SPI_DATA;
- +}
- diff --git a/atusb/spi.h b/atusb/spi.h
- new file mode 100644
- index 0000000..6e04f4e
- --- /dev/null
- +++ b/atusb/spi.h
- @@ -0,0 +1,30 @@
- +/*
- + * fw/spi.h - ATmega8 family SPI I/O
- + *
- + * Written 2011, 2013 by Werner Almesberger
- + * Copyright 2011, 2013 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +#ifndef SPI_H
- +#define SPI_H
- +
- +#include <stdint.h>
- +
- +
- +void spi_begin(void);
- +uint8_t spi_io(uint8_t v);
- +void spi_end(void);
- +void spi_off(void);
- +void spi_init(void);
- +
- +#define spi_send(v) (void) spi_io(v)
- +#define spi_recv(v) spi_io(0)
- +
- +void spi_recv_block(uint8_t *buf, uint8_t n);
- +
- +#endif /* !SPI_H */
- diff --git a/atusb/uart.c b/atusb/uart.c
- new file mode 100644
- index 0000000..44bec27
- --- /dev/null
- +++ b/atusb/uart.c
- @@ -0,0 +1,64 @@
- +/*
- + * fw/uart.h - Functions needed for debugging over uart
- + *
- + * Code adapted from http://www.roboternetz.de/wissen/index.php/UART_mit_avr-gcc
- + * and http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
- + *
- + * Published under the Creative Commons Share-Alike licence
- + * https://creativecommons.org/licenses/by-sa/2.0/de/
- + *
- + * S. Salewski 2007
- + *
- + * Adapted by
- + * Josef Filzmaier 2017
- + */
- +
- +#include <avr/io.h>
- +#include "uart.h"
- +
- +#define USART_BAUD 38400UL
- +#define F_CPU 8000000UL
- +
- +#define Wait_USART_Ready() while (!(UCSR1A & (1<<UDRE1)))
- +#define UART_UBRR (F_CPU/(16L*USART_BAUD)-1)
- +
- +// initialize USART, 8N1 mode
- +void
- +uart_init(void)
- +{
- +/* TODO: Find a working configuration for uart for the atmega32u2 */
- +#if CHIP == at90usb1287
- + CLKPR = (1 << CLKPCE);
- + CLKPR = 0; // clock prescaler == 0, so we have 16 MHz mpu frequency
- + UBRR1 = UART_UBRR;
- + UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
- + UCSR1B = (1 << TXEN1);
- + do
- + {
- + UDR1;
- + }
- + while (UCSR1A & (1 << RXC1));
- +#endif
- +
- +}
- +
- +int uart_write_char(char c, FILE* stream)
- +{
- + if (c == '\n'){
- + uart_new_line();
- + }
- + else {
- + Wait_USART_Ready();
- + UDR1 = c;
- + }
- + return 0;
- +}
- +
- +void
- +uart_new_line(void)
- +{
- + Wait_USART_Ready();
- + UDR1 = '\r';
- + Wait_USART_Ready();
- + UDR1 = '\n';
- +}
- diff --git a/atusb/uart.h b/atusb/uart.h
- new file mode 100644
- index 0000000..4810f9c
- --- /dev/null
- +++ b/atusb/uart.h
- @@ -0,0 +1,25 @@
- +/*
- + * fw/uart.h - Functions needed for debugging over uart
- + *
- + * Code adapted from http://www.roboternetz.de/wissen/index.php/UART_mit_avr-gcc
- + * and http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
- + *
- + * Published under the Creative Commons Share-Alike licence
- + * https://creativecommons.org/licenses/by-sa/2.0/de/
- + *
- + * S. Salewski 2007
- + *
- + * Adapted by
- + * Josef Filzmaier 2017
- + */
- +
- +#ifndef UART_H_
- +#define UART_H_
- +
- +#include <stdio.h>
- +
- +void uart_init(void);
- +int uart_write_char(char c, FILE* stream);
- +void uart_new_line(void);
- +
- +#endif /* UART_H_ */
- diff --git a/atusb/usb/atu2.c b/atusb/usb/atu2.c
- new file mode 100644
- index 0000000..98158bf
- --- /dev/null
- +++ b/atusb/usb/atu2.c
- @@ -0,0 +1,247 @@
- +/*
- + * fw/usb/atu2.c - Chip-specific driver for Atmel ATxxxU2 USB chips
- + *
- + * Written 2008-2011, 2013-2014 by Werner Almesberger
- + * Copyright 2008-2011, 2013-2014 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +/*
- + * Known issues:
- + * - no suspend/resume
- + * - we don't call back after failed transmissions,
- + * - we don't reset the EP buffer after failed receptions
- + * - enumeration often encounters an error -71 (from which it recovers)
- + */
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#define F_CPU 8000000UL
- +#include <util/delay.h>
- +
- +#include <avr/io.h>
- +#include <avr/interrupt.h>
- +#include "usb.h"
- +#include "board.h"
- +
- +
- +#ifndef NULL
- +#define NULL 0
- +#endif
- +
- +#if 1
- +#define BUG_ON(cond) do { if (cond) panic(); } while (0)
- +#else
- +#define BUG_ON(cond)
- +#endif
- +
- +
- +struct ep_descr eps[NUM_EPS];
- +
- +
- +static uint16_t usb_read_word(void)
- +{
- + uint8_t low;
- +
- + low = UEDATX;
- + return low | UEDATX << 8;
- +}
- +
- +
- +static void enable_addr(void *user)
- +{
- + while (!(UEINTX & (1 << TXINI)));
- + UDADDR |= 1 << ADDEN;
- +}
- +
- +
- +void set_addr(uint8_t addr)
- +{
- + UDADDR = addr;
- + usb_send(&eps[0], NULL, 0, enable_addr, NULL);
- +}
- +
- +
- +void usb_ep_change(struct ep_descr *ep)
- +{
- + if (ep->state == EP_TX) {
- + UENUM = ep-eps;
- + UEIENX |= 1 << TXINE;
- + }
- +}
- +
- +
- +static bool ep_setup(void)
- +{
- + struct setup_request setup;
- +
- + BUG_ON(UEBCLX < 8);
- +
- + setup.bmRequestType = UEDATX;
- + setup.bRequest = UEDATX;
- + setup.wValue = usb_read_word();
- + setup.wIndex = usb_read_word();
- + setup.wLength = usb_read_word();
- +
- + if (!handle_setup(&setup))
- + return 0;
- + if (!(setup.bmRequestType & 0x80) && eps[0].state == EP_IDLE)
- + usb_send(&eps[0], NULL, 0, NULL, NULL);
- + return 1;
- +}
- +
- +
- +static bool ep_rx(struct ep_descr *ep)
- +{
- + uint8_t size;
- +
- + size = UEBCLX;
- + if (size > ep->end-ep->buf)
- + return 0;
- + while (size--)
- + *ep->buf++ = UEDATX;
- + if (ep->buf == ep->end) {
- + ep->state = EP_IDLE;
- + if (ep->callback)
- + ep->callback(ep->user);
- +// if (ep == &eps[0])
- + usb_send(ep, NULL, 0, NULL, NULL);
- + }
- + return 1;
- +}
- +
- +
- +static void ep_tx(struct ep_descr *ep)
- +{
- + uint8_t size = ep->end-ep->buf;
- + uint8_t left;
- +
- + if (size > ep->size)
- + size = ep->size;
- + for (left = size; left; left--)
- + UEDATX = *ep->buf++;
- + if (size == ep->size)
- + return;
- + ep->state = EP_IDLE;
- +}
- +
- +
- +static void handle_ep(int n)
- +{
- + struct ep_descr *ep = eps+n;
- + uint8_t mask;
- +
- + UENUM = n;
- + if (UEINTX & (1 << RXSTPI)) {
- + /* @@@ EP_RX. EP_TX: cancel */
- + ep->state = EP_IDLE;
- + if (!ep_setup())
- + goto stall;
- + UEINTX = ~(1 << RXSTPI);
- + }
- + if (UEINTX & (1 << RXOUTI)) {
- + /* @@ EP_TX: cancel */
- + if (ep->state != EP_RX)
- + goto stall;
- + if (!ep_rx(ep))
- + goto stall;
- + /* @@@ gcc 4.5.2 wants this cast */
- + UEINTX = (uint8_t) ~(1 << RXOUTI | 1 << FIFOCON);
- + }
- + if (UEINTX & (1 << STALLEDI)) {
- + ep->state = EP_IDLE;
- + UEINTX = ~(1 << STALLEDI);
- + }
- + if (UEINTX & (1 << TXINI)) {
- + /* @@ EP_RX: cancel (?) */
- + if (ep->state == EP_TX) {
- + ep_tx(ep);
- + mask = 1 << TXINI;
- + if (n)
- + mask |= 1 << FIFOCON;
- + UEINTX = ~mask;
- + if (ep->state == EP_IDLE && ep->callback)
- + ep->callback(ep->user);
- + } else {
- + UEIENX &= ~(1 << TXINE);
- + }
- + }
- + return;
- +
- +stall:
- + UEINTX = ~(1 << RXSTPI | 1 << RXOUTI | 1 << STALLEDI);
- + ep->state = EP_IDLE;
- + UECONX |= 1 << STALLRQ;
- +}
- +
- +
- +void ep_init(void)
- +{
- + UENUM = 0;
- + UECONX = (1 << RSTDT) | (1 << EPEN); /* enable */
- + UECFG0X = 0; /* control, direction is ignored */
- + UECFG1X = 3 << EPSIZE0; /* 64 bytes */
- + UECFG1X |= 1 << ALLOC;
- +
- + while (!(UESTA0X & (1 << CFGOK)));
- +
- + UEIENX =
- + (1 << RXSTPE) | (1 << RXOUTE) | (1 << STALLEDE) | (1 << TXINE);
- +
- + eps[0].state = EP_IDLE;
- + eps[0].size = 64;
- +
- +#ifndef BOOT_LOADER
- +
- + UENUM = 1;
- + UECONX = (1 << RSTDT) | (1 << EPEN); /* enable */
- + UECFG0X = (1 << EPTYPE1) | (1 << EPDIR); /* bulk IN */
- + UECFG1X = 3 << EPSIZE0; /* 64 bytes */
- + UECFG1X |= 1 << ALLOC;
- +
- + while (!(UESTA0X & (1 << CFGOK)));
- +
- + UEIENX = (1 << STALLEDE) | (1 << TXINE);
- +
- + eps[1].state = EP_IDLE;
- + eps[1].size = 64;
- +
- +#endif
- +}
- +
- +
- +ISR(USB_GEN_vect)
- +{
- + uint8_t flags;
- +
- + flags = UDINT;
- + if (flags & (1 << EORSTI)) {
- + if (user_reset)
- + user_reset();
- + ep_init();
- + UDINT = ~(1 << EORSTI);
- + }
- +}
- +
- +
- +ISR(USB_COM_vect)
- +{
- + uint8_t flags, i;
- +
- + flags = UEINT;
- + for (i = 0; i != NUM_EPS; i++)
- + if (flags & (1 << i))
- + handle_ep(i);
- +}
- +
- +
- +void usb_reset(void)
- +{
- + UDCON |= 1 << DETACH; /* detach the pull-up */
- + _delay_ms(1);
- +}
- diff --git a/atusb/usb/dfu.c b/atusb/usb/dfu.c
- new file mode 100644
- index 0000000..c84a28d
- --- /dev/null
- +++ b/atusb/usb/dfu.c
- @@ -0,0 +1,260 @@
- +/*
- + * boot/dfu.c - DFU protocol engine
- + *
- + * Written 2008-2011, 2013-2015 by Werner Almesberger
- + * Copyright 2008-2011, 2013-2015 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +/*
- + * http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf
- + */
- +
- +/*
- + * A few, erm, shortcuts:
- + *
- + * - we don't bother with the app* states since DFU is all this firmware does
- + * - after DFU_DNLOAD, we just block until things are written, so we never
- + * enter dfuDNLOAD_SYNC or dfuDNBUSY
- + * - no dfuMANIFEST_SYNC, dfuMANIFEST, or dfuMANIFEST_WAIT_RESET
- + * - to keep our buffers small, we only accept EP0-sized blocks
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include "usb.h"
- +#include "dfu.h"
- +
- +#include "board.h"
- +
- +
- +#ifndef NULL
- +#define NULL 0
- +#endif
- +
- +#define debug(...)
- +#define error(...)
- +
- +
- +#ifndef DFU_ALT_SETTINGS
- +#define DFU_ALT_SETTINGS 1
- +#endif
- +
- +#ifndef DFU_ALT_NAME_0_IDX
- +#define DFU_ALT_NAME_0_IDX 0
- +#endif
- +
- +#ifndef DFU_ALT_NAME_1_IDX
- +#define DFU_ALT_NAME_1_IDX 0
- +#endif
- +
- +#ifndef DFU_ALT_NAME_2_IDX
- +#define DFU_ALT_NAME_2_IDX 0
- +#endif
- +
- +
- +const uint8_t device_descriptor[] = {
- + 18, /* bLength */
- + USB_DT_DEVICE, /* bDescriptorType */
- + LE(0x100), /* bcdUSB */
- + USB_CLASS_APP_SPEC, /* bDeviceClass */
- + 0x00, /* bDeviceSubClass (per interface) */
- + 0x00, /* bDeviceProtocol (per interface) */
- + EP0_SIZE, /* bMaxPacketSize */
- + LE(DFU_USB_VENDOR), /* idVendor */
- + LE(DFU_USB_PRODUCT), /* idProduct */
- + LE(0x0001), /* bcdDevice */
- + 0, /* iManufacturer */
- + 0, /* iProduct */
- +#ifdef HAS_BOARD_SERNUM
- + 1, /* iSerialNumber */
- +#else
- + 0, /* iSerialNumber */
- +#endif
- + 1 /* bNumConfigurations */
- +};
- +
- +
- +const uint8_t config_descriptor[] = {
- + 9, /* bLength */
- + USB_DT_CONFIG, /* bDescriptorType */
- + LE(9+9*DFU_ALT_SETTINGS), /* wTotalLength */
- + 1, /* bNumInterfaces */
- + 1, /* bConfigurationValue (> 0 !) */
- + 0, /* iConfiguration */
- +// USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED,
- + USB_ATTR_BUS_POWERED, /* bmAttributes */
- + ((BOARD_MAX_mA)+1)/2, /* bMaxPower */
- +
- + /* Interface #0 */
- +
- + DFU_ITF_DESCR(0, 0, dfu_proto_dfu, DFU_ALT_NAME_0_IDX)
- +#if DFU_ALT_SETTINGS > 1
- + DFU_ITF_DESCR(0, 1, dfu_proto_dfu, DFU_ALT_NAME_1_IDX)
- +#endif
- +#if DFU_ALT_SETTINGS > 2
- + DFU_ITF_DESCR(0, 2, dfu_proto_dfu, DFU_ALT_NAME_2_IDX)
- +#endif
- +};
- +
- +
- +static uint16_t next_block = 0;
- +static bool did_download;
- +
- +
- +static uint8_t buf[EP0_SIZE];
- +
- +
- +static void block_write(void *user)
- +{
- + uint16_t *size = user;
- +
- + dfu_flash_ops->write(buf, *size);
- +}
- +
- +
- +static bool block_receive(uint16_t length)
- +{
- + static uint16_t size;
- +
- + if (!dfu_flash_ops->can_write(length)) {
- + dfu.state = dfuERROR;
- + dfu.status = errADDRESS;
- + return 0;
- + }
- + if (length > EP0_SIZE) {
- + dfu.state = dfuERROR;
- + dfu.status = errUNKNOWN;
- + return 0;
- + }
- + size = length;
- + usb_recv(&eps[0], buf, size, block_write, &size);
- + return 1;
- +}
- +
- +
- +static bool block_transmit(uint16_t length)
- +{
- + uint16_t got;
- +
- + if (length > EP0_SIZE) {
- + dfu.state = dfuERROR;
- + dfu.status = errUNKNOWN;
- + return 1;
- + }
- + got = dfu_flash_ops->read(buf, length);
- + if (got < length) {
- + length = got;
- + dfu.state = dfuIDLE;
- + }
- + usb_send(&eps[0], buf, length, NULL, NULL);
- + return 1;
- +}
- +
- +
- +static bool my_setup(const struct setup_request *setup)
- +{
- + bool ok;
- +
- + switch (setup->bmRequestType | setup->bRequest << 8) {
- + case DFU_TO_DEV(DFU_DETACH):
- + debug("DFU_DETACH\n");
- + /*
- + * The DFU spec says thay this is sent in protocol 1 only.
- + * However, dfu-util also sends it to get out of DFU mode,
- + * so we just don't make a fuss and ignore it.
- + */
- + return 1;
- + case DFU_TO_DEV(DFU_DNLOAD):
- + debug("DFU_DNLOAD\n");
- + if (dfu.state == dfuIDLE) {
- + next_block = setup->wValue;
- + dfu_flash_ops->start();
- + }
- + else if (dfu.state != dfuDNLOAD_IDLE) {
- + error("bad state\n");
- + return 0;
- + }
- + if (dfu.state != dfuIDLE && setup->wValue == next_block-1) {
- + debug("retransmisson\n");
- + return 1;
- + }
- + if (setup->wValue != next_block) {
- + debug("bad block (%d vs. %d)\n",
- + setup->wValue, next_block);
- + dfu.state = dfuERROR;
- + dfu.status = errUNKNOWN;
- + return 1;
- + }
- + if (!setup->wLength) {
- + debug("DONE\n");
- + dfu_flash_ops->end_write();
- + dfu.state = dfuIDLE;
- + did_download = 1;
- + return 1;
- + }
- + ok = block_receive(setup->wLength);
- + next_block++;
- + dfu.state = dfuDNLOAD_IDLE;
- + return ok;
- + case DFU_FROM_DEV(DFU_UPLOAD):
- + debug("DFU_UPLOAD\n");
- + if (dfu.state == dfuIDLE) {
- + next_block = setup->wValue;
- + dfu_flash_ops->start();
- + }
- + else if (dfu.state != dfuUPLOAD_IDLE)
- + return 0;
- + if (dfu.state != dfuIDLE && setup->wValue == next_block-1) {
- + debug("retransmisson\n");
- + /* @@@ try harder */
- + dfu.state = dfuERROR;
- + dfu.status = errUNKNOWN;
- + return 1;
- + }
- + if (setup->wValue != next_block) {
- + debug("bad block (%d vs. %d)\n",
- + setup->wValue, next_block);
- + dfu.state = dfuERROR;
- + dfu.status = errUNKNOWN;
- + return 1;
- + }
- + ok = block_transmit(setup->wLength);
- + next_block++;
- + dfu.state = dfuUPLOAD_IDLE;
- + return ok;
- + case DFU_TO_DEV(DFU_ABORT):
- + debug("DFU_ABORT\n");
- + dfu.state = dfuIDLE;
- + dfu.status = OK;
- + return 1;
- + default:
- + return dfu_setup_common(setup);
- + }
- +}
- +
- +
- +static void my_reset(void)
- +{
- +#if 0
- + /* @@@ not nice -- think about where this should go */
- + extern void run_payload(void);
- +
- + if (did_download)
- + run_payload();
- +#endif
- +}
- +
- +
- +void dfu_init(void)
- +{
- + user_setup = my_setup;
- + user_get_descriptor = dfu_my_descr;
- + user_reset = my_reset;
- +}
- diff --git a/atusb/usb/dfu.h b/atusb/usb/dfu.h
- new file mode 100644
- index 0000000..bc35bbc
- --- /dev/null
- +++ b/atusb/usb/dfu.h
- @@ -0,0 +1,119 @@
- +/*
- + * boot/dfu.h - DFU protocol constants and data structures
- + *
- + * Written 2008, 2011, 2013-2015 by Werner Almesberger
- + * Copyright 2008, 2011, 2013-2015 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#ifndef DFU_H
- +#define DFU_H
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include "usb.h"
- +
- +
- +enum dfu_request {
- + DFU_DETACH,
- + DFU_DNLOAD,
- + DFU_UPLOAD,
- + DFU_GETSTATUS,
- + DFU_CLRSTATUS,
- + DFU_GETSTATE,
- + DFU_ABORT,
- +};
- +
- +
- +enum dfu_status {
- + OK,
- + errTARGET,
- + errFILE,
- + errWRITE,
- + errERASE,
- + errCHECK_ERASED,
- + errPROG,
- + errVERIFY,
- + errADDRESS,
- + errNOTDONE,
- + errFIRMWARE,
- + errVENDOR,
- + errUSBR,
- + errPOR,
- + errUNKNOWN,
- + errSTALLEDPKT,
- +};
- +
- +
- +enum dfu_state {
- + appIDLE,
- + appDETACH,
- + dfuIDLE,
- + dfuDNLOAD_SYNC,
- + dfuDNBUSY,
- + dfuDNLOAD_IDLE,
- + dfuMANIFEST_SYNC,
- + dfuMANIFEST,
- + dfuMANIFEST_WAIT_RESET,
- + dfuUPLOAD_IDLE,
- + dfuERROR
- +};
- +
- +enum dfu_itf_proto {
- + dfu_proto_runtime = 1, /* Runtime protocol */
- + dfu_proto_dfu = 2, /* DFU mode protocol */
- +};
- +
- +
- +#define DFU_DT_FUNCTIONAL 0x21 /* DFU FUNCTIONAL descriptor type */
- +
- +
- +#define DFU_TO_DEV(req) (0x21 | (req) << 8)
- +#define DFU_FROM_DEV(req) (0xa1 | (req) << 8)
- +
- +
- +struct dfu {
- + uint8_t status; /* bStatus */
- + uint8_t toL, toM, toH; /* bwPollTimeout */
- + uint8_t state; /* bState */
- + uint8_t iString;
- +};
- +
- +
- +#define DFU_ITF_DESCR(itf, alt, proto, idx) \
- + 9, /* bLength */ \
- + USB_DT_INTERFACE, /* bDescriptorType */ \
- + (itf), /* bInterfaceNumber */ \
- + (alt), /* bAlternateSetting */ \
- + 0, /* bNumEndpoints */ \
- + 0xfe, /* bInterfaceClass (application specific) */ \
- + 0x01, /* bInterfaceSubClass (device fw upgrade) */ \
- + (proto), /* bInterfaceProtocol (dfu_proto_*) */ \
- + (idx), /* iInterface */
- +
- +
- +struct dfu_flash_ops {
- + void (*start)(void);
- + bool (*can_write)(uint16_t size);
- + void (*write)(const uint8_t *buf, uint16_t size);
- + void (*end_write)(void);
- + uint16_t (*read)(uint8_t *buf, uint16_t size);
- +};
- +
- +extern struct dfu dfu;
- +extern const struct dfu_flash_ops *dfu_flash_ops;
- +
- +
- +bool dfu_setup_common(const struct setup_request *setup);
- +bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
- + uint8_t *size);
- +
- +void dfu_init(void);
- +
- +#endif /* !DFU_H */
- diff --git a/atusb/usb/dfu_common.c b/atusb/usb/dfu_common.c
- new file mode 100644
- index 0000000..9b6feef
- --- /dev/null
- +++ b/atusb/usb/dfu_common.c
- @@ -0,0 +1,101 @@
- +/*
- + * boot/dfu_common.c - DFU protocol engine parts common to App/DFU
- + *
- + * Written 2008-2011, 2013-2014 by Werner Almesberger
- + * Copyright 2008-2011, 2013-2014 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +/*
- + * http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf
- + */
- +
- +/*
- + * A few, erm, shortcuts:
- + *
- + * - we don't bother with the app* states since DFU is all this firmware does
- + * - after DFU_DNLOAD, we just block until things are written, so we never
- + * enter dfuDNLOAD_SYNC or dfuDNBUSY
- + * - no dfuMANIFEST_SYNC, dfuMANIFEST, or dfuMANIFEST_WAIT_RESET
- + * - to keep our buffers small, we only accept EP0-sized blocks
- + */
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include "usb.h"
- +#include "dfu.h"
- +
- +#include "board.h"
- +#include "../sernum.h"
- +
- +
- +#ifndef NULL
- +#define NULL 0
- +#endif
- +
- +#define debug(...)
- +#define error(...)
- +
- +
- +static const uint8_t functional_descriptor[] = {
- + 9, /* bLength */
- + DFU_DT_FUNCTIONAL, /* bDescriptorType */
- + 0xf, /* bmAttributes (claim omnipotence :-) */
- + LE(0xffff), /* wDetachTimeOut (we're very patient) */
- + LE(EP0_SIZE), /* wTransferSize */
- + LE(0x101), /* bcdDFUVersion */
- +};
- +
- +
- +/*
- + * The worst-case activity would be flashing a one page and erasing another
- + * one, would should take less than 10 ms. A 100 ms timeout ought to be plenty.
- + */
- +
- +struct dfu dfu = {
- + OK, /* bStatus */
- + LE(100), 0, /* bwPollTimeout, 100 ms */
- + dfuIDLE, /* bState */
- + 0, /* iString */
- +};
- +
- +
- +bool dfu_setup_common(const struct setup_request *setup)
- +{
- + switch (setup->bmRequestType | setup->bRequest << 8) {
- + case DFU_FROM_DEV(DFU_GETSTATUS):
- + debug("DFU_GETSTATUS\n");
- + usb_send(&eps[0], (uint8_t *) &dfu, sizeof(dfu), NULL, NULL);
- + return 1;
- + case DFU_TO_DEV(DFU_CLRSTATUS):
- + debug("DFU_CLRSTATUS\n");
- + dfu.state = dfuIDLE;
- + dfu.status = OK;
- + return 1;
- + case DFU_FROM_DEV(DFU_GETSTATE):
- + debug("DFU_GETSTATE\n");
- + usb_send(&eps[0], &dfu.state, 1, NULL, NULL);
- + return 1;
- + default:
- + error("DFU rt %x, rq%x ?\n",
- + setup->bmRequestType, setup->bRequest);
- + return 0;
- + }
- +}
- +
- +
- +bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
- + uint8_t *size)
- +{
- + if (type != DFU_DT_FUNCTIONAL)
- + return sernum_get_descr(type, index, reply, size);
- + *reply = functional_descriptor;
- + *size = sizeof(functional_descriptor);
- + return 1;
- +}
- diff --git a/atusb/usb/usb.c b/atusb/usb/usb.c
- new file mode 100644
- index 0000000..543d8c2
- --- /dev/null
- +++ b/atusb/usb/usb.c
- @@ -0,0 +1,181 @@
- +/*
- + * fw/usb/usb.c - USB hardware setup and standard device requests
- + *
- + * Written 2008-2011, 2013, 2015 by Werner Almesberger
- + * Copyright 2008-2011, 2013, 2015 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +/*
- + * Known issues:
- + * - no suspend/resume
- + * - should support EP clearing and stalling
- + */
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +#include "usb.h"
- +#include "board.h"
- +
- +
- +#ifndef NULL
- +#define NULL 0
- +#endif
- +
- +#if 1
- +extern void panic(void);
- +#define BUG_ON(cond) do { if (cond) panic(); } while (0)
- +#else
- +#define BUG_ON(cond)
- +#endif
- +
- +bool (*user_setup)(const struct setup_request *setup);
- +void (*user_set_interface)(int nth);
- +bool (*user_get_descriptor)(uint8_t type, uint8_t index,
- + const uint8_t **reply, uint8_t *size);
- +void (*user_reset)(void);
- +
- +
- +void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
- + uint8_t size, void (*callback)(void *user), void *user)
- +{
- + BUG_ON(ep->state);
- + ep->state = state;
- + ep->buf = buf;
- + ep->end = buf+size;
- + ep->callback = callback;
- + ep->user = user;
- + usb_ep_change(ep);
- +}
- +
- +
- +static bool get_descriptor(uint8_t type, uint8_t index, uint16_t length)
- +{
- + const uint8_t *reply;
- + uint8_t size;
- +
- + switch (type) {
- + case USB_DT_DEVICE:
- + reply = device_descriptor;
- + size = reply[0];
- + break;
- + case USB_DT_CONFIG:
- + if (index)
- + return 0;
- + reply = config_descriptor;
- + size = reply[2];
- + break;
- + default:
- + if (!user_get_descriptor)
- + return 0;
- + if (!user_get_descriptor(type, index, &reply, &size))
- + return 0;
- + }
- + if (length < size)
- + size = length;
- + usb_send(&eps[0], reply, size, NULL, NULL);
- + return 1;
- +}
- +
- +
- +bool handle_setup(const struct setup_request *setup)
- +{
- + switch (setup->bmRequestType | setup->bRequest << 8) {
- +
- + /*
- + * Device request
- + *
- + * See http://www.beyondlogic.org/usbnutshell/usb6.htm
- + */
- +
- + case FROM_DEVICE(GET_STATUS):
- + if (setup->wLength != 2)
- + return 0;
- + usb_send(&eps[0], "\000", 2, NULL, NULL);
- + break;
- + case TO_DEVICE(CLEAR_FEATURE):
- + break;
- + case TO_DEVICE(SET_FEATURE):
- + return 0;
- + case TO_DEVICE(SET_ADDRESS):
- + set_addr(setup->wValue);
- + break;
- + case FROM_DEVICE(GET_DESCRIPTOR):
- + case FROM_INTERFACE(GET_DESCRIPTOR):
- + if (!get_descriptor(setup->wValue >> 8, setup->wValue,
- + setup->wLength))
- + return 0;
- + break;
- + case TO_DEVICE(SET_DESCRIPTOR):
- + return 0;
- + case FROM_DEVICE(GET_CONFIGURATION):
- + usb_send(&eps[0], "", 1, NULL, NULL);
- + break;
- + case TO_DEVICE(SET_CONFIGURATION):
- + if (setup->wValue != config_descriptor[5])
- + return 0;
- + break;
- +
- + /*
- + * Interface request
- + */
- +
- + case FROM_INTERFACE(GET_STATUS):
- + return 0;
- + case TO_INTERFACE(CLEAR_FEATURE):
- + return 0;
- + case TO_INTERFACE(SET_FEATURE):
- + return 0;
- + case FROM_INTERFACE(GET_INTERFACE):
- + return 0;
- + case TO_INTERFACE(SET_INTERFACE):
- + {
- + const uint8_t *interface_descriptor =
- + config_descriptor+9;
- + const uint8_t *p;
- + int i;
- +
- + i = 0;
- + for (p = interface_descriptor;
- + p != config_descriptor+config_descriptor[2];
- + p += p[0]) {
- + if (p[1] != USB_DT_INTERFACE)
- + continue;
- + if (p[2] == setup->wIndex &&
- + p[3] == setup->wValue) {
- + if (user_set_interface)
- + user_set_interface(i);
- + return 1;
- + }
- + i++;
- + }
- + return 0;
- + }
- + break;
- +
- + /*
- + * Endpoint request
- + */
- +
- + case FROM_ENDPOINT(GET_STATUS):
- + return 0;
- + case TO_ENDPOINT(CLEAR_FEATURE):
- + return 0;
- + case TO_ENDPOINT(SET_FEATURE):
- + return 0;
- + case FROM_ENDPOINT(SYNCH_FRAME):
- + return 0;
- +
- + default:
- + if (user_setup)
- + return user_setup(setup);
- + return 0;
- + }
- +
- + return 1;
- +}
- diff --git a/atusb/usb/usb.h b/atusb/usb/usb.h
- new file mode 100644
- index 0000000..cb40f9e
- --- /dev/null
- +++ b/atusb/usb/usb.h
- @@ -0,0 +1,189 @@
- +/*
- + * fw/usb//usb.h - USB hardware setup and standard device requests
- + *
- + * Written 2008, 2009, 2011, 2013, 2015 by Werner Almesberger
- + * Copyright 2008, 2009, 2011, 2013, 2015 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#ifndef USB_H
- +#define USB_H
- +
- +
- +#include <stdbool.h>
- +#include <stdint.h>
- +
- +
- +/*
- + * Packet identifier types
- + */
- +
- +#define PID_OUT 0x1
- +#define PID_IN 0x9
- +#define PID_SOF 0x5
- +#define PID_SETUP 0xd
- +#define PID_DATA0 0x3
- +#define PID_DATA1 0xb
- +#define PID_ACK 0x2
- +#define PID_NAK 0xa
- +#define PID_STALL 0xe
- +
- +/*
- + * Descriptor types
- + *
- + * Reuse libusb naming scheme (/usr/include/usb.h)
- + */
- +
- +#define USB_DT_DEVICE 1
- +#define USB_DT_CONFIG 2
- +#define USB_DT_STRING 3
- +#define USB_DT_INTERFACE 4
- +#define USB_DT_ENDPOINT 5
- +
- +/*
- + * Device classes
- + *
- + * Reuse libusb naming scheme (/usr/include/usb.h)
- + */
- +
- +#define USB_CLASS_PER_INTERFACE 0
- +#define USB_CLASS_COMM 2
- +#define USB_CLASS_HID 3
- +#define USB_CLASS_MASS_STORAGE 8
- +#define USB_CLASS_HUB 9
- +#define USB_CLASS_DATA 10
- +#define USB_CLASS_APP_SPEC 0xfe
- +#define USB_CLASS_VENDOR_SPEC 0xff
- +
- +/*
- + * Configuration attributes
- + */
- +
- +#define USB_ATTR_BUS_POWERED 0x80
- +#define USB_ATTR_SELF_POWERED 0x40
- +#define USB_ATTR_REMOTE_WAKEUP 0x20
- +
- +/*
- + * Endpoint type
- + */
- +
- +#define USB_ENDPOINT_TYPE_CONTROL 0
- +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1
- +#define USB_ENDPOINT_TYPE_BULK 2
- +#define USB_ENDPOINT_TYPE_INTERRUPT 3
- +
- +/*
- + * Setup request types
- + */
- +
- +#define TO_DEVICE(req) (0x00 | (req) << 8)
- +#define FROM_DEVICE(req) (0x80 | (req) << 8)
- +#define TO_INTERFACE(req) (0x01 | (req) << 8)
- +#define FROM_INTERFACE(req) (0x81 | (req) << 8)
- +#define TO_ENDPOINT(req) (0x02 | (req) << 8)
- +#define FROM_ENDPOINT(req) (0x82 | (req) << 8)
- +
- +/*
- + * Setup requests
- + */
- +
- +#define GET_STATUS 0x00
- +#define CLEAR_FEATURE 0x01
- +#define SET_FEATURE 0x03
- +#define SET_ADDRESS 0x05
- +#define GET_DESCRIPTOR 0x06
- +#define SET_DESCRIPTOR 0x07
- +#define GET_CONFIGURATION 0x08
- +#define SET_CONFIGURATION 0x09
- +#define GET_INTERFACE 0x0a
- +#define SET_INTERFACE 0x0b
- +#define SYNCH_FRAME 0x0c
- +
- +/*
- + * USB Language ID codes
- + *
- + * http://www.usb.org/developers/docs/USB_LANGIDs.pdf
- + */
- +
- +#define USB_LANGID_ENGLISH_US 0x409
- +
- +
- +/*
- + * Odd. sdcc seems to think "x" assumes the size of the destination, i.e.,
- + * uint8_t. Hence the cast.
- + */
- +
- +#define LE(x) ((uint16_t) (x) & 0xff), ((uint16_t) (x) >> 8)
- +
- +#define LO(x) (((uint8_t *) &(x))[0])
- +#define HI(x) (((uint8_t *) &(x))[1])
- +
- +
- +#ifdef LOW_SPEED
- +#define EP0_SIZE 8
- +#else
- +#define EP0_SIZE 64
- +#endif
- +
- +#define EP1_SIZE 64 /* simplify */
- +
- +
- +enum ep_state {
- + EP_IDLE,
- + EP_RX,
- + EP_TX,
- + EP_STALL,
- +};
- +
- +struct ep_descr {
- + enum ep_state state;
- + uint8_t *buf;
- + uint8_t *end;
- + uint8_t size;
- + void (*callback)(void *user);
- + void *user;
- +};
- +
- +struct setup_request {
- + uint8_t bmRequestType;
- + uint8_t bRequest;
- + uint16_t wValue;
- + uint16_t wIndex;
- + uint16_t wLength;
- +};
- +
- +
- +extern const uint8_t device_descriptor[];
- +extern const uint8_t config_descriptor[];
- +extern struct ep_descr eps[];
- +
- +extern bool (*user_setup)(const struct setup_request *setup);
- +extern void (*user_set_interface)(int nth);
- +extern bool (*user_get_descriptor)(uint8_t type, uint8_t index,
- + const uint8_t **reply, uint8_t *size);
- +extern void (*user_reset)(void);
- +
- +
- +#define usb_left(ep) ((ep)->end-(ep)->buf)
- +#define usb_send(ep, buf, size, callback, user) \
- + usb_io(ep, EP_TX, (void *) buf, size, callback, user)
- +#define usb_recv(ep, buf, size, callback, user) \
- + usb_io(ep, EP_RX, buf, size, callback, user)
- +
- +void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
- + uint8_t size, void (*callback)(void *user), void *user);
- +
- +bool handle_setup(const struct setup_request *setup);
- +void set_addr(uint8_t addr);
- +void usb_ep_change(struct ep_descr *ep);
- +void usb_reset(void);
- +void usb_init(void);
- +
- +void ep_init(void);
- +
- +#endif /* !USB_H */
- diff --git a/atusb/version.h b/atusb/version.h
- new file mode 100644
- index 0000000..8fd6a2c
- --- /dev/null
- +++ b/atusb/version.h
- @@ -0,0 +1,23 @@
- +/*
- + * fw/version.h - Automatically generated version string
- + *
- + * Written 2008, 2011 by Werner Almesberger
- + * Copyright 2008, 2011 Werner Almesberger
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License as published by
- + * the Free Software Foundation; either version 2 of the License, or
- + * (at your option) any later version.
- + */
- +
- +
- +#ifndef VERSION_H
- +#define VERSION_H
- +
- +#include <stdint.h>
- +
- +
- +extern const char *build_date;
- +extern const uint16_t build_number;
- +
- +#endif /* !VERSION_H */
- --
- 2.26.0
|