0002-Add-firmware-for-the-ATUSB-IEEE-802.15.4-USB-Adapter.patch 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894
  1. From dd4bc9ff49b9a7075e579fdd62fd930d27a9a7df Mon Sep 17 00:00:00 2001
  2. From: Jason Self <j@jxself.org>
  3. Date: Thu, 4 Jul 2019 15:55:48 -0700
  4. Subject: [PATCH 2/8] Add firmware for the ATUSB IEEE 802.15.4 USB Adapter
  5. http://shop.sysmocom.de/products/atusb/
  6. ---
  7. INSTALL | 20 +-
  8. Makefile | 6 +-
  9. WHENCE | 12 ++
  10. atusb/Makefile | 236 +++++++++++++++++++++
  11. atusb/README | 94 +++++++++
  12. atusb/an/README | 25 +++
  13. atusb/an/dec.py | 127 ++++++++++++
  14. atusb/an/get.py | 31 +++
  15. atusb/an/plot | 12 ++
  16. atusb/atusb.c | 63 ++++++
  17. atusb/board.c | 120 +++++++++++
  18. atusb/board.h | 95 +++++++++
  19. atusb/board_app.c | 173 ++++++++++++++++
  20. atusb/board_atusb.c | 162 +++++++++++++++
  21. atusb/board_atusb.h | 48 +++++
  22. atusb/board_hulusb.c | 179 ++++++++++++++++
  23. atusb/board_hulusb.h | 66 ++++++
  24. atusb/board_rzusb.c | 169 +++++++++++++++
  25. atusb/board_rzusb.h | 48 +++++
  26. atusb/boot.c | 77 +++++++
  27. atusb/descr.c | 104 ++++++++++
  28. atusb/ep0.c | 338 ++++++++++++++++++++++++++++++
  29. atusb/flash.c | 97 +++++++++
  30. atusb/include/at86rf230.h | 402 ++++++++++++++++++++++++++++++++++++
  31. atusb/include/atusb/atusb.h | 97 +++++++++
  32. atusb/include/atusb/ep0.h | 64 ++++++
  33. atusb/mac.c | 250 ++++++++++++++++++++++
  34. atusb/mac.h | 26 +++
  35. atusb/sernum.c | 47 +++++
  36. atusb/sernum.h | 37 ++++
  37. atusb/spi.c | 51 +++++
  38. atusb/spi.h | 30 +++
  39. atusb/uart.c | 64 ++++++
  40. atusb/uart.h | 25 +++
  41. atusb/usb/atu2.c | 247 ++++++++++++++++++++++
  42. atusb/usb/dfu.c | 260 +++++++++++++++++++++++
  43. atusb/usb/dfu.h | 119 +++++++++++
  44. atusb/usb/dfu_common.c | 101 +++++++++
  45. atusb/usb/usb.c | 181 ++++++++++++++++
  46. atusb/usb/usb.h | 189 +++++++++++++++++
  47. atusb/version.h | 23 +++
  48. 42 files changed, 4512 insertions(+), 3 deletions(-)
  49. create mode 100644 atusb/Makefile
  50. create mode 100644 atusb/README
  51. create mode 100644 atusb/an/README
  52. create mode 100755 atusb/an/dec.py
  53. create mode 100755 atusb/an/get.py
  54. create mode 100755 atusb/an/plot
  55. create mode 100644 atusb/atusb.c
  56. create mode 100644 atusb/board.c
  57. create mode 100644 atusb/board.h
  58. create mode 100644 atusb/board_app.c
  59. create mode 100644 atusb/board_atusb.c
  60. create mode 100644 atusb/board_atusb.h
  61. create mode 100644 atusb/board_hulusb.c
  62. create mode 100644 atusb/board_hulusb.h
  63. create mode 100644 atusb/board_rzusb.c
  64. create mode 100644 atusb/board_rzusb.h
  65. create mode 100644 atusb/boot.c
  66. create mode 100644 atusb/descr.c
  67. create mode 100644 atusb/ep0.c
  68. create mode 100644 atusb/flash.c
  69. create mode 100644 atusb/include/at86rf230.h
  70. create mode 100644 atusb/include/atusb/atusb.h
  71. create mode 100644 atusb/include/atusb/ep0.h
  72. create mode 100644 atusb/mac.c
  73. create mode 100644 atusb/mac.h
  74. create mode 100644 atusb/sernum.c
  75. create mode 100644 atusb/sernum.h
  76. create mode 100644 atusb/spi.c
  77. create mode 100644 atusb/spi.h
  78. create mode 100644 atusb/uart.c
  79. create mode 100644 atusb/uart.h
  80. create mode 100644 atusb/usb/atu2.c
  81. create mode 100644 atusb/usb/dfu.c
  82. create mode 100644 atusb/usb/dfu.h
  83. create mode 100644 atusb/usb/dfu_common.c
  84. create mode 100644 atusb/usb/usb.c
  85. create mode 100644 atusb/usb/usb.h
  86. create mode 100644 atusb/version.h
  87. diff --git a/INSTALL b/INSTALL
  88. index 74c5cfd..7fb1116 100644
  89. --- a/INSTALL
  90. +++ b/INSTALL
  91. @@ -16,6 +16,8 @@ In order to build everything you will need the following on the host
  92. system:
  93. * A C/C++ compiler, like GCC
  94. + * AVR-GCC
  95. + * Standard C library for AVR-GCC
  96. * Cmake
  97. * GNU Bison/YACC
  98. * GNU Flex
  99. @@ -32,13 +34,27 @@ system:
  100. On GNU/Linux distros that use apt you can install these with:
  101. - apt install binutils-arm-linux-gnueabi binutils-arm-none-eabi bison \
  102. - cmake flex g++ gcc gcc-arm-linux-gnueabi gcc-arm-none-eabi gperf make wget
  103. + apt install avr-gcc avr-libc binutils-arm-linux-gnueabi \
  104. + binutils-arm-none-eabi bison cmake flex g++ gcc \
  105. + gcc-arm-linux-gnueabi gcc-arm-none-eabi gperf make wget
  106. CARL9170 Firmware Configuration
  107. +-------------------------------
  108. When building the carl9170 firmware you will be prompted with
  109. configuration questions.
  110. +atusb: Firmware for the ATUSB IEEE 802.15.4 USB Adapter
  111. +-------------------------------------------------------
  112. +
  113. +To flash the firmware you need dfu-util on the host. Issue
  114. +
  115. + make dfu
  116. +
  117. +right after plugging the device into the USB port while the red led is
  118. +still on.
  119. +
  120. +Refer to the included README file for more information.
  121. +
  122. Licensing
  123. ---------
  124. diff --git a/Makefile b/Makefile
  125. index 21d16fb..8474b30 100644
  126. --- a/Makefile
  127. +++ b/Makefile
  128. @@ -17,7 +17,7 @@ shell=/bin/sh
  129. prefix=/lib/firmware
  130. install_program=install
  131. -.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
  132. +.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
  133. all: aica ath9k_htc av7110 carl9170fw cis dsp56k isci keyspan_pda openfwwf usbdux
  134. @@ -36,6 +36,9 @@ ath9k_htc_toolchain:
  135. ath9k_htc: ath9k_htc_toolchain
  136. cd ath9k_htc && $(MAKE) -C target_firmware
  137. +atusb:
  138. + cd atusb && $(MAKE)
  139. +
  140. av7110:
  141. cd av7110 && $(MAKE)
  142. @@ -81,6 +84,7 @@ clean:
  143. if [ -a as31/Makefile ]; then cd as31 && $(MAKE) clean; fi;
  144. cd ath9k_htc && $(MAKE) toolchain-clean
  145. cd ath9k_htc && $(MAKE) -C target_firmware clean
  146. + cd atusb && $(MAKE) clean
  147. cd av7110 && $(MAKE) clean
  148. cd carl9170fw/toolchain && $(MAKE) clean
  149. if [ -a carl9170fw/Makefile ]; then cd carl9170fw && $(MAKE) clean; fi;
  150. diff --git a/WHENCE b/WHENCE
  151. index 2932155..756de43 100644
  152. --- a/WHENCE
  153. +++ b/WHENCE
  154. @@ -112,6 +112,18 @@ From https://github.com/qca/open-ath9k-htc-firmware
  155. --------------------------------------------------------------------------
  156. +atusb: Firmware for the ATUSB IEEE 802.15.4 USB Adapter
  157. +http://shop.sysmocom.de/products/atusb/
  158. +
  159. +From http://projects.qi-hardware.com/index.php/p/ben-wpan/source/tree/master/atusb/fw
  160. +
  161. +License: GPL-2.0-or-later
  162. +
  163. +Version: Based on commit 805db6ebf5d80692158acadf88e239da9d3e67af
  164. +dated September 13 2017
  165. +
  166. +--------------------------------------------------------------------------
  167. +
  168. Driver: b43 - OpenFWWF -- Free firmware for some Broadcom 43xx series WLAN chips
  169. License: GPLv2
  170. diff --git a/atusb/Makefile b/atusb/Makefile
  171. new file mode 100644
  172. index 0000000..c79cb26
  173. --- /dev/null
  174. +++ b/atusb/Makefile
  175. @@ -0,0 +1,236 @@
  176. +#
  177. +# Makefile - Makefile of the ATUSB firmware
  178. +#
  179. +# Written 2010-2011, 2013 by Werner Almesberger
  180. +# Copyright 2010-2011, 2013 by Werner Almesberger
  181. +#
  182. +# This program is free software; you can redistribute it and/or modify
  183. +# it under the terms of the GNU General Public License as published by
  184. +# the Free Software Foundation; either version 2 of the License, or
  185. +# (at your option) any later version.
  186. +#
  187. +
  188. +SHELL = /bin/bash
  189. +
  190. +NAME = atusb
  191. +DEBUG = false
  192. +
  193. +CFLAGS = -g -mmcu=$(CHIP) -DBOOT_ADDR=$(BOOT_ADDR) \
  194. + -Wall -Wextra -Wshadow -Werror -Wno-unused-parameter \
  195. + -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes
  196. +
  197. +ifeq ($(DEBUG),true)
  198. +CFLAGS += -DDEBUG
  199. +endif
  200. +
  201. +ifeq ($(NAME),rzusb)
  202. +CHIP=at90usb1287
  203. +CFLAGS += -DRZUSB -DAT86RF230
  204. +else ifeq ($(NAME),hulusb)
  205. +CHIP=at90usb1287
  206. +CFLAGS += -DHULUSB -DAT86RF212
  207. +else
  208. +CHIP=atmega32u2
  209. +CFLAGS += -DATUSB -DAT86RF231
  210. +endif
  211. +HOST=jlime
  212. +BOOT_ADDR=0x7000
  213. +
  214. +AVR_PREFIX = $(BIN_PATH) avr-
  215. +CC = $(AVR_PREFIX)gcc
  216. +OBJCOPY = $(AVR_PREFIX)objcopy
  217. +#OBJDUMP = $(AVR_PREFIX)objdump
  218. +SIZE = $(AVR_PREFIX)size
  219. +
  220. +# BCD notion is 0xJJMM with JJ being major and MM being minor. Thus 0x0020 is
  221. +# version 0.2 */
  222. +USB_BCD_VERSION = 0030
  223. +USB_VENDOR_ID = 20b7
  224. +USB_PRODUCT_ID = 1540
  225. +USB_ID = $(USB_VENDOR_ID):$(USB_PRODUCT_ID)
  226. +
  227. +OBJS = atusb.o board.o board_app.o sernum.o spi.o descr.o ep0.o \
  228. + dfu_common.o usb.o app-atu2.o mac.o
  229. +BOOT_OBJS = boot.o board.o sernum.o spi.o flash.o dfu.o \
  230. + dfu_common.o usb.o boot-atu2.o
  231. +
  232. +ifeq ($(DEBUG),true)
  233. +OBJS += uart.o
  234. +endif
  235. +
  236. +ifeq ($(NAME),rzusb)
  237. +OBJS += board_rzusb.o
  238. +BOOT_OBJS += board_rzusb.o
  239. +else ifeq ($(NAME),hulusb)
  240. +OBJS += board_hulusb.o
  241. +BOOT_OBJS += board_hulusb.o
  242. +else
  243. +OBJS += board_atusb.o
  244. +BOOT_OBJS += board_atusb.o
  245. +endif
  246. +
  247. +
  248. +vpath %.c usb/
  249. +
  250. +CFLAGS += -Iinclude -Iusb -I.
  251. +
  252. +# ----- Verbosity control -----------------------------------------------------
  253. +
  254. +CC_normal := $(CC)
  255. +BUILD_normal :=
  256. +DEPEND_normal := $(CPP) $(CFLAGS) -MM -MG
  257. +
  258. +CC_quiet = @echo " CC " $@ && $(CC_normal)
  259. +BUILD_quiet = @echo " BUILD " $@ && $(BUILD_normal)
  260. +DEPEND_quiet = @$(DEPEND_normal)
  261. +
  262. +ifeq ($(V),1)
  263. + CC = $(CC_normal)
  264. + BUILD = $(BUILD_normal)
  265. + DEPEND = $(DEPEND_normal)
  266. +else
  267. + CC = $(CC_quiet)
  268. + BUILD = $(BUILD_quiet)
  269. + DEPEND = $(DEPEND_quiet)
  270. +endif
  271. +
  272. +# ----- Rules -----------------------------------------------------------------
  273. +
  274. +.PHONY: all clean upload prog dfu update version.c bindist
  275. +.PHONY: prog-app prog-read on off reset
  276. +
  277. +all: $(NAME).bin boot.hex
  278. +
  279. +$(NAME).elf: $(OBJS)
  280. + $(MAKE) version.o
  281. + $(CC) $(CFLAGS) -o $@ $(OBJS) version.o
  282. + $(SIZE) $@
  283. +
  284. +boot.elf: $(BOOT_OBJS)
  285. + $(CC) $(CFLAGS) -o $@ $(BOOT_OBJS) \
  286. + -Wl,--section-start=.text=$(BOOT_ADDR)
  287. + $(SIZE) $@
  288. +
  289. +%.bin: %.elf
  290. + $(BUILD) $(OBJCOPY) -j .text -j .data -O binary $< $@
  291. + @echo "build #`cat .version`, `ls -l $@`"
  292. +
  293. +%.dfu: %.bin
  294. + cp $(NAME).bin $(NAME).dfu
  295. + dfu-suffix -a $(NAME).dfu -d 0x$(USB_BCD_VERSION) \
  296. + -p 0x$(USB_PRODUCT_ID) -v 0x$(USB_VENDOR_ID)
  297. +
  298. +%.hex: %.elf
  299. + $(BUILD) $(OBJCOPY) -j .text -j .data -O ihex $< $@
  300. + @echo "Size: `$(SIZE) -A boot.hex | sed '/Total */s///p;d'` B"
  301. +
  302. +# ----- Cleanup ---------------------------------------------------------------
  303. +
  304. +clean:
  305. + rm -f $(NAME).bin $(NAME).elf $(NAME).dfu
  306. + rm -f $(OBJS) $(OBJS:.o=.d)
  307. + rm -f boot.hex boot.elf
  308. + rm -f $(BOOT_OBJS) $(BOOT_OBJS:.o=.d)
  309. + rm -f version.c version.d version.o
  310. +
  311. +# ----- Build version ---------------------------------------------------------
  312. +
  313. +version.c:
  314. + @if [ -f .version ]; then \
  315. + v=`cat .version`; \
  316. + expr $$v + 1 >.version; \
  317. + else \
  318. + echo 0 >.version; \
  319. + fi
  320. + @[ -s .version ] || echo 0 >.version
  321. + @echo '/* MACHINE-GENERATED. DO NOT EDIT ! */' >version.c
  322. + @echo '#include "version.h"' >>version.c
  323. + @echo "const char *build_date = \"`date`\";" >>version.c
  324. + @echo "const uint16_t build_number = `cat .version`;" \
  325. + >>version.c
  326. +
  327. +# ----- Dependencies ----------------------------------------------------------
  328. +
  329. +MKDEP = \
  330. + $(DEPEND) $< | \
  331. + sed \
  332. + -e 's|^$(basename $(notdir $<)).o:|$@:|' \
  333. + -e '/^\(.*:\)\? */{p;s///;s/ *\\\?$$/ /;s/ */:\n/g;H;}' \
  334. + -e '$${g;p;}' \
  335. + -e d >$(basename $@).d; \
  336. + [ "$${PIPESTATUS[*]}" = "0 0" ] || \
  337. + { rm -f $(basename $@).d; exit 1; }
  338. +
  339. +%.o: %.c
  340. + $(CC) $(CFLAGS) -Os -c $<
  341. + $(MKDEP)
  342. +
  343. +-include $(OBJS:.o=.d)
  344. +
  345. +# ----- Object file variants --------------------------------------------------
  346. +
  347. +app-%.o: usb/%.c
  348. + $(CC) $(CFLAGS) -Os -o $@ -c $<
  349. + $(MKDEP)
  350. +
  351. +boot-%.o: usb/%.c
  352. + $(CC) $(CFLAGS) -DBOOT_LOADER -Os -o $@ -c $<
  353. + $(MKDEP)
  354. +
  355. +# ----- Distribution ----------------------------------------------------------
  356. +
  357. +BINDIST_BASE=http://downloads.qi-hardware.com/people/werner/wpan/bindist
  358. +ATUSB_BIN_NAME=atusb-`git rev-parse HEAD | cut -c 1-7`.bin
  359. +
  360. +bindist:
  361. + qippl atusb.bin wpan/bindist/$(ATUSB_BIN_NAME)
  362. + @echo $(BINDIST_BASE)/$(ATUSB_BIN_NAME)
  363. + @echo md5sum: `md5sum atusb.bin | sed 's/ .*//'`
  364. + @echo atrf-id: \
  365. + `sed '/.*number = \(.*\);/s//#\1/p;d' version.c` \
  366. + `sed '/.*date = "\(.*\)";/s//\1/p;d' version.c`
  367. +
  368. +# ----- Programming and device control ----------------------------------------
  369. +
  370. +upload: $(NAME).bin boot.hex
  371. + scp $(NAME).bin boot.hex $(HOST):
  372. +
  373. +# lfuse: external clock, slow start-up
  374. +# hfuse: 4 kB boot loader, reset into boot loader
  375. +# lock: allow everything but SPM to the boot loader
  376. +# Note: when trying to program 0xef, we get back 0x2f, failing
  377. +# verification. So we just program 0x2f.
  378. +
  379. +prog-app:
  380. + ssh $(HOST) avrdude -F -p $(CHIP) -c nanonote_atusb -e \
  381. + -U flash:w:atusb.bin:r \
  382. + -U lfuse:w:0x60:m
  383. +
  384. +prog:
  385. + ssh $(HOST) avrdude -F -p $(CHIP) -c nanonote_atusb -e \
  386. + -U flash:w:boot.hex:i \
  387. + -U lfuse:w:0x60:m \
  388. + -U hfuse:w:0xd8:m \
  389. + -U lock:w:0x2f:m
  390. +
  391. +prog-read:
  392. + ssh $(HOST) avrdude -F -p $(CHIP) -c nanonote_atusb \
  393. + -U flash:r:mcu.bin:r
  394. +
  395. +dfu: $(NAME).dfu
  396. + dfu-util -d $(USB_ID) -D $(NAME).dfu
  397. +
  398. +update: $(NAME).bin
  399. + -atrf-reset -a
  400. + usbwait -r -i 0.01 -t 5 $(USB_ID)
  401. + $(MAKE) dfu
  402. +
  403. +on:
  404. + ssh $(HOST) poke 0x10010318 4
  405. +
  406. +off:
  407. + ssh $(HOST) poke 0x10010314 4
  408. +
  409. +reset:
  410. + ssh $(HOST) poke 0x10010318 2048
  411. + ssh $(HOST) poke 0x10010314 2048
  412. diff --git a/atusb/README b/atusb/README
  413. new file mode 100644
  414. index 0000000..99ceb22
  415. --- /dev/null
  416. +++ b/atusb/README
  417. @@ -0,0 +1,94 @@
  418. +Requires a very recent toolchain, because ATmega32U2 is relatively new.
  419. +
  420. +- Building:
  421. +
  422. + make
  423. +
  424. +- Uploading the firmware to a Ben (for flashing with the atusb-pgm cable):
  425. +
  426. + make HOST=<hostname> upload
  427. +
  428. + Example:
  429. +
  430. + make HOST=ben upload
  431. +
  432. + HOST defaults to "jlime".
  433. +
  434. +- Flashing the boot loader:
  435. +
  436. + Prerequisite: avrdude on the Ben.
  437. +
  438. + Disconnect the atusb board from USB. Insert the atusb-pgm connector into
  439. + the Ben. Place the atusb-pgm adapter on the exposed contact pads of the
  440. + atusb board and push it down. Then run
  441. +
  442. + make prog
  443. +
  444. + This takes about 30 seconds. If the programming fails with an error
  445. + message like "Yikes! Invalid device signature.", verify that the
  446. + atusb-pgm board is properly connected and placed, then try again.
  447. +
  448. +- Uploading the application:
  449. +
  450. + Prerequisite: dfu-util installed on the PC.
  451. +
  452. + Insert atusb into the PC, then run
  453. +
  454. + make dfu
  455. +
  456. + Note: since the boot loader resets the USB bus after timing out,
  457. + this operation can fail with a message like "No DFU capable USB device
  458. + found". Just retry, and it will eventually get through.
  459. +
  460. +
  461. +HULUSB notes:
  462. +-------------
  463. +To prepare and flash the firmware on a HULUSB device some additional steps are
  464. +needed;
  465. +
  466. +avr-objcopy -O ihex -R .signature -R .fuse -R .eeprom hulusb.elf hulusb.hex
  467. +dfu-programmer at90usb1287 flash hulusb.hex
  468. +dfu-programmer at90usb1287 reset
  469. +
  470. +--------------------------
  471. +
  472. +Making the toolchain:
  473. +
  474. +# patches according to
  475. +# http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=789527
  476. +
  477. +# some gcc prerequisites
  478. +
  479. +apt-get remove avr-libc gcc-avr binutils-avr
  480. +apt-get install libmpfr-dev libmpc-dev
  481. +
  482. +# binutils
  483. +
  484. +wget http://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.bz2
  485. +tar xfj binutils-2.21.tar.bz2
  486. +cd binutils-2.21
  487. +./configure --target=avr --disable-nls
  488. +make
  489. +make install
  490. +
  491. +# gcc
  492. +
  493. +wget http://ftpmirror.gnu.org/gcc/gcc-4.5.2/gcc-4.5.2.tar.bz2
  494. +wget -O gcc_452_avr.patch http://gcc.gnu.org/bugzilla/attachment.cgi?id=23050
  495. +tar xfj gcc-4.5.2.tar.bz2
  496. +cd gcc-4.5.2
  497. +patch -p1 -s <../gcc_452_avr.patch
  498. +mkdir obj-avr
  499. +cd obj-avr
  500. +../configure --target=avr --enable-languages=c \
  501. + --disable-nls --disable-libssp --with-dwarf2
  502. +make
  503. +make install
  504. +
  505. +wget http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.7.1.tar.bz2
  506. +tar xfj avr-libc-1.7.1.tar.bz2
  507. +cd avr-libc-1.7.1
  508. +./bootstrap # the automake at the end takes a while
  509. +./configure --build=`./config.guess` --host=avr
  510. +make
  511. +make install
  512. diff --git a/atusb/an/README b/atusb/an/README
  513. new file mode 100644
  514. index 0000000..8e0d2fc
  515. --- /dev/null
  516. +++ b/atusb/an/README
  517. @@ -0,0 +1,25 @@
  518. +workflow:
  519. +
  520. +- connect zprobe (note: it currently inverts because it didn't have any
  521. + other chips around. this may change later.)
  522. +
  523. +- capture the USB signals at an interesting moment with a sample rate of
  524. + 50 MSa/s
  525. +
  526. +- zoom into the frame(s) of interest
  527. +
  528. +- download the data with
  529. + ./get.py
  530. +
  531. +- decode with
  532. + ./dec.py
  533. +
  534. + For manual decoding, set the coders to D+ and D- (we need D- for SE0
  535. + and SE1 detection), then click on a rising clock edge left of the
  536. + packet and move the cursor to the right.
  537. +
  538. +- if there are problems with the clock, the analog signal and digital
  539. + signals derived from it can be examined after running dec.py with
  540. + ./plot
  541. +
  542. + (Note that the digital zprobe hides any analog anomalies.)
  543. diff --git a/atusb/an/dec.py b/atusb/an/dec.py
  544. new file mode 100755
  545. index 0000000..8534857
  546. --- /dev/null
  547. +++ b/atusb/an/dec.py
  548. @@ -0,0 +1,127 @@
  549. +#!/usr/bin/python
  550. +
  551. +from tmc.wave import *
  552. +from tmc.dxplore import dxplore
  553. +from tmc.decode import d_usb_stream
  554. +
  555. +
  556. +#
  557. +# Clock recovery: we assume that each change in the wave is triggered by a
  558. +# clock edge. We know the clock's nominal period and resynchronize on each
  559. +# edge. Additionally, we can obtain a list of times when a timing violation
  560. +# has occurred.
  561. +#
  562. +# Note that the timing violations logic doesn't make much sense in its present
  563. +# form, since it mainly measures noise (particularly if we're digitizing slow
  564. +# edges) and not clock drift.
  565. +#
  566. +# A more useful metric would be accumulated error from some point of reference
  567. +# or at least the timing of same edges, to eliminate (generally harmless) time
  568. +# offsets introduced by digitizing.
  569. +#
  570. +# So it would probably make more sense for "recover" not to check for timing
  571. +# violations at all, and leave this to more specialized functions.
  572. +#
  573. +def recover(self, period, min = None, max = None, t0 = None):
  574. + if t0 is None:
  575. + t0 = self.data[0]
  576. + v = not self.initial
  577. + res = []
  578. + violations = []
  579. + for t in self.data:
  580. + v = not v
  581. + if t <= t0:
  582. + continue
  583. + n = 0
  584. + while t0 < t-period/2:
  585. + res.append(t0)
  586. + t0 += period
  587. + n += 1
  588. + if min is not None:
  589. + if t0-t > n*min:
  590. + violations.append(t)
  591. + if max is not None:
  592. + if t-t0 > n*max:
  593. + violations.append(t)
  594. + t0 = t
  595. + return res, violations
  596. +
  597. +
  598. +#
  599. +# Load the analog waves saved by get.py
  600. +#
  601. +wv = waves()
  602. +wv.load("_wv")
  603. +
  604. +#
  605. +# Digitize the waves and save the result.
  606. +#
  607. +dp = wv[0].digitize(1.5, 1.8)
  608. +dm = wv[1].digitize(1.5, 1.8)
  609. +wv = waves(dp, dm, dp-dm)
  610. +wv.save("_dig")
  611. +
  612. +#
  613. +# Also record the differential signal.
  614. +#
  615. +wd = wv[1]-wv[0]
  616. +dd = wd.digitize(-0.5, 0.5)
  617. +wd.save("_diff")
  618. +
  619. +#
  620. +# Run clock recovery on D+/D-. We only need one, but check both to be sure.
  621. +#
  622. +#p = 1/1.5e6
  623. +p = 1/12e6
  624. +dp_t, viol = recover(dp, p, p*0.9, p*1.1)
  625. +print viol
  626. +dm_t, viol = recover(dm, p, p*.9, p*1.1, t0 = dp.data[0])
  627. +print viol
  628. +
  629. +#
  630. +# Shift the clock by half a period, add a few periods to get steady state and
  631. +# SE0s (if any), and then sample the data lines.
  632. +#
  633. +clk = map(lambda t: t+p/2, dp_t)
  634. +clk.extend((clk[-1]+p, clk[-1]+2*p, clk[-1]+3*p))
  635. +dp_bv = dp.get(clk)
  636. +dm_bv = dm.get(clk)
  637. +
  638. +#
  639. +# Save a wave with the recovered clock to make it easier to find the bits in
  640. +# analog graphs.
  641. +#
  642. +dd.data = dp_t;
  643. +dd.save("_clk")
  644. +
  645. +#
  646. +# For decoding, we need a fake bit clock. We generate it by doubling each data
  647. +# bit and generating a L->H transition during this bit.
  648. +#
  649. +dpd = []
  650. +dmd = []
  651. +dck = []
  652. +
  653. +# err, silly, seems that we've mixed up D+ and D- all over the place :-)
  654. +print d_usb_stream(dm_bv[:], dp_bv[:])
  655. +
  656. +for v in dp_bv:
  657. + dpd.append(v)
  658. + dpd.append(v)
  659. + dck.append(0)
  660. + dck.append(1)
  661. +
  662. +for v in dm_bv:
  663. + dmd.append(v)
  664. + dmd.append(v)
  665. +
  666. +#
  667. +# Display the reconstructed digital signal. Note that the absolute time is only
  668. +# correct at the beginning and that relative time is only accurate over
  669. +# intervals in which no significant clock resynchronization has occurred.
  670. +#
  671. +# In fact, dxplore should probably have an option to either turn off time
  672. +# entirely or to display a user-provided time axis. The latter may be a bit
  673. +# tricky to implement.
  674. +#
  675. +dxplore((dmd, dpd, dck), 0, p/2, labels = ("D+", "D-", "CLK"))
  676. diff --git a/atusb/an/get.py b/atusb/an/get.py
  677. new file mode 100755
  678. index 0000000..685e00f
  679. --- /dev/null
  680. +++ b/atusb/an/get.py
  681. @@ -0,0 +1,31 @@
  682. +#!/usr/bin/python
  683. +
  684. +from tmc.scope import rigol_ds1000c
  685. +
  686. +#-800, +1600
  687. +s = rigol_ds1000c()
  688. +#s.debug = False
  689. +
  690. +pos = s.hor.pos
  691. +scale = s.hor.scale
  692. +t0 = pos-scale*s.div_hor/2
  693. +t1 = pos+scale*s.div_hor/2
  694. +print t0, t1
  695. +
  696. +#zoom = 10
  697. +#step = scale/s.samples_per_div/zoom
  698. +#print step
  699. +step = 4e-9
  700. +step = 2e-9
  701. +
  702. +w = s.wave((s.ch[0], s.ch[1]), start = t0, end = t1, step = step)
  703. +w[0] = 3.3-w[0]
  704. +w[1] = 3.3-w[1]
  705. +
  706. +s.hor.pos = pos
  707. +s.hor.scale = scale
  708. +
  709. +w[0].label = "D+";
  710. +w[1].label = "D-";
  711. +
  712. +w.save("_wv")
  713. diff --git a/atusb/an/plot b/atusb/an/plot
  714. new file mode 100755
  715. index 0000000..1dea789
  716. --- /dev/null
  717. +++ b/atusb/an/plot
  718. @@ -0,0 +1,12 @@
  719. +#!/bin/sh
  720. +#
  721. +# Plot output of "dec"
  722. +#
  723. +gnuplot -persist <<EOF
  724. +set style data lines
  725. +plot "_wv" using 1:(\$2-4), \
  726. + "_dig" using 1:(\$2*3.3-4) lw 2, \
  727. + "_wv" using 1:3, \
  728. + "_dig" using 1:(\$3*3.3) lw 2, \
  729. + "_clk" using 1:(\$2+1) lt 7
  730. +EOF
  731. diff --git a/atusb/atusb.c b/atusb/atusb.c
  732. new file mode 100644
  733. index 0000000..28faf40
  734. --- /dev/null
  735. +++ b/atusb/atusb.c
  736. @@ -0,0 +1,63 @@
  737. +/*
  738. + * fw/atusb.c - ATUSB initialization and main loop
  739. + *
  740. + * Written 2008-2011 by Werner Almesberger
  741. + * Copyright 2008-2011 Werner Almesberger
  742. + *
  743. + * This program is free software; you can redistribute it and/or modify
  744. + * it under the terms of the GNU General Public License as published by
  745. + * the Free Software Foundation; either version 2 of the License, or
  746. + * (at your option) any later version.
  747. + */
  748. +
  749. +
  750. +#include <stdint.h>
  751. +
  752. +#include <avr/io.h>
  753. +#include <avr/sleep.h>
  754. +#include <avr/interrupt.h>
  755. +
  756. +#include "usb.h"
  757. +
  758. +#include "board.h"
  759. +#include "sernum.h"
  760. +#include "spi.h"
  761. +#include "atusb/ep0.h"
  762. +
  763. +#ifdef DEBUG
  764. +#include "uart.h"
  765. +#endif
  766. +
  767. +
  768. +int main(void)
  769. +{
  770. + board_init();
  771. + board_app_init();
  772. + reset_rf();
  773. +
  774. + user_get_descriptor = sernum_get_descr;
  775. +
  776. + /* now we should be at 8 MHz */
  777. +
  778. +#ifdef DEBUG
  779. + uart_init();
  780. + static FILE atben_stdout = FDEV_SETUP_STREAM(uart_write_char, NULL,
  781. + _FDEV_SETUP_WRITE);
  782. + stdout = &atben_stdout;
  783. +#endif
  784. +
  785. + usb_init();
  786. + ep0_init();
  787. +#ifdef ATUSB
  788. + timer_init();
  789. +
  790. + /* move interrupt vectors to 0 */
  791. + MCUCR = 1 << IVCE;
  792. + MCUCR = 0;
  793. +#endif
  794. +
  795. + sei();
  796. +
  797. + while (1)
  798. + sleep_mode();
  799. +}
  800. diff --git a/atusb/board.c b/atusb/board.c
  801. new file mode 100644
  802. index 0000000..c3b8d26
  803. --- /dev/null
  804. +++ b/atusb/board.c
  805. @@ -0,0 +1,120 @@
  806. +/*
  807. + * fw/board.c - Board-specific functions (for boot loader and application)
  808. + *
  809. + * Written 2011, 2013 by Werner Almesberger
  810. + * Copyright 2011, 2013 Werner Almesberger
  811. + *
  812. + * This program is free software; you can redistribute it and/or modify
  813. + * it under the terms of the GNU General Public License as published by
  814. + * the Free Software Foundation; either version 2 of the License, or
  815. + * (at your option) any later version.
  816. + */
  817. +
  818. +
  819. +#include <stdbool.h>
  820. +#include <stdint.h>
  821. +
  822. +#include <avr/io.h>
  823. +#include <avr/interrupt.h>
  824. +#include <avr/boot.h>
  825. +
  826. +#define F_CPU 8000000UL
  827. +#include <util/delay.h>
  828. +
  829. +#include "usb.h"
  830. +#include "at86rf230.h"
  831. +#include "board.h"
  832. +#include "spi.h"
  833. +
  834. +
  835. +uint8_t board_sernum[42] = { 42, USB_DT_STRING };
  836. +
  837. +/* ----- Register access --------------------------------------------------- */
  838. +
  839. +void change_state(uint8_t new)
  840. +{
  841. + while ((reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK) ==
  842. + TRX_STATUS_TRANSITION);
  843. + reg_write(REG_TRX_STATE, new);
  844. +}
  845. +
  846. +
  847. +uint8_t reg_read(uint8_t reg)
  848. +{
  849. + uint8_t value;
  850. +
  851. + spi_begin();
  852. + spi_send(AT86RF230_REG_READ | reg);
  853. + value = spi_recv();
  854. + spi_end();
  855. +
  856. + return value;
  857. +}
  858. +
  859. +
  860. +uint8_t subreg_read(uint8_t address, uint8_t mask, uint8_t position)
  861. +{
  862. + /* Read current register value and mask out subregister. */
  863. + uint8_t register_value = reg_read(address);
  864. + register_value &= mask;
  865. + register_value >>= position; /* Align subregister value. */
  866. +
  867. + return register_value;
  868. +}
  869. +
  870. +
  871. +void reg_write(uint8_t reg, uint8_t value)
  872. +{
  873. + spi_begin();
  874. + spi_send(AT86RF230_REG_WRITE | reg);
  875. + spi_send(value);
  876. + spi_end();
  877. +}
  878. +
  879. +
  880. +void subreg_write(uint8_t address, uint8_t mask, uint8_t position, uint8_t value)
  881. +{
  882. + /* Read current register value and mask area outside the subregister. */
  883. + uint8_t register_value = reg_read(address);
  884. + register_value &= ~mask;
  885. +
  886. + /* Start preparing the new subregister value. shift in place and mask. */
  887. + value <<= position;
  888. + value &= mask;
  889. +
  890. + value |= register_value; /* Set the new subregister value. */
  891. +
  892. + /* Write the modified register value. */
  893. + reg_write(address, value);
  894. +}
  895. +
  896. +
  897. +void panic(void)
  898. +{
  899. + cli();
  900. + while (1) {
  901. + SET(LED);
  902. + _delay_ms(100);
  903. + CLR(LED);
  904. + _delay_ms(100);
  905. + }
  906. +}
  907. +
  908. +
  909. +static char hex(uint8_t nibble)
  910. +{
  911. + return nibble < 10 ? '0'+nibble : 'a'+nibble-10;
  912. +}
  913. +
  914. +
  915. +void get_sernum(void)
  916. +{
  917. + uint8_t sig;
  918. + uint8_t i;
  919. +
  920. + for (i = 0; i != 10; i++) {
  921. + sig = boot_signature_byte_get(i+0xe);
  922. + board_sernum[(i << 2)+2] = hex(sig >> 4);
  923. + board_sernum[(i << 2)+4] = hex(sig & 0xf);
  924. + }
  925. +}
  926. diff --git a/atusb/board.h b/atusb/board.h
  927. new file mode 100644
  928. index 0000000..dbcd410
  929. --- /dev/null
  930. +++ b/atusb/board.h
  931. @@ -0,0 +1,95 @@
  932. +/*
  933. + * fw/board.h - Board-specific functions and definitions
  934. + *
  935. + * Written 2008-2011, 2013, 2013 by Werner Almesberger
  936. + * Copyright 2008-2011, 2013, 2013 Werner Almesberger
  937. + *
  938. + * This program is free software; you can redistribute it and/or modify
  939. + * it under the terms of the GNU General Public License as published by
  940. + * the Free Software Foundation; either version 2 of the License, or
  941. + * (at your option) any later version.
  942. + */
  943. +
  944. +#ifndef BOARD_H
  945. +#define BOARD_H
  946. +
  947. +#include <stdbool.h>
  948. +#include <stdint.h>
  949. +
  950. +#include <atusb/atusb.h>
  951. +
  952. +#ifdef ATUSB
  953. +#include "board_atusb.h"
  954. +#endif
  955. +#ifdef RZUSB
  956. +#include "board_rzusb.h"
  957. +#endif
  958. +#ifdef HULUSB
  959. +#include "board_hulusb.h"
  960. +#endif
  961. +
  962. +#define SET_2(p, b) PORT##p |= 1 << (b)
  963. +#define CLR_2(p, b) PORT##p &= ~(1 << (b))
  964. +#define IN_2(p, b) DDR##p &= ~(1 << (b))
  965. +#define OUT_2(p, b) DDR##p |= 1 << (b)
  966. +#define PIN_2(p, b) ((PIN##p >> (b)) & 1)
  967. +
  968. +#define SET_1(p, b) SET_2(p, b)
  969. +#define CLR_1(p, b) CLR_2(p, b)
  970. +#define IN_1(p, b) IN_2(p, b)
  971. +#define OUT_1(p, b) OUT_2(p, b)
  972. +#define PIN_1(p, b) PIN_2(p, b)
  973. +
  974. +#define SET(n) SET_1(n##_PORT, n##_BIT)
  975. +#define CLR(n) CLR_1(n##_PORT, n##_BIT)
  976. +#define IN(n) IN_1(n##_PORT, n##_BIT)
  977. +#define OUT(n) OUT_1(n##_PORT, n##_BIT)
  978. +#define PIN(n) PIN_1(n##_PORT, n##_BIT)
  979. +
  980. +
  981. +#define USB_VENDOR ATUSB_VENDOR_ID
  982. +#define USB_PRODUCT ATUSB_PRODUCT_ID
  983. +
  984. +#define DFU_USB_VENDOR USB_VENDOR
  985. +#define DFU_USB_PRODUCT USB_PRODUCT
  986. +
  987. +
  988. +#define BOARD_MAX_mA 40
  989. +
  990. +#ifdef BOOT_LOADER
  991. +#define NUM_EPS 1
  992. +#else
  993. +#define NUM_EPS 2
  994. +#endif
  995. +
  996. +#define HAS_BOARD_SERNUM
  997. +
  998. +extern uint8_t board_sernum[42];
  999. +extern uint8_t irq_serial;
  1000. +
  1001. +
  1002. +void reset_rf(void);
  1003. +void reset_cpu(void);
  1004. +uint8_t read_irq(void);
  1005. +void slp_tr(void);
  1006. +
  1007. +void led(bool on);
  1008. +void panic(void);
  1009. +
  1010. +uint64_t timer_read(void);
  1011. +void timer_init(void);
  1012. +
  1013. +bool gpio(uint8_t port, uint8_t data, uint8_t dir, uint8_t mask, uint8_t *res);
  1014. +void gpio_cleanup(void);
  1015. +
  1016. +void get_sernum(void);
  1017. +
  1018. +void board_app_init(void);
  1019. +
  1020. +uint8_t reg_read(uint8_t reg);
  1021. +uint8_t subreg_read(uint8_t address, uint8_t mask, uint8_t position);
  1022. +void reg_write(uint8_t reg, uint8_t value);
  1023. +void subreg_write(uint8_t address, uint8_t mask, uint8_t position, uint8_t value);
  1024. +void change_state(uint8_t new);
  1025. +
  1026. +#endif /* !BOARD_H */
  1027. diff --git a/atusb/board_app.c b/atusb/board_app.c
  1028. new file mode 100644
  1029. index 0000000..1fa9bf4
  1030. --- /dev/null
  1031. +++ b/atusb/board_app.c
  1032. @@ -0,0 +1,173 @@
  1033. +/*
  1034. + * fw/board_app.c - Board-specific functions (for the application)
  1035. + *
  1036. + * Written 2011, 2013 by Werner Almesberger
  1037. + * Copyright 2011, 2013 Werner Almesberger
  1038. + *
  1039. + * This program is free software; you can redistribute it and/or modify
  1040. + * it under the terms of the GNU General Public License as published by
  1041. + * the Free Software Foundation; either version 2 of the License, or
  1042. + * (at your option) any later version.
  1043. + */
  1044. +
  1045. +
  1046. +#include <stddef.h>
  1047. +#include <stdbool.h>
  1048. +#include <stdint.h>
  1049. +
  1050. +#include <avr/io.h>
  1051. +#include <avr/interrupt.h>
  1052. +
  1053. +#define F_CPU 8000000UL
  1054. +#include <util/delay.h>
  1055. +
  1056. +#include "usb.h"
  1057. +#include "at86rf230.h"
  1058. +#include "spi.h"
  1059. +#include "mac.h"
  1060. +#include "board.h"
  1061. +
  1062. +
  1063. +static volatile uint32_t timer_h = 0; /* 2^(16+32) / 8 MHz = ~1.1 years */
  1064. +
  1065. +
  1066. +void reset_cpu(void)
  1067. +{
  1068. + WDTCSR = 1 << WDE;
  1069. +}
  1070. +
  1071. +
  1072. +uint8_t read_irq(void)
  1073. +{
  1074. + return PIN(IRQ_RF);
  1075. +}
  1076. +
  1077. +
  1078. +void slp_tr(void)
  1079. +{
  1080. + SET(SLP_TR);
  1081. + CLR(SLP_TR);
  1082. +}
  1083. +
  1084. +
  1085. +ISR(TIMER1_OVF_vect)
  1086. +{
  1087. + timer_h++;
  1088. +}
  1089. +
  1090. +
  1091. +uint64_t timer_read(void)
  1092. +{
  1093. + uint32_t high;
  1094. + uint8_t low, mid;
  1095. +
  1096. + do {
  1097. + if (TIFR1 & (1 << TOV1)) {
  1098. + TIFR1 = 1 << TOV1;
  1099. + timer_h++;
  1100. + }
  1101. + high = timer_h;
  1102. + low = TCNT1L;
  1103. + mid = TCNT1H;
  1104. + }
  1105. + while (TIFR1 & (1 << TOV1));
  1106. +
  1107. + /*
  1108. + * We need all these casts because the intermediate results are handled
  1109. + * as if they were signed and thus get sign-expanded. Sounds wrong-ish.
  1110. + */
  1111. + return (uint64_t) high << 16 | (uint64_t) mid << 8 | (uint64_t) low;
  1112. +}
  1113. +
  1114. +
  1115. +void timer_init(void)
  1116. +{
  1117. + /* configure timer 1 as a free-running CLK counter */
  1118. +
  1119. + TCCR1A = 0;
  1120. + TCCR1B = 1 << CS10;
  1121. +
  1122. + /* enable timer overflow interrupt */
  1123. +
  1124. + TIMSK1 = 1 << TOIE1;
  1125. +}
  1126. +
  1127. +
  1128. +bool gpio(uint8_t port, uint8_t data, uint8_t dir, uint8_t mask, uint8_t *res)
  1129. +{
  1130. + EIMSK = 0; /* recover INT_RF to ATUSB_GPIO_CLEANUP or an MCU reset */
  1131. +
  1132. + switch (port) {
  1133. + case 1:
  1134. + DDRB = (DDRB & ~mask) | dir;
  1135. + PORTB = (PORTB & ~mask) | data;
  1136. + break;
  1137. + case 2:
  1138. + DDRC = (DDRC & ~mask) | dir;
  1139. + PORTC = (PORTC & ~mask) | data;
  1140. + break;
  1141. + case 3:
  1142. + DDRD = (DDRD & ~mask) | dir;
  1143. + PORTD = (PORTD & ~mask) | data;
  1144. + break;
  1145. + default:
  1146. + return 0;
  1147. + }
  1148. +
  1149. + /* disable the UART so that we can meddle with these pins as well. */
  1150. + spi_off();
  1151. + _delay_ms(1);
  1152. +
  1153. + switch (port) {
  1154. + case 1:
  1155. + res[0] = PINB;
  1156. + res[1] = PORTB;
  1157. + res[2] = DDRB;
  1158. + break;
  1159. + case 2:
  1160. + res[0] = PINC;
  1161. + res[1] = PORTC;
  1162. + res[2] = DDRC;
  1163. + break;
  1164. + case 3:
  1165. + res[0] = PIND;
  1166. + res[1] = PORTD;
  1167. + res[2] = DDRD;
  1168. + break;
  1169. + }
  1170. +
  1171. + return 1;
  1172. +}
  1173. +
  1174. +
  1175. +void gpio_cleanup(void)
  1176. +{
  1177. + EIMSK = 1 << 0;
  1178. +}
  1179. +
  1180. +
  1181. +static void done(void *user)
  1182. +{
  1183. + led(0);
  1184. +}
  1185. +
  1186. +
  1187. +uint8_t irq_serial;
  1188. +
  1189. +#if defined(ATUSB) || defined(HULUSB)
  1190. +ISR(INT0_vect)
  1191. +#endif
  1192. +#ifdef RZUSB
  1193. +ISR(TIMER1_CAPT_vect)
  1194. +#endif
  1195. +{
  1196. + if (mac_irq) {
  1197. + if (mac_irq())
  1198. + return;
  1199. + }
  1200. + if (eps[1].state == EP_IDLE) {
  1201. + led(1);
  1202. + irq_serial = (irq_serial+1) | 0x80;
  1203. + usb_send(&eps[1], &irq_serial, 1, done, NULL);
  1204. + }
  1205. +}
  1206. diff --git a/atusb/board_atusb.c b/atusb/board_atusb.c
  1207. new file mode 100644
  1208. index 0000000..a02fb7f
  1209. --- /dev/null
  1210. +++ b/atusb/board_atusb.c
  1211. @@ -0,0 +1,162 @@
  1212. +/*
  1213. + * fw/board_atusb.c - ATUSB Board-specific functions (for boot loader and application)
  1214. + *
  1215. + * Written 2016 by Stefan Schmidt
  1216. + * Copyright 2016 Stefan Schmidt
  1217. + *
  1218. + * This program is free software; you can redistribute it and/or modify
  1219. + * it under the terms of the GNU General Public License as published by
  1220. + * the Free Software Foundation; either version 2 of the License, or
  1221. + * (at your option) any later version.
  1222. + */
  1223. +
  1224. +
  1225. +#include <stdbool.h>
  1226. +#include <stdint.h>
  1227. +
  1228. +#include <avr/io.h>
  1229. +#include <avr/interrupt.h>
  1230. +#include <avr/boot.h>
  1231. +
  1232. +#define F_CPU 8000000UL
  1233. +#include <util/delay.h>
  1234. +
  1235. +#include "usb.h"
  1236. +#include "at86rf230.h"
  1237. +#include "board.h"
  1238. +#include "spi.h"
  1239. +#include "usb/usb.h"
  1240. +
  1241. +static bool spi_initialized = 0;
  1242. +
  1243. +void reset_rf(void)
  1244. +{
  1245. + /* set up all the outputs; default port value is 0 */
  1246. +
  1247. + DDRB = 0;
  1248. + DDRC = 0;
  1249. + DDRD = 0;
  1250. + PORTB = 0;
  1251. + PORTC = 0;
  1252. + PORTD = 0;
  1253. +
  1254. + OUT(LED);
  1255. + OUT(nRST_RF); /* this also resets the transceiver */
  1256. + OUT(SLP_TR);
  1257. +
  1258. + spi_init();
  1259. +
  1260. + /* AT86RF231 data sheet, 12.4.13, reset pulse width: 625 ns (min) */
  1261. +
  1262. + CLR(nRST_RF);
  1263. + _delay_us(2);
  1264. + SET(nRST_RF);
  1265. +
  1266. + /* 12.4.14: SPI access latency after reset: 625 ns (min) */
  1267. +
  1268. + _delay_us(2);
  1269. +
  1270. + /* we must restore TRX_CTRL_0 after each reset (9.6.4) */
  1271. +
  1272. + set_clkm();
  1273. +}
  1274. +
  1275. +void led(bool on)
  1276. +{
  1277. + if (on)
  1278. + SET(LED);
  1279. + else
  1280. + CLR(LED);
  1281. +}
  1282. +
  1283. +void set_clkm(void)
  1284. +{
  1285. + /* switch CLKM to 8 MHz */
  1286. +
  1287. + /*
  1288. + * @@@ Note: Atmel advise against changing the external clock in
  1289. + * mid-flight. We should therefore switch to the RC clock first, then
  1290. + * crank up the external clock, and finally switch back to the external
  1291. + * clock. The clock switching procedure is described in the ATmega32U2
  1292. + * data sheet in secton 8.2.2.
  1293. + */
  1294. + spi_begin();
  1295. + spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0);
  1296. + spi_send(CLKM_CTRL_8MHz);
  1297. + spi_end();
  1298. +}
  1299. +
  1300. +void board_init(void)
  1301. +{
  1302. + /* Disable the watchdog timer */
  1303. +
  1304. + MCUSR = 0; /* Remove override */
  1305. + WDTCSR |= 1 << WDCE; /* Enable change */
  1306. + WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
  1307. + change */
  1308. +
  1309. + CLKPR = 1 << CLKPCE;
  1310. + /* We start with a 1 MHz/8 clock. Disable the prescaler. */
  1311. + CLKPR = 0;
  1312. +
  1313. + get_sernum();
  1314. +}
  1315. +
  1316. +void spi_begin(void)
  1317. +{
  1318. + if (!spi_initialized)
  1319. + spi_init();
  1320. + CLR(nSS);
  1321. +}
  1322. +
  1323. +void spi_off(void)
  1324. +{
  1325. + spi_initialized = 0;
  1326. + UCSR1B = 0;
  1327. +}
  1328. +
  1329. +void spi_init(void)
  1330. +{
  1331. + SET(nSS);
  1332. + OUT(SCLK);
  1333. + OUT(MOSI);
  1334. + OUT(nSS);
  1335. + IN(MISO);
  1336. +
  1337. + UBRR1 = 0; /* set bit rate to zero to begin */
  1338. + UCSR1C = 1 << UMSEL11 | 1 << UMSEL10;
  1339. + /* set MSPI, MSB first, SPI data mode 0 */
  1340. + UCSR1B = 1 << RXEN1 | 1 << TXEN1;
  1341. + /* enable receiver and transmitter */
  1342. + UBRR1 = 0; /* reconfirm the bit rate */
  1343. +
  1344. + spi_initialized = 1;
  1345. +}
  1346. +
  1347. +void usb_init(void)
  1348. +{
  1349. + USBCON |= 1 << FRZCLK; /* freeze the clock */
  1350. +
  1351. + /* enable the PLL and wait for it to lock */
  1352. + PLLCSR &= ~(1 << PLLP2 | 1 << PLLP1 | 1 << PLLP0);
  1353. + PLLCSR |= 1 << PLLE;
  1354. + while (!(PLLCSR & (1 << PLOCK)));
  1355. +
  1356. + USBCON &= ~(1 << USBE); /* reset the controller */
  1357. + USBCON |= 1 << USBE;
  1358. +
  1359. + USBCON &= ~(1 << FRZCLK); /* thaw the clock */
  1360. +
  1361. + UDCON &= ~(1 << DETACH); /* attach the pull-up */
  1362. + UDIEN = 1 << EORSTE; /* enable device interrupts */
  1363. +// UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
  1364. +
  1365. + ep_init();
  1366. +}
  1367. +
  1368. +void board_app_init(void)
  1369. +{
  1370. + /* enable INT0, trigger on rising edge */
  1371. + EICRA = 1 << ISC01 | 1 << ISC00;
  1372. + EIMSK = 1 << 0;
  1373. +}
  1374. diff --git a/atusb/board_atusb.h b/atusb/board_atusb.h
  1375. new file mode 100644
  1376. index 0000000..e5974c7
  1377. --- /dev/null
  1378. +++ b/atusb/board_atusb.h
  1379. @@ -0,0 +1,48 @@
  1380. +/*
  1381. + * fw/board_atusb.h - ATUSB Board-specific functions and definitions
  1382. + *
  1383. + * Written 2016 by Stefan Schmidt
  1384. + * Copyright 2016 Stefan Schmidt
  1385. + *
  1386. + * This program is free software; you can redistribute it and/or modify
  1387. + * it under the terms of the GNU General Public License as published by
  1388. + * the Free Software Foundation; either version 2 of the License, or
  1389. + * (at your option) any later version.
  1390. + */
  1391. +
  1392. +#ifndef BOARD_ATUSB_H
  1393. +#define BOARD_ATUSB_H
  1394. +
  1395. +#include <stdbool.h>
  1396. +#include <stdint.h>
  1397. +
  1398. +#define LED_PORT B
  1399. +#define LED_BIT 6
  1400. +#define nRST_RF_PORT C
  1401. +#define nRST_RF_BIT 7
  1402. +#define SLP_TR_PORT B
  1403. +#define SLP_TR_BIT 4
  1404. +
  1405. +#define SCLK_PORT D
  1406. +#define SCLK_BIT 5
  1407. +#define MOSI_PORT D
  1408. +#define MOSI_BIT 3
  1409. +
  1410. +#define MISO_PORT D
  1411. +#define MISO_BIT 2
  1412. +#define nSS_PORT D
  1413. +#define nSS_BIT 1
  1414. +#define IRQ_RF_PORT D
  1415. +#define IRQ_RF_BIT 0
  1416. +
  1417. +#define SPI_WAIT_DONE() while (!(UCSR1A & 1 << RXC1))
  1418. +#define SPI_DATA UDR1
  1419. +
  1420. +void set_clkm(void);
  1421. +void board_init(void);
  1422. +
  1423. +void spi_begin(void);
  1424. +void spi_off(void);
  1425. +void spi_init(void);
  1426. +
  1427. +#endif /* !BOARD_H */
  1428. diff --git a/atusb/board_hulusb.c b/atusb/board_hulusb.c
  1429. new file mode 100644
  1430. index 0000000..084714e
  1431. --- /dev/null
  1432. +++ b/atusb/board_hulusb.c
  1433. @@ -0,0 +1,179 @@
  1434. +/*
  1435. + * fw/board_hulusb.c - Busware HUL Board-specific functions (for boot loader and application)
  1436. + *
  1437. + * Written 2017 by Filzmaier Josef
  1438. + * Based on fw/board_rzusb written and Copyright 2016 Stefan Schmidt
  1439. + *
  1440. + * This program is free software; you can redistribute it and/or modify
  1441. + * it under the terms of the GNU General Public License as published by
  1442. + * the Free Software Foundation; either version 2 of the License, or
  1443. + * (at your option) any later version.
  1444. + */
  1445. +
  1446. +
  1447. +#include <stdbool.h>
  1448. +#include <stdint.h>
  1449. +
  1450. +#include <avr/io.h>
  1451. +#include <avr/interrupt.h>
  1452. +#include <avr/boot.h>
  1453. +
  1454. +#define F_CPU 8000000UL
  1455. +#include <util/delay.h>
  1456. +
  1457. +#include "usb.h"
  1458. +#include "at86rf230.h"
  1459. +#include "board.h"
  1460. +#include "spi.h"
  1461. +#include "usb/usb.h"
  1462. +
  1463. +static bool spi_initialized = 0;
  1464. +
  1465. +void reset_rf(void)
  1466. +{
  1467. + /* set up all the outputs; default port value is 0 */
  1468. +
  1469. + DDRB = 0;
  1470. + DDRC = 0;
  1471. + DDRD = 0;
  1472. + PORTB = 0;
  1473. + PORTC = 0;
  1474. + PORTD = 0;
  1475. +
  1476. + OUT(LED_RED);
  1477. + OUT(LED_GREEN);
  1478. + SET(LED_RED); /* Leds are active low on HULUSB board */
  1479. + CLR(LED_GREEN); /* Green Led indicates the dongle is running */
  1480. + OUT(nRST_RF); /* this also resets the transceiver */
  1481. + OUT(SLP_TR);
  1482. +
  1483. + spi_init();
  1484. +
  1485. + /* AT86RF212 data sheet, Appendix B, p166 Power-On Reset procedure */
  1486. + /*-----------------------------------------------------------------*/
  1487. + CLR(SLP_TR);
  1488. + SET(nRST_RF);
  1489. + SET(nSS);
  1490. + _delay_us(400);
  1491. +
  1492. + CLR(nRST_RF);
  1493. + _delay_us(2);
  1494. + SET(nRST_RF);
  1495. +
  1496. + /* 5.1.4.5: Wait t10: 625 ns (min) */
  1497. +
  1498. + _delay_us(2);
  1499. +
  1500. + reg_write(REG_TRX_CTRL_0, 0x19);
  1501. +
  1502. + change_state(TRX_CMD_FORCE_TRX_OFF);
  1503. + /*-----------------------------------------------------------------*/
  1504. +
  1505. + /* we must restore TRX_CTRL_0 after each reset (7.7.4) */
  1506. +
  1507. + set_clkm();
  1508. +}
  1509. +
  1510. +void led_red(bool on) {
  1511. + if (on)
  1512. + CLR(LED_RED);
  1513. + else
  1514. + SET(LED_RED);
  1515. +}
  1516. +
  1517. +void led_green(bool on) {
  1518. + if (on)
  1519. + CLR(LED_GREEN);
  1520. + else
  1521. + SET(LED_GREEN);
  1522. +}
  1523. +
  1524. +void led(bool on)
  1525. +{
  1526. + led_red(on);
  1527. +}
  1528. +
  1529. +void set_clkm(void)
  1530. +{
  1531. + /* CLKM is not connected on BUSWARE HUL and therefore it is running in
  1532. + * async mode. */
  1533. + reg_write(REG_TRX_CTRL_0, 0x00);
  1534. +
  1535. + /* TX_AUTO_CRC_ON, default disabled */
  1536. + subreg_write(SR_TX_AUTO_CRC_ON, 1);
  1537. +}
  1538. +
  1539. +void board_init(void)
  1540. +{
  1541. + /* Disable the watchdog timer */
  1542. +
  1543. + MCUSR = 0; /* Remove override */
  1544. + WDTCSR |= 1 << WDCE; /* Enable change */
  1545. + WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
  1546. + change */
  1547. +
  1548. + CLKPR = 1 << CLKPCE;
  1549. + /* We start with a 16 MHz/8 clock. Put the prescaler to 2. */
  1550. + CLKPR = 1 << CLKPS0;
  1551. +
  1552. + get_sernum();
  1553. +}
  1554. +
  1555. +void spi_begin(void)
  1556. +{
  1557. + if (!spi_initialized)
  1558. + spi_init();
  1559. + CLR(nSS);
  1560. +}
  1561. +
  1562. +void spi_off(void)
  1563. +{
  1564. + spi_initialized = 0;
  1565. + SPCR &= ~(1 << SPE);
  1566. +}
  1567. +
  1568. +void spi_init(void)
  1569. +{
  1570. + SET(nSS);
  1571. + OUT(SCLK);
  1572. + OUT(MOSI);
  1573. + OUT(nSS);
  1574. + IN(MISO);
  1575. +
  1576. + SPCR = (1 << SPE) | (1 << MSTR);
  1577. + SPSR = (1 << SPI2X);
  1578. +
  1579. + spi_initialized = 1;
  1580. +}
  1581. +
  1582. +void usb_init(void)
  1583. +{
  1584. + USBCON |= 1 << FRZCLK; /* freeze the clock */
  1585. +
  1586. + /* enable the PLL and wait for it to lock */
  1587. + /* TODO sheet page 50 For Atmel AT90USB128x only. Do not use with Atmel AT90USB64x. */
  1588. + /* FOR 8 XTAL Mhz only!!! */
  1589. + PLLCSR = ((1 << PLLP1) | (1 << PLLP0));
  1590. + PLLCSR |= 1 << PLLE;
  1591. + while (!(PLLCSR & (1 << PLOCK)));
  1592. +
  1593. + UHWCON |= (1 << UVREGE);
  1594. +
  1595. + USBCON &= ~((1 << USBE) | (1 << OTGPADE)); /* reset the controller */
  1596. + USBCON |= ((1 << USBE) | (1 << OTGPADE));
  1597. +
  1598. + USBCON &= ~(1 << FRZCLK); /* thaw the clock */
  1599. +
  1600. + UDCON &= ~(1 << DETACH); /* attach the pull-up */
  1601. + UDIEN = 1 << EORSTE; /* enable device interrupts */
  1602. + // UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
  1603. +
  1604. + ep_init();
  1605. +}
  1606. +
  1607. +void board_app_init(void)
  1608. +{
  1609. + /* enable INT0, trigger on rising edge */
  1610. + EICRA = 1 << ISC01 | 1 << ISC00;
  1611. + EIMSK = 1 << INT0;
  1612. +}
  1613. diff --git a/atusb/board_hulusb.h b/atusb/board_hulusb.h
  1614. new file mode 100644
  1615. index 0000000..a1dadf0
  1616. --- /dev/null
  1617. +++ b/atusb/board_hulusb.h
  1618. @@ -0,0 +1,66 @@
  1619. +/*
  1620. + * fw/board_hulusb.h - Busware HUL Board-specific functions (for boot loader and application)
  1621. + *
  1622. + * Written 2017 by Filzmaier Josef
  1623. + * Based on fw/board_rzusb written and Copyright 2016 Stefan Schmidt
  1624. + *
  1625. + * This program is free software; you can redistribute it and/or modify
  1626. + * it under the terms of the GNU General Public License as published by
  1627. + * the Free Software Foundation; either version 2 of the License, or
  1628. + * (at your option) any later version.
  1629. + */
  1630. +
  1631. +#ifndef BOARD_HULUSB_H
  1632. +#define BOARD_HULUSB_H
  1633. +
  1634. +#include <stdbool.h>
  1635. +#include <stdint.h>
  1636. +
  1637. +#define LED_RED_PORT A
  1638. +#define LED_GREEN_PORT A
  1639. +#define LED_RED_BIT 3
  1640. +#define LED_GREEN_BIT 4
  1641. +#define LED_PORT LED_RED_PORT
  1642. +#define LED_BIT LED_RED_BIT
  1643. +
  1644. +#define nRST_RF_PORT B
  1645. +#define nRST_RF_BIT 5
  1646. +#define SLP_TR_PORT B
  1647. +#define SLP_TR_BIT 4
  1648. +
  1649. +#define SCLK_PORT B
  1650. +#define SCLK_BIT 1
  1651. +#define MOSI_PORT B
  1652. +#define MOSI_BIT 2
  1653. +
  1654. +#define MISO_PORT B
  1655. +#define MISO_BIT 3
  1656. +#define nSS_PORT B
  1657. +#define nSS_BIT 0
  1658. +#define IRQ_RF_PORT D
  1659. +#define IRQ_RF_BIT 4
  1660. +
  1661. +#define SR_TX_AUTO_CRC_ON 0x04, 0x20, 5
  1662. +#define SR_CHANNEL 0x08, 0x1f, 0
  1663. +
  1664. +#define RG_CC_CTRL_1 (0x14)
  1665. +
  1666. +#define SPI_WAIT_DONE() while ((SPSR & (1 << SPIF)) == 0)
  1667. +#define SPI_DATA SPDR
  1668. +
  1669. +void set_clkm(void);
  1670. +void board_init(void);
  1671. +
  1672. +void led_red(bool on);
  1673. +void led_green(bool on);
  1674. +
  1675. +void spi_begin(void);
  1676. +void spi_off(void);
  1677. +void spi_init(void);
  1678. +
  1679. +#ifdef DEBUG
  1680. +void printStatus(void);
  1681. +#define PRINT_STATUS() printStatus()
  1682. +#endif
  1683. +
  1684. +#endif /* !BOARD_HULUSB_H */
  1685. diff --git a/atusb/board_rzusb.c b/atusb/board_rzusb.c
  1686. new file mode 100644
  1687. index 0000000..e83d6fa
  1688. --- /dev/null
  1689. +++ b/atusb/board_rzusb.c
  1690. @@ -0,0 +1,169 @@
  1691. +/*
  1692. + * fw/board_rzusb.c - RZUSB Board-specific functions (for boot loader and application)
  1693. + *
  1694. + * Written 2016 by Stefan Schmidt
  1695. + * Copyright 2016 Stefan Schmidt
  1696. + *
  1697. + * This program is free software; you can redistribute it and/or modify
  1698. + * it under the terms of the GNU General Public License as published by
  1699. + * the Free Software Foundation; either version 2 of the License, or
  1700. + * (at your option) any later version.
  1701. + */
  1702. +
  1703. +
  1704. +#include <stdbool.h>
  1705. +#include <stdint.h>
  1706. +
  1707. +#include <avr/io.h>
  1708. +#include <avr/interrupt.h>
  1709. +#include <avr/boot.h>
  1710. +
  1711. +#define F_CPU 8000000UL
  1712. +#include <util/delay.h>
  1713. +
  1714. +#include "usb.h"
  1715. +#include "at86rf230.h"
  1716. +#include "board.h"
  1717. +#include "spi.h"
  1718. +#include "usb/usb.h"
  1719. +
  1720. +static bool spi_initialized = 0;
  1721. +
  1722. +void reset_rf(void)
  1723. +{
  1724. + /* set up all the outputs; default port value is 0 */
  1725. +
  1726. + DDRB = 0;
  1727. + DDRC = 0;
  1728. + DDRD = 0;
  1729. + PORTB = 0;
  1730. + PORTC = 0;
  1731. + PORTD = 0;
  1732. +
  1733. + OUT(LED);
  1734. + OUT(nRST_RF); /* this also resets the transceiver */
  1735. + OUT(SLP_TR);
  1736. +
  1737. + spi_init();
  1738. +
  1739. + /* AT86RF231 data sheet, 12.4.13, reset pulse width: 625 ns (min) */
  1740. +
  1741. + CLR(nRST_RF);
  1742. + _delay_us(2);
  1743. + SET(nRST_RF);
  1744. +
  1745. + /* 12.4.14: SPI access latency after reset: 625 ns (min) */
  1746. +
  1747. + _delay_us(2);
  1748. +
  1749. + /* we must restore TRX_CTRL_0 after each reset (9.6.4) */
  1750. +
  1751. + set_clkm();
  1752. +}
  1753. +
  1754. +void led(bool on)
  1755. +{
  1756. + if (on)
  1757. + SET(LED);
  1758. + else
  1759. + CLR(LED);
  1760. +}
  1761. +
  1762. +void set_clkm(void)
  1763. +{
  1764. + /* switch CLKM to 8 MHz */
  1765. +
  1766. + /*
  1767. + * @@@ Note: Atmel advise against changing the external clock in
  1768. + * mid-flight. We should therefore switch to the RC clock first, then
  1769. + * crank up the external clock, and finally switch back to the external
  1770. + * clock. The clock switching procedure is described in the ATmega32U2
  1771. + * data sheet in secton 8.2.2.
  1772. + */
  1773. + spi_begin();
  1774. + spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0);
  1775. + spi_send(0x10);
  1776. + spi_end();
  1777. +
  1778. + /* TX_AUTO_CRC_ON, default disabled */
  1779. + spi_begin();
  1780. + spi_send(AT86RF230_REG_WRITE | 0x05);
  1781. + spi_send(0x80);
  1782. + spi_end();
  1783. +}
  1784. +
  1785. +void board_init(void)
  1786. +{
  1787. + /* Disable the watchdog timer */
  1788. +
  1789. + MCUSR = 0; /* Remove override */
  1790. + WDTCSR |= 1 << WDCE; /* Enable change */
  1791. + WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
  1792. + change */
  1793. +
  1794. + CLKPR = 1 << CLKPCE;
  1795. + /* We start with a 16 MHz/8 clock. Put the prescaler to 2. */
  1796. + CLKPR = 1 << CLKPS0;
  1797. +
  1798. + get_sernum();
  1799. +}
  1800. +
  1801. +void spi_begin(void)
  1802. +{
  1803. + if (!spi_initialized)
  1804. + spi_init();
  1805. + CLR(nSS);
  1806. +}
  1807. +
  1808. +void spi_off(void)
  1809. +{
  1810. + spi_initialized = 0;
  1811. + SPCR &= ~(1 << SPE);
  1812. +}
  1813. +
  1814. +void spi_init(void)
  1815. +{
  1816. + SET(nSS);
  1817. + OUT(SCLK);
  1818. + OUT(MOSI);
  1819. + OUT(nSS);
  1820. + IN(MISO);
  1821. +
  1822. + SPCR = (1 << SPE) | (1 << MSTR);
  1823. + SPSR = (1 << SPI2X);
  1824. +
  1825. + spi_initialized = 1;
  1826. +}
  1827. +
  1828. +void usb_init(void)
  1829. +{
  1830. + USBCON |= 1 << FRZCLK; /* freeze the clock */
  1831. +
  1832. + /* enable the PLL and wait for it to lock */
  1833. + /* TODO sheet page 50 For Atmel AT90USB128x only. Do not use with Atmel AT90USB64x. */
  1834. + /* FOR 8 XTAL Mhz only!!! */
  1835. + PLLCSR = ((1 << PLLP1) | (1 << PLLP0));
  1836. + PLLCSR |= 1 << PLLE;
  1837. + while (!(PLLCSR & (1 << PLOCK)));
  1838. +
  1839. + UHWCON |= (1 << UVREGE);
  1840. +
  1841. + USBCON &= ~((1 << USBE) | (1 << OTGPADE)); /* reset the controller */
  1842. + USBCON |= ((1 << USBE) | (1 << OTGPADE));
  1843. +
  1844. + USBCON &= ~(1 << FRZCLK); /* thaw the clock */
  1845. +
  1846. + UDCON &= ~(1 << DETACH); /* attach the pull-up */
  1847. + UDIEN = 1 << EORSTE; /* enable device interrupts */
  1848. +// UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
  1849. +
  1850. + ep_init();
  1851. +}
  1852. +
  1853. +void board_app_init(void)
  1854. +{
  1855. + /* enable timer input capture 1, trigger on rising edge */
  1856. + TCCR1B = (1 << ICES1);
  1857. + TIFR1 = (1 << ICF1);
  1858. + TIMSK1 = (1 << ICIE1);
  1859. +}
  1860. diff --git a/atusb/board_rzusb.h b/atusb/board_rzusb.h
  1861. new file mode 100644
  1862. index 0000000..c2e518f
  1863. --- /dev/null
  1864. +++ b/atusb/board_rzusb.h
  1865. @@ -0,0 +1,48 @@
  1866. +/*
  1867. + * fw/board_rzusb.h - RZUSB Board-specific functions and definitions
  1868. + *
  1869. + * Written 2016 by Stefan Schmidt
  1870. + * Copyright 2016 Stefan Schmidt
  1871. + *
  1872. + * This program is free software; you can redistribute it and/or modify
  1873. + * it under the terms of the GNU General Public License as published by
  1874. + * the Free Software Foundation; either version 2 of the License, or
  1875. + * (at your option) any later version.
  1876. + */
  1877. +
  1878. +#ifndef BOARD_RZUSB_H
  1879. +#define BOARD_RZUSB_H
  1880. +
  1881. +#include <stdbool.h>
  1882. +#include <stdint.h>
  1883. +
  1884. +#define LED_PORT D
  1885. +#define LED_BIT 7
  1886. +#define nRST_RF_PORT B
  1887. +#define nRST_RF_BIT 5
  1888. +#define SLP_TR_PORT B
  1889. +#define SLP_TR_BIT 4
  1890. +
  1891. +#define SCLK_PORT B
  1892. +#define SCLK_BIT 1
  1893. +#define MOSI_PORT B
  1894. +#define MOSI_BIT 2
  1895. +
  1896. +#define MISO_PORT B
  1897. +#define MISO_BIT 3
  1898. +#define nSS_PORT B
  1899. +#define nSS_BIT 0
  1900. +#define IRQ_RF_PORT D
  1901. +#define IRQ_RF_BIT 4
  1902. +
  1903. +#define SPI_WAIT_DONE() while ((SPSR & (1 << SPIF)) == 0)
  1904. +#define SPI_DATA SPDR
  1905. +
  1906. +void set_clkm(void);
  1907. +void board_init(void);
  1908. +
  1909. +void spi_begin(void);
  1910. +void spi_off(void);
  1911. +void spi_init(void);
  1912. +
  1913. +#endif /* !BOARD_H */
  1914. diff --git a/atusb/boot.c b/atusb/boot.c
  1915. new file mode 100644
  1916. index 0000000..6826ac6
  1917. --- /dev/null
  1918. +++ b/atusb/boot.c
  1919. @@ -0,0 +1,77 @@
  1920. +/*
  1921. + * fw/boot.c - DFU boot loader for ATUSB
  1922. + *
  1923. + * Written 2008-2011 by Werner Almesberger
  1924. + * Copyright 2008-2011 Werner Almesberger
  1925. + *
  1926. + * This program is free software; you can redistribute it and/or modify
  1927. + * it under the terms of the GNU General Public License as published by
  1928. + * the Free Software Foundation; either version 2 of the License, or
  1929. + * (at your option) any later version.
  1930. + */
  1931. +
  1932. +
  1933. +#include <stdint.h>
  1934. +
  1935. +#include <avr/io.h>
  1936. +#include <avr/interrupt.h>
  1937. +#include <avr/pgmspace.h>
  1938. +
  1939. +#define F_CPU 8000000UL
  1940. +#include <util/delay.h>
  1941. +
  1942. +#include "usb.h"
  1943. +#include "dfu.h"
  1944. +
  1945. +#include "board.h"
  1946. +#include "spi.h"
  1947. +#include "atusb/ep0.h"
  1948. +
  1949. +
  1950. +#define MS_TO_LOOPS(ms) ((uint32_t) (ms)*335)
  1951. +
  1952. +
  1953. +static void (*run_payload)(void) = 0;
  1954. +
  1955. +
  1956. +int main(void)
  1957. +{
  1958. + /*
  1959. + * pgm_read_byte gets cached and there doesn't seem to be any other
  1960. + * way to dissuade gcc from doing this.
  1961. + */
  1962. + volatile int zero = 0;
  1963. + uint32_t loop = 0;
  1964. +
  1965. + board_init();
  1966. + reset_rf();
  1967. +
  1968. + /* now we should be at 8 MHz */
  1969. +
  1970. + usb_init();
  1971. + dfu_init();
  1972. +
  1973. + /* move interrupt vectors to the boot loader */
  1974. + MCUCR = 1 << IVCE;
  1975. + MCUCR = 1 << IVSEL;
  1976. +
  1977. + sei();
  1978. +
  1979. + led(1);
  1980. +
  1981. + while (loop != MS_TO_LOOPS(2500)) {
  1982. + if (dfu.state == dfuIDLE && pgm_read_byte(zero) != 0xff)
  1983. + loop++;
  1984. + else
  1985. + loop = 0;
  1986. + }
  1987. +
  1988. + led(0);
  1989. +
  1990. + cli();
  1991. +
  1992. + usb_reset();
  1993. + run_payload();
  1994. +
  1995. + while (1); /* not reached */
  1996. +}
  1997. diff --git a/atusb/descr.c b/atusb/descr.c
  1998. new file mode 100644
  1999. index 0000000..f96b0ee
  2000. --- /dev/null
  2001. +++ b/atusb/descr.c
  2002. @@ -0,0 +1,104 @@
  2003. +/*
  2004. + * fw/descr.c - USB descriptors
  2005. + *
  2006. + * Written 2008-2011, 2014 by Werner Almesberger
  2007. + * Copyright 2008-2011, 2014 Werner Almesberger
  2008. + *
  2009. + * This program is free software; you can redistribute it and/or modify
  2010. + * it under the terms of the GNU General Public License as published by
  2011. + * the Free Software Foundation; either version 2 of the License, or
  2012. + * (at your option) any later version.
  2013. + */
  2014. +
  2015. +
  2016. +#include "usb.h"
  2017. +#include "dfu.h"
  2018. +#include "board.h"
  2019. +
  2020. +
  2021. +#define LE(x) ((uint16_t) (x) & 0xff), ((uint16_t) (x) >> 8)
  2022. +
  2023. +/*
  2024. + * Device descriptor
  2025. + */
  2026. +
  2027. +const uint8_t device_descriptor[18] = {
  2028. + 18, /* bLength */
  2029. + USB_DT_DEVICE, /* bDescriptorType */
  2030. + LE(0x200), /* bcdUSB */
  2031. + USB_CLASS_VENDOR_SPEC, /* bDeviceClass */
  2032. + 0x00, /* bDeviceSubClass */
  2033. + 0x00, /* bDeviceProtocol */
  2034. + EP0_SIZE, /* bMaxPacketSize */
  2035. + LE(USB_VENDOR), /* idVendor */
  2036. + LE(USB_PRODUCT), /* idProduct */
  2037. + LE(0x0001), /* bcdDevice */
  2038. + 0, /* iManufacturer */
  2039. + 0, /* iProduct */
  2040. +#ifdef HAS_BOARD_SERNUM
  2041. + 1, /* iSerialNumber */
  2042. +#else
  2043. + 0, /* iSerialNumber */
  2044. +#endif
  2045. + 1 /* bNumConfigurations */
  2046. +};
  2047. +
  2048. +
  2049. +/*
  2050. + * Our configuration
  2051. + *
  2052. + * We're always bus-powered.
  2053. + */
  2054. +
  2055. +const uint8_t config_descriptor[] = {
  2056. + 9, /* bLength */
  2057. + USB_DT_CONFIG, /* bDescriptorType */
  2058. +#if 0
  2059. + LE(9+9+7+7), /* wTotalLength */
  2060. +#else
  2061. + LE(9+9+7+9), /* wTotalLength */
  2062. +#endif
  2063. + 2, /* bNumInterfaces */
  2064. + 1, /* bConfigurationValue (> 0 !) */
  2065. + 0, /* iConfiguration */
  2066. + USB_ATTR_BUS_POWERED, /* bmAttributes */
  2067. + ((BOARD_MAX_mA)+1)/2, /* bMaxPower */
  2068. +
  2069. + /* Interface #0 */
  2070. +
  2071. + 9, /* bLength */
  2072. + USB_DT_INTERFACE, /* bDescriptorType */
  2073. + 0, /* bInterfaceNumber */
  2074. + 0, /* bAlternateSetting */
  2075. + 1, /* bNumEndpoints */
  2076. + USB_CLASS_VENDOR_SPEC, /* bInterfaceClass */
  2077. + 0, /* bInterfaceSubClass */
  2078. + 0, /* bInterfaceProtocol */
  2079. + 0, /* iInterface */
  2080. +
  2081. +#if 0
  2082. + /* EP OUT */
  2083. +
  2084. + 7, /* bLength */
  2085. + USB_DT_ENDPOINT, /* bDescriptorType */
  2086. + 0x01, /* bEndPointAddress */
  2087. + 0x02, /* bmAttributes (bulk) */
  2088. + LE(EP1_SIZE), /* wMaxPacketSize */
  2089. + 0, /* bInterval */
  2090. +#endif
  2091. +
  2092. +#if 1
  2093. + /* EP IN */
  2094. +
  2095. + 7, /* bLength */
  2096. + USB_DT_ENDPOINT, /* bDescriptorType */
  2097. + 0x81, /* bEndPointAddress */
  2098. + 0x02, /* bmAttributes (bulk) */
  2099. + LE(EP1_SIZE), /* wMaxPacketSize */
  2100. + 0, /* bInterval */
  2101. +#endif
  2102. +
  2103. + /* Interface #1 */
  2104. +
  2105. + DFU_ITF_DESCR(1, 0, dfu_proto_runtime, 0)
  2106. +};
  2107. diff --git a/atusb/ep0.c b/atusb/ep0.c
  2108. new file mode 100644
  2109. index 0000000..fa43f3b
  2110. --- /dev/null
  2111. +++ b/atusb/ep0.c
  2112. @@ -0,0 +1,338 @@
  2113. +/*
  2114. + * fw/ep0.c - EP0 extension protocol
  2115. + *
  2116. + * Written 2008-2011, 2013 by Werner Almesberger
  2117. + * Copyright 2008-2011, 2013 Werner Almesberger
  2118. + * Copyright 2015-2016 Stefan Schmidt
  2119. + *
  2120. + * This program is free software; you can redistribute it and/or modify
  2121. + * it under the terms of the GNU General Public License as published by
  2122. + * the Free Software Foundation; either version 2 of the License, or
  2123. + * (at your option) any later version.
  2124. + */
  2125. +
  2126. +
  2127. +#include <stdbool.h>
  2128. +#include <stdint.h>
  2129. +#include <string.h>
  2130. +
  2131. +#include <avr/io.h>
  2132. +#include <avr/eeprom.h>
  2133. +
  2134. +#define F_CPU 8000000UL
  2135. +#include <util/delay.h>
  2136. +
  2137. +#ifndef NULL
  2138. +#define NULL 0
  2139. +#endif
  2140. +
  2141. +#include "usb.h"
  2142. +#include "dfu.h"
  2143. +
  2144. +#include "at86rf230.h"
  2145. +#include "atusb/ep0.h"
  2146. +#include "version.h"
  2147. +#include "board.h"
  2148. +#include "sernum.h"
  2149. +#include "spi.h"
  2150. +#include "mac.h"
  2151. +
  2152. +#ifdef ATUSB
  2153. +#define HW_TYPE ATUSB_HW_TYPE_110131
  2154. +#endif
  2155. +
  2156. +#ifdef RZUSB
  2157. +#define HW_TYPE ATUSB_HW_TYPE_RZUSB
  2158. +#endif
  2159. +
  2160. +#ifdef HULUSB
  2161. +#define HW_TYPE ATUSB_HW_TYPE_HULUSB
  2162. +#endif
  2163. +
  2164. +#ifdef DEBUG
  2165. +#include "uart.h"
  2166. +#include <stdio.h>
  2167. +#define debug(FORMAT,args...) printf(FORMAT,##args)
  2168. +#define error(FORMAT,args...) printf(FORMAT,##args)
  2169. +#else
  2170. +#define debug(...)
  2171. +#define error(...)
  2172. +#endif
  2173. +
  2174. +
  2175. +static const uint8_t id[] = { EP0ATUSB_MAJOR, EP0ATUSB_MINOR, HW_TYPE };
  2176. +static uint8_t buf[MAX_PSDU+3]; /* command, PHDR, and LQI */
  2177. +static uint8_t size;
  2178. +
  2179. +
  2180. +static void do_eeprom_write(void *user)
  2181. +{
  2182. + int i;
  2183. +
  2184. + for (i = 0; i < size; i++)
  2185. + eeprom_update_byte((uint8_t*)i, buf[i]);
  2186. +}
  2187. +
  2188. +static void do_buf_write(void *user)
  2189. +{
  2190. + uint8_t i;
  2191. +
  2192. + spi_begin();
  2193. + for (i = 0; i != size; i++)
  2194. + spi_send(buf[i]);
  2195. + spi_end();
  2196. +}
  2197. +
  2198. +
  2199. +#define BUILD_OFFSET 7 /* '#' plus "65535" plus ' ' */
  2200. +
  2201. +
  2202. +static bool my_setup(const struct setup_request *setup)
  2203. +{
  2204. + uint16_t req = setup->bmRequestType | setup->bRequest << 8;
  2205. + unsigned tmp;
  2206. + uint8_t i;
  2207. + uint64_t tmp64;
  2208. +
  2209. + switch (req) {
  2210. + case ATUSB_FROM_DEV(ATUSB_ID):
  2211. + debug("ATUSB_ID\n");
  2212. + if (setup->wLength > 3)
  2213. + return 0;
  2214. + usb_send(&eps[0], id, setup->wLength, NULL, NULL);
  2215. + return 1;
  2216. + case ATUSB_FROM_DEV(ATUSB_BUILD):
  2217. + debug("ATUSB_BUILD\n");
  2218. + tmp = build_number;
  2219. + for (i = BUILD_OFFSET-2; tmp; i--) {
  2220. + buf[i] = (tmp % 10)+'0';
  2221. + tmp /= 10;
  2222. + }
  2223. + buf[i] = '#';
  2224. + buf[BUILD_OFFSET-1] = ' ';
  2225. + for (size = 0; build_date[size]; size++)
  2226. + buf[BUILD_OFFSET+size] = build_date[size];
  2227. + size += BUILD_OFFSET-i;
  2228. + if (size > setup->wLength)
  2229. + return 0;
  2230. + usb_send(&eps[0], buf+i, size, NULL, NULL);
  2231. + return 1;
  2232. +
  2233. + case ATUSB_TO_DEV(ATUSB_RESET):
  2234. + debug("ATUSB_RESET\n");
  2235. + reset_cpu();
  2236. + while (1);
  2237. +
  2238. + case ATUSB_TO_DEV(ATUSB_RF_RESET):
  2239. + debug("ATUSB_RF_RESET\n");
  2240. + reset_rf();
  2241. + mac_reset();
  2242. + //ep_send_zlp(EP_CTRL);
  2243. + return 1;
  2244. +
  2245. + case ATUSB_FROM_DEV(ATUSB_POLL_INT):
  2246. + debug("ATUSB_POLL_INT\n");
  2247. + if (setup->wLength < 1)
  2248. + return 0;
  2249. + *buf = read_irq();
  2250. + usb_send(&eps[0], buf, 1, NULL, NULL);
  2251. + return 1;
  2252. +
  2253. + case ATUSB_FROM_DEV(ATUSB_TIMER):
  2254. + debug("ATUSB_TIMER\n");
  2255. + size = setup->wLength;
  2256. + if (size > sizeof(tmp64))
  2257. + size = sizeof(tmp64);
  2258. + tmp64 = timer_read();
  2259. + memcpy(buf, &tmp64, sizeof(tmp64));
  2260. + usb_send(&eps[0], buf, size, NULL, NULL);
  2261. + return 1;
  2262. +
  2263. + case ATUSB_FROM_DEV(ATUSB_GPIO):
  2264. + debug("ATUSB_GPIO\n");
  2265. + if (setup->wLength < 3)
  2266. + return 0;
  2267. + if (!gpio(setup->wIndex, setup->wValue, setup->wValue >> 8,
  2268. + setup->wIndex >> 8, buf))
  2269. + return 0;
  2270. + usb_send(&eps[0], buf, 3, NULL, NULL);
  2271. + return 1;
  2272. + case ATUSB_TO_DEV(ATUSB_GPIO_CLEANUP):
  2273. + gpio_cleanup();
  2274. + return 1;
  2275. +
  2276. + case ATUSB_TO_DEV(ATUSB_SLP_TR):
  2277. + debug("ATUSB_SLP_TR\n");
  2278. + slp_tr();
  2279. + return 1;
  2280. +
  2281. + case ATUSB_TO_DEV(ATUSB_REG_WRITE):
  2282. + debug("ATUSB_REG_WRITE\n");
  2283. + spi_begin();
  2284. + spi_send(AT86RF230_REG_WRITE | setup->wIndex);
  2285. + spi_send(setup->wValue);
  2286. + spi_end();
  2287. + //ep_send_zlp(EP_CTRL);
  2288. + return 1;
  2289. + case ATUSB_FROM_DEV(ATUSB_REG_READ):
  2290. + debug("ATUSB_REG_READ\n");
  2291. + spi_begin();
  2292. + spi_send(AT86RF230_REG_READ | setup->wIndex);
  2293. + *buf = spi_recv();
  2294. + spi_end();
  2295. + usb_send(&eps[0], buf, 1, NULL, NULL);
  2296. + return 1;
  2297. +
  2298. + case ATUSB_TO_DEV(ATUSB_BUF_WRITE):
  2299. + debug("ATUSB_BUF_WRITE\n");
  2300. + if (setup->wLength < 1)
  2301. + return 0;
  2302. + if (setup->wLength > MAX_PSDU)
  2303. + return 0;
  2304. + buf[0] = AT86RF230_BUF_WRITE;
  2305. + buf[1] = setup->wLength;
  2306. + size = setup->wLength+2;
  2307. + usb_recv(&eps[0], buf+2, setup->wLength, do_buf_write, NULL);
  2308. + return 1;
  2309. + case ATUSB_FROM_DEV(ATUSB_BUF_READ):
  2310. + debug("ATUSB_BUF_READ\n");
  2311. + if (setup->wLength < 2) /* PHR+LQI */
  2312. + return 0;
  2313. + if (setup->wLength > MAX_PSDU+2) /* PHR+PSDU+LQI */
  2314. + return 0;
  2315. + spi_begin();
  2316. + spi_send(AT86RF230_BUF_READ);
  2317. + size = spi_recv();
  2318. + if (size >= setup->wLength)
  2319. + size = setup->wLength-1;
  2320. + for (i = 0; i != size+1; i++)
  2321. + buf[i] = spi_recv();
  2322. + spi_end();
  2323. + usb_send(&eps[0], buf, size+1, NULL, NULL);
  2324. + return 1;
  2325. +
  2326. + case ATUSB_TO_DEV(ATUSB_SRAM_WRITE):
  2327. + debug("ATUSB_SRAM_WRITE\n");
  2328. + if (setup->wIndex > SRAM_SIZE)
  2329. + return 0;
  2330. + if (setup->wIndex+setup->wLength > SRAM_SIZE)
  2331. + return 0;
  2332. + buf[0] = AT86RF230_SRAM_WRITE;
  2333. + buf[1] = setup->wIndex;
  2334. + size = setup->wLength+2;
  2335. + usb_recv(&eps[0], buf+2, setup->wLength, do_buf_write, NULL);
  2336. + return 1;
  2337. + case ATUSB_FROM_DEV(ATUSB_SRAM_READ):
  2338. + debug("ATUSB_SRAM_READ\n");
  2339. + if (setup->wIndex > SRAM_SIZE)
  2340. + return 0;
  2341. + if (setup->wIndex+setup->wLength > SRAM_SIZE)
  2342. + return 0;
  2343. + spi_begin();
  2344. + spi_send(AT86RF230_SRAM_READ);
  2345. + spi_send(setup->wIndex);
  2346. + for (i = 0; i != setup->wLength; i++)
  2347. + buf[i] = spi_recv();
  2348. + spi_end();
  2349. + usb_send(&eps[0], buf, setup->wLength, NULL, NULL);
  2350. + return 1;
  2351. +
  2352. + case ATUSB_TO_DEV(ATUSB_SPI_WRITE):
  2353. + size = setup->wLength+2;
  2354. + if (size > sizeof(buf))
  2355. + return 0;
  2356. + buf[0] = setup->wValue;
  2357. + buf[1] = setup->wIndex;
  2358. + if (setup->wLength)
  2359. + usb_recv(&eps[0], buf+2, setup->wLength,
  2360. + do_buf_write, NULL);
  2361. + else
  2362. + do_buf_write(NULL);
  2363. + return 1;
  2364. + case ATUSB_FROM_DEV(ATUSB_SPI_WRITE2_SYNC):
  2365. + spi_begin();
  2366. + spi_send(setup->wValue);
  2367. + spi_send(setup->wIndex);
  2368. + spi_end();
  2369. + buf[0] = irq_serial;
  2370. + if (setup->wLength)
  2371. + usb_send(&eps[0], buf, 1, NULL, NULL);
  2372. + return 1;
  2373. +
  2374. + case ATUSB_FROM_DEV(ATUSB_SPI_READ1):
  2375. + case ATUSB_FROM_DEV(ATUSB_SPI_READ2):
  2376. + spi_begin();
  2377. + spi_send(setup->wValue);
  2378. + if (req == ATUSB_FROM_DEV(ATUSB_SPI_READ2))
  2379. + spi_send(setup->wIndex);
  2380. + for (i = 0; i != setup->wLength; i++)
  2381. + buf[i] = spi_recv();
  2382. + spi_end();
  2383. + usb_send(&eps[0], buf, setup->wLength, NULL, NULL);
  2384. + return 1;
  2385. +
  2386. + case ATUSB_TO_DEV(ATUSB_RX_MODE):
  2387. + return mac_rx(setup->wValue);
  2388. + case ATUSB_TO_DEV(ATUSB_TX):
  2389. + return mac_tx(setup->wValue, setup->wIndex, setup->wLength);
  2390. + case ATUSB_TO_DEV(ATUSB_EUI64_WRITE):
  2391. + debug("ATUSB_EUI64_WRITE\n");
  2392. + usb_recv(&eps[0], buf, setup->wLength, do_eeprom_write, NULL);
  2393. + _delay_ms(100);
  2394. + reset_cpu();
  2395. + return 1;
  2396. +
  2397. + case ATUSB_FROM_DEV(ATUSB_EUI64_READ):
  2398. + debug("ATUSB_EUI64_READ\n");
  2399. + eeprom_read_block(buf, (const void*)0, 8);
  2400. + usb_send(&eps[0], buf, 8, NULL, NULL);
  2401. + return 1;
  2402. +
  2403. + default:
  2404. + error("Unrecognized SETUP: 0x%02x 0x%02x ...\n",
  2405. + setup->bmRequestType, setup->bRequest);
  2406. + return 0;
  2407. + }
  2408. +}
  2409. +
  2410. +
  2411. +static bool my_dfu_setup(const struct setup_request *setup)
  2412. +{
  2413. + switch (setup->bmRequestType | setup->bRequest << 8) {
  2414. + case DFU_TO_DEV(DFU_DETACH):
  2415. + /* @@@ should use wTimeout */
  2416. + dfu.state = appDETACH;
  2417. + return 1;
  2418. + default:
  2419. + return dfu_setup_common(setup);
  2420. + }
  2421. +}
  2422. +
  2423. +
  2424. +static void my_set_interface(int nth)
  2425. +{
  2426. + if (nth) {
  2427. + user_setup = my_dfu_setup;
  2428. + user_get_descriptor = dfu_my_descr;
  2429. + dfu.state = appIDLE;
  2430. + } else {
  2431. + user_setup = my_setup;
  2432. + user_get_descriptor = sernum_get_descr;
  2433. + }
  2434. +}
  2435. +
  2436. +
  2437. +static void my_reset(void)
  2438. +{
  2439. + if (dfu.state == appDETACH)
  2440. + reset_cpu();
  2441. +}
  2442. +
  2443. +
  2444. +void ep0_init(void)
  2445. +{
  2446. + user_setup = my_setup;
  2447. + user_set_interface = my_set_interface;
  2448. + my_set_interface(0);
  2449. + user_reset = my_reset;
  2450. +}
  2451. diff --git a/atusb/flash.c b/atusb/flash.c
  2452. new file mode 100644
  2453. index 0000000..1f8e59d
  2454. --- /dev/null
  2455. +++ b/atusb/flash.c
  2456. @@ -0,0 +1,97 @@
  2457. +/*
  2458. + * fw/flash.c - Board-specific flash functions
  2459. + *
  2460. + * Written 2011, 2013-2015 by Werner Almesberger
  2461. + * Copyright 2011, 2013-2015 Werner Almesberger
  2462. + *
  2463. + * This program is free software; you can redistribute it and/or modify
  2464. + * it under the terms of the GNU General Public License as published by
  2465. + * the Free Software Foundation; either version 2 of the License, or
  2466. + * (at your option) any later version.
  2467. + */
  2468. +
  2469. +
  2470. +#include <stdbool.h>
  2471. +#include <stdint.h>
  2472. +
  2473. +#include <avr/boot.h>
  2474. +#include <avr/pgmspace.h>
  2475. +
  2476. +#include "dfu.h"
  2477. +#include "board.h"
  2478. +
  2479. +
  2480. +static uint32_t payload;
  2481. +
  2482. +
  2483. +static void flash_start(void)
  2484. +{
  2485. + payload = 0;
  2486. +}
  2487. +
  2488. +
  2489. +static bool flash_can_write(uint16_t size)
  2490. +{
  2491. + return payload+size <= BOOT_ADDR;
  2492. +}
  2493. +
  2494. +
  2495. +static void flash_write(const uint8_t *buf, uint16_t size)
  2496. +{
  2497. + static uint8_t last;
  2498. + const uint8_t *p;
  2499. +
  2500. + for (p = buf; p != buf+size; p++) {
  2501. + if (!(payload & (SPM_PAGESIZE-1))) {
  2502. + boot_page_erase(payload);
  2503. + boot_spm_busy_wait();
  2504. + }
  2505. +
  2506. + if (payload & 1)
  2507. + boot_page_fill(payload, last | (*p << 8));
  2508. + else
  2509. + last = *p;
  2510. + payload++;
  2511. +
  2512. + if (!(payload & (SPM_PAGESIZE-1))) {
  2513. + boot_page_write(payload-SPM_PAGESIZE);
  2514. + boot_spm_busy_wait();
  2515. + }
  2516. + }
  2517. +}
  2518. +
  2519. +
  2520. +static void flash_end_write(void)
  2521. +{
  2522. + if (payload & (SPM_PAGESIZE-1)) {
  2523. + boot_page_write(payload & ~(SPM_PAGESIZE-1));
  2524. + boot_spm_busy_wait();
  2525. + }
  2526. + boot_rww_enable();
  2527. +}
  2528. +
  2529. +
  2530. +static uint16_t flash_read(uint8_t *buf, uint16_t size)
  2531. +{
  2532. + uint16_t got = 0;
  2533. +
  2534. + while (size && payload != (uint32_t) FLASHEND+1) {
  2535. + *buf++ = pgm_read_byte(payload);
  2536. + payload++;
  2537. + size--;
  2538. + got++;
  2539. + }
  2540. + return got;
  2541. +}
  2542. +
  2543. +
  2544. +static const struct dfu_flash_ops flash_ops = {
  2545. + .start = flash_start,
  2546. + .can_write = flash_can_write,
  2547. + .write = flash_write,
  2548. + .end_write = flash_end_write,
  2549. + .read = flash_read,
  2550. +};
  2551. +
  2552. +
  2553. +const struct dfu_flash_ops *dfu_flash_ops = &flash_ops;
  2554. diff --git a/atusb/include/at86rf230.h b/atusb/include/at86rf230.h
  2555. new file mode 100644
  2556. index 0000000..4c3ae22
  2557. --- /dev/null
  2558. +++ b/atusb/include/at86rf230.h
  2559. @@ -0,0 +1,402 @@
  2560. +/*
  2561. + * include/at86rf230.h - AT86RF230/AT86RF231 protocol and register definitions
  2562. + *
  2563. + * Written 2008-2011 by Werner Almesberger
  2564. + * Copyright 2008-2011 Werner Almesberger
  2565. + *
  2566. + * This program is free software; you can redistribute it and/or modify
  2567. + * it under the terms of the GNU General Public License as published by
  2568. + * the Free Software Foundation; either version 2 of the License, or
  2569. + * (at your option) any later version.
  2570. + */
  2571. +
  2572. +
  2573. +#ifndef AT86RF230_H
  2574. +#define AT86RF230_H
  2575. +
  2576. +enum {
  2577. + AT86RF230_REG_WRITE = 0xc0, /* 11... */
  2578. + AT86RF230_REG_READ = 0x80, /* 10... */
  2579. + AT86RF230_BUF_WRITE = 0x60, /* 011... */
  2580. + AT86RF230_BUF_READ = 0x20, /* 001... */
  2581. + AT86RF230_SRAM_WRITE = 0x40, /* 010... */
  2582. + AT86RF230_SRAM_READ = 0x00 /* 000... */
  2583. +};
  2584. +
  2585. +#define MAX_PSDU 127 /* octets, see AT86RF230 manual section 8.1 */
  2586. +#define SRAM_SIZE 128
  2587. +
  2588. +
  2589. +/* --- Registers ----------------------------------------------------------- */
  2590. +
  2591. +enum {
  2592. + REG_TRX_STATUS = 0x01,
  2593. + REG_TRX_STATE = 0x02,
  2594. + REG_TRX_CTRL_0 = 0x03,
  2595. +
  2596. + REG_TRX_CTRL_1 = 0x04, /* 231 only */
  2597. +
  2598. + REG_PHY_TX_PWR = 0x05,
  2599. + REG_PHY_RSSI = 0x06,
  2600. + REG_PHY_ED_LEVEL = 0x07,
  2601. + REG_PHY_CC_CCA = 0x08,
  2602. + REG_CCA_THRES = 0x09,
  2603. +
  2604. + REG_RX_CTRL = 0x0a, /* 231 only */
  2605. + REG_SFD_VALUE = 0x0b, /* 231 only */
  2606. + REG_TRX_CTRL_2 = 0x0c, /* 231 only */
  2607. + REG_ANT_DIV = 0x0d, /* 231 only */
  2608. +
  2609. + REG_IRQ_MASK = 0x0e,
  2610. + REG_IRQ_STATUS = 0x0f,
  2611. + REG_VREG_CTRL = 0x10,
  2612. + REG_BATMON = 0x11,
  2613. + REG_XOSC_CTRL = 0x12,
  2614. +
  2615. + REG_RX_SYN = 0x15, /* 231 only */
  2616. + REG_XAH_CTRL_1 = 0x17, /* 231 only */
  2617. + REG_FTN_CTRL = 0x18, /* 231 only */
  2618. +
  2619. + REG_PLL_CF = 0x1a,
  2620. + REL_PLL_DCU = 0x1b,
  2621. + REG_PART_NUM = 0x1c,
  2622. + REG_VERSION_NUM = 0x1d,
  2623. + REG_MAN_ID_0 = 0x1e,
  2624. + REG_MAN_ID_1 = 0x1f,
  2625. + REG_SHORT_ADDR_0 = 0x20,
  2626. + REG_SHORT_ADDR_1 = 0x21,
  2627. + REG_PAN_ID_0 = 0x22,
  2628. + REG_PAN_ID_1 = 0x23,
  2629. + REG_IEEE_ADDR_0 = 0x24,
  2630. + REG_IEEE_ADDR_1 = 0x25,
  2631. + REG_IEEE_ADDR_2 = 0x26,
  2632. + REG_IEEE_ADDR_3 = 0x27,
  2633. + REG_IEEE_ADDR_4 = 0x28,
  2634. + REG_IEEE_ADDR_5 = 0x29,
  2635. + REG_IEEE_ADDR_6 = 0x2a,
  2636. + REG_IEEE_ADDR_7 = 0x2b,
  2637. +
  2638. + REG_XAH_CTRL_0 = 0x2c, /* XAH_CTRL in 230 */
  2639. + REG_CSMA_SEED_0 = 0x2d,
  2640. + REG_CSMA_SEED_1 = 0x2e,
  2641. + REG_CSMA_BE = 0x2f, /* 231 only */
  2642. +
  2643. + REG_CONT_TX_0 = 0x36,
  2644. + REG_CONT_TX_1 = 0x3d, /* 230 only */
  2645. +};
  2646. +
  2647. +/* --- TRX_STATUS --- ------------------------------------------------------ */
  2648. +
  2649. +#define CCA_DONE (1 << 7)
  2650. +#define CCA_STATUS (1 << 6)
  2651. +
  2652. +#define TRX_STATUS_SHIFT 0
  2653. +#define TRX_STATUS_MASK 0x1f
  2654. +
  2655. +enum {
  2656. + TRX_STATUS_P_ON = 0x00, /* reset default */
  2657. + TRX_STATUS_BUSY_RX = 0x01,
  2658. + TRX_STATUS_BUSY_TX = 0x02,
  2659. + TRX_STATUS_RX_ON = 0x06,
  2660. + TRX_STATUS_TRX_OFF = 0x08,
  2661. + TRX_STATUS_PLL_ON = 0x09,
  2662. + TRX_STATUS_SLEEP = 0x0f,
  2663. + TRX_STATUS_BUSY_RX_AACK = 0x11,
  2664. + TRX_STATUS_BUSY_TX_ARET = 0x12,
  2665. + TRX_STATUS_RX_AACK_ON = 0x16,
  2666. + TRX_STATUS_TX_ARET_ON = 0x19,
  2667. + TRX_STATUS_RX_ON_NOCLK = 0x1c,
  2668. + TRX_STATUS_RX_AACK_ON_NOCLK = 0x1d,
  2669. + TRX_STATUS_BUSY_RX_AACK_NOCLK = 0x1e,
  2670. + TRX_STATUS_TRANSITION = 0x1f /* ..._IN_PROGRESS */
  2671. +};
  2672. +
  2673. +/* --- TRX_STATE ----------------------------------------------------------- */
  2674. +
  2675. +#define TRAC_STATUS_SHIFT 5
  2676. +#define TRAC_STATUS_MASK 7
  2677. +
  2678. +enum {
  2679. + TRAC_STATUS_SUCCESS = 0, /* reset default */
  2680. + TRAC_STATUS_SUCCESS_DATA_PENDING = 1,
  2681. + TRAC_STATUS_SUCCESS_WAIT_FOR_ACK = 2, /* 231 only */
  2682. + TRAC_STATUS_CHANNEL_ACCESS_FAILURE = 3,
  2683. + TRAC_STATUS_NO_ACK = 5,
  2684. + TRAC_STATUS_INVALID = 7
  2685. +};
  2686. +
  2687. +#define TRX_CMD_SHIFT 0
  2688. +#define TRX_CMD_MASK 0x1f
  2689. +
  2690. +enum {
  2691. + TRX_CMD_NOP = 0x00, /* reset default */
  2692. + TRX_CMD_TX_START = 0x02,
  2693. + TRX_CMD_FORCE_TRX_OFF = 0x03,
  2694. + TRX_CMD_FORCE_PLL_ON = 0x04, /* 231 only */
  2695. + TRX_CMD_RX_ON = 0x06,
  2696. + TRX_CMD_TRX_OFF = 0x08,
  2697. + TRX_CMD_PLL_ON = 0x09,
  2698. + TRX_CMD_RX_AACK_ON = 0x16,
  2699. + TRX_CMD_TX_ARET_ON = 0x19,
  2700. +};
  2701. +
  2702. +/* --- TRX_CTRL_0 ---------------------------------------------------------- */
  2703. +
  2704. +#define PAD_IO_SHIFT 6
  2705. +#define PAD_IO_MASK 3
  2706. +
  2707. +enum {
  2708. + PAD_IO_2mA, /* reset default */
  2709. + PAD_IO_4mA,
  2710. + PAD_IO_6mA,
  2711. + PAD_IO_8mA
  2712. +};
  2713. +
  2714. +#define PAD_IO_CLKM_SHIFT 4
  2715. +#define PAD_IO_CLKM_MASK 3
  2716. +
  2717. +enum {
  2718. + PAD_IO_CLKM_2mA,
  2719. + PAD_IO_CLKM_4mA, /* reset default */
  2720. + PAD_IO_CLKM_5mA,
  2721. + PAD_IO_CLKM_8mA,
  2722. +};
  2723. +
  2724. +#define CLKM_SHA_SEL (1 << 3)
  2725. +
  2726. +#define CLKM_CTRL_SHIFT 0
  2727. +#define CLKM_CTRL_MASK 7
  2728. +
  2729. +enum {
  2730. + CLKM_CTRL_OFF = 0,
  2731. + CLKM_CTRL_1MHz = 1, /* reset default */
  2732. + CLKM_CTRL_2MHz = 2,
  2733. + CLKM_CTRL_4MHz = 3,
  2734. + CLKM_CTRL_8MHz = 4,
  2735. + CLKM_CTRL_16MHz = 5
  2736. +};
  2737. +
  2738. +/* --- TRX_CTRL_1 (231 only) ----------------------------------------------- */
  2739. +
  2740. +#define PA_EXT_EN (1 << 7)
  2741. +#define IRQ_2_EXT_EN (1 << 6)
  2742. +#define TX_AUTO_CRC_ON (1 << 5) /* 231 location */
  2743. +#define RX_BL_CTRL (1 << 4)
  2744. +
  2745. +#define SPI_CMD_MODE_SHIFT 2
  2746. +#define SPI_CMD_MODE_MASK 3
  2747. +
  2748. +enum {
  2749. + SPI_CMD_MODE_EMPTY = 0, /* reset default */
  2750. + SPI_CMD_MODE_TRX_STATUS = 1,
  2751. + SPI_CMD_MODE_PHY_RSSI = 2,
  2752. + SPI_CMD_MODE_IRQ_STATUS = 3,
  2753. +};
  2754. +
  2755. +#define IRQ_MASK_MODE (1 << 1)
  2756. +#define IRQ_POLARITY (1 << 0)
  2757. +
  2758. +/* --- PHY_TX_PWR ---------------------------------------------------------- */
  2759. +
  2760. +#define TX_AUTO_CRC_ON_230 (1 << 7) /* 230 location */
  2761. +
  2762. +#define PA_BUF_LT_SHIFT 6
  2763. +#define PA_BUF_LT_MASK 3
  2764. +
  2765. +#define PA_LT_SHIFT 4
  2766. +#define PA_LT_MASK 3
  2767. +
  2768. +#define TX_PWR_SHIFT 0
  2769. +#define TX_PWR_MASK 0x0f
  2770. +
  2771. +/* --- PHY_RSSI ------------------------------------------------------------ */
  2772. +
  2773. +#define RX_CRC_VALID (1 << 7)
  2774. +
  2775. +#define RND_VALUE_SHIFT 5 /* 231 only */
  2776. +#define RND_VALUE_MASK 3
  2777. +
  2778. +#define RSSI_SHIFT 0
  2779. +#define RSSI_MASK 0x1f
  2780. +
  2781. +/* --- PHY_CC_CCA ---------------------------------------------------------- */
  2782. +
  2783. +#define CCA_REQUEST (1 << 7)
  2784. +
  2785. +#define CCA_MODE_SHIFT 5
  2786. +#define CCA_MODE_MASK 3
  2787. +
  2788. +enum {
  2789. + CCA_MODE_CARRIER_OR_ENERGY = 0, /* 231 only */
  2790. + CCA_MODE_ENERGY = 1, /* reset default */
  2791. + CCA_MODE_CARRIER = 2,
  2792. + CCA_MODE_CARRIER_AND_ENERGY = 3
  2793. +};
  2794. +
  2795. +#define CHANNEL_SHIFT 0
  2796. +#define CHANNEL_MASK 0x1f
  2797. +
  2798. +/* --- CCA_THRES ----------------------------------------------------------- */
  2799. +
  2800. +#define CCA_ED_THRES_SHIFT 0
  2801. +#define CCA_ED_THRES_MASK 0x0f
  2802. +
  2803. +/* --- RX_CTRL (231 only) -------------------------------------------------- */
  2804. +
  2805. +#define PDT_THRES_SHIFT 0
  2806. +#define PDT_THRES_MASK 0x0f
  2807. +
  2808. +enum {
  2809. + PDT_THRES_DEFAULT = 0x07, /* reset default */
  2810. + PDT_THRES_DIVERSITY = 0x03,
  2811. +};
  2812. +
  2813. +/* --- TRX_CTRL_2 (231 only) ----------------------------------------------- */
  2814. +
  2815. +#define RX_SAFE_MODE (1 << 7)
  2816. +
  2817. +#define OQPSK_DATA_RATE_SHIFT 0
  2818. +#define OQPSK_DATA_RATE_MASK 3
  2819. +
  2820. +enum {
  2821. + OQPSK_DATA_RATE_250 = 0, /* reset default */
  2822. + OQPSK_DATA_RATE_500 = 1,
  2823. + OQPSK_DATA_RATE_1000 = 2,
  2824. + OQPSK_DATA_RATE_2000 = 3
  2825. +};
  2826. +
  2827. +/* --- ANT_DIV (231 only) -------------------------------------------------- */
  2828. +
  2829. +#define ANT_SEL (1 << 7)
  2830. +#define ANT_DIV_EN (1 << 3)
  2831. +#define ANT_EXT_SW_EN (1 << 2)
  2832. +
  2833. +#define ANT_CTRL_SHIFT 0
  2834. +#define ANT_CTRL_MASK 3
  2835. +
  2836. +enum {
  2837. + ANT_CTRL_ANT_0 = 1,
  2838. + ANT_CTRL_ANT_1 = 2,
  2839. + ANT_CTRL_NODIV = 3, /* reset default */
  2840. +};
  2841. +
  2842. +/* --- IRQ_MASK/IRQ_STATUS ------------------------------------------------- */
  2843. +
  2844. +enum {
  2845. + IRQ_PLL_LOCK = 1 << 0,
  2846. + IRQ_PLL_UNLOCK = 1 << 1,
  2847. + IRQ_RX_START = 1 << 2,
  2848. + IRQ_TRX_END = 1 << 3,
  2849. + IRQ_CCA_ED_DONE = 1 << 4, /* 231 only */
  2850. + IRQ_AMI = 1 << 5, /* 231 only */
  2851. + IRQ_TRX_UR = 1 << 6,
  2852. + IRQ_BAT_LOW = 1 << 7
  2853. +};
  2854. +
  2855. +/* --- VREG_CTRL ----------------------------------------------------------- */
  2856. +
  2857. +#define AVREG_EXT (1 << 7)
  2858. +#define AVDD_OK (1 << 6)
  2859. +#define DVREG_EXT (1 << 3)
  2860. +#define DVDD_OK (1 << 2)
  2861. +
  2862. +/* --- BATMON -------------------------------------------------------------- */
  2863. +
  2864. +#define BATMON_OK (1 << 5)
  2865. +#define BATMON_HR (1 << 4)
  2866. +
  2867. +#define BATMON_VTH_SHIFT 0
  2868. +#define BATMON_VTH_MASK 0x0f
  2869. +
  2870. +/* --- XOSC_CTRL ----------------------------------------------------------- */
  2871. +
  2872. +#define XTAL_MODE_SHIFT 4
  2873. +#define XTAL_MODE_MASK 0x0f
  2874. +
  2875. +enum {
  2876. + XTAL_MODE_OFF = 0x0, /* 230 only */
  2877. + XTAL_MODE_EXT = 0x4,
  2878. + XTAL_MODE_INT = 0xf /* reset default */
  2879. +};
  2880. +
  2881. +#define XTAL_TRIM_SHIFT 4
  2882. +#define XTAL_TRIM_MASK 0x0f
  2883. +
  2884. +/* --- RX_SYN (231 only) --------------------------------------------------- */
  2885. +
  2886. +#define RX_PDT_DIS (1 << 7)
  2887. +
  2888. +#define RX_PDT_LEVEL_SHIFT 0
  2889. +#define RX_PDT_LEVEL_MASK 0xf
  2890. +
  2891. +/* --- XAH_CTRL_1 (231 only) ----------------------------------------------- */
  2892. +
  2893. +#define AACK_FLTR_RES_FT (1 << 5)
  2894. +#define AACK_UPLD_RES_FT (1 << 4)
  2895. +#define AACK_ACK_TIME (1 << 2)
  2896. +#define AACK_PROM_MODE (1 << 1)
  2897. +
  2898. +/* --- FTN_CTRL (231 only) ------------------------------------------------- */
  2899. +
  2900. +#define FTN_START (1 << 7)
  2901. +
  2902. +/* --- PLL_CF -------------------------------------------------------------- */
  2903. +
  2904. +#define PLL_CF_START (1 << 7)
  2905. +
  2906. +/* --- PLL_DCU ------------------------------------------------------------- */
  2907. +
  2908. +#define PLL_DCU_START (1 << 7)
  2909. +
  2910. +/* --- XAH_CTRL_0 (XAH_CTRL in 230) ---------------------------------------- */
  2911. +
  2912. +#define MAX_FRAME_RETRIES_SHIFT 4
  2913. +#define MAX_FRAME_RETRIES_MASK 0x0f
  2914. +
  2915. +#define MAX_CSMA_RETRIES_SHIFT 1
  2916. +#define MAX_CSMA_RETRIES_MASK 0x07
  2917. +
  2918. +#define SLOTTED_OPERATION (1 << 0) /* 231 only */
  2919. +
  2920. +/* --- CSMA_SEED_1 --------------------------------------------------------- */
  2921. +
  2922. +#define MIN_BE_SHIFT_230 6 /* 230 location */
  2923. +#define MIN_BE_MASK_230 3
  2924. +
  2925. +#define AACK_FVN_MODE_SHIFT 6 /* 231 only */
  2926. +#define AACK_FVN_MODE_MASK 3
  2927. +
  2928. +enum {
  2929. + AACK_FVN_MODE_0 = 0,
  2930. + AACK_FVN_MODE_01 = 1, /* reset default */
  2931. + AACK_FVN_MODE_012 = 2,
  2932. + AACK_FVN_MODE_ANY = 3
  2933. +};
  2934. +
  2935. +#define AACK_SET_PD (1 << 5)
  2936. +#define AACK_DIS_ACK (1 << 4) /* 231 only */
  2937. +#define I_AM_COORD (1 << 3)
  2938. +
  2939. +#define CSMA_SEED_1_SHIFT 0
  2940. +#define CSMA_SEED_1_MASK 7
  2941. +
  2942. +/* --- CSMA_BE ------------------------------------------------------------- */
  2943. +
  2944. +#define MAX_BE_SHIFT 4
  2945. +#define MAX_BE_MASK 0x0f
  2946. +
  2947. +#define MIN_BE_SHIFT 0 /* 231 location */
  2948. +#define MIN_BE_MASK 0x0f
  2949. +
  2950. +/* --- REG_CONT_TX_0 ------------------------------------------------------- */
  2951. +
  2952. +#define CONT_TX_MAGIC 0x0f
  2953. +
  2954. +/* --- REG_CONT_TX_1 (230 only) -------------------------------------------- */
  2955. +
  2956. +#define CONT_TX_MOD 0x00 /* modulated */
  2957. +#define CONT_TX_M2M 0x10 /* f_CH-2 MHz */
  2958. +#define CONT_TX_M500K 0x80 /* f_CH-0.5 MHz */
  2959. +#define CONT_TX_P500K 0xc0 /* f_CH+0.5 MHz */
  2960. +
  2961. +#endif /* !AT86RF230_H */
  2962. diff --git a/atusb/include/atusb/atusb.h b/atusb/include/atusb/atusb.h
  2963. new file mode 100644
  2964. index 0000000..555d14b
  2965. --- /dev/null
  2966. +++ b/atusb/include/atusb/atusb.h
  2967. @@ -0,0 +1,97 @@
  2968. +/*
  2969. + * atusb.h - Definitions shared between kernel and ATUSB firmware
  2970. + *
  2971. + * Written 2013 by Werner Almesberger <werner@almesberger.net>
  2972. + *
  2973. + * This program is free software; you can redistribute it and/or
  2974. + * modify it under the terms of the GNU General Public License as
  2975. + * published by the Free Software Foundation, version 2, or
  2976. + * (at your option) any later version.
  2977. + *
  2978. + * This file should be identical for kernel and firmware.
  2979. + * Kernel: drivers/net/ieee802154/atusb.h
  2980. + * Firmware: ben-wpan/atusb/fw/include/atusb/atusb.h
  2981. + */
  2982. +
  2983. +#ifndef _ATUSB_H
  2984. +#define _ATUSB_H
  2985. +
  2986. +#define ATUSB_VENDOR_ID 0x20b7 /* Qi Hardware*/
  2987. +#define ATUSB_PRODUCT_ID 0x1540 /* 802.15.4, device 0 */
  2988. + /* -- - - */
  2989. +
  2990. +#define ATUSB_BUILD_SIZE 256 /* maximum build version/date message length */
  2991. +
  2992. +/* Commands to our device. Make sure this is synced with the firmware */
  2993. +enum atusb_requests {
  2994. + ATUSB_ID = 0x00, /* system status/control grp */
  2995. + ATUSB_BUILD,
  2996. + ATUSB_RESET,
  2997. + ATUSB_RF_RESET = 0x10, /* debug/test group */
  2998. + ATUSB_POLL_INT,
  2999. + ATUSB_TEST, /* atusb-sil only */
  3000. + ATUSB_TIMER,
  3001. + ATUSB_GPIO,
  3002. + ATUSB_SLP_TR,
  3003. + ATUSB_GPIO_CLEANUP,
  3004. + ATUSB_REG_WRITE = 0x20, /* transceiver group */
  3005. + ATUSB_REG_READ,
  3006. + ATUSB_BUF_WRITE,
  3007. + ATUSB_BUF_READ,
  3008. + ATUSB_SRAM_WRITE,
  3009. + ATUSB_SRAM_READ,
  3010. + ATUSB_SPI_WRITE = 0x30, /* SPI group */
  3011. + ATUSB_SPI_READ1,
  3012. + ATUSB_SPI_READ2,
  3013. + ATUSB_SPI_WRITE2_SYNC,
  3014. + ATUSB_RX_MODE = 0x40, /* HardMAC group */
  3015. + ATUSB_TX,
  3016. + ATUSB_EUI64_WRITE = 0x50, /* Parameter in EEPROM grp */
  3017. + ATUSB_EUI64_READ,
  3018. +};
  3019. +
  3020. +enum {
  3021. + ATUSB_HW_TYPE_100813, /* 2010-08-13 */
  3022. + ATUSB_HW_TYPE_101216, /* 2010-12-16 */
  3023. + ATUSB_HW_TYPE_110131, /* 2011-01-31, ATmega32U2-based */
  3024. + ATUSB_HW_TYPE_RZUSB, /* Atmel Raven USB dongle with at86rf230 */
  3025. + ATUSB_HW_TYPE_HULUSB, /* Busware HUL USB dongle with at86rf212 */
  3026. +};
  3027. +
  3028. +/*
  3029. + * Direction bRequest wValue wIndex wLength
  3030. + *
  3031. + * ->host ATUSB_ID - - 3
  3032. + * ->host ATUSB_BUILD - - #bytes
  3033. + * host-> ATUSB_RESET - - 0
  3034. + *
  3035. + * host-> ATUSB_RF_RESET - - 0
  3036. + * ->host ATUSB_POLL_INT - - 1
  3037. + * host-> ATUSB_TEST - - 0
  3038. + * ->host ATUSB_TIMER - - #bytes (6)
  3039. + * ->host ATUSB_GPIO dir+data mask+p# 3
  3040. + * host-> ATUSB_SLP_TR - - 0
  3041. + * host-> ATUSB_GPIO_CLEANUP - - 0
  3042. + *
  3043. + * host-> ATUSB_REG_WRITE value addr 0
  3044. + * ->host ATUSB_REG_READ - addr 1
  3045. + * host-> ATUSB_BUF_WRITE - - #bytes
  3046. + * ->host ATUSB_BUF_READ - - #bytes
  3047. + * host-> ATUSB_SRAM_WRITE - addr #bytes
  3048. + * ->host ATUSB_SRAM_READ - addr #bytes
  3049. + *
  3050. + * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes
  3051. + * ->host ATUSB_SPI_READ1 byte0 - #bytes
  3052. + * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes
  3053. + * ->host ATUSB_SPI_WRITE2_SYNC byte0 byte1 0/1
  3054. + *
  3055. + * host-> ATUSB_RX_MODE on - 0
  3056. + * host-> ATUSB_TX flags ack_seq #bytes
  3057. + * host-> ATUSB_EUI64_WRITE - - #bytes (8)
  3058. + * ->host ATUSB_EUI64_READ - - #bytes (8)
  3059. + */
  3060. +
  3061. +#define ATUSB_REQ_FROM_DEV (USB_TYPE_VENDOR | USB_DIR_IN)
  3062. +#define ATUSB_REQ_TO_DEV (USB_TYPE_VENDOR | USB_DIR_OUT)
  3063. +
  3064. +#endif /* !_ATUSB_H */
  3065. diff --git a/atusb/include/atusb/ep0.h b/atusb/include/atusb/ep0.h
  3066. new file mode 100644
  3067. index 0000000..7777345
  3068. --- /dev/null
  3069. +++ b/atusb/include/atusb/ep0.h
  3070. @@ -0,0 +1,64 @@
  3071. +/*
  3072. + * include/atusb/ep0.h - EP0 extension protocol
  3073. + *
  3074. + * Written 2008-2011, 2013 by Werner Almesberger
  3075. + * Copyright 2008-2011, 2013 Werner Almesberger
  3076. + *
  3077. + * This program is free software; you can redistribute it and/or modify
  3078. + * it under the terms of the GNU General Public License as published by
  3079. + * the Free Software Foundation; either version 2 of the License, or
  3080. + * (at your option) any later version.
  3081. + */
  3082. +
  3083. +
  3084. +#ifndef EP0_H
  3085. +#define EP0_H
  3086. +
  3087. +#include <atusb/atusb.h>
  3088. +
  3089. +
  3090. +/*
  3091. + * EP0 protocol:
  3092. + *
  3093. + * 0.0 initial release
  3094. + * 0.1 addition of ATUSB_TEST
  3095. + * 0.2 First public release
  3096. + * 0.3 ATUSB_EUI64_READ/WRITE for permanent EUI64 handling
  3097. + * Support to run the firmware on Atmel Raven USB dongles
  3098. + * Remove FCS frame check from firmware and leave it to the driver
  3099. + * Use extended operation mode for TX for automatic ACK handling
  3100. + */
  3101. +
  3102. +#define EP0ATUSB_MAJOR 0 /* EP0 protocol, major revision */
  3103. +#define EP0ATUSB_MINOR 3 /* EP0 protocol, minor revision */
  3104. +
  3105. +
  3106. +/*
  3107. + * bmRequestType:
  3108. + *
  3109. + * D7 D6..5 D4...0
  3110. + * | | |
  3111. + * direction (0 = host->dev)
  3112. + * type (2 = vendor)
  3113. + * recipient (0 = device)
  3114. + */
  3115. +
  3116. +#ifndef USB_TYPE_VENDOR
  3117. +#define USB_TYPE_VENDOR 0x40
  3118. +#endif
  3119. +
  3120. +#ifndef USB_DIR_IN
  3121. +#define USB_DIR_IN 0x80
  3122. +#endif
  3123. +
  3124. +#ifndef USB_DIR_OUT
  3125. +#define USB_DIR_OUT 0x00
  3126. +#endif
  3127. +
  3128. +#define ATUSB_FROM_DEV(req) (ATUSB_REQ_FROM_DEV | (req) << 8)
  3129. +#define ATUSB_TO_DEV(req) (ATUSB_REQ_TO_DEV | (req) << 8)
  3130. +
  3131. +
  3132. +void ep0_init(void);
  3133. +
  3134. +#endif /* !EP0_H */
  3135. diff --git a/atusb/mac.c b/atusb/mac.c
  3136. new file mode 100644
  3137. index 0000000..835002c
  3138. --- /dev/null
  3139. +++ b/atusb/mac.c
  3140. @@ -0,0 +1,250 @@
  3141. +/*
  3142. + * fw/mac.c - HardMAC functions
  3143. + *
  3144. + * Written 2011, 2013 by Werner Almesberger
  3145. + * Copyright 2011, 2013 Werner Almesberger
  3146. + *
  3147. + * This program is free software; you can redistribute it and/or modify
  3148. + * it under the terms of the GNU General Public License as published by
  3149. + * the Free Software Foundation; either version 2 of the License, or
  3150. + * (at your option) any later version.
  3151. + */
  3152. +
  3153. +#include <stddef.h>
  3154. +#include <stdbool.h>
  3155. +#include <stdint.h>
  3156. +
  3157. +#include "usb.h"
  3158. +
  3159. +#include "at86rf230.h"
  3160. +#include "spi.h"
  3161. +#include "board.h"
  3162. +#include "mac.h"
  3163. +
  3164. +#define RX_BUFS 3
  3165. +
  3166. +
  3167. +bool (*mac_irq)(void) = NULL;
  3168. +
  3169. +
  3170. +static uint8_t rx_buf[RX_BUFS][MAX_PSDU+2]; /* PHDR+payload+LQ */
  3171. +static uint8_t tx_buf[MAX_PSDU];
  3172. +static uint8_t tx_size = 0;
  3173. +static bool txing = 0;
  3174. +static bool queued_tx_ack = 0;
  3175. +static uint8_t next_seq, this_seq, queued_seq;
  3176. +
  3177. +
  3178. +/* ----- Receive buffer management ----------------------------------------- */
  3179. +
  3180. +
  3181. +static uint8_t rx_in = 0, rx_out = 0;
  3182. +
  3183. +
  3184. +static inline void next_buf(uint8_t *index)
  3185. +{
  3186. + *index = (*index+1) % RX_BUFS;
  3187. +}
  3188. +
  3189. +
  3190. +/* ----- Interrupt handling ------------------------------------------------ */
  3191. +
  3192. +
  3193. +static void rx_done(void *user);
  3194. +static void tx_ack_done(void *user);
  3195. +
  3196. +
  3197. +static void usb_next(void)
  3198. +{
  3199. + const uint8_t *buf;
  3200. +
  3201. + if (rx_in != rx_out) {
  3202. + buf = rx_buf[rx_out];
  3203. + led(1);
  3204. + usb_send(&eps[1], buf, buf[0]+2, rx_done, NULL);
  3205. + }
  3206. +
  3207. + if (queued_tx_ack) {
  3208. + usb_send(&eps[1], &queued_seq, 1, tx_ack_done, NULL);
  3209. + queued_tx_ack = 0;
  3210. + }
  3211. +}
  3212. +
  3213. +
  3214. +static void tx_ack_done(void *user)
  3215. +{
  3216. + usb_next();
  3217. +}
  3218. +
  3219. +static void rx_done(void *user)
  3220. +{
  3221. + led(0);
  3222. + next_buf(&rx_out);
  3223. + usb_next();
  3224. +#ifdef AT86RF230
  3225. + /* slap at86rf230 - reduce fragmentation issue */
  3226. + change_state(TRX_STATUS_RX_AACK_ON);
  3227. +#endif
  3228. +}
  3229. +
  3230. +
  3231. +static void receive_frame(void)
  3232. +{
  3233. + uint8_t size;
  3234. + uint8_t *buf;
  3235. +
  3236. + spi_begin();
  3237. + spi_io(AT86RF230_BUF_READ);
  3238. +
  3239. + size = spi_recv();
  3240. + if (!size || (size & 0x80)) {
  3241. + spi_end();
  3242. + return;
  3243. + }
  3244. +
  3245. + buf = rx_buf[rx_in];
  3246. + spi_recv_block(buf+1, size+1);
  3247. + spi_end();
  3248. +
  3249. + buf[0] = size;
  3250. + next_buf(&rx_in);
  3251. +
  3252. + if (eps[1].state == EP_IDLE)
  3253. + usb_next();
  3254. +}
  3255. +
  3256. +
  3257. +static bool handle_irq(void)
  3258. +{
  3259. + uint8_t irq;
  3260. +
  3261. + irq = reg_read(REG_IRQ_STATUS);
  3262. + if (!(irq & IRQ_TRX_END))
  3263. + return 1;
  3264. +
  3265. + if (txing) {
  3266. + if (eps[1].state == EP_IDLE) {
  3267. + usb_send(&eps[1], &this_seq, 1, tx_ack_done, NULL);
  3268. + } else {
  3269. + queued_tx_ack = 1;
  3270. + queued_seq = this_seq;
  3271. + }
  3272. + txing = 0;
  3273. + return 1;
  3274. + }
  3275. +
  3276. + /* likely */
  3277. + if (eps[1].state == EP_IDLE || rx_in != rx_out)
  3278. + receive_frame();
  3279. +
  3280. + return 1;
  3281. +}
  3282. +
  3283. +
  3284. +/* ----- TX/RX ------------------------------------------------------------- */
  3285. +
  3286. +
  3287. +bool mac_rx(int on)
  3288. +{
  3289. + if (on) {
  3290. + mac_irq = handle_irq;
  3291. + reg_read(REG_IRQ_STATUS);
  3292. + change_state(TRX_CMD_RX_AACK_ON);
  3293. + } else {
  3294. + mac_irq = NULL;
  3295. + change_state(TRX_CMD_FORCE_TRX_OFF);
  3296. + txing = 0;
  3297. + }
  3298. + return 1;
  3299. +}
  3300. +
  3301. +
  3302. +static void do_tx(void *user)
  3303. +{
  3304. + uint16_t timeout = 0xffff;
  3305. + uint8_t status;
  3306. + uint8_t i;
  3307. +
  3308. + /*
  3309. + * If we time out here, the host driver will time out waiting for the
  3310. + * TRX_END acknowledgement.
  3311. + */
  3312. + do {
  3313. + if (!--timeout)
  3314. + return;
  3315. + status = reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK;
  3316. + }
  3317. + while (status != TRX_STATUS_RX_ON && status != TRX_STATUS_RX_AACK_ON);
  3318. +
  3319. +#ifdef AT86RF231
  3320. + /*
  3321. + * We use TRX_CMD_FORCE_PLL_ON instead of TRX_CMD_PLL_ON because a new
  3322. + * reception may have begun while we were still working on the previous
  3323. + * one.
  3324. + */
  3325. + reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
  3326. +#endif
  3327. +#ifdef AT86RF230
  3328. + /*
  3329. + * at86rf230 doesn't support force change, nevetherless this works
  3330. + * somehow
  3331. + */
  3332. + reg_write(REG_TRX_STATE, TRX_CMD_PLL_ON);
  3333. +#endif
  3334. +#ifdef AT86RF212
  3335. + /*
  3336. + * We use TRX_CMD_FORCE_PLL_ON instead of TRX_CMD_PLL_ON because a new
  3337. + * reception may have begun while we were still working on the previous
  3338. + * one.
  3339. + */
  3340. + reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
  3341. +#endif
  3342. +
  3343. + handle_irq();
  3344. +
  3345. + spi_begin();
  3346. + spi_send(AT86RF230_BUF_WRITE);
  3347. + spi_send(tx_size+2); /* CRC */
  3348. + for (i = 0; i != tx_size; i++)
  3349. + spi_send(tx_buf[i]);
  3350. + spi_end();
  3351. +
  3352. + change_state(TRX_STATUS_TX_ARET_ON);
  3353. +
  3354. + slp_tr();
  3355. +
  3356. + txing = 1;
  3357. + this_seq = next_seq;
  3358. +
  3359. + /*
  3360. + * Wait until we reach BUSY_TX_ARET, so that we command the transition to
  3361. + * RX_AACK_ON which will be executed upon TX completion.
  3362. + */
  3363. + change_state(TRX_CMD_PLL_ON);
  3364. + change_state(TRX_CMD_RX_AACK_ON);
  3365. +}
  3366. +
  3367. +
  3368. +bool mac_tx(uint16_t flags, uint8_t seq, uint16_t len)
  3369. +{
  3370. + if (len > MAX_PSDU)
  3371. + return 0;
  3372. + tx_size = len;
  3373. + next_seq = seq;
  3374. + usb_recv(&eps[0], tx_buf, len, do_tx, NULL);
  3375. + return 1;
  3376. +}
  3377. +
  3378. +
  3379. +void mac_reset(void)
  3380. +{
  3381. + mac_irq = NULL;
  3382. + txing = 0;
  3383. + queued_tx_ack = 0;
  3384. + rx_in = rx_out = 0;
  3385. + next_seq = this_seq = queued_seq = 0;
  3386. +
  3387. + /* enable CRC and PHY_RSSI (with RX_CRC_VALID) in SPI status return */
  3388. + reg_write(REG_TRX_CTRL_1,
  3389. + TX_AUTO_CRC_ON | SPI_CMD_MODE_PHY_RSSI << SPI_CMD_MODE_SHIFT);
  3390. +}
  3391. diff --git a/atusb/mac.h b/atusb/mac.h
  3392. new file mode 100644
  3393. index 0000000..f3c92fb
  3394. --- /dev/null
  3395. +++ b/atusb/mac.h
  3396. @@ -0,0 +1,26 @@
  3397. +/*
  3398. + * fw/mac.h - HardMAC functions
  3399. + *
  3400. + * Written 2011, 2013 by Werner Almesberger
  3401. + * Copyright 2011, 2013 Werner Almesberger
  3402. + *
  3403. + * This program is free software; you can redistribute it and/or modify
  3404. + * it under the terms of the GNU General Public License as published by
  3405. + * the Free Software Foundation; either version 2 of the License, or
  3406. + * (at your option) any later version.
  3407. + */
  3408. +
  3409. +#ifndef MAC_H
  3410. +#define MAC_H
  3411. +
  3412. +#include <stdbool.h>
  3413. +#include <stdint.h>
  3414. +
  3415. +
  3416. +extern bool (*mac_irq)(void);
  3417. +
  3418. +bool mac_rx(int on);
  3419. +bool mac_tx(uint16_t flags, uint8_t seq, uint16_t len);
  3420. +void mac_reset(void);
  3421. +
  3422. +#endif /* !MAC_H */
  3423. diff --git a/atusb/sernum.c b/atusb/sernum.c
  3424. new file mode 100644
  3425. index 0000000..41e434c
  3426. --- /dev/null
  3427. +++ b/atusb/sernum.c
  3428. @@ -0,0 +1,47 @@
  3429. +/*
  3430. + * fw/sernum.c - ATUSB serial number
  3431. + *
  3432. + * Written 2008-2011, 2013 by Werner Almesberger
  3433. + * Copyright 2008-2011, 2013 Werner Almesberger
  3434. + *
  3435. + * This program is free software; you can redistribute it and/or modify
  3436. + * it under the terms of the GNU General Public License as published by
  3437. + * the Free Software Foundation; either version 2 of the License, or
  3438. + * (at your option) any later version.
  3439. + */
  3440. +
  3441. +
  3442. +#include <stdbool.h>
  3443. +#include <stdint.h>
  3444. +
  3445. +#include "usb.h"
  3446. +
  3447. +#include "board.h"
  3448. +#include "sernum.h"
  3449. +
  3450. +
  3451. +static const uint8_t string_descriptor_0[] = {
  3452. + 4, /* blength */
  3453. + USB_DT_STRING, /* bDescriptorType */
  3454. + LE(USB_LANGID_ENGLISH_US) /* wLANGID[0] */
  3455. +};
  3456. +
  3457. +
  3458. +bool sernum_get_descr(uint8_t type, uint8_t index, const uint8_t **reply,
  3459. + uint8_t *size)
  3460. +{
  3461. + if (type != USB_DT_STRING)
  3462. + return 0;
  3463. + switch (index) {
  3464. + case 0:
  3465. + *reply = string_descriptor_0;
  3466. + *size = sizeof(string_descriptor_0);
  3467. + return 1;
  3468. + case 1:
  3469. + *reply = board_sernum;
  3470. + *size = sizeof(board_sernum);
  3471. + return 1;
  3472. + default:
  3473. + return 0;
  3474. + }
  3475. +}
  3476. diff --git a/atusb/sernum.h b/atusb/sernum.h
  3477. new file mode 100644
  3478. index 0000000..31a8e27
  3479. --- /dev/null
  3480. +++ b/atusb/sernum.h
  3481. @@ -0,0 +1,37 @@
  3482. +/*
  3483. + * fw/sernum.h - ATUSB serial number
  3484. + *
  3485. + * Written 2011, 2013 by Werner Almesberger
  3486. + * Copyright 2011, 2013 Werner Almesberger
  3487. + *
  3488. + * This program is free software; you can redistribute it and/or modify
  3489. + * it under the terms of the GNU General Public License as published by
  3490. + * the Free Software Foundation; either version 2 of the License, or
  3491. + * (at your option) any later version.
  3492. + */
  3493. +
  3494. +#ifndef SERNUM_H
  3495. +#define SERNUM_H
  3496. +
  3497. +#include <stdbool.h>
  3498. +#include <stdint.h>
  3499. +
  3500. +#include "board.h"
  3501. +
  3502. +
  3503. +#ifdef HAS_BOARD_SERNUM
  3504. +
  3505. +bool sernum_get_descr(uint8_t type, uint8_t index, const uint8_t **reply,
  3506. + uint8_t *size);
  3507. +
  3508. +#else /* HAS_BOARD_SERNUM */
  3509. +
  3510. +static inline bool sernum_get_descr(uint8_t type, uint8_t index,
  3511. + const uint8_t **reply, uint8_t *size)
  3512. +{
  3513. + return 0;
  3514. +}
  3515. +
  3516. +#endif /* !HAS_BOARD_SERNUM */
  3517. +
  3518. +#endif /* !SERNUM_H */
  3519. diff --git a/atusb/spi.c b/atusb/spi.c
  3520. new file mode 100644
  3521. index 0000000..3fa5715
  3522. --- /dev/null
  3523. +++ b/atusb/spi.c
  3524. @@ -0,0 +1,51 @@
  3525. +/*
  3526. + * fw/spi.c - ATmega8 family SPI I/O
  3527. + *
  3528. + * Written 2011, 2013 by Werner Almesberger
  3529. + * Copyright 2011, 2013 Werner Almesberger
  3530. + *
  3531. + * This program is free software; you can redistribute it and/or modify
  3532. + * it under the terms of the GNU General Public License as published by
  3533. + * the Free Software Foundation; either version 2 of the License, or
  3534. + * (at your option) any later version.
  3535. + */
  3536. +
  3537. +
  3538. +#include <stdbool.h>
  3539. +#include <stdint.h>
  3540. +
  3541. +#include <avr/io.h>
  3542. +
  3543. +#include "board.h"
  3544. +#include "spi.h"
  3545. +
  3546. +
  3547. +uint8_t spi_io(uint8_t v)
  3548. +{
  3549. +// while (!(UCSR1A & 1 << UDRE1));
  3550. + SPI_DATA = v;
  3551. + SPI_WAIT_DONE();
  3552. + return SPI_DATA;
  3553. +}
  3554. +
  3555. +
  3556. +void spi_end(void)
  3557. +{
  3558. +// while (!(UCSR1A & 1 << TXC1));
  3559. + SET(nSS);
  3560. +}
  3561. +
  3562. +
  3563. +void spi_recv_block(uint8_t *buf, uint8_t n)
  3564. +{
  3565. + if (!n)
  3566. + return;
  3567. + SPI_DATA = 0;
  3568. + while (--n) {
  3569. + SPI_WAIT_DONE();
  3570. + *buf++ = SPI_DATA;
  3571. + SPI_DATA = 0;
  3572. + }
  3573. + SPI_WAIT_DONE();
  3574. + *buf++ = SPI_DATA;
  3575. +}
  3576. diff --git a/atusb/spi.h b/atusb/spi.h
  3577. new file mode 100644
  3578. index 0000000..6e04f4e
  3579. --- /dev/null
  3580. +++ b/atusb/spi.h
  3581. @@ -0,0 +1,30 @@
  3582. +/*
  3583. + * fw/spi.h - ATmega8 family SPI I/O
  3584. + *
  3585. + * Written 2011, 2013 by Werner Almesberger
  3586. + * Copyright 2011, 2013 Werner Almesberger
  3587. + *
  3588. + * This program is free software; you can redistribute it and/or modify
  3589. + * it under the terms of the GNU General Public License as published by
  3590. + * the Free Software Foundation; either version 2 of the License, or
  3591. + * (at your option) any later version.
  3592. + */
  3593. +
  3594. +#ifndef SPI_H
  3595. +#define SPI_H
  3596. +
  3597. +#include <stdint.h>
  3598. +
  3599. +
  3600. +void spi_begin(void);
  3601. +uint8_t spi_io(uint8_t v);
  3602. +void spi_end(void);
  3603. +void spi_off(void);
  3604. +void spi_init(void);
  3605. +
  3606. +#define spi_send(v) (void) spi_io(v)
  3607. +#define spi_recv(v) spi_io(0)
  3608. +
  3609. +void spi_recv_block(uint8_t *buf, uint8_t n);
  3610. +
  3611. +#endif /* !SPI_H */
  3612. diff --git a/atusb/uart.c b/atusb/uart.c
  3613. new file mode 100644
  3614. index 0000000..44bec27
  3615. --- /dev/null
  3616. +++ b/atusb/uart.c
  3617. @@ -0,0 +1,64 @@
  3618. +/*
  3619. + * fw/uart.h - Functions needed for debugging over uart
  3620. + *
  3621. + * Code adapted from http://www.roboternetz.de/wissen/index.php/UART_mit_avr-gcc
  3622. + * and http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
  3623. + *
  3624. + * Published under the Creative Commons Share-Alike licence
  3625. + * https://creativecommons.org/licenses/by-sa/2.0/de/
  3626. + *
  3627. + * S. Salewski 2007
  3628. + *
  3629. + * Adapted by
  3630. + * Josef Filzmaier 2017
  3631. + */
  3632. +
  3633. +#include <avr/io.h>
  3634. +#include "uart.h"
  3635. +
  3636. +#define USART_BAUD 38400UL
  3637. +#define F_CPU 8000000UL
  3638. +
  3639. +#define Wait_USART_Ready() while (!(UCSR1A & (1<<UDRE1)))
  3640. +#define UART_UBRR (F_CPU/(16L*USART_BAUD)-1)
  3641. +
  3642. +// initialize USART, 8N1 mode
  3643. +void
  3644. +uart_init(void)
  3645. +{
  3646. +/* TODO: Find a working configuration for uart for the atmega32u2 */
  3647. +#if CHIP == at90usb1287
  3648. + CLKPR = (1 << CLKPCE);
  3649. + CLKPR = 0; // clock prescaler == 0, so we have 16 MHz mpu frequency
  3650. + UBRR1 = UART_UBRR;
  3651. + UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
  3652. + UCSR1B = (1 << TXEN1);
  3653. + do
  3654. + {
  3655. + UDR1;
  3656. + }
  3657. + while (UCSR1A & (1 << RXC1));
  3658. +#endif
  3659. +
  3660. +}
  3661. +
  3662. +int uart_write_char(char c, FILE* stream)
  3663. +{
  3664. + if (c == '\n'){
  3665. + uart_new_line();
  3666. + }
  3667. + else {
  3668. + Wait_USART_Ready();
  3669. + UDR1 = c;
  3670. + }
  3671. + return 0;
  3672. +}
  3673. +
  3674. +void
  3675. +uart_new_line(void)
  3676. +{
  3677. + Wait_USART_Ready();
  3678. + UDR1 = '\r';
  3679. + Wait_USART_Ready();
  3680. + UDR1 = '\n';
  3681. +}
  3682. diff --git a/atusb/uart.h b/atusb/uart.h
  3683. new file mode 100644
  3684. index 0000000..4810f9c
  3685. --- /dev/null
  3686. +++ b/atusb/uart.h
  3687. @@ -0,0 +1,25 @@
  3688. +/*
  3689. + * fw/uart.h - Functions needed for debugging over uart
  3690. + *
  3691. + * Code adapted from http://www.roboternetz.de/wissen/index.php/UART_mit_avr-gcc
  3692. + * and http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
  3693. + *
  3694. + * Published under the Creative Commons Share-Alike licence
  3695. + * https://creativecommons.org/licenses/by-sa/2.0/de/
  3696. + *
  3697. + * S. Salewski 2007
  3698. + *
  3699. + * Adapted by
  3700. + * Josef Filzmaier 2017
  3701. + */
  3702. +
  3703. +#ifndef UART_H_
  3704. +#define UART_H_
  3705. +
  3706. +#include <stdio.h>
  3707. +
  3708. +void uart_init(void);
  3709. +int uart_write_char(char c, FILE* stream);
  3710. +void uart_new_line(void);
  3711. +
  3712. +#endif /* UART_H_ */
  3713. diff --git a/atusb/usb/atu2.c b/atusb/usb/atu2.c
  3714. new file mode 100644
  3715. index 0000000..98158bf
  3716. --- /dev/null
  3717. +++ b/atusb/usb/atu2.c
  3718. @@ -0,0 +1,247 @@
  3719. +/*
  3720. + * fw/usb/atu2.c - Chip-specific driver for Atmel ATxxxU2 USB chips
  3721. + *
  3722. + * Written 2008-2011, 2013-2014 by Werner Almesberger
  3723. + * Copyright 2008-2011, 2013-2014 Werner Almesberger
  3724. + *
  3725. + * This program is free software; you can redistribute it and/or modify
  3726. + * it under the terms of the GNU General Public License as published by
  3727. + * the Free Software Foundation; either version 2 of the License, or
  3728. + * (at your option) any later version.
  3729. + */
  3730. +
  3731. +/*
  3732. + * Known issues:
  3733. + * - no suspend/resume
  3734. + * - we don't call back after failed transmissions,
  3735. + * - we don't reset the EP buffer after failed receptions
  3736. + * - enumeration often encounters an error -71 (from which it recovers)
  3737. + */
  3738. +
  3739. +#include <stdbool.h>
  3740. +#include <stdint.h>
  3741. +
  3742. +#define F_CPU 8000000UL
  3743. +#include <util/delay.h>
  3744. +
  3745. +#include <avr/io.h>
  3746. +#include <avr/interrupt.h>
  3747. +#include "usb.h"
  3748. +#include "board.h"
  3749. +
  3750. +
  3751. +#ifndef NULL
  3752. +#define NULL 0
  3753. +#endif
  3754. +
  3755. +#if 1
  3756. +#define BUG_ON(cond) do { if (cond) panic(); } while (0)
  3757. +#else
  3758. +#define BUG_ON(cond)
  3759. +#endif
  3760. +
  3761. +
  3762. +struct ep_descr eps[NUM_EPS];
  3763. +
  3764. +
  3765. +static uint16_t usb_read_word(void)
  3766. +{
  3767. + uint8_t low;
  3768. +
  3769. + low = UEDATX;
  3770. + return low | UEDATX << 8;
  3771. +}
  3772. +
  3773. +
  3774. +static void enable_addr(void *user)
  3775. +{
  3776. + while (!(UEINTX & (1 << TXINI)));
  3777. + UDADDR |= 1 << ADDEN;
  3778. +}
  3779. +
  3780. +
  3781. +void set_addr(uint8_t addr)
  3782. +{
  3783. + UDADDR = addr;
  3784. + usb_send(&eps[0], NULL, 0, enable_addr, NULL);
  3785. +}
  3786. +
  3787. +
  3788. +void usb_ep_change(struct ep_descr *ep)
  3789. +{
  3790. + if (ep->state == EP_TX) {
  3791. + UENUM = ep-eps;
  3792. + UEIENX |= 1 << TXINE;
  3793. + }
  3794. +}
  3795. +
  3796. +
  3797. +static bool ep_setup(void)
  3798. +{
  3799. + struct setup_request setup;
  3800. +
  3801. + BUG_ON(UEBCLX < 8);
  3802. +
  3803. + setup.bmRequestType = UEDATX;
  3804. + setup.bRequest = UEDATX;
  3805. + setup.wValue = usb_read_word();
  3806. + setup.wIndex = usb_read_word();
  3807. + setup.wLength = usb_read_word();
  3808. +
  3809. + if (!handle_setup(&setup))
  3810. + return 0;
  3811. + if (!(setup.bmRequestType & 0x80) && eps[0].state == EP_IDLE)
  3812. + usb_send(&eps[0], NULL, 0, NULL, NULL);
  3813. + return 1;
  3814. +}
  3815. +
  3816. +
  3817. +static bool ep_rx(struct ep_descr *ep)
  3818. +{
  3819. + uint8_t size;
  3820. +
  3821. + size = UEBCLX;
  3822. + if (size > ep->end-ep->buf)
  3823. + return 0;
  3824. + while (size--)
  3825. + *ep->buf++ = UEDATX;
  3826. + if (ep->buf == ep->end) {
  3827. + ep->state = EP_IDLE;
  3828. + if (ep->callback)
  3829. + ep->callback(ep->user);
  3830. +// if (ep == &eps[0])
  3831. + usb_send(ep, NULL, 0, NULL, NULL);
  3832. + }
  3833. + return 1;
  3834. +}
  3835. +
  3836. +
  3837. +static void ep_tx(struct ep_descr *ep)
  3838. +{
  3839. + uint8_t size = ep->end-ep->buf;
  3840. + uint8_t left;
  3841. +
  3842. + if (size > ep->size)
  3843. + size = ep->size;
  3844. + for (left = size; left; left--)
  3845. + UEDATX = *ep->buf++;
  3846. + if (size == ep->size)
  3847. + return;
  3848. + ep->state = EP_IDLE;
  3849. +}
  3850. +
  3851. +
  3852. +static void handle_ep(int n)
  3853. +{
  3854. + struct ep_descr *ep = eps+n;
  3855. + uint8_t mask;
  3856. +
  3857. + UENUM = n;
  3858. + if (UEINTX & (1 << RXSTPI)) {
  3859. + /* @@@ EP_RX. EP_TX: cancel */
  3860. + ep->state = EP_IDLE;
  3861. + if (!ep_setup())
  3862. + goto stall;
  3863. + UEINTX = ~(1 << RXSTPI);
  3864. + }
  3865. + if (UEINTX & (1 << RXOUTI)) {
  3866. + /* @@ EP_TX: cancel */
  3867. + if (ep->state != EP_RX)
  3868. + goto stall;
  3869. + if (!ep_rx(ep))
  3870. + goto stall;
  3871. + /* @@@ gcc 4.5.2 wants this cast */
  3872. + UEINTX = (uint8_t) ~(1 << RXOUTI | 1 << FIFOCON);
  3873. + }
  3874. + if (UEINTX & (1 << STALLEDI)) {
  3875. + ep->state = EP_IDLE;
  3876. + UEINTX = ~(1 << STALLEDI);
  3877. + }
  3878. + if (UEINTX & (1 << TXINI)) {
  3879. + /* @@ EP_RX: cancel (?) */
  3880. + if (ep->state == EP_TX) {
  3881. + ep_tx(ep);
  3882. + mask = 1 << TXINI;
  3883. + if (n)
  3884. + mask |= 1 << FIFOCON;
  3885. + UEINTX = ~mask;
  3886. + if (ep->state == EP_IDLE && ep->callback)
  3887. + ep->callback(ep->user);
  3888. + } else {
  3889. + UEIENX &= ~(1 << TXINE);
  3890. + }
  3891. + }
  3892. + return;
  3893. +
  3894. +stall:
  3895. + UEINTX = ~(1 << RXSTPI | 1 << RXOUTI | 1 << STALLEDI);
  3896. + ep->state = EP_IDLE;
  3897. + UECONX |= 1 << STALLRQ;
  3898. +}
  3899. +
  3900. +
  3901. +void ep_init(void)
  3902. +{
  3903. + UENUM = 0;
  3904. + UECONX = (1 << RSTDT) | (1 << EPEN); /* enable */
  3905. + UECFG0X = 0; /* control, direction is ignored */
  3906. + UECFG1X = 3 << EPSIZE0; /* 64 bytes */
  3907. + UECFG1X |= 1 << ALLOC;
  3908. +
  3909. + while (!(UESTA0X & (1 << CFGOK)));
  3910. +
  3911. + UEIENX =
  3912. + (1 << RXSTPE) | (1 << RXOUTE) | (1 << STALLEDE) | (1 << TXINE);
  3913. +
  3914. + eps[0].state = EP_IDLE;
  3915. + eps[0].size = 64;
  3916. +
  3917. +#ifndef BOOT_LOADER
  3918. +
  3919. + UENUM = 1;
  3920. + UECONX = (1 << RSTDT) | (1 << EPEN); /* enable */
  3921. + UECFG0X = (1 << EPTYPE1) | (1 << EPDIR); /* bulk IN */
  3922. + UECFG1X = 3 << EPSIZE0; /* 64 bytes */
  3923. + UECFG1X |= 1 << ALLOC;
  3924. +
  3925. + while (!(UESTA0X & (1 << CFGOK)));
  3926. +
  3927. + UEIENX = (1 << STALLEDE) | (1 << TXINE);
  3928. +
  3929. + eps[1].state = EP_IDLE;
  3930. + eps[1].size = 64;
  3931. +
  3932. +#endif
  3933. +}
  3934. +
  3935. +
  3936. +ISR(USB_GEN_vect)
  3937. +{
  3938. + uint8_t flags;
  3939. +
  3940. + flags = UDINT;
  3941. + if (flags & (1 << EORSTI)) {
  3942. + if (user_reset)
  3943. + user_reset();
  3944. + ep_init();
  3945. + UDINT = ~(1 << EORSTI);
  3946. + }
  3947. +}
  3948. +
  3949. +
  3950. +ISR(USB_COM_vect)
  3951. +{
  3952. + uint8_t flags, i;
  3953. +
  3954. + flags = UEINT;
  3955. + for (i = 0; i != NUM_EPS; i++)
  3956. + if (flags & (1 << i))
  3957. + handle_ep(i);
  3958. +}
  3959. +
  3960. +
  3961. +void usb_reset(void)
  3962. +{
  3963. + UDCON |= 1 << DETACH; /* detach the pull-up */
  3964. + _delay_ms(1);
  3965. +}
  3966. diff --git a/atusb/usb/dfu.c b/atusb/usb/dfu.c
  3967. new file mode 100644
  3968. index 0000000..c84a28d
  3969. --- /dev/null
  3970. +++ b/atusb/usb/dfu.c
  3971. @@ -0,0 +1,260 @@
  3972. +/*
  3973. + * boot/dfu.c - DFU protocol engine
  3974. + *
  3975. + * Written 2008-2011, 2013-2015 by Werner Almesberger
  3976. + * Copyright 2008-2011, 2013-2015 Werner Almesberger
  3977. + *
  3978. + * This program is free software; you can redistribute it and/or modify
  3979. + * it under the terms of the GNU General Public License as published by
  3980. + * the Free Software Foundation; either version 2 of the License, or
  3981. + * (at your option) any later version.
  3982. + */
  3983. +
  3984. +/*
  3985. + * http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf
  3986. + */
  3987. +
  3988. +/*
  3989. + * A few, erm, shortcuts:
  3990. + *
  3991. + * - we don't bother with the app* states since DFU is all this firmware does
  3992. + * - after DFU_DNLOAD, we just block until things are written, so we never
  3993. + * enter dfuDNLOAD_SYNC or dfuDNBUSY
  3994. + * - no dfuMANIFEST_SYNC, dfuMANIFEST, or dfuMANIFEST_WAIT_RESET
  3995. + * - to keep our buffers small, we only accept EP0-sized blocks
  3996. + */
  3997. +
  3998. +
  3999. +#include <stdbool.h>
  4000. +#include <stdint.h>
  4001. +
  4002. +#include "usb.h"
  4003. +#include "dfu.h"
  4004. +
  4005. +#include "board.h"
  4006. +
  4007. +
  4008. +#ifndef NULL
  4009. +#define NULL 0
  4010. +#endif
  4011. +
  4012. +#define debug(...)
  4013. +#define error(...)
  4014. +
  4015. +
  4016. +#ifndef DFU_ALT_SETTINGS
  4017. +#define DFU_ALT_SETTINGS 1
  4018. +#endif
  4019. +
  4020. +#ifndef DFU_ALT_NAME_0_IDX
  4021. +#define DFU_ALT_NAME_0_IDX 0
  4022. +#endif
  4023. +
  4024. +#ifndef DFU_ALT_NAME_1_IDX
  4025. +#define DFU_ALT_NAME_1_IDX 0
  4026. +#endif
  4027. +
  4028. +#ifndef DFU_ALT_NAME_2_IDX
  4029. +#define DFU_ALT_NAME_2_IDX 0
  4030. +#endif
  4031. +
  4032. +
  4033. +const uint8_t device_descriptor[] = {
  4034. + 18, /* bLength */
  4035. + USB_DT_DEVICE, /* bDescriptorType */
  4036. + LE(0x100), /* bcdUSB */
  4037. + USB_CLASS_APP_SPEC, /* bDeviceClass */
  4038. + 0x00, /* bDeviceSubClass (per interface) */
  4039. + 0x00, /* bDeviceProtocol (per interface) */
  4040. + EP0_SIZE, /* bMaxPacketSize */
  4041. + LE(DFU_USB_VENDOR), /* idVendor */
  4042. + LE(DFU_USB_PRODUCT), /* idProduct */
  4043. + LE(0x0001), /* bcdDevice */
  4044. + 0, /* iManufacturer */
  4045. + 0, /* iProduct */
  4046. +#ifdef HAS_BOARD_SERNUM
  4047. + 1, /* iSerialNumber */
  4048. +#else
  4049. + 0, /* iSerialNumber */
  4050. +#endif
  4051. + 1 /* bNumConfigurations */
  4052. +};
  4053. +
  4054. +
  4055. +const uint8_t config_descriptor[] = {
  4056. + 9, /* bLength */
  4057. + USB_DT_CONFIG, /* bDescriptorType */
  4058. + LE(9+9*DFU_ALT_SETTINGS), /* wTotalLength */
  4059. + 1, /* bNumInterfaces */
  4060. + 1, /* bConfigurationValue (> 0 !) */
  4061. + 0, /* iConfiguration */
  4062. +// USB_ATTR_SELF_POWERED | USB_ATTR_BUS_POWERED,
  4063. + USB_ATTR_BUS_POWERED, /* bmAttributes */
  4064. + ((BOARD_MAX_mA)+1)/2, /* bMaxPower */
  4065. +
  4066. + /* Interface #0 */
  4067. +
  4068. + DFU_ITF_DESCR(0, 0, dfu_proto_dfu, DFU_ALT_NAME_0_IDX)
  4069. +#if DFU_ALT_SETTINGS > 1
  4070. + DFU_ITF_DESCR(0, 1, dfu_proto_dfu, DFU_ALT_NAME_1_IDX)
  4071. +#endif
  4072. +#if DFU_ALT_SETTINGS > 2
  4073. + DFU_ITF_DESCR(0, 2, dfu_proto_dfu, DFU_ALT_NAME_2_IDX)
  4074. +#endif
  4075. +};
  4076. +
  4077. +
  4078. +static uint16_t next_block = 0;
  4079. +static bool did_download;
  4080. +
  4081. +
  4082. +static uint8_t buf[EP0_SIZE];
  4083. +
  4084. +
  4085. +static void block_write(void *user)
  4086. +{
  4087. + uint16_t *size = user;
  4088. +
  4089. + dfu_flash_ops->write(buf, *size);
  4090. +}
  4091. +
  4092. +
  4093. +static bool block_receive(uint16_t length)
  4094. +{
  4095. + static uint16_t size;
  4096. +
  4097. + if (!dfu_flash_ops->can_write(length)) {
  4098. + dfu.state = dfuERROR;
  4099. + dfu.status = errADDRESS;
  4100. + return 0;
  4101. + }
  4102. + if (length > EP0_SIZE) {
  4103. + dfu.state = dfuERROR;
  4104. + dfu.status = errUNKNOWN;
  4105. + return 0;
  4106. + }
  4107. + size = length;
  4108. + usb_recv(&eps[0], buf, size, block_write, &size);
  4109. + return 1;
  4110. +}
  4111. +
  4112. +
  4113. +static bool block_transmit(uint16_t length)
  4114. +{
  4115. + uint16_t got;
  4116. +
  4117. + if (length > EP0_SIZE) {
  4118. + dfu.state = dfuERROR;
  4119. + dfu.status = errUNKNOWN;
  4120. + return 1;
  4121. + }
  4122. + got = dfu_flash_ops->read(buf, length);
  4123. + if (got < length) {
  4124. + length = got;
  4125. + dfu.state = dfuIDLE;
  4126. + }
  4127. + usb_send(&eps[0], buf, length, NULL, NULL);
  4128. + return 1;
  4129. +}
  4130. +
  4131. +
  4132. +static bool my_setup(const struct setup_request *setup)
  4133. +{
  4134. + bool ok;
  4135. +
  4136. + switch (setup->bmRequestType | setup->bRequest << 8) {
  4137. + case DFU_TO_DEV(DFU_DETACH):
  4138. + debug("DFU_DETACH\n");
  4139. + /*
  4140. + * The DFU spec says thay this is sent in protocol 1 only.
  4141. + * However, dfu-util also sends it to get out of DFU mode,
  4142. + * so we just don't make a fuss and ignore it.
  4143. + */
  4144. + return 1;
  4145. + case DFU_TO_DEV(DFU_DNLOAD):
  4146. + debug("DFU_DNLOAD\n");
  4147. + if (dfu.state == dfuIDLE) {
  4148. + next_block = setup->wValue;
  4149. + dfu_flash_ops->start();
  4150. + }
  4151. + else if (dfu.state != dfuDNLOAD_IDLE) {
  4152. + error("bad state\n");
  4153. + return 0;
  4154. + }
  4155. + if (dfu.state != dfuIDLE && setup->wValue == next_block-1) {
  4156. + debug("retransmisson\n");
  4157. + return 1;
  4158. + }
  4159. + if (setup->wValue != next_block) {
  4160. + debug("bad block (%d vs. %d)\n",
  4161. + setup->wValue, next_block);
  4162. + dfu.state = dfuERROR;
  4163. + dfu.status = errUNKNOWN;
  4164. + return 1;
  4165. + }
  4166. + if (!setup->wLength) {
  4167. + debug("DONE\n");
  4168. + dfu_flash_ops->end_write();
  4169. + dfu.state = dfuIDLE;
  4170. + did_download = 1;
  4171. + return 1;
  4172. + }
  4173. + ok = block_receive(setup->wLength);
  4174. + next_block++;
  4175. + dfu.state = dfuDNLOAD_IDLE;
  4176. + return ok;
  4177. + case DFU_FROM_DEV(DFU_UPLOAD):
  4178. + debug("DFU_UPLOAD\n");
  4179. + if (dfu.state == dfuIDLE) {
  4180. + next_block = setup->wValue;
  4181. + dfu_flash_ops->start();
  4182. + }
  4183. + else if (dfu.state != dfuUPLOAD_IDLE)
  4184. + return 0;
  4185. + if (dfu.state != dfuIDLE && setup->wValue == next_block-1) {
  4186. + debug("retransmisson\n");
  4187. + /* @@@ try harder */
  4188. + dfu.state = dfuERROR;
  4189. + dfu.status = errUNKNOWN;
  4190. + return 1;
  4191. + }
  4192. + if (setup->wValue != next_block) {
  4193. + debug("bad block (%d vs. %d)\n",
  4194. + setup->wValue, next_block);
  4195. + dfu.state = dfuERROR;
  4196. + dfu.status = errUNKNOWN;
  4197. + return 1;
  4198. + }
  4199. + ok = block_transmit(setup->wLength);
  4200. + next_block++;
  4201. + dfu.state = dfuUPLOAD_IDLE;
  4202. + return ok;
  4203. + case DFU_TO_DEV(DFU_ABORT):
  4204. + debug("DFU_ABORT\n");
  4205. + dfu.state = dfuIDLE;
  4206. + dfu.status = OK;
  4207. + return 1;
  4208. + default:
  4209. + return dfu_setup_common(setup);
  4210. + }
  4211. +}
  4212. +
  4213. +
  4214. +static void my_reset(void)
  4215. +{
  4216. +#if 0
  4217. + /* @@@ not nice -- think about where this should go */
  4218. + extern void run_payload(void);
  4219. +
  4220. + if (did_download)
  4221. + run_payload();
  4222. +#endif
  4223. +}
  4224. +
  4225. +
  4226. +void dfu_init(void)
  4227. +{
  4228. + user_setup = my_setup;
  4229. + user_get_descriptor = dfu_my_descr;
  4230. + user_reset = my_reset;
  4231. +}
  4232. diff --git a/atusb/usb/dfu.h b/atusb/usb/dfu.h
  4233. new file mode 100644
  4234. index 0000000..bc35bbc
  4235. --- /dev/null
  4236. +++ b/atusb/usb/dfu.h
  4237. @@ -0,0 +1,119 @@
  4238. +/*
  4239. + * boot/dfu.h - DFU protocol constants and data structures
  4240. + *
  4241. + * Written 2008, 2011, 2013-2015 by Werner Almesberger
  4242. + * Copyright 2008, 2011, 2013-2015 Werner Almesberger
  4243. + *
  4244. + * This program is free software; you can redistribute it and/or modify
  4245. + * it under the terms of the GNU General Public License as published by
  4246. + * the Free Software Foundation; either version 2 of the License, or
  4247. + * (at your option) any later version.
  4248. + */
  4249. +
  4250. +
  4251. +#ifndef DFU_H
  4252. +#define DFU_H
  4253. +
  4254. +#include <stdbool.h>
  4255. +#include <stdint.h>
  4256. +
  4257. +#include "usb.h"
  4258. +
  4259. +
  4260. +enum dfu_request {
  4261. + DFU_DETACH,
  4262. + DFU_DNLOAD,
  4263. + DFU_UPLOAD,
  4264. + DFU_GETSTATUS,
  4265. + DFU_CLRSTATUS,
  4266. + DFU_GETSTATE,
  4267. + DFU_ABORT,
  4268. +};
  4269. +
  4270. +
  4271. +enum dfu_status {
  4272. + OK,
  4273. + errTARGET,
  4274. + errFILE,
  4275. + errWRITE,
  4276. + errERASE,
  4277. + errCHECK_ERASED,
  4278. + errPROG,
  4279. + errVERIFY,
  4280. + errADDRESS,
  4281. + errNOTDONE,
  4282. + errFIRMWARE,
  4283. + errVENDOR,
  4284. + errUSBR,
  4285. + errPOR,
  4286. + errUNKNOWN,
  4287. + errSTALLEDPKT,
  4288. +};
  4289. +
  4290. +
  4291. +enum dfu_state {
  4292. + appIDLE,
  4293. + appDETACH,
  4294. + dfuIDLE,
  4295. + dfuDNLOAD_SYNC,
  4296. + dfuDNBUSY,
  4297. + dfuDNLOAD_IDLE,
  4298. + dfuMANIFEST_SYNC,
  4299. + dfuMANIFEST,
  4300. + dfuMANIFEST_WAIT_RESET,
  4301. + dfuUPLOAD_IDLE,
  4302. + dfuERROR
  4303. +};
  4304. +
  4305. +enum dfu_itf_proto {
  4306. + dfu_proto_runtime = 1, /* Runtime protocol */
  4307. + dfu_proto_dfu = 2, /* DFU mode protocol */
  4308. +};
  4309. +
  4310. +
  4311. +#define DFU_DT_FUNCTIONAL 0x21 /* DFU FUNCTIONAL descriptor type */
  4312. +
  4313. +
  4314. +#define DFU_TO_DEV(req) (0x21 | (req) << 8)
  4315. +#define DFU_FROM_DEV(req) (0xa1 | (req) << 8)
  4316. +
  4317. +
  4318. +struct dfu {
  4319. + uint8_t status; /* bStatus */
  4320. + uint8_t toL, toM, toH; /* bwPollTimeout */
  4321. + uint8_t state; /* bState */
  4322. + uint8_t iString;
  4323. +};
  4324. +
  4325. +
  4326. +#define DFU_ITF_DESCR(itf, alt, proto, idx) \
  4327. + 9, /* bLength */ \
  4328. + USB_DT_INTERFACE, /* bDescriptorType */ \
  4329. + (itf), /* bInterfaceNumber */ \
  4330. + (alt), /* bAlternateSetting */ \
  4331. + 0, /* bNumEndpoints */ \
  4332. + 0xfe, /* bInterfaceClass (application specific) */ \
  4333. + 0x01, /* bInterfaceSubClass (device fw upgrade) */ \
  4334. + (proto), /* bInterfaceProtocol (dfu_proto_*) */ \
  4335. + (idx), /* iInterface */
  4336. +
  4337. +
  4338. +struct dfu_flash_ops {
  4339. + void (*start)(void);
  4340. + bool (*can_write)(uint16_t size);
  4341. + void (*write)(const uint8_t *buf, uint16_t size);
  4342. + void (*end_write)(void);
  4343. + uint16_t (*read)(uint8_t *buf, uint16_t size);
  4344. +};
  4345. +
  4346. +extern struct dfu dfu;
  4347. +extern const struct dfu_flash_ops *dfu_flash_ops;
  4348. +
  4349. +
  4350. +bool dfu_setup_common(const struct setup_request *setup);
  4351. +bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
  4352. + uint8_t *size);
  4353. +
  4354. +void dfu_init(void);
  4355. +
  4356. +#endif /* !DFU_H */
  4357. diff --git a/atusb/usb/dfu_common.c b/atusb/usb/dfu_common.c
  4358. new file mode 100644
  4359. index 0000000..9b6feef
  4360. --- /dev/null
  4361. +++ b/atusb/usb/dfu_common.c
  4362. @@ -0,0 +1,101 @@
  4363. +/*
  4364. + * boot/dfu_common.c - DFU protocol engine parts common to App/DFU
  4365. + *
  4366. + * Written 2008-2011, 2013-2014 by Werner Almesberger
  4367. + * Copyright 2008-2011, 2013-2014 Werner Almesberger
  4368. + *
  4369. + * This program is free software; you can redistribute it and/or modify
  4370. + * it under the terms of the GNU General Public License as published by
  4371. + * the Free Software Foundation; either version 2 of the License, or
  4372. + * (at your option) any later version.
  4373. + */
  4374. +
  4375. +/*
  4376. + * http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf
  4377. + */
  4378. +
  4379. +/*
  4380. + * A few, erm, shortcuts:
  4381. + *
  4382. + * - we don't bother with the app* states since DFU is all this firmware does
  4383. + * - after DFU_DNLOAD, we just block until things are written, so we never
  4384. + * enter dfuDNLOAD_SYNC or dfuDNBUSY
  4385. + * - no dfuMANIFEST_SYNC, dfuMANIFEST, or dfuMANIFEST_WAIT_RESET
  4386. + * - to keep our buffers small, we only accept EP0-sized blocks
  4387. + */
  4388. +
  4389. +
  4390. +#include <stdbool.h>
  4391. +#include <stdint.h>
  4392. +
  4393. +#include "usb.h"
  4394. +#include "dfu.h"
  4395. +
  4396. +#include "board.h"
  4397. +#include "../sernum.h"
  4398. +
  4399. +
  4400. +#ifndef NULL
  4401. +#define NULL 0
  4402. +#endif
  4403. +
  4404. +#define debug(...)
  4405. +#define error(...)
  4406. +
  4407. +
  4408. +static const uint8_t functional_descriptor[] = {
  4409. + 9, /* bLength */
  4410. + DFU_DT_FUNCTIONAL, /* bDescriptorType */
  4411. + 0xf, /* bmAttributes (claim omnipotence :-) */
  4412. + LE(0xffff), /* wDetachTimeOut (we're very patient) */
  4413. + LE(EP0_SIZE), /* wTransferSize */
  4414. + LE(0x101), /* bcdDFUVersion */
  4415. +};
  4416. +
  4417. +
  4418. +/*
  4419. + * The worst-case activity would be flashing a one page and erasing another
  4420. + * one, would should take less than 10 ms. A 100 ms timeout ought to be plenty.
  4421. + */
  4422. +
  4423. +struct dfu dfu = {
  4424. + OK, /* bStatus */
  4425. + LE(100), 0, /* bwPollTimeout, 100 ms */
  4426. + dfuIDLE, /* bState */
  4427. + 0, /* iString */
  4428. +};
  4429. +
  4430. +
  4431. +bool dfu_setup_common(const struct setup_request *setup)
  4432. +{
  4433. + switch (setup->bmRequestType | setup->bRequest << 8) {
  4434. + case DFU_FROM_DEV(DFU_GETSTATUS):
  4435. + debug("DFU_GETSTATUS\n");
  4436. + usb_send(&eps[0], (uint8_t *) &dfu, sizeof(dfu), NULL, NULL);
  4437. + return 1;
  4438. + case DFU_TO_DEV(DFU_CLRSTATUS):
  4439. + debug("DFU_CLRSTATUS\n");
  4440. + dfu.state = dfuIDLE;
  4441. + dfu.status = OK;
  4442. + return 1;
  4443. + case DFU_FROM_DEV(DFU_GETSTATE):
  4444. + debug("DFU_GETSTATE\n");
  4445. + usb_send(&eps[0], &dfu.state, 1, NULL, NULL);
  4446. + return 1;
  4447. + default:
  4448. + error("DFU rt %x, rq%x ?\n",
  4449. + setup->bmRequestType, setup->bRequest);
  4450. + return 0;
  4451. + }
  4452. +}
  4453. +
  4454. +
  4455. +bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
  4456. + uint8_t *size)
  4457. +{
  4458. + if (type != DFU_DT_FUNCTIONAL)
  4459. + return sernum_get_descr(type, index, reply, size);
  4460. + *reply = functional_descriptor;
  4461. + *size = sizeof(functional_descriptor);
  4462. + return 1;
  4463. +}
  4464. diff --git a/atusb/usb/usb.c b/atusb/usb/usb.c
  4465. new file mode 100644
  4466. index 0000000..543d8c2
  4467. --- /dev/null
  4468. +++ b/atusb/usb/usb.c
  4469. @@ -0,0 +1,181 @@
  4470. +/*
  4471. + * fw/usb/usb.c - USB hardware setup and standard device requests
  4472. + *
  4473. + * Written 2008-2011, 2013, 2015 by Werner Almesberger
  4474. + * Copyright 2008-2011, 2013, 2015 Werner Almesberger
  4475. + *
  4476. + * This program is free software; you can redistribute it and/or modify
  4477. + * it under the terms of the GNU General Public License as published by
  4478. + * the Free Software Foundation; either version 2 of the License, or
  4479. + * (at your option) any later version.
  4480. + */
  4481. +
  4482. +/*
  4483. + * Known issues:
  4484. + * - no suspend/resume
  4485. + * - should support EP clearing and stalling
  4486. + */
  4487. +
  4488. +#include <stdbool.h>
  4489. +#include <stdint.h>
  4490. +
  4491. +#include "usb.h"
  4492. +#include "board.h"
  4493. +
  4494. +
  4495. +#ifndef NULL
  4496. +#define NULL 0
  4497. +#endif
  4498. +
  4499. +#if 1
  4500. +extern void panic(void);
  4501. +#define BUG_ON(cond) do { if (cond) panic(); } while (0)
  4502. +#else
  4503. +#define BUG_ON(cond)
  4504. +#endif
  4505. +
  4506. +bool (*user_setup)(const struct setup_request *setup);
  4507. +void (*user_set_interface)(int nth);
  4508. +bool (*user_get_descriptor)(uint8_t type, uint8_t index,
  4509. + const uint8_t **reply, uint8_t *size);
  4510. +void (*user_reset)(void);
  4511. +
  4512. +
  4513. +void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
  4514. + uint8_t size, void (*callback)(void *user), void *user)
  4515. +{
  4516. + BUG_ON(ep->state);
  4517. + ep->state = state;
  4518. + ep->buf = buf;
  4519. + ep->end = buf+size;
  4520. + ep->callback = callback;
  4521. + ep->user = user;
  4522. + usb_ep_change(ep);
  4523. +}
  4524. +
  4525. +
  4526. +static bool get_descriptor(uint8_t type, uint8_t index, uint16_t length)
  4527. +{
  4528. + const uint8_t *reply;
  4529. + uint8_t size;
  4530. +
  4531. + switch (type) {
  4532. + case USB_DT_DEVICE:
  4533. + reply = device_descriptor;
  4534. + size = reply[0];
  4535. + break;
  4536. + case USB_DT_CONFIG:
  4537. + if (index)
  4538. + return 0;
  4539. + reply = config_descriptor;
  4540. + size = reply[2];
  4541. + break;
  4542. + default:
  4543. + if (!user_get_descriptor)
  4544. + return 0;
  4545. + if (!user_get_descriptor(type, index, &reply, &size))
  4546. + return 0;
  4547. + }
  4548. + if (length < size)
  4549. + size = length;
  4550. + usb_send(&eps[0], reply, size, NULL, NULL);
  4551. + return 1;
  4552. +}
  4553. +
  4554. +
  4555. +bool handle_setup(const struct setup_request *setup)
  4556. +{
  4557. + switch (setup->bmRequestType | setup->bRequest << 8) {
  4558. +
  4559. + /*
  4560. + * Device request
  4561. + *
  4562. + * See http://www.beyondlogic.org/usbnutshell/usb6.htm
  4563. + */
  4564. +
  4565. + case FROM_DEVICE(GET_STATUS):
  4566. + if (setup->wLength != 2)
  4567. + return 0;
  4568. + usb_send(&eps[0], "\000", 2, NULL, NULL);
  4569. + break;
  4570. + case TO_DEVICE(CLEAR_FEATURE):
  4571. + break;
  4572. + case TO_DEVICE(SET_FEATURE):
  4573. + return 0;
  4574. + case TO_DEVICE(SET_ADDRESS):
  4575. + set_addr(setup->wValue);
  4576. + break;
  4577. + case FROM_DEVICE(GET_DESCRIPTOR):
  4578. + case FROM_INTERFACE(GET_DESCRIPTOR):
  4579. + if (!get_descriptor(setup->wValue >> 8, setup->wValue,
  4580. + setup->wLength))
  4581. + return 0;
  4582. + break;
  4583. + case TO_DEVICE(SET_DESCRIPTOR):
  4584. + return 0;
  4585. + case FROM_DEVICE(GET_CONFIGURATION):
  4586. + usb_send(&eps[0], "", 1, NULL, NULL);
  4587. + break;
  4588. + case TO_DEVICE(SET_CONFIGURATION):
  4589. + if (setup->wValue != config_descriptor[5])
  4590. + return 0;
  4591. + break;
  4592. +
  4593. + /*
  4594. + * Interface request
  4595. + */
  4596. +
  4597. + case FROM_INTERFACE(GET_STATUS):
  4598. + return 0;
  4599. + case TO_INTERFACE(CLEAR_FEATURE):
  4600. + return 0;
  4601. + case TO_INTERFACE(SET_FEATURE):
  4602. + return 0;
  4603. + case FROM_INTERFACE(GET_INTERFACE):
  4604. + return 0;
  4605. + case TO_INTERFACE(SET_INTERFACE):
  4606. + {
  4607. + const uint8_t *interface_descriptor =
  4608. + config_descriptor+9;
  4609. + const uint8_t *p;
  4610. + int i;
  4611. +
  4612. + i = 0;
  4613. + for (p = interface_descriptor;
  4614. + p != config_descriptor+config_descriptor[2];
  4615. + p += p[0]) {
  4616. + if (p[1] != USB_DT_INTERFACE)
  4617. + continue;
  4618. + if (p[2] == setup->wIndex &&
  4619. + p[3] == setup->wValue) {
  4620. + if (user_set_interface)
  4621. + user_set_interface(i);
  4622. + return 1;
  4623. + }
  4624. + i++;
  4625. + }
  4626. + return 0;
  4627. + }
  4628. + break;
  4629. +
  4630. + /*
  4631. + * Endpoint request
  4632. + */
  4633. +
  4634. + case FROM_ENDPOINT(GET_STATUS):
  4635. + return 0;
  4636. + case TO_ENDPOINT(CLEAR_FEATURE):
  4637. + return 0;
  4638. + case TO_ENDPOINT(SET_FEATURE):
  4639. + return 0;
  4640. + case FROM_ENDPOINT(SYNCH_FRAME):
  4641. + return 0;
  4642. +
  4643. + default:
  4644. + if (user_setup)
  4645. + return user_setup(setup);
  4646. + return 0;
  4647. + }
  4648. +
  4649. + return 1;
  4650. +}
  4651. diff --git a/atusb/usb/usb.h b/atusb/usb/usb.h
  4652. new file mode 100644
  4653. index 0000000..cb40f9e
  4654. --- /dev/null
  4655. +++ b/atusb/usb/usb.h
  4656. @@ -0,0 +1,189 @@
  4657. +/*
  4658. + * fw/usb//usb.h - USB hardware setup and standard device requests
  4659. + *
  4660. + * Written 2008, 2009, 2011, 2013, 2015 by Werner Almesberger
  4661. + * Copyright 2008, 2009, 2011, 2013, 2015 Werner Almesberger
  4662. + *
  4663. + * This program is free software; you can redistribute it and/or modify
  4664. + * it under the terms of the GNU General Public License as published by
  4665. + * the Free Software Foundation; either version 2 of the License, or
  4666. + * (at your option) any later version.
  4667. + */
  4668. +
  4669. +
  4670. +#ifndef USB_H
  4671. +#define USB_H
  4672. +
  4673. +
  4674. +#include <stdbool.h>
  4675. +#include <stdint.h>
  4676. +
  4677. +
  4678. +/*
  4679. + * Packet identifier types
  4680. + */
  4681. +
  4682. +#define PID_OUT 0x1
  4683. +#define PID_IN 0x9
  4684. +#define PID_SOF 0x5
  4685. +#define PID_SETUP 0xd
  4686. +#define PID_DATA0 0x3
  4687. +#define PID_DATA1 0xb
  4688. +#define PID_ACK 0x2
  4689. +#define PID_NAK 0xa
  4690. +#define PID_STALL 0xe
  4691. +
  4692. +/*
  4693. + * Descriptor types
  4694. + *
  4695. + * Reuse libusb naming scheme (/usr/include/usb.h)
  4696. + */
  4697. +
  4698. +#define USB_DT_DEVICE 1
  4699. +#define USB_DT_CONFIG 2
  4700. +#define USB_DT_STRING 3
  4701. +#define USB_DT_INTERFACE 4
  4702. +#define USB_DT_ENDPOINT 5
  4703. +
  4704. +/*
  4705. + * Device classes
  4706. + *
  4707. + * Reuse libusb naming scheme (/usr/include/usb.h)
  4708. + */
  4709. +
  4710. +#define USB_CLASS_PER_INTERFACE 0
  4711. +#define USB_CLASS_COMM 2
  4712. +#define USB_CLASS_HID 3
  4713. +#define USB_CLASS_MASS_STORAGE 8
  4714. +#define USB_CLASS_HUB 9
  4715. +#define USB_CLASS_DATA 10
  4716. +#define USB_CLASS_APP_SPEC 0xfe
  4717. +#define USB_CLASS_VENDOR_SPEC 0xff
  4718. +
  4719. +/*
  4720. + * Configuration attributes
  4721. + */
  4722. +
  4723. +#define USB_ATTR_BUS_POWERED 0x80
  4724. +#define USB_ATTR_SELF_POWERED 0x40
  4725. +#define USB_ATTR_REMOTE_WAKEUP 0x20
  4726. +
  4727. +/*
  4728. + * Endpoint type
  4729. + */
  4730. +
  4731. +#define USB_ENDPOINT_TYPE_CONTROL 0
  4732. +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1
  4733. +#define USB_ENDPOINT_TYPE_BULK 2
  4734. +#define USB_ENDPOINT_TYPE_INTERRUPT 3
  4735. +
  4736. +/*
  4737. + * Setup request types
  4738. + */
  4739. +
  4740. +#define TO_DEVICE(req) (0x00 | (req) << 8)
  4741. +#define FROM_DEVICE(req) (0x80 | (req) << 8)
  4742. +#define TO_INTERFACE(req) (0x01 | (req) << 8)
  4743. +#define FROM_INTERFACE(req) (0x81 | (req) << 8)
  4744. +#define TO_ENDPOINT(req) (0x02 | (req) << 8)
  4745. +#define FROM_ENDPOINT(req) (0x82 | (req) << 8)
  4746. +
  4747. +/*
  4748. + * Setup requests
  4749. + */
  4750. +
  4751. +#define GET_STATUS 0x00
  4752. +#define CLEAR_FEATURE 0x01
  4753. +#define SET_FEATURE 0x03
  4754. +#define SET_ADDRESS 0x05
  4755. +#define GET_DESCRIPTOR 0x06
  4756. +#define SET_DESCRIPTOR 0x07
  4757. +#define GET_CONFIGURATION 0x08
  4758. +#define SET_CONFIGURATION 0x09
  4759. +#define GET_INTERFACE 0x0a
  4760. +#define SET_INTERFACE 0x0b
  4761. +#define SYNCH_FRAME 0x0c
  4762. +
  4763. +/*
  4764. + * USB Language ID codes
  4765. + *
  4766. + * http://www.usb.org/developers/docs/USB_LANGIDs.pdf
  4767. + */
  4768. +
  4769. +#define USB_LANGID_ENGLISH_US 0x409
  4770. +
  4771. +
  4772. +/*
  4773. + * Odd. sdcc seems to think "x" assumes the size of the destination, i.e.,
  4774. + * uint8_t. Hence the cast.
  4775. + */
  4776. +
  4777. +#define LE(x) ((uint16_t) (x) & 0xff), ((uint16_t) (x) >> 8)
  4778. +
  4779. +#define LO(x) (((uint8_t *) &(x))[0])
  4780. +#define HI(x) (((uint8_t *) &(x))[1])
  4781. +
  4782. +
  4783. +#ifdef LOW_SPEED
  4784. +#define EP0_SIZE 8
  4785. +#else
  4786. +#define EP0_SIZE 64
  4787. +#endif
  4788. +
  4789. +#define EP1_SIZE 64 /* simplify */
  4790. +
  4791. +
  4792. +enum ep_state {
  4793. + EP_IDLE,
  4794. + EP_RX,
  4795. + EP_TX,
  4796. + EP_STALL,
  4797. +};
  4798. +
  4799. +struct ep_descr {
  4800. + enum ep_state state;
  4801. + uint8_t *buf;
  4802. + uint8_t *end;
  4803. + uint8_t size;
  4804. + void (*callback)(void *user);
  4805. + void *user;
  4806. +};
  4807. +
  4808. +struct setup_request {
  4809. + uint8_t bmRequestType;
  4810. + uint8_t bRequest;
  4811. + uint16_t wValue;
  4812. + uint16_t wIndex;
  4813. + uint16_t wLength;
  4814. +};
  4815. +
  4816. +
  4817. +extern const uint8_t device_descriptor[];
  4818. +extern const uint8_t config_descriptor[];
  4819. +extern struct ep_descr eps[];
  4820. +
  4821. +extern bool (*user_setup)(const struct setup_request *setup);
  4822. +extern void (*user_set_interface)(int nth);
  4823. +extern bool (*user_get_descriptor)(uint8_t type, uint8_t index,
  4824. + const uint8_t **reply, uint8_t *size);
  4825. +extern void (*user_reset)(void);
  4826. +
  4827. +
  4828. +#define usb_left(ep) ((ep)->end-(ep)->buf)
  4829. +#define usb_send(ep, buf, size, callback, user) \
  4830. + usb_io(ep, EP_TX, (void *) buf, size, callback, user)
  4831. +#define usb_recv(ep, buf, size, callback, user) \
  4832. + usb_io(ep, EP_RX, buf, size, callback, user)
  4833. +
  4834. +void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
  4835. + uint8_t size, void (*callback)(void *user), void *user);
  4836. +
  4837. +bool handle_setup(const struct setup_request *setup);
  4838. +void set_addr(uint8_t addr);
  4839. +void usb_ep_change(struct ep_descr *ep);
  4840. +void usb_reset(void);
  4841. +void usb_init(void);
  4842. +
  4843. +void ep_init(void);
  4844. +
  4845. +#endif /* !USB_H */
  4846. diff --git a/atusb/version.h b/atusb/version.h
  4847. new file mode 100644
  4848. index 0000000..8fd6a2c
  4849. --- /dev/null
  4850. +++ b/atusb/version.h
  4851. @@ -0,0 +1,23 @@
  4852. +/*
  4853. + * fw/version.h - Automatically generated version string
  4854. + *
  4855. + * Written 2008, 2011 by Werner Almesberger
  4856. + * Copyright 2008, 2011 Werner Almesberger
  4857. + *
  4858. + * This program is free software; you can redistribute it and/or modify
  4859. + * it under the terms of the GNU General Public License as published by
  4860. + * the Free Software Foundation; either version 2 of the License, or
  4861. + * (at your option) any later version.
  4862. + */
  4863. +
  4864. +
  4865. +#ifndef VERSION_H
  4866. +#define VERSION_H
  4867. +
  4868. +#include <stdint.h>
  4869. +
  4870. +
  4871. +extern const char *build_date;
  4872. +extern const uint16_t build_number;
  4873. +
  4874. +#endif /* !VERSION_H */
  4875. --
  4876. 2.26.0