diff --git a/hardware/openrov/samd/CHANGELOG b/hardware/openrov/samd/CHANGELOG deleted file mode 100644 index e1baa74..0000000 --- a/hardware/openrov/samd/CHANGELOG +++ /dev/null @@ -1,4 +0,0 @@ -OPENROV SAMD CORE 1.0.0 2016.01.8 - -* First public release. - diff --git a/hardware/openrov/samd/boards.txt b/hardware/openrov/samd/boards.txt index e5c85c7..df6c94a 100644 --- a/hardware/openrov/samd/boards.txt +++ b/hardware/openrov/samd/boards.txt @@ -14,48 +14,17 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -trident_alpha.name=Trident Alpha -trident_alpha.vid.0=0x2341 -trident_alpha.pid.0=0x804d -trident_alpha.vid.1=0x2341 -trident_alpha.pid.1=0x004d -trident_alpha.upload.tool=bossac -trident_alpha.upload.protocol=sam-ba -trident_alpha.upload.maximum_size=262144 -trident_alpha.upload.use_1200bps_touch=true -trident_alpha.upload.wait_for_upload_port=true -trident_alpha.upload.native_usb=false -trident_alpha.build.mcu=cortex-m0plus -trident_alpha.build.f_cpu=48000000L -trident_alpha.build.board=OPENROV_TRIDENT_ALPHA -trident_alpha.build.core=samd21j18a -trident_alpha.build.extra_flags=-D__SAMD21J18A__ -trident_alpha.build.ldscript=linker_scripts/gcc/flash_without_bootloader.ld -trident_alpha.build.openocdscript= -trident_alpha.build.variant=trident_alpha -trident_alpha.build.variant_system_lib= -trident_alpha.build.vid=0x2341 -trident_alpha.build.pid=0x804d - -trident.name=Trident -trident.vid.0=0x2341 -trident.pid.0=0x804d -trident.vid.1=0x2341 -trident.pid.1=0x004d -trident.upload.tool=bossac -trident.upload.protocol=sam-ba -trident.upload.maximum_size=262144 -trident.upload.use_1200bps_touch=true -trident.upload.wait_for_upload_port=true -trident.upload.native_usb=false -trident.build.mcu=cortex-m0plus -trident.build.f_cpu=48000000L -trident.build.board=OPENROV_trident -trident.build.core=samd21j18a -trident.build.extra_flags=-D__SAMD21J18A__ -trident.build.ldscript=linker_scripts/gcc/flash_without_bootloader.ld -trident.build.openocdscript= -trident.build.variant=trident -trident.build.variant_system_lib= -trident.build.vid=0x2341 -trident.build.pid=0x804d \ No newline at end of file +tridentDev.name = Trident +tridentDev.vid.0 = 0x2341 +tridentDev.pid.0 = 0x804d +tridentDev.vid.1 = 0x2341 +tridentDev.pid.1 = 0x004d +tridentDev.build.mcu = cortex-m0plus +tridentDev.build.f_cpu = 48000000L +tridentDev.build.board = OPENROV_tridentDev +tridentDev.build.core = samd21g18a +tridentDev.build.extra_flags = -D__SAMD21G18A__ +tridentDev.build.ldscript = linker_scripts/gcc/flash_without_bootloader.ld +tridentDev.build.variant = tridentDev +tridentDev.build.vid = 0x2341 +tridentDev.build.pid = 0x804d \ No newline at end of file diff --git a/hardware/openrov/samd/bootloaders/samd21/samba_both.hex b/hardware/openrov/samd/bootloaders/samd21/samba_both.hex deleted file mode 100644 index ecb70f8..0000000 --- a/hardware/openrov/samd/bootloaders/samd21/samba_both.hex +++ /dev/null @@ -1,316 +0,0 @@ -:1000000070040020E9120000D1120000D11200009B -:1000100000000000000000000000000000000000E0 -:10002000000000000000000000000000D1120000ED -:100030000000000000000000D1120000D1120000FA -:10004000D1120000D1120000D1120000D112000024 -:10005000D1120000D1120000D1120000D112000014 -:10006000D1120000D1120000D1120000D112000004 -:10007000D1120000D1120000D1120000D1120000F4 -:10008000D1120000D1120000D1120000D1120000E4 -:10009000D1120000D1120000D1120000D1120000D4 -:1000A000D1120000D1120000D1120000D1120000C4 -:1000B00038B5AE48016820220A430260AC490120ED -:1000C0000A7F02430A770A78F02313400B70062256 -:1000D0000B7806241C430C704B7F03434B770B7843 -:1000E0001B071B0F0B700B7860241C430C7000BFA8 -:1000F0002AA1096800919F490B889F4C1C4022430C -:100100000A800A886B461B889C4C1C402243822331 -:10011000DB0113430B809A490A7802430A708A78FC -:100120000242FCD11F20974A13685B0B03401F2B30 -:1001300000D105230C8D944D25409B012B430B854D -:1001400013689B0C18401F2800D11D200B8D8F4C6D -:100150001C402043088510688001400F072800D10B -:1001600003200A8D8A4B1340000318430885087842 -:100170004006400E08700878042202430A70854841 -:1001800048620A89844B13400B810A89834B1340D0 -:100190000B81802100F030FB31BD00000000000029 -:1001A00001600021017141717D4981607D49C1601B -:1001B0007D49016101680A78022313430B7070477F -:1001C00070B5040021688020400008180A31082218 -:1001D0004B8A134228D04B8A1A434A8280220A70E3 -:1001E00011210170402141710271C0239B05BD4D59 -:1001F000684A56682E401E435660566935402B4368 -:1002000053616A4B13601300943313615368684D54 -:100210001D40CB022B43536053689B0B9B035360E1 -:1002200001710020207105E0C079C00602D52000D0 -:1002300000F0CEF8207970BDF2B582B006680025D6 -:1002400000950124534859495A4B1B78002B14D16F -:100250000B0040330364436C9B0B9B034364436C70 -:10026000534F1F404764A2235B00F75C40233B438E -:10027000A2277F00F3554F4B1C70A2235B00F3189D -:10028000DB78DB0719D54C4B476C1F40974203D2F4 -:10029000406C0340009300E00092009A40310298C5 -:1002A00000F0ACFAA22040003018C0780443A2202D -:1002B00040003018C4703F4805700098FEBDF4B58A -:1002C0000668180000D001205D01324A5419009BD5 -:1002D0009C46012763695B005B0FDB1C9F40BC45AC -:1002E00005D36069802212060243626107E0800143 -:1002F000171894376246380000F080FA39002161FF -:100300006069800B800300998904890C0143616155 -:100310006069274901406161FF20801D711908183B -:10032000022182780A43827002788023134303708B -:1003300082780A42FCD00098F2BD80B50023FFF716 -:10034000BEFF01BD13494A69920B92034A61FF2126 -:10035000891D4018022182780A4382700278802326 -:100360001343037082780A42FCD070471C0400409B -:100370003C440041020C0040C0FF0000FF70000040 -:1003800000500041246080003FF80000E0FF0000C2 -:10039000FF8F000064000020F3FF0000FEFF00005C -:1003A000C1010000BF0200003902000078010020F6 -:1003B000FF3F00F066020020FF3F0000FF22921D79 -:1003C0008018002901D0202100E010210170704721 -:1003D000F1B50568822040002818C078102101433B -:1003E000822040002818C170BF4CC04F3878207060 -:1003F00078786070B878A080A088F9780902014305 -:10040000A1803879E080E088797909020143E180B0 -:10041000B87920812089F97909020143218140209E -:10042000822149006854627800200F218026120240 -:1004300023781A43803A012A00D87BE0921E00D12B -:100440007AE07F3A15D0521E00D1B6E0BC4BD21AEA -:100450000FD0521E00D190E05B1ED21A2CD07E3BF2 -:10046000D21A11D08033D21A60D0803A2BD0B54B3B -:10047000D21A00D1F6E0C0235B00D21A00D1F5E019 -:10048000803A00D1FEE001E1A088F131884207D135 -:100490002089132801D3122200E022897EA1EDE0F9 -:1004A000A08849008842EED12089442801D3432204 -:1004B00000E022890C34E0E02800FFF743FFA08829 -:1004C0000643AE72F1BDA088009908712800FFF7BD -:1004D00039FF032092214900691808770007014974 -:1004E00002E000BFFFFFFF8FB14A536C0B40034394 -:1004F0005364FF234633EB1840241C7040371764C5 -:10050000302482277F00EF193C77546B0C40204346 -:100510005063922040002E541000D43010634020CD -:10052000D876506F01405167DE77F1BD0122009906 -:10053000091DA3E060811DE06081E0885022024037 -:10054000A270E0880140E180E088042823DAA078E6 -:100550000028E08806D08321490040012818405C2B -:10056000810605E08321490040012818405CC1064E -:10057000C90F618102220A347FE0E0880640A6703C -:10058000E0880140E180A08800281ED1E088002892 -:100590007CD0E088042879DAA078002806D0FF20F3 -:1005A000801DE1884901691820225AE0FF20801D42 -:1005B000E18849016918102253E0E0880640A670DE -:1005C000E0880140E180A08800285FD1E088002811 -:1005D0005CD0E088042859DAA0780028E08820D090 -:1005E0008321490040012818405C80063AD5881EC6 -:1005F000E1884901691820220A54E088FF21083166 -:1006000040012818405C40062CD50846E188490185 -:10061000691840220A54C01EE18849016918022263 -:100620001FE08321490040012818405CC00619D50D -:10063000881EE1884901691810220A54E088FF21C8 -:10064000083140012818405C80060BD50846E18837 -:100650004901691820220A54C01EE188490169181D -:1006600001220A542800FFF76DFEF1BD20890928F8 -:1006700001D3082200E02289503421000098FFF7BE -:100680005CFEF1BDA08800994871EBE701212800CC -:10069000FFF794FEF1BD00001201100102000040BE -:1006A000EB032461100100000001000010B5414C73 -:1006B00041482060FFF7FCFC21682000FFF770FD37 -:1006C000200010BD01B50123012269463948FFF71A -:1006D000F6FD012002BD80B5012269463548FFF7CD -:1006E000ABFD6846007802BD0400002078010020C0 -:1006F00010B5304C2000FFF763FD002805D0FF2027 -:1007000048302168095CC807C00F10BD10B50C0047 -:100710000123220001002748FFF7D1FD200010BD72 -:1007200070B505000E00234C2000FFF749FD00289E -:1007300004D0320029002000FFF77EFD70BD0000CC -:10074000FF01000021170000F8B504000F00184D4C -:100750002E0080363000FFF733FD002826D03068A9 -:10076000A22149004018402214490B78002B05D0E3 -:10077000437840261E43467000230B702C64696C3E -:10078000890B89036964696C0D4B0B40B9030D4CEF -:100790000C401C436C6401780A430270C178C9079D -:1007A000FCD5C17801220A43C2703800F2BD0000B6 -:1007B00064000020E4000020005000416602002098 -:1007C000FF3F00F000C0FF0F130030B4140015000D -:1007D000103902D310393CC0FCD2490700D30CC0F9 -:1007E00000D504C0890002D30280801C002900D5F6 -:1007F000027030BC704700000022E5E710B504002D -:1008000000F002F8200010BD124207D08B0706D07E -:100810000B78491C0370401C521EF7D870478307A1 -:1008200006D00B78491C0370401C521EF9D170474A -:1008300070B4103A03D378C9103A78C0FBD253078A -:1008400001D318C918C001D508C908C0D20704D3FC -:100850000B880380891C801C002A01D50B7803704B -:1008600070BC704738B501257548C17E01220A4326 -:10087000C2760178F0220A400270017802220A430F -:100880000270017F01220A43027701780907090FEC -:100890000170017820220A430270AA4C200000F067 -:1008A000ABF9A9490A68831C9D4015430D6000BF40 -:1008B00011A109680091A5490A88A54B134014307D -:1008C0008006800E1843088008886A461288A14B6B -:1008D000134018430A0C02430A80802252039E49A7 -:1008E000200000F09DF99D48002101704170817049 -:1008F000C1700171417131BD0000000080B5C1B20D -:10090000904800F0BBF9012002BD80B58D48017E02 -:100910004907FCD500F0B7F902BD80B5B2480078B0 -:10092000400705D5FFF7F1FF232801D1012002BDC3 -:10093000002002BDAC4801784807C00F704770B571 -:100940000D000400002604E02078FFF7D7FF641CA8 -:10095000761CAE42F8D3300070BD10B50400FFF72E -:10096000D4FF2070012010BD000248400821420041 -:10097000000402D59D48504000E01000491EF6D109 -:1009800080B27047F3B581B000260027984D17E07C -:100990003100E0B2FFF7E8FF06002889002802D105 -:1009A000A87900280BD0019804700198401C019090 -:1009B00068460089802802D12889401E28817F1C32 -:1009C00068460089BFB2874207D2FFF79EFF040046 -:1009D00068790028DCD00120FEBD3000FEBDF8B5EE -:1009E00005000C0002216846FFF7CCFF802128009B -:1009F000FFF7C8FF05007E4E7079002808D1FFF789 -:100A000084FF0702FFF781FF38187179012901D1AE -:100A10000020F2BD80B2A84208D168460178A14208 -:100A200004D14078E143C9B2884203D01820FFF7CF -:100A300065FFEDE70620FFF761FF0120F2BD000032 -:100A40003B440041FEB50F0001216B461970029036 -:100A50000020674A5071002F01D017810021917149 -:100A6000780602D080377F208743FFF74EFF60492A -:100A70004979002908D000205D494871FFF745FFFA -:100A80005B494979002940D1C0B2152805D04328D7 -:100A900003D07128E9D10020FEBD02980190002604 -:100AA0000120FFF72BFF68460078FFF727FF684615 -:100AB0000178C843C0B2FFF721FF80244C48008969 -:100AC000002805D14A498979002901D1002506E08D -:100AD00001990D78491C0191401E45490881280063 -:100AE000FFF70CFF31002800FFF73EFF0600641EF1 -:100AF000E4D1000AFFF702FFF0B2FFF7FFFEFFF7B5 -:100B000004FF3B494979002903D000203849487146 -:100B1000FEBDC0B2062808D168460078401C694670 -:100B20000870803F029880300290002FB5D10420D9 -:100B3000FFF7E4FEFFF7E9FE00202D498871012050 -:100B4000FEBD00000014004220040040020C0040E2 -:100B5000C0FF0000FF70000004C500005C02002020 -:100B6000F8B500906426012001240025204F7D71F6 -:100B7000002901D1B87101E03981BD714320FFF72F -:100B8000BDFE1C4802E0002806D0401E1649097828 -:100B90004907F8D5002806D1761EEFD116E00128C6 -:100BA00016D000281CD0FFF7B0FE797900290CD1AF -:100BB000C0B2012802D004280FD011E0E1B20098A1 -:100BC000FFF70DFF79790029E9D07D710020F2BD92 -:100BD000641C009880300090E5E70620FFF78EFE49 -:100BE000BD710120F2BD0000181400422110000068 -:100BF0005C02002000350C0010B586B00400684689 -:100C00002DA11822FFF714FE00206A4681005158DA -:100C10008C4203D0401C0628F8D3002006B010BD3B -:100C200030B50123C46964081C40FBD10468022567 -:100C3000AC430460C4691C40FCD104681C430460DC -:100C400004681C40FCD1C4691C40FCD1C469640820 -:100C50001C40F8D1164C14430460C26992081A4033 -:100C6000FBD1C022920242608181C16949081940CA -:100C7000FBD1016802220A43026030BD027ED20726 -:100C8000FCD5018570470121027E92080A42FBD003 -:100C9000428B0A4207D1428B52080A4203D1428B4F -:100CA00092080A4201D0034A1170008DC0B2704709 -:100CB000040000406802002000080042000C0042CE -:100CC000001000420014004200180042001C0042C4 -:100CD0003949012805D100BF05A0486001204870AE -:100CE0007047002802D100BF08A04860704700008C -:100CF000FD0800000B090000350900003F09000055 -:100D00005B090000450A0000610B0000C5060000F9 -:100D1000D7060000F10600000D07000021070000C3 -:100D20000D07000049070000F0B585B0AF4A137801 -:100D3000002B2CD0042901D1006804E0022901D144 -:100D4000008800E00078490001AB5C180094641C46 -:100D50000025302604E0373727700009641E6D1C1B -:100D60008D4205D207073F0F0A2FF4DA3743F3E726 -:100D70001E70782058700A20009B98700D20009BF0 -:100D8000D870091D01A85268D268904702E05268E5 -:100D9000D268904705B0F0BD72B6BFF35F8F0021F7 -:100DA000934A1170EFF30881904A9160016881F3D2 -:100DB0000888406800477047F8010020F8B5002512 -:100DC0008A4CA5617A20A0704021200024306268FE -:100DD00012699047606120002430E061256107E0DE -:100DE000A070E560E069401CE0612069401C206162 -:100DF000206961698842E7D2E06900780100FF2933 -:100E0000F3D0232900D0D6E02078002804D0022196 -:100E100078A06268D2689047A178A06953292BD145 -:100E2000616922698A4216D2E3695B1CE361521C44 -:100E30002261891AE268914200D3110021620A46B8 -:100E40001946FFF7E1FC206A216909182161E1696F -:100E50000918E161E0702069401E2061E069401ED0 -:100E6000E061E078E168884204D2091AA06962680A -:100E70009269904700BF92E0522904D1E16862680C -:100E8000526990478BE04F2902D1E168017086E0FA -:100E9000482902D1E168018081E0572902D1E16847 -:100EA00001607CE06F2901D101210CE0682903D1A8 -:100EB0000088E060022104E0772907D10068E06043 -:100EC000042120000C30FFF72FFF68E0012647299E -:100ED00012D1E068FFF760FFA06880F308884448FB -:100EE0000670BFF35F8F62B66078002857D0062087 -:100EF00061680968884752E0542901D1267049E0A9 -:100F00004E2909D12078002804D1022139A0626835 -:100F1000D2689047257042E0562940D1012136A081 -:100F20006268D268904700BF3CA000F079F80100E9 -:100F30003AA06268D2689047012130A06268D26806 -:100F4000904700BF2FA0E061256101E0491C2161AD -:100F5000E069411CE161216900780028F6D100BFF9 -:100F600028A06268D2689047012124A06268D268F4 -:100F70009047256126A0E06101E0491C2161E069FC -:100F8000411CE161216900780028F6D120A0626847 -:100F9000D2689047022117A06268D26890477A20F1 -:100FA000A070E5602078002804D0012114A06268B8 -:100FB000D268904716E70600E26813013700303F19 -:100FC0000A2F03D230391943E1600BE73700413F64 -:100FD000062F01D23739F6E7613E062E01D2573986 -:100FE000F1E72C2900D0FBE6A261FAE6F801002027 -:100FF0005D0000200A0D00007600000020000000C7 -:101000003E0000004175672031312032303134001C -:1010100032303A33343A323100000000312E3100A0 -:10102000010000E0491C0A78002AFBD1081A704729 -:10103000F8B5694801681E22914302220A43026002 -:1010400066484169664A0A40426100BF72A10B6866 -:101050006449C91C0A680F24A2430A60C91E0A78A1 -:101060001206FCD4C91C0C685F4A13401D00832380 -:101070005B022B431C430C60C91E0C782406FCD475 -:1010800066A42468009400BF65A42468574E3568A0 -:10109000AD0E3F2D00D11F257668B605B60D970D14 -:1010A000BE4200D1D60D240C2404AD022E432643AB -:1010B00034006D462D884E4E2E4091256D003543EF -:1010C0006E463580058B4B4E2E4006830568ED0637 -:1010D000FCD5494D0562C4616C462488048300BF79 -:1010E00050A000680090491C0888BC0104400C8096 -:1010F00008886C462488414D254028430C0C044345 -:101100000C80891C08680F24A043012404430C6050 -:10111000C91E08780006FCD4C91C08681A40104390 -:10112000374A02430A60C91E08780006FCD4F1BDA4 -:1011300070B582B08024A40500202060200C416896 -:101140000022D243914215D02E4A83001360062517 -:101150002D4E35705361D2691204D30F6A46137055 -:101160001278002A06D0006880F30888200C274AED -:1011700010600847FFF75CFF012525480570BFF3A5 -:101180005F8F62B6660C206880192060FFF76AFBEB -:10119000206880192060FFF789FA04001D4E2000A6 -:1011A000A1688847002800D035703078002805D025 -:1011B0000020FFF78DFDFFF701FEFCE730780028E7 -:1011C000EDD1FFF7AAFB0028E9D00120FFF780FD51 -:1011D000FFF7F4FDFCE70000044000410C0800406C -:1011E000FFFCFFFF010C0040FFE0DFFF24608000F8 -:1011F000FFF900007FFF000080BB0000FF700000CF -:1012000000070100044400414F44004108ED00E0A4 -:101210005D000020670200200000000000000000C8 -:10122000000000000000000038B401210268001D29 -:10123000002A0FD00368C318446808300C4202D05B -:101240004D466D1E64191D6825601B1D241D121F4F -:10125000ECD0F8E732BC704738B4012100220368B3 -:10126000001D002B0BD00468001D0C4202D04D461F -:101270006D1E64192260241D1B1FF0D0FAE732BCDA -:101280007047000010B5074979441831064C7C447A -:10129000163404E0081D0A68891888470100A14235 -:1012A000F8D110BD0800000028000000ADFFFFFFCE -:1012B0000802000064000020000000006DFFFFFF36 -:1012C000600000007C00000004000020000000001E -:1012D000FEE70348FF218843024908600120704768 -:1012E0000000000008ED00E080B500F001F801BD4D -:1012F000C046C046C046C04600F000F8FFF7E9FF10 -:10130000002801D0FFF7BEFF0020C046C046FFF70F -:101310000FFF00F000F880B500F002F801BD0000FA -:101320000746384600F002F8FBE7000080B5C046EB -:10133000C046024A11001820ABBEFBE7260002009F -:10134000000000000000000000000000090243004F -:10135000020100C00009040000010202000005248F -:1013600000100104240200052406000105240100E8 -:1013700001070583030800FF09040100020A0000B9 -:10138000000705810240000007050202400000003E -:1013900000C2010000000800000100000000000081 -:04000005000012F1F4 -:00000001FF diff --git a/hardware/openrov/samd/bootloaders/samd21/samd21j18a_flash.ld b/hardware/openrov/samd/bootloaders/samd21/samd21j18a_flash.ld deleted file mode 100644 index c9385c4..0000000 --- a/hardware/openrov/samd/bootloaders/samd21/samd21j18a_flash.ld +++ /dev/null @@ -1,157 +0,0 @@ -/** - * \file - * - * \brief Linker script for running in internal FLASH on the SAMD21J18A - * - * Copyright (c) 2013-2014 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -SEARCH_DIR(.) - -/* Memory Spaces Definitions */ -MEMORY -{ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ -} - -/* The stack size used by the application. NOTE: you need to adjust according to your application. */ -STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; - -/* Section Definitions */ -SECTIONS -{ - .text : - { - . = ALIGN(4); - _sfixed = .; - KEEP(*(.vectors .vectors.*)) - *(.text .text.* .gnu.linkonce.t.*) - *(.glue_7t) *(.glue_7) - *(.rodata .rodata* .gnu.linkonce.r.*) - *(.ARM.extab* .gnu.linkonce.armextab.*) - - /* Support C constructors, and C destructors in both user code - and the C library. This also provides support for C++ code. */ - . = ALIGN(4); - KEEP(*(.init)) - . = ALIGN(4); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(4); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - __init_array_end = .; - - . = ALIGN(4); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - - . = ALIGN(4); - KEEP(*(.fini)) - - . = ALIGN(4); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - __fini_array_end = .; - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - - . = ALIGN(4); - _efixed = .; /* End of text section */ - } > rom - - /* .ARM.exidx is sorted, so has to go in its own output section. */ - PROVIDE_HIDDEN (__exidx_start = .); - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > rom - PROVIDE_HIDDEN (__exidx_end = .); - - . = ALIGN(4); - _etext = .; - - .relocate : AT (_etext) - { - . = ALIGN(4); - _srelocate = .; - *(.ramfunc .ramfunc.*); - *(.data .data.*); - . = ALIGN(4); - _erelocate = .; - } > ram - - /* .bss section which is used for uninitialized data */ - .bss (NOLOAD) : - { - . = ALIGN(4); - _sbss = . ; - _szero = .; - *(.bss .bss.*) - *(COMMON) - . = ALIGN(4); - _ebss = . ; - _ezero = .; - } > ram - - /* stack section */ - .stack (NOLOAD): - { - . = ALIGN(8); - _sstack = .; - . = . + STACK_SIZE; - . = ALIGN(8); - _estack = .; - } > ram - - . = ALIGN(4); - _end = . ; -} diff --git a/hardware/openrov/samd/cores/samd21g18a/Arduino.h b/hardware/openrov/samd/cores/samd21g18a/Arduino.h new file mode 100644 index 0000000..49945d2 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Arduino.h @@ -0,0 +1,117 @@ +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Arduino_h +#define Arduino_h + +#include +#include +#include +#include +#include + +typedef bool boolean; +typedef uint8_t byte; +typedef uint16_t word; + +// some libraries and sketches depend on this AVR stuff, +// assuming Arduino.h or WProgram.h automatically includes it... +// +#include "avr/pgmspace.h" +#include "avr/interrupt.h" + +#include "binary.h" +#include "itoa.h" + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +// Include Atmel headers +#include "sam.h" + +#include "wiring_constants.h" + +#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L ) +#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (SystemCoreClock / 1000L) ) +#define microsecondsToClockCycles(a) ( (a) * (SystemCoreClock / 1000000L) ) + +void yield( void ) ; + +/* sketch */ +void setup( void ) ; +void loop( void ) ; + +#include "WVariant.h" + +#ifdef __cplusplus +} // extern "C" +#endif + +// The following headers are for C++ only compilation +#ifdef __cplusplus + #include "WCharacter.h" + #include "WString.h" + #include "WMath.h" + #include "HardwareSerial.h" + #include "pulse.h" +#endif +#include "delay.h" +#ifdef __cplusplus + #include "Uart.h" +#endif + +// Include board variant +#include "variant.h" + +#include "wiring.h" +#include "wiring_digital.h" +#include "wiring_analog.h" +#include "wiring_shift.h" +#include "WInterrupts.h" + +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif // abs + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define abs(x) ((x)>0?(x):-(x)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define interrupts() __enable_irq() +#define noInterrupts() __disable_irq() + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + +#define bit(b) (1UL << (b)) + + +#endif // Arduino_h diff --git a/hardware/openrov/samd/cores/samd21g18a/HardwareSerial.h b/hardware/openrov/samd/cores/samd21g18a/HardwareSerial.h new file mode 100644 index 0000000..7c3a76a --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/HardwareSerial.h @@ -0,0 +1,84 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef HardwareSerial_h +#define HardwareSerial_h + +#include + +#include "Stream.h" + +#define HARDSER_PARITY_EVEN (0x1ul) +#define HARDSER_PARITY_ODD (0x2ul) +#define HARDSER_PARITY_NONE (0x3ul) +#define HARDSER_PARITY_MASK (0xFul) + +#define HARDSER_STOP_BIT_1 (0x10ul) +#define HARDSER_STOP_BIT_1_5 (0x20ul) +#define HARDSER_STOP_BIT_2 (0x30ul) +#define HARDSER_STOP_BIT_MASK (0xF0ul) + +#define HARDSER_DATA_5 (0x100ul) +#define HARDSER_DATA_6 (0x200ul) +#define HARDSER_DATA_7 (0x300ul) +#define HARDSER_DATA_8 (0x400ul) +#define HARDSER_DATA_MASK (0xF00ul) + +#define SERIAL_5N1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_NONE | HARDSER_DATA_5) +#define SERIAL_6N1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_NONE | HARDSER_DATA_6) +#define SERIAL_7N1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_NONE | HARDSER_DATA_7) +#define SERIAL_8N1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_NONE | HARDSER_DATA_8) +#define SERIAL_5N2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_NONE | HARDSER_DATA_5) +#define SERIAL_6N2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_NONE | HARDSER_DATA_6) +#define SERIAL_7N2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_NONE | HARDSER_DATA_7) +#define SERIAL_8N2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_NONE | HARDSER_DATA_8) +#define SERIAL_5E1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_EVEN | HARDSER_DATA_5) +#define SERIAL_6E1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_EVEN | HARDSER_DATA_6) +#define SERIAL_7E1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_EVEN | HARDSER_DATA_7) +#define SERIAL_8E1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_EVEN | HARDSER_DATA_8) +#define SERIAL_5E2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_EVEN | HARDSER_DATA_5) +#define SERIAL_6E2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_EVEN | HARDSER_DATA_6) +#define SERIAL_7E2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_EVEN | HARDSER_DATA_7) +#define SERIAL_8E2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_EVEN | HARDSER_DATA_8) +#define SERIAL_5O1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_ODD | HARDSER_DATA_5) +#define SERIAL_6O1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_ODD | HARDSER_DATA_6) +#define SERIAL_7O1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_ODD | HARDSER_DATA_7) +#define SERIAL_8O1 (HARDSER_STOP_BIT_1 | HARDSER_PARITY_ODD | HARDSER_DATA_8) +#define SERIAL_5O2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_ODD | HARDSER_DATA_5) +#define SERIAL_6O2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_ODD | HARDSER_DATA_6) +#define SERIAL_7O2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_ODD | HARDSER_DATA_7) +#define SERIAL_8O2 (HARDSER_STOP_BIT_2 | HARDSER_PARITY_ODD | HARDSER_DATA_8) + +class HardwareSerial : public Stream +{ + public: + virtual void begin(unsigned long); + virtual void begin(unsigned long baudrate, uint8_t config); + virtual void end(); + virtual int available(void) = 0; + virtual int peek(void) = 0; + virtual int read(void) = 0; + virtual void flush(void) = 0; + virtual size_t write(uint8_t) = 0; + using Print::write; // pull in write(str) and write(buf, size) from Print + virtual operator bool() = 0; +}; + +extern void serialEventRun(void) __attribute__((weak)); + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/Print.cpp b/hardware/openrov/samd/cores/samd21g18a/Print.cpp new file mode 100644 index 0000000..98eb4fd --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Print.cpp @@ -0,0 +1,253 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include "Arduino.h" + +#include "Print.h" + +// Public Methods ////////////////////////////////////////////////////////////// + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + if (write(*buffer++)) n++; + else break; + } + return n; +} + +size_t Print::print(const __FlashStringHelper *ifsh) +{ + return print(reinterpret_cast(ifsh)); +} + +size_t Print::print(const String &s) +{ + return write(s.c_str(), s.length()); +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + +size_t Print::print(const Printable& x) +{ + return x.printTo(*this); +} + +size_t Print::println(void) +{ + return write("\r\n"); +} + +size_t Print::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +size_t Print::println(const Printable& x) +{ + size_t n = print(x); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + if (isnan(number)) return print("nan"); + if (isinf(number)) return print("inf"); + if (number > 4294967040.0) return print ("ovf"); // constant determined empirically + if (number <-4294967040.0) return print ("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/hardware/openrov/samd/cores/samd21g18a/Print.h b/hardware/openrov/samd/cores/samd21g18a/Print.h new file mode 100644 index 0000000..9fc2674 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Print.h @@ -0,0 +1,83 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Print_h +#define Print_h + +#include +#include // for size_t + +#include "WString.h" +#include "Printable.h" + +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 + +class Print +{ + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + protected: + void setWriteError(int err = 1) { write_error = err; } + public: + Print() : write_error(0) {} + + int getWriteError() { return write_error; } + void clearWriteError() { setWriteError(0); } + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { + if (str == NULL) return 0; + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *)buffer, size); + } + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); +}; + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/Printable.h b/hardware/openrov/samd/cores/samd21g18a/Printable.h new file mode 100644 index 0000000..34ad5b4 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Printable.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Printable_h +#define Printable_h + +#include + +class Print; + +/** The Printable class provides a way for new classes to allow themselves to be printed. + By deriving from Printable and implementing the printTo method, it will then be possible + for users to print out instances of this class by passing them into the usual + Print::print and Print::println methods. +*/ + +class Printable +{ + public: + virtual size_t printTo(Print& p) const = 0; +}; + +#endif + diff --git a/hardware/openrov/samd/cores/samd21g18a/Reset.cpp b/hardware/openrov/samd/cores/samd21g18a/Reset.cpp new file mode 100644 index 0000000..8809907 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Reset.cpp @@ -0,0 +1,73 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include "Reset.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NVM_MEMORY ((volatile uint16_t *)0x000000) +#define APP_START 0x00002004 + +static inline bool nvmReady(void) { + return NVMCTRL->INTFLAG.reg & NVMCTRL_INTFLAG_READY; +} + +__attribute__ ((long_call, section (".ramfunc"))) +static void banzai() { + // Disable all interrupts + __disable_irq(); + + // Erase application + while (!nvmReady()) + ; + NVMCTRL->STATUS.reg |= NVMCTRL_STATUS_MASK; + NVMCTRL->ADDR.reg = (uintptr_t)&NVM_MEMORY[APP_START / 4]; + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_ER | NVMCTRL_CTRLA_CMDEX_KEY; + while (!nvmReady()) + ; + + // Reset the device + NVIC_SystemReset() ; + + while (true); +} + +static int ticks = -1; + +void initiateReset(int _ticks) { + ticks = _ticks; +} + +void cancelReset() { + ticks = -1; +} + +void tickReset() { + if (ticks == -1) + return; + ticks--; + if (ticks == 0) + banzai(); +} + +#ifdef __cplusplus +} +#endif diff --git a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp b/hardware/openrov/samd/cores/samd21g18a/Reset.h similarity index 70% rename from hardware/openrov/samd/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp rename to hardware/openrov/samd/cores/samd21g18a/Reset.h index 1681b0a..1ddefbf 100644 --- a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp +++ b/hardware/openrov/samd/cores/samd21g18a/Reset.h @@ -16,16 +16,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "SAMD_AnalogCorrection.h" +#pragma once -void analogReadCorrection (int offset, uint16_t gain) -{ - // Set correction values - ADC->OFFSETCORR.reg = ADC_OFFSETCORR_OFFSETCORR(offset); - ADC->GAINCORR.reg = ADC_GAINCORR_GAINCORR(gain); +#ifdef __cplusplus +extern "C" { +#endif - // Enable digital correction logic - ADC->CTRLB.bit.CORREN = 1; - while(ADC->STATUS.bit.SYNCBUSY); -} +void initiateReset(int ms); +void tickReset(); +void cancelReset(); +#ifdef __cplusplus +} +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/RingBuffer.cpp b/hardware/openrov/samd/cores/samd21g18a/RingBuffer.cpp new file mode 100644 index 0000000..d877a6e --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/RingBuffer.cpp @@ -0,0 +1,86 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "RingBuffer.h" +#include + +RingBuffer::RingBuffer( void ) +{ + memset( _aucBuffer, 0, SERIAL_BUFFER_SIZE ) ; + clear(); +} + +void RingBuffer::store_char( uint8_t c ) +{ + int i = nextIndex(_iHead); + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if ( i != _iTail ) + { + _aucBuffer[_iHead] = c ; + _iHead = i ; + } +} + +void RingBuffer::clear() +{ + _iHead = 0; + _iTail = 0; +} + +int RingBuffer::read_char() +{ + if(_iTail == _iHead) + return -1; + + uint8_t value = _aucBuffer[_iTail]; + _iTail = nextIndex(_iTail); + + return value; +} + +int RingBuffer::available() +{ + int delta = _iHead - _iTail; + + if(delta < 0) + return SERIAL_BUFFER_SIZE + delta; + else + return delta; +} + +int RingBuffer::peek() +{ + if(_iTail == _iHead) + return -1; + + return _aucBuffer[_iTail]; +} + +int RingBuffer::nextIndex(int index) +{ + return (uint32_t)(index + 1) % SERIAL_BUFFER_SIZE; +} + +bool RingBuffer::isFull() +{ + return (nextIndex(_iHead) == _iTail); +} diff --git a/hardware/openrov/samd/cores/samd21g18a/RingBuffer.h b/hardware/openrov/samd/cores/samd21g18a/RingBuffer.h new file mode 100644 index 0000000..e212e6b --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/RingBuffer.h @@ -0,0 +1,50 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _RING_BUFFER_ +#define _RING_BUFFER_ + +#include + +// Define constants and variables for buffering incoming serial data. We're +// using a ring buffer (I think), in which head is the index of the location +// to which to write the next incoming character and tail is the index of the +// location from which to read. +#define SERIAL_BUFFER_SIZE 64 + +class RingBuffer +{ + public: + uint8_t _aucBuffer[SERIAL_BUFFER_SIZE] ; + int _iHead ; + int _iTail ; + + public: + RingBuffer( void ) ; + void store_char( uint8_t c ) ; + void clear(); + int read_char(); + int available(); + int peek(); + bool isFull(); + + private: + int nextIndex(int index); +} ; + +#endif /* _RING_BUFFER_ */ diff --git a/hardware/openrov/samd/cores/samd21g18a/SERCOM.cpp b/hardware/openrov/samd/cores/samd21g18a/SERCOM.cpp new file mode 100644 index 0000000..456c88b --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/SERCOM.cpp @@ -0,0 +1,999 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "SERCOM.h" +#include "Arduino.h" +#include "variant.h" + +#define STANDARD_MODE_FAST_MODE 0x0 +#define FAST_MODE_PLUS 0X01 +#define HIGHSPEED_MODE 0X02 + +SERCOM::SERCOM( Sercom *s ) +{ + sercom = s; +} + +/* ========================= + ===== Sercom UART + ========================= +*/ +void SERCOM::initUART( SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate ) +{ + InitClockNVIC(); + resetUART(); + + //Setting the CTRLA register + sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE( mode ) | + SERCOM_USART_CTRLA_SAMPR( sampleRate ); + + //Setting the Interrupt register + sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC | //Received complete + SERCOM_USART_INTENSET_ERROR; //All others errors + + if( mode == UART_INT_CLOCK ) + { + uint16_t sampleRateValue; + + if( sampleRate == SAMPLE_RATE_x16 ) + { + sampleRateValue = 16; + } + else + { + sampleRateValue = 8; + } + + // Asynchronous fractional mode (Table 24-2 in datasheet) + // BAUD = fref / (sampleRateValue * fbaud) + // (multiply by 8, to calculate fractional piece) + uint32_t baudTimes8 = ( SystemCoreClock * 8 ) / ( sampleRateValue * baudrate ); + + sercom->USART.BAUD.FRAC.FP = ( baudTimes8 % 8 ); + sercom->USART.BAUD.FRAC.BAUD = ( baudTimes8 / 8 ); + } +} +void SERCOM::initFrame( SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits ) +{ + //Setting the CTRLA register + sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_FORM( ( parityMode == SERCOM_NO_PARITY ? 0 : 1 ) ) | + dataOrder << SERCOM_USART_CTRLA_DORD_Pos; + + //Setting the CTRLB register + sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE( charSize ) | + nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos | + ( parityMode == SERCOM_NO_PARITY ? 0 : parityMode ) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value +} + +void SERCOM::initPads( SercomUartTXPad txPad, SercomRXPad rxPad ) +{ + //Setting the CTRLA register + sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO( txPad ) | + SERCOM_USART_CTRLA_RXPO( rxPad ); + + // Enable Transceiver and Receiver + sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ; +} + +void SERCOM::resetUART() +{ + // Start the Software Reset + sercom->USART.CTRLA.bit.SWRST = 1 ; + + while( sercom->USART.CTRLA.bit.SWRST || sercom->USART.SYNCBUSY.bit.SWRST ) + { + // Wait for both bits Software Reset from CTRLA and SYNCBUSY coming back to 0 + } +} + +void SERCOM::enableUART() +{ + //Setting the enable bit to 1 + sercom->USART.CTRLA.bit.ENABLE = 0x1u; + + //Wait for then enable bit from SYNCBUSY is equal to 0; + while( sercom->USART.SYNCBUSY.bit.ENABLE ); +} + +void SERCOM::flushUART() +{ + // Wait for transmission to complete + while( sercom->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE ); +} + +void SERCOM::clearStatusUART() +{ + //Reset (with 0) the STATUS register + sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE; +} + +bool SERCOM::availableDataUART() +{ + //RXC : Receive Complete + return sercom->USART.INTFLAG.bit.RXC; +} + +bool SERCOM::isUARTError() +{ + return sercom->USART.INTFLAG.bit.ERROR; +} + +void SERCOM::acknowledgeUARTError() +{ + sercom->USART.INTFLAG.bit.ERROR = 1; +} + +bool SERCOM::isBufferOverflowErrorUART() +{ + //BUFOVF : Buffer Overflow + return sercom->USART.STATUS.bit.BUFOVF; +} + +bool SERCOM::isFrameErrorUART() +{ + //FERR : Frame Error + return sercom->USART.STATUS.bit.FERR; +} + +bool SERCOM::isParityErrorUART() +{ + //PERR : Parity Error + return sercom->USART.STATUS.bit.PERR; +} + +bool SERCOM::isDataRegisterEmptyUART() +{ + //DRE : Data Register Empty + return sercom->USART.INTFLAG.bit.DRE; +} + +uint8_t SERCOM::readDataUART() +{ + return sercom->USART.DATA.bit.DATA; +} + +int SERCOM::writeDataUART( uint8_t data ) +{ + //Flush UART buffer + flushUART(); + + //Put data into DATA register + sercom->USART.DATA.reg = ( uint16_t )data; + return 1; +} + +/* ========================= + ===== Sercom SPI + ========================= +*/ +void SERCOM::initSPI( SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder ) +{ + resetSPI(); + InitClockNVIC(); + + //Setting the CTRLA register + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER | + SERCOM_SPI_CTRLA_DOPO( mosi ) | + SERCOM_SPI_CTRLA_DIPO( miso ) | + dataOrder << SERCOM_SPI_CTRLA_DORD_Pos; + + //Setting the CTRLB register + sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE( charSize ) | + SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver. + + +} + +void SERCOM::initSPIClock( SercomSpiClockMode clockMode, uint32_t baudrate ) +{ + //Extract data from clockMode + int cpha, cpol; + + if( ( clockMode & ( 0x1ul ) ) == 0 ) + { + cpha = 0; + } + else + { + cpha = 1; + } + + if( ( clockMode & ( 0x2ul ) ) == 0 ) + { + cpol = 0; + } + else + { + cpol = 1; + } + + //Setting the CTRLA register + sercom->SPI.CTRLA.reg |= ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) | + ( cpol << SERCOM_SPI_CTRLA_CPOL_Pos ); + + //Synchronous arithmetic + sercom->SPI.BAUD.reg = CalculateBaudrateSynchronous( baudrate ); +} + +void SERCOM::resetSPI() +{ + //Setting the Software Reset bit to 1 + sercom->SPI.CTRLA.bit.SWRST = 1; + + //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0 + while( sercom->SPI.CTRLA.bit.SWRST || sercom->SPI.SYNCBUSY.bit.SWRST ); +} + +void SERCOM::enableSPI() +{ + //Setting the enable bit to 1 + sercom->SPI.CTRLA.bit.ENABLE = 1; + + while( sercom->SPI.SYNCBUSY.bit.ENABLE ) + { + //Waiting then enable bit from SYNCBUSY is equal to 0; + } +} + +void SERCOM::disableSPI() +{ + //Setting the enable bit to 0 + sercom->SPI.CTRLA.bit.ENABLE = 0; + + while( sercom->SPI.SYNCBUSY.bit.ENABLE ) + { + //Waiting then enable bit from SYNCBUSY is equal to 0; + } +} + +void SERCOM::setDataOrderSPI( SercomDataOrder dataOrder ) +{ + //Register enable-protected + disableSPI(); + + sercom->SPI.CTRLA.bit.DORD = dataOrder; + + enableSPI(); +} + +SercomDataOrder SERCOM::getDataOrderSPI() +{ + return ( sercom->SPI.CTRLA.bit.DORD ? LSB_FIRST : MSB_FIRST ); +} + +void SERCOM::setBaudrateSPI( uint8_t divider ) +{ + //Can't divide by 0 + if( divider == 0 ) + { + return; + } + + //Register enable-protected + disableSPI(); + + sercom->SPI.BAUD.reg = CalculateBaudrateSynchronous( SERCOM_FREQ_REF / divider ); + + enableSPI(); +} + +void SERCOM::setClockModeSPI( SercomSpiClockMode clockMode ) +{ + int cpha, cpol; + + if( ( clockMode & ( 0x1ul ) ) == 0 ) + { + cpha = 0; + } + else + { + cpha = 1; + } + + if( ( clockMode & ( 0x2ul ) ) == 0 ) + { + cpol = 0; + } + else + { + cpol = 1; + } + + //Register enable-protected + disableSPI(); + + sercom->SPI.CTRLA.bit.CPOL = cpol; + sercom->SPI.CTRLA.bit.CPHA = cpha; + + enableSPI(); +} + +void SERCOM::writeDataSPI( uint8_t data ) +{ + while( sercom->SPI.INTFLAG.bit.DRE == 0 ) + { + // Waiting Data Registry Empty + } + + sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register + + while( sercom->SPI.INTFLAG.bit.TXC == 0 || sercom->SPI.INTFLAG.bit.DRE == 0 ) + { + // Waiting Complete Transmission + } +} + +uint16_t SERCOM::readDataSPI() +{ + while( sercom->SPI.INTFLAG.bit.DRE == 0 || sercom->SPI.INTFLAG.bit.RXC == 0 ) + { + // Waiting Complete Reception + } + + return sercom->SPI.DATA.bit.DATA; // Reading data +} + +bool SERCOM::isBufferOverflowErrorSPI() +{ + return sercom->SPI.STATUS.bit.BUFOVF; +} + +bool SERCOM::isDataRegisterEmptySPI() +{ + //DRE : Data Register Empty + return sercom->SPI.INTFLAG.bit.DRE; +} + +//bool SERCOM::isTransmitCompleteSPI() +//{ +// //TXC : Transmit complete +// return sercom->SPI.INTFLAG.bit.TXC; +//} +// +//bool SERCOM::isReceiveCompleteSPI() +//{ +// //RXC : Receive complete +// return sercom->SPI.INTFLAG.bit.RXC; +//} + + + +// ========================= +// ===== Sercom I2C +// ========================= + +I2C::ERetCode SERCOM::InitMasterMode_I2C( const I2C::TOptions &optionsIn ) +{ + // Set up interrupts and clocks + InitClockNVIC(); + + if( IsEnabled_I2C() ) + { + // Can't initialize while interface is enabled + return I2C::ERetCode::ERR_DENIED; + } + + // Reset + Reset_I2C(); + + // Set options + m_i2cOptions = optionsIn; + + // Set sercom peripheral to operate in I2C Master Mode + SetBitsCTRLA_I2C( SERCOM_I2CM_CTRLA_MODE_I2C_MASTER + | ( m_i2cOptions.setSCLSM ? SERCOM_I2CM_CTRLA_SCLSM : 0 ) // Interrupts only occur after ACK/NACK sent + | ( m_i2cOptions.enableINACTOUT ? SERCOM_I2CM_CTRLA_INACTOUT( 0x3 ) : 0 ) // Inactivity timeout + | ( m_i2cOptions.enableMEXTOUT ? SERCOM_I2CM_CTRLA_MEXTTOEN : 0 ) // Cumulative transaction time timeout + | ( m_i2cOptions.enableLOWTOUT ? SERCOM_I2CM_CTRLA_LOWTOUTEN : 0 ) ); // SCL low timeout + + // Enable Smart Mode (The currently set CTRLB.ACKACT is sent automatically when DATA.DATA is read) + SetBitsCTRLB_I2C( ( m_i2cOptions.setSMEN ? SERCOM_I2CM_CTRLB_SMEN : 0 ) ); + + // Set the baud rate + if( SetBaudRate_I2C( m_i2cOptions.baudRate ) ) + { + return I2C::ERetCode::ERR_BAUDRATE_UNAVAILABLE; + } + + m_isInitialized = true; + return I2C::ERetCode::SUCCESS; +} + +void SERCOM::DeinitMasterMode_I2C() +{ + // Clear enable + ClearBitsCTRLA_I2C( SERCOM_I2CM_CTRLA_ENABLE ); + + // Reset + Reset_I2C(); + + m_isInitialized = false; +} + +I2C::ERetCode SERCOM::SetBaudRate_I2C( uint32_t baudRateIn ) +{ + uint32_t tmp; + + if( IsEnabled_I2C() ) + { + // Can't change baudrate while enabled + return I2C::ERetCode::ERR_DENIED; + } + + if( baudRateIn > I2C_MAX_BAUD ) + { + return I2C::ERetCode::ERR_DENIED; + } + + // NOTE: All clock units are in Hz + tmp = (uint32_t)( ( SystemCoreClock - 10 * baudRateIn - baudRateIn * SystemCoreClock * ( m_i2cOptions.tRise_ns * 0.000000001 ) ) / ( 2 * baudRateIn ) ); + + // Add 1 to make sure the baud rate falls slightly below the target baud rate and not above + tmp += 1; + + // Set speed to standard (up to 100KHz) / fast (up to 400KHz) + SetBitsCTRLA_I2C( SERCOM_I2CM_CTRLA_SPEED( 0x0 ) ); + + // Set baud registers + sercom->I2CM.BAUD.reg = SERCOM_I2CM_BAUD_BAUDLOW( 0x0 ) | SERCOM_I2CM_BAUD_BAUD( tmp ); + + return I2C::ERetCode::SUCCESS; +} + +void SERCOM::Reset_I2C() +{ + // Reset Peripheral + SetBitsCTRLA_I2C( SERCOM_I2CM_CTRLA_SWRST ); +} + +void SERCOM::Enable_I2C() +{ + // Enable the peripheral + SetBitsCTRLA_I2C( SERCOM_I2CM_CTRLA_ENABLE ); + + // Move to the Idle bus state. Usually starts at Unknown state. + WaitForIdleBusState_I2C(); +} + +void SERCOM::Disable_I2C() +{ + SyncReset_I2C(); + SyncEnable_I2C(); + + // Disable the peripheral + ClearBitsCTRLA_I2C( SERCOM_I2CM_CTRLA_ENABLE ); +} + +void SERCOM::WaitForIdleBusState_I2C() +{ + // Set timeout value + m_timer = 0; + + // Wait for bus to move from Unknown state to Idle. Can also be moved to idle by INACTOUT triggering + while( !IsBusStateIdle_I2C() ) + { + m_timer++; + + // Bus state never changed, something is wrong and the I2C bus should not be used + if( m_timer >= m_i2cOptions.timeoutPeriod ) + { + // Force to idle + SetBitsSTATUS_I2C( SERCOM_I2CM_STATUS_BUSSTATE( I2C::EBusState::IDLE ) ); + } + } +} + +I2C::ERetCode SERCOM::WaitForInterrupt_I2C( uint8_t &flagsOut ) +{ + m_timer = 0; + + do + { + ++m_timer; + flagsOut = ReadRegisterINTFLAG_I2C(); + + if( m_timer > m_i2cOptions.timeoutPeriod ) + { + // Timeout occurred + // Not sure how this happens yet, but seemingly possible to reach this state due to triggered SMBus timeouts + return I2C::ERetCode::ERR_TIMEOUT; + } + } while( !( flagsOut & I2C::EInterruptFlags::INTFLAG_MB ) && !( flagsOut & I2C::EInterruptFlags::INTFLAG_SB ) ); + + return I2C::ERetCode::SUCCESS; +} + +I2C::ERetCode SERCOM::PerformTransfer_I2C( I2C::TTransfer *transferIn ) +{ + I2C::ERetCode ret; + + // Check to see if bus is idle or owner + if( !(IsBusStateIdle_I2C() || IsBusStateOwner_I2C() ) ) + { + // Bus is currently busy + return I2C::ERetCode::ERR_BUSY; + } + + // Now busy performing a transfer + m_transferActive = true; + + // Copy the message to be transferred + m_pTransfer = transferIn; + + if( m_pTransfer == nullptr ) + { + return I2C::ERetCode::ERR_BAD_TRANSFER; + } + + // Start transaction + ret = StartTransaction_I2C(); + + uint8_t flags = 0; + + // Handle any further transactions with this slave (multi-byte reads and writes) + while( m_transferActive ) + { + // Wait for interrupts + ret = WaitForInterrupt_I2C( flags ); + + // Check for timeout + if( ret == I2C::ERetCode::ERR_TIMEOUT ) + { + m_transferActive = false; + } + else + { + // Finish Transaction + ret = FinishTransaction_I2C( flags ); + } + } + + return ret; +} + +I2C::ERetCode SERCOM::StartTransaction_I2C() +{ + // Perform bounds checking on slave address + if( m_pTransfer->slaveAddress > 0x7F ) + { + return I2C::ERetCode::ERR_BAD_ADDRESS; + } + + I2C::ERetCode ret; + uint8_t flags = 0; + + // For reads, prepare ACK/NACK to be sent after reading the data + if( m_pTransfer->length == 1 && m_i2cOptions.setSCLSM ) + { + // Only a one byte transaction, respond with NACK to end transaction with slave + PrepareNack_I2C(); + } + else + { + // More bytes to read after this transaction, send ACK + PrepareAck_I2C(); + } + + // Set the address and R/W bit + WriteADDR_I2C( ( m_pTransfer->slaveAddress << 1 ) | m_pTransfer->action ); + + // Wait for interrupts + ret = WaitForInterrupt_I2C( flags ); + + if( ret == I2C::ERetCode::ERR_TIMEOUT ) + { + m_transferActive = false; + return ret; + } + + return FinishTransaction_I2C( flags ); +} + +I2C::ERetCode SERCOM::FinishTransaction_I2C( uint8_t flagsIn ) +{ + // Get Bus Status + sercom_i2cm_status_reg_t status = ReadRegisterSTATUS_I2C(); + + if( flagsIn & I2C::EInterruptFlags::INTFLAG_MB ) + { + if( status & SERCOM_I2CM_STATUS_ARBLOST ) + { + // We can arrive here in multiple ways: + // 1. Arbitration lost or bus error during address transmit + // 2. Arbitration lost or bus error during data transmit + // 3. Arbitration lost or bus error during ACK/NACK of read op + + // Arbitration lost + ClearInterruptMB_I2C(); + + // TODO: May need to specify that we kill it here + // Now that MB is cleared, the while loop in transfer will time out + m_transferActive = false; + + if( status & SERCOM_I2CM_STATUS_BUSERR ) + { + // Bus error + return I2C::ERetCode::ERR_BUS; + } + + // Otherwise, bad address/non-existent slave + return I2C::ERetCode::ERR_BAD_ADDRESS; + } + else + { + // Handle NACK from slave (either an explicit NACK or a non-present slave) + if( status & SERCOM_I2CM_STATUS_RXNACK ) + { + // Send a stop. Whether it is a failure from sending an address or transmitting data, a NACK with MB means a failed transfer. + SendBusCommand_I2C( I2C::EBusCommand::STOP ); + m_transferActive = false; + + return I2C::ERetCode::NACK; + } + + // Handle end of transfer + if( m_pTransfer->length == 0 ) + { + // If the user intends to perform another transfer after this, don't send a stop. The next ADDR write will automatically send a repeated start + if( !m_pTransfer->issueRepeatedStart ) + { + SendBusCommand_I2C( I2C::EBusCommand::STOP ); + } + + m_transferActive = false; + } + else + { + // Write the next byte of data - this will also clear the MB intflag + WriteDATA_I2C( *m_pTransfer->buffer ); + + // Move forward in transfer buffer + m_pTransfer->buffer++; + m_pTransfer->length--; + + // Transfer is still active until this function is called again and we've reached length == 0 + } + + return I2C::ERetCode::SUCCESS; + } + } + else if( flagsIn & I2C::EInterruptFlags::INTFLAG_SB ) + { + + if( ( m_pTransfer->length > 0 ) && !( status & SERCOM_I2CM_STATUS_RXNACK ) ) + { + // Slave accepted read request and there are more bytes to read + m_pTransfer->length--; + + // If we are coming up on the last byte in the transfer, prepare a NACK accordingly + if( ( m_pTransfer->length == 0 && !m_i2cOptions.setSCLSM ) || ( m_pTransfer->length == 1 && m_i2cOptions.setSCLSM ) ) + { + PrepareNack_I2C(); + } + + // Transaction complete + if( m_pTransfer->length == 0 ) + { + // If the user intends to perform another transfer after this, don't send a stop. The next ADDR write will automatically send a repeated start + if( !m_pTransfer->issueRepeatedStart ) + { + SendBusCommand_I2C( I2C::EBusCommand::STOP ); + } + + m_transferActive = false; + } + + // Read byte from DATA register + // NOTE: If SMEN is enabled, this will automatically trigger an ACK/NACK and clear the SB interrupt flag + *m_pTransfer->buffer++ = ReadRegisterDATA_I2C(); + + // If smart mode is off, we need to explicitly send a bus command to get the ACK to fire to receive the next byte + if( !m_i2cOptions.setSMEN ) + { + SendBusCommand_I2C( I2C::EBusCommand::BYTE_READ ); + } + } + else + { + // Send a stop. Whether it is a failure from sending an address or transmitting data, a NACK with SB means a failed transfer. + SendBusCommand_I2C( I2C::EBusCommand::STOP ); + m_transferActive = false; + + ClearInterruptSB_I2C(); + + return I2C::ERetCode::NACK; + } + + ClearInterruptSB_I2C(); + } + + return I2C::ERetCode::SUCCESS; +} + +// ----------------------------------------------------------- +// Register interactions + +bool SERCOM::IsEnabled_I2C() +{ + SyncReset_I2C(); + SyncEnable_I2C(); + + return ( sercom->I2CM.CTRLA.reg & SERCOM_I2CM_CTRLA_ENABLE ); +} + +void SERCOM::SyncReset_I2C() +{ + // Sync after setting CTRLA.SWRST + while( sercom->I2CM.SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_SWRST ); +} + +void SERCOM::SyncEnable_I2C() +{ + // Sync after setting CTRLA.ENABLE + while( sercom->I2CM.SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_ENABLE ); +} + +void SERCOM::SyncSysOp_I2C() +{ + // Sync after: + // Writing to STATUS.BUSSTATE in Master Mode + // Writing to ADDR.ADDR in Master Mode + // Writing to DATA in Master Mode + + while( sercom->I2CM.SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_SYSOP ); +} + +void SERCOM::SyncBusy_I2C() +{ + // Sync after all types of sync events are complete + while( sercom->I2CM.SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_MASK ); +} + +bool SERCOM::IsBusStateIdle_I2C() +{ + SyncSysOp_I2C(); + + return ( ReadValueSTATUS_BUSSTATE_I2C() == I2C::EBusState::IDLE ); +} + +bool SERCOM::IsBusStateOwner_I2C() +{ + SyncSysOp_I2C(); + + return ( ReadValueSTATUS_BUSSTATE_I2C() == I2C::EBusState::OWNER ); +} + +sercom_i2cm_intflag_reg_t SERCOM::ReadRegisterINTFLAG_I2C() +{ + return sercom->I2CM.INTFLAG.reg; +} + +void SERCOM::SendBusCommand_I2C( I2C::EBusCommand commandIn ) +{ + // Set CTRLB.CMD to issue the specified master operation + SetBitsCTRLB_I2C( SERCOM_I2CM_CTRLB_CMD( commandIn ) ); +} + +void SERCOM::PrepareNack_I2C() +{ + // Set ACKACT to NACK (0x1) + SetBitsCTRLB_I2C( SERCOM_I2CM_CTRLB_ACKACT ); +} + +void SERCOM::PrepareAck_I2C() +{ + // Clear ACKACT to ACK (0x0) + ClearBitsCTRLB_I2C( SERCOM_I2CM_CTRLB_ACKACT ); +} + +void SERCOM::ClearInterruptMB_I2C() +{ + // Setting INTFLAG.MB to 1 clears the interrupt + // Note: The following other actions also clear this bit: + // - Writing to ADDR.ADDR + // - Writing to DATA.DATA + // - Reading DATA.DATA when Smart Mode is enabled + // - Writing a valid command to CTRLB.CMD + sercom->I2CM.INTFLAG.reg |= SERCOM_I2CM_INTFLAG_MB; +} + +void SERCOM::ClearInterruptSB_I2C() +{ + // Setting INTFLAG.SB to 1 clears the interrupt + // Note: The following other actions also clear this bit: + // - Writing to ADDR.ADDR + // - Writing to DATA.DATA + // - Reading DATA.DATA when Smart Mode is enabled + // - Writing a valid command to CTRLB.CMD + sercom->I2CM.INTFLAG.reg |= SERCOM_I2CM_INTFLAG_SB; +} + +sercom_i2cm_status_reg_t SERCOM::ReadRegisterSTATUS_I2C() +{ + SyncSysOp_I2C(); + + return sercom->I2CM.STATUS.reg; +} + +uint8_t SERCOM::ReadValueCTRLA_SCLSM_I2C() +{ + return ( sercom->I2CM.CTRLA.reg & SERCOM_I2CM_CTRLA_SCLSM ); +} + +uint8_t SERCOM::ReadValueSTATUS_BUSSTATE_I2C() +{ + SyncSysOp_I2C(); + + return ( sercom->I2CM.STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE_Msk ) >> SERCOM_I2CM_STATUS_BUSSTATE_Pos; +} + +sercom_i2cm_data_reg_t SERCOM::ReadRegisterDATA_I2C() +{ + SyncSysOp_I2C(); + + return sercom->I2CM.DATA.reg; +} + +void SERCOM::WriteDATA_I2C( sercom_i2cm_data_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.DATA.reg = dataIn; +} + +void SERCOM::WriteADDR_I2C( sercom_i2cm_addr_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.ADDR.reg = dataIn; +} + +void SERCOM::SetBitsCTRLA_I2C( sercom_i2cm_ctrla_reg_t dataIn ) +{ + SyncReset_I2C(); + SyncEnable_I2C(); + + sercom->I2CM.CTRLA.reg |= dataIn; +} + +void SERCOM::ClearBitsCTRLA_I2C( sercom_i2cm_ctrla_reg_t dataIn ) +{ + SyncReset_I2C(); + SyncEnable_I2C(); + + sercom->I2CM.CTRLA.reg &= ~dataIn; +} + +void SERCOM::WriteCTRLA_I2C( sercom_i2cm_ctrla_reg_t dataIn ) +{ + SyncReset_I2C(); + SyncEnable_I2C(); + + sercom->I2CM.CTRLA.reg = dataIn; +} + +void SERCOM::SetBitsCTRLB_I2C( sercom_i2cm_ctrlb_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.CTRLB.reg |= dataIn; +} + +void SERCOM::ClearBitsCTRLB_I2C( sercom_i2cm_ctrlb_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.CTRLB.reg &= ~dataIn; +} + +void SERCOM::WriteCTRLB_I2C( sercom_i2cm_ctrlb_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.CTRLB.reg = dataIn; +} + +void SERCOM::SetBitsSTATUS_I2C( sercom_i2cm_status_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.STATUS.reg |= dataIn; +} + +void SERCOM::ClearBitsSTATUS_I2C( sercom_i2cm_status_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.STATUS.reg &= ~dataIn; +} + +void SERCOM::WriteSTATUS_I2C( sercom_i2cm_status_reg_t dataIn ) +{ + SyncSysOp_I2C(); + + sercom->I2CM.STATUS.reg = dataIn; +} + +/* ========================= + ===== Sercom Shared + ========================= +*/ + +uint8_t SERCOM::CalculateBaudrateSynchronous( uint32_t baudRateIn ) +{ + return SERCOM_FREQ_REF / ( 2 * baudRateIn ) - 1; +} + + +void SERCOM::InitClockNVIC() +{ + uint8_t clockId = 0; + IRQn_Type IdNvic = PendSV_IRQn ; // Dummy init to intercept potential error later + + if( sercom == SERCOM0 ) + { + clockId = GCM_SERCOM0_CORE; + IdNvic = SERCOM0_IRQn; + } + else if( sercom == SERCOM1 ) + { + clockId = GCM_SERCOM1_CORE; + IdNvic = SERCOM1_IRQn; + } + else if( sercom == SERCOM2 ) + { + clockId = GCM_SERCOM2_CORE; + IdNvic = SERCOM2_IRQn; + } + else if( sercom == SERCOM3 ) + { + clockId = GCM_SERCOM3_CORE; + IdNvic = SERCOM3_IRQn; + } + else if( sercom == SERCOM4 ) + { + clockId = GCM_SERCOM4_CORE; + IdNvic = SERCOM4_IRQn; + } + else if( sercom == SERCOM5 ) + { + clockId = GCM_SERCOM5_CORE; + IdNvic = SERCOM5_IRQn; + } + + if( IdNvic == PendSV_IRQn ) + { + // We got a problem here + return ; + } + + // Setting NVIC + NVIC_EnableIRQ( IdNvic ); + NVIC_SetPriority( IdNvic, ( 1 << __NVIC_PRIO_BITS ) - 1 ); /* set Priority */ + + //Setting clock + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // SERCOM clock id + // GCLK_CLKCTRL_ID( GCM_SERCOMx_SLOW ) | // SERCOM slow clock. Hopefully this is idempotent + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN; + + while( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } +} diff --git a/hardware/openrov/samd/cores/samd21g18a/SERCOM.h b/hardware/openrov/samd/cores/samd21g18a/SERCOM.h new file mode 100644 index 0000000..87f1e47 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/SERCOM.h @@ -0,0 +1,329 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _SERCOM_CLASS_ +#define _SERCOM_CLASS_ + +#include "sam.h" + +#define SERCOM_FREQ_REF 48000000 + +typedef enum +{ + UART_EXT_CLOCK = 0, + UART_INT_CLOCK = 0x1u +} SercomUartMode; + +typedef enum +{ + SPI_SLAVE_OPERATION = 0x2u, + SPI_MASTER_OPERATION = 0x3u +} SercomSpiMode; + +typedef enum +{ + SERCOM_EVEN_PARITY = 0, + SERCOM_ODD_PARITY, + SERCOM_NO_PARITY +} SercomParityMode; + +typedef enum +{ + SERCOM_STOP_BIT_1 = 0, + SERCOM_STOP_BITS_2 +} SercomNumberStopBit; + +typedef enum +{ + MSB_FIRST = 0, + LSB_FIRST +} SercomDataOrder; + +typedef enum +{ + UART_CHAR_SIZE_8_BITS = 0, + UART_CHAR_SIZE_9_BITS, + UART_CHAR_SIZE_5_BITS = 0x5u, + UART_CHAR_SIZE_6_BITS, + UART_CHAR_SIZE_7_BITS +} SercomUartCharSize; + +typedef enum +{ + SERCOM_RX_PAD_0 = 0, + SERCOM_RX_PAD_1, + SERCOM_RX_PAD_2, + SERCOM_RX_PAD_3 +} SercomRXPad; + +typedef enum +{ + UART_TX_PAD_0 = 0x0ul, // Only for UART + UART_TX_PAD_2 = 0x1ul, // Only for UART + UART_TX_RTS_CTS_PAD_0_2_3 = 0x2ul, // Only for UART with TX on PAD0, RTS on PAD2 and CTS on PAD3 +} SercomUartTXPad; + +typedef enum +{ + SAMPLE_RATE_x16 = 0x1, //Fractional + SAMPLE_RATE_x8 = 0x3, //Fractional +} SercomUartSampleRate; + +typedef enum +{ + SERCOM_SPI_MODE_0 = 0, // CPOL : 0 | CPHA : 0 + SERCOM_SPI_MODE_1, // CPOL : 0 | CPHA : 1 + SERCOM_SPI_MODE_2, // CPOL : 1 | CPHA : 0 + SERCOM_SPI_MODE_3 // CPOL : 1 | CPHA : 1 +} SercomSpiClockMode; + +typedef enum +{ + SPI_PAD_0_SCK_1 = 0, + SPI_PAD_2_SCK_3, + SPI_PAD_3_SCK_1, + SPI_PAD_0_SCK_3 +} SercomSpiTXPad; + +typedef enum +{ + SPI_CHAR_SIZE_8_BITS = 0x0ul, + SPI_CHAR_SIZE_9_BITS +} SercomSpiCharSize; + +// ---------------------------------------- +// I2C Definitions +// ---------------------------------------- + +#define I2C_DEFAULT_BAUD 100000 +#define I2C_MAX_BAUD 400000 + +typedef uint16_t sercom_i2cm_status_reg_t; +typedef uint32_t sercom_i2cm_addr_reg_t; +typedef uint32_t sercom_i2cm_baud_reg_t; +typedef uint32_t sercom_i2cm_ctrla_reg_t; +typedef uint32_t sercom_i2cm_ctrlb_reg_t; +typedef uint32_t sercom_i2cm_syncbusy_reg_t; +typedef uint8_t sercom_i2cm_data_reg_t; +typedef uint8_t sercom_i2cm_inten_reg_t; +typedef uint8_t sercom_i2cm_intflag_reg_t; + +namespace I2C +{ + enum EMode : uint8_t + { + SLAVE = 0x4, + MASTER = 0x5 + }; + + enum EBusState: uint8_t + { + UNKNOWN = 0x0, + IDLE = 0x1, + OWNER = 0x2, + BUSY = 0x3 + }; + + enum EAction: uint8_t + { + WRITE = 0x0, + READ = 0x1 + }; + + enum EBusCommand: uint8_t + { + NO_ACTION = 0x0, + REPEAT_START = 0x1, + BYTE_READ = 0x2, + STOP = 0x3 + }; + + enum ERetCode: int32_t + { + SUCCESS = 0, // Operation successful + ACK = -1, // Received ACK from device on I2C bus + NACK = -2, // Received NACK from device on I2C bus + ERR_ARBLOST = -3, // Arbitration lost + ERR_BAD_ADDRESS = -4, // Bad address + ERR_BUS = -5, // Bus error + ERR_BUSY = -6, // Device busy + ERR_PACKAGE_COLLISION = -7, // Package collision + ERR_TIMEOUT = -8, + ERR_INVALID_ARG = -9, + ERR_DENIED = -10, + ERR_ALREADY_INITIALIZED = -11, + ERR_NOT_INITIALIZED = -12, + ERR_BAUDRATE_UNAVAILABLE = -13, + ERR_UNSUPPORTED_OP = -14, + ERR_NOT_READY = -15, + ERR_BAD_TRANSFER = -16 + }; + + enum EInterruptFlags: uint8_t + { + INTFLAG_MB = (1 << 0), + INTFLAG_SB = (1 << 1), + INTFLAG_ERROR = (1 << 7) + }; + + struct TTransfer + { + uint8_t slaveAddress; + uint32_t length; + uint8_t *buffer; + + EAction action; + bool issueRepeatedStart; + }; + + struct TOptions + { + bool setSCLSM = false; + bool setSMEN = false; + bool enableINACTOUT = false; + bool enableMEXTOUT = false; + bool enableLOWTOUT = false; + + uint32_t baudRate = 100000; + uint32_t timeoutPeriod = 65535; + uint16_t tRise_ns = 215; + }; +} + +class SERCOM +{ +public: + SERCOM( Sercom *s ) ; + + /* ========== UART ========== */ + void initUART( SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate = 0 ) ; + void initFrame( SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits ) ; + void initPads( SercomUartTXPad txPad, SercomRXPad rxPad ); + + void resetUART( void ) ; + void enableUART( void ) ; + void flushUART( void ) ; + void clearStatusUART( void ) ; + bool availableDataUART( void ) ; + bool isBufferOverflowErrorUART( void ) ; + bool isFrameErrorUART( void ) ; + bool isParityErrorUART( void ) ; + bool isDataRegisterEmptyUART( void ) ; + uint8_t readDataUART( void ) ; + int writeDataUART( uint8_t data ) ; + bool isUARTError() ; + void acknowledgeUARTError() ; + + /* ========== SPI ========== */ + void initSPI( SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder ) ; + void initSPIClock( SercomSpiClockMode clockMode, uint32_t baudrate ) ; + + void resetSPI( void ) ; + void enableSPI( void ) ; + void disableSPI( void ) ; + void setDataOrderSPI( SercomDataOrder dataOrder ) ; + SercomDataOrder getDataOrderSPI( void ) ; + void setBaudrateSPI( uint8_t divider ) ; + void setClockModeSPI( SercomSpiClockMode clockMode ) ; + void writeDataSPI( uint8_t data ) ; + uint16_t readDataSPI( void ) ; + bool isBufferOverflowErrorSPI( void ) ; + bool isDataRegisterEmptySPI( void ) ; + bool isTransmitCompleteSPI( void ) ; + bool isReceiveCompleteSPI( void ) ; + + // ----------------------------------------------------------------------------------------- + /* ========== I2C ========== */ + I2C::ERetCode InitMasterMode_I2C( const I2C::TOptions &optionsIn ); + void DeinitMasterMode_I2C(); + + void Enable_I2C(); + void Disable_I2C(); + void Reset_I2C(); + I2C::ERetCode SetBaudRate_I2C( uint32_t baudRateIn ); + + void WaitForIdleBusState_I2C(); + I2C::ERetCode WaitForInterrupt_I2C( uint8_t &flagsOut ); + + I2C::ERetCode PerformTransfer_I2C( I2C::TTransfer *transferIn ); + I2C::ERetCode StartTransaction_I2C(); + I2C::ERetCode FinishTransaction_I2C( uint8_t flagsIn ); + + void SendBusCommand_I2C( I2C::EBusCommand commandIn ); + + void PrepareNack_I2C(); + void PrepareAck_I2C(); + + void SyncReset_I2C(); + void SyncEnable_I2C(); + void SyncSysOp_I2C(); + void SyncBusy_I2C(); + + void ClearInterruptMB_I2C(); + void ClearInterruptSB_I2C(); + + // ----------------------- + // Reads + sercom_i2cm_intflag_reg_t ReadRegisterINTFLAG_I2C(); + sercom_i2cm_status_reg_t ReadRegisterSTATUS_I2C(); + sercom_i2cm_data_reg_t ReadRegisterDATA_I2C(); + + uint8_t ReadValueSTATUS_BUSSTATE_I2C(); + uint8_t ReadValueCTRLA_SCLSM_I2C(); + + bool IsEnabled_I2C(); + bool IsBusStateIdle_I2C(); + bool IsBusStateOwner_I2C(); + + // ----------------------- + // Sets, Clears, Writes + void SetBitsCTRLA_I2C( sercom_i2cm_ctrla_reg_t dataIn ); + void ClearBitsCTRLA_I2C( sercom_i2cm_ctrla_reg_t dataIn ); + void WriteCTRLA_I2C( sercom_i2cm_ctrla_reg_t dataIn ); + + void SetBitsCTRLB_I2C( sercom_i2cm_ctrlb_reg_t dataIn ); + void ClearBitsCTRLB_I2C( sercom_i2cm_ctrlb_reg_t dataIn ); + void WriteCTRLB_I2C( sercom_i2cm_ctrlb_reg_t dataIn ); + + void SetBitsSTATUS_I2C( sercom_i2cm_status_reg_t dataIn ); + void ClearBitsSTATUS_I2C( sercom_i2cm_status_reg_t dataIn ); + void WriteSTATUS_I2C( sercom_i2cm_status_reg_t dataIn ); + + void WriteADDR_I2C( sercom_i2cm_addr_reg_t dataIn ); + void WriteDATA_I2C( sercom_i2cm_data_reg_t dataIn ); + +private: + // Shared private members + Sercom* sercom; + + // Shared private methods + uint8_t CalculateBaudrateSynchronous( uint32_t baudrateIn ); + void InitClockNVIC(); + + // ---------------- + // I2C attributes + I2C::TOptions m_i2cOptions; + I2C::TTransfer *m_pTransfer = nullptr; + + bool m_isInitialized = false; + bool m_transferActive = false; + uint32_t m_timer = 0; + const uint16_t m_kTRise_ns = 215; +}; + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/Stream.cpp b/hardware/openrov/samd/cores/samd21g18a/Stream.cpp new file mode 100644 index 0000000..f665465 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Stream.cpp @@ -0,0 +1,319 @@ +/* + Stream.cpp - adds parsing methods to Stream class + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Created July 2011 + parsing functions based on TextFinder library by Michael Margolis + + findMulti/findUntil routines written by Jim Leonard/Xuth + */ + +#include "Arduino.h" +#include "Stream.h" + +#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait + +// private method to read stream with timeout +int Stream::timedRead() +{ + int c; + _startMillis = millis(); + do { + c = read(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// private method to peek stream with timeout +int Stream::timedPeek() +{ + int c; + _startMillis = millis(); + do { + c = peek(); + if (c >= 0) return c; + } while(millis() - _startMillis < _timeout); + return -1; // -1 indicates timeout +} + +// returns peek of the next digit in the stream or -1 if timeout +// discards non-numeric characters +int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal) +{ + int c; + while (1) { + c = timedPeek(); + + if( c < 0 || + c == '-' || + (c >= '0' && c <= '9') || + (detectDecimal && c == '.')) return c; + + switch( lookahead ){ + case SKIP_NONE: return -1; // Fail code. + case SKIP_WHITESPACE: + switch( c ){ + case ' ': + case '\t': + case '\r': + case '\n': break; + default: return -1; // Fail code. + } + case SKIP_ALL: + break; + } + read(); // discard non-numeric + } +} + +// Public Methods +////////////////////////////////////////////////////////////// + +void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait +{ + _timeout = timeout; +} + + // find returns true if the target string is found +bool Stream::find(char *target) +{ + return findUntil(target, strlen(target), NULL, 0); +} + +// reads data from the stream until the target string of given length is found +// returns true if target string is found, false if timed out +bool Stream::find(char *target, size_t length) +{ + return findUntil(target, length, NULL, 0); +} + +// as find but search ends if the terminator string is found +bool Stream::findUntil(char *target, char *terminator) +{ + return findUntil(target, strlen(target), terminator, strlen(terminator)); +} + +// reads data from the stream until the target string of the given length is found +// search terminated if the terminator string is found +// returns true if target string is found, false if terminated or timed out +bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen) +{ + if (terminator == NULL) { + MultiTarget t[1] = {{target, targetLen, 0}}; + return findMulti(t, 1) == 0 ? true : false; + } else { + MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}}; + return findMulti(t, 2) == 0 ? true : false; + } +} + +// returns the first valid (long) integer value from the current position. +// lookahead determines how parseInt looks ahead in the stream. +// See LookaheadMode enumeration at the top of the file. +// Lookahead is terminated by the first character that is not a valid part of an integer. +// Once parsing commences, 'ignore' will be skipped in the stream. +long Stream::parseInt(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + long value = 0; + int c; + + c = peekNextDigit(lookahead, false); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore this character + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || c == ignore ); + + if(isNegative) + value = -value; + return value; +} + +// as parseInt but returns a floating point value +float Stream::parseFloat(LookaheadMode lookahead, char ignore) +{ + bool isNegative = false; + bool isFraction = false; + long value = 0; + int c; + float fraction = 1.0; + + c = peekNextDigit(lookahead, true); + // ignore non numeric leading characters + if(c < 0) + return 0; // zero returned if timeout + + do{ + if(c == ignore) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + read(); // consume the character we got with peek + c = timedPeek(); + } + while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore ); + + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + +// read characters from stream into buffer +// terminates if length characters have been read, or timeout (see setTimeout) +// returns the number of characters placed in the buffer +// the buffer is NOT null terminated. +// +size_t Stream::readBytes(char *buffer, size_t length) +{ + size_t count = 0; + while (count < length) { + int c = timedRead(); + if (c < 0) break; + *buffer++ = (char)c; + count++; + } + return count; +} + + +// as readBytes with terminator character +// terminates if length characters have been read, timeout, or if the terminator character detected +// returns the number of characters placed in the buffer (0 means no valid data found) + +size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) +{ + if (length < 1) return 0; + size_t index = 0; + while (index < length) { + int c = timedRead(); + if (c < 0 || c == terminator) break; + *buffer++ = (char)c; + index++; + } + return index; // return number of characters, not including null terminator +} + +String Stream::readString() +{ + String ret; + int c = timedRead(); + while (c >= 0) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +String Stream::readStringUntil(char terminator) +{ + String ret; + int c = timedRead(); + while (c >= 0 && c != terminator) + { + ret += (char)c; + c = timedRead(); + } + return ret; +} + +int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) { + // any zero length target string automatically matches and would make + // a mess of the rest of the algorithm. + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + if (t->len <= 0) + return t - targets; + } + + while (1) { + int c = timedRead(); + if (c < 0) + return -1; + + for (struct MultiTarget *t = targets; t < targets+tCount; ++t) { + // the simple case is if we match, deal with that first. + if (c == t->str[t->index]) { + if (++t->index == t->len) + return t - targets; + else + continue; + } + + // if not we need to walk back and see if we could have matched further + // down the stream (ie '1112' doesn't match the first position in '11112' + // but it will match the second position so we can't just reset the current + // index to 0 when we find a mismatch. + if (t->index == 0) + continue; + + int origIndex = t->index; + do { + --t->index; + // first check if current char works against the new current index + if (c != t->str[t->index]) + continue; + + // if it's the only char then we're good, nothing more to check + if (t->index == 0) { + t->index++; + break; + } + + // otherwise we need to check the rest of the found string + int diff = origIndex - t->index; + size_t i; + for (i = 0; i < t->index; ++i) { + if (t->str[i] != t->str[i + diff]) + break; + } + + // if we successfully got through the previous loop then our current + // index is good. + if (i == t->index) { + t->index++; + break; + } + + // otherwise we just try the next index + } while (t->index); + } + } + // unreachable + return -1; +} diff --git a/hardware/openrov/samd/cores/samd21g18a/Stream.h b/hardware/openrov/samd/cores/samd21g18a/Stream.h new file mode 100644 index 0000000..684aa7e --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Stream.h @@ -0,0 +1,129 @@ +/* + Stream.h - base class for character-based streams. + Copyright (c) 2010 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + parsing functions based on TextFinder library by Michael Margolis +*/ + +#ifndef Stream_h +#define Stream_h + +#include +#include "Print.h" + +// compatability macros for testing +/* +#define getInt() parseInt() +#define getInt(ignore) parseInt(ignore) +#define getFloat() parseFloat() +#define getFloat(ignore) parseFloat(ignore) +#define getString( pre_string, post_string, buffer, length) +readBytesBetween( pre_string, terminator, buffer, length) +*/ + +// This enumeration provides the lookahead options for parseInt(), parseFloat() +// The rules set out here are used until either the first valid character is found +// or a time out occurs due to lack of input. +enum LookaheadMode{ + SKIP_ALL, // All invalid characters are ignored. + SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid. + SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped. +}; + +#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field + +class Stream : public Print +{ + protected: + unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read + unsigned long _startMillis; // used for timeout measurement + int timedRead(); // private method to read stream with timeout + int timedPeek(); // private method to peek stream with timeout + int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout + + public: + virtual int available() = 0; + virtual int read() = 0; + virtual int peek() = 0; + virtual void flush() = 0; + + Stream() {_timeout=1000;} + +// parsing methods + + void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second + + bool find(char *target); // reads data from the stream until the target string is found + bool find(uint8_t *target) { return find ((char *)target); } + // returns true if target string is found, false if timed out (see setTimeout) + + bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found + bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } + // returns true if target string is found, false if timed out + + bool find(char target) { return find (&target, 1); } + + bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found + bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } + + bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found + bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } + + long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // returns the first valid (long) integer value from the current position. + // lookahead determines how parseInt looks ahead in the stream. + // See LookaheadMode enumeration at the top of the file. + // Lookahead is terminated by the first character that is not a valid part of an integer. + // Once parsing commences, 'ignore' will be skipped in the stream. + + float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR); + // float version of parseInt + + size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer + size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } + // terminates if length characters have been read or timeout (see setTimeout) + // returns the number of characters placed in the buffer (0 means no valid data found) + + size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character + size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } + // terminates if length characters have been read, timeout, or if the terminator character detected + // returns the number of characters placed in the buffer (0 means no valid data found) + + // Arduino String functions to be added here + String readString(); + String readStringUntil(char terminator); + + protected: + long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); } + float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); } + // These overload exists for compatibility with any class that has derived + // Stream and used parseFloat/Int with a custom ignore character. To keep + // the public API simple, these overload remains protected. + + struct MultiTarget { + const char *str; // string you're searching for + size_t len; // length of string you're searching for + size_t index; // index used by the search routine. + }; + + // This allows you to search for an arbitrary number of strings. + // Returns index of the target that is found first or -1 if timeout occurs. + int findMulti(struct MultiTarget *targets, int tCount); +}; + +#undef NO_IGNORE_CHAR +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/Uart.cpp b/hardware/openrov/samd/cores/samd21g18a/Uart.cpp new file mode 100644 index 0000000..6f24bed --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Uart.cpp @@ -0,0 +1,143 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Uart.h" +#include "Arduino.h" +#include "wiring_private.h" + +Uart::Uart(SERCOM *_s, uint8_t _pinRX, uint8_t _pinTX, SercomRXPad _padRX, SercomUartTXPad _padTX) +{ + sercom = _s; + uc_pinRX = _pinRX; + uc_pinTX = _pinTX; + uc_padRX=_padRX ; + uc_padTX=_padTX; +} + +void Uart::begin(unsigned long baudrate) +{ + begin(baudrate, (uint8_t)SERIAL_8N1); +} + +void Uart::begin(unsigned long baudrate, uint8_t config) +{ + pinPeripheral(uc_pinRX, g_APinDescription[uc_pinRX].ulPinType); + pinPeripheral(uc_pinTX, g_APinDescription[uc_pinTX].ulPinType); + + sercom->initUART(UART_INT_CLOCK, SAMPLE_RATE_x16, baudrate); + sercom->initFrame(extractCharSize(config), LSB_FIRST, extractParity(config), extractNbStopBit(config)); + sercom->initPads(uc_padTX, uc_padRX); + + sercom->enableUART(); +} + +void Uart::end() +{ + sercom->resetUART(); + rxBuffer.clear(); +} + +void Uart::flush() +{ + sercom->flushUART(); +} + +void Uart::IrqHandler() +{ + if (sercom->availableDataUART()) { + rxBuffer.store_char(sercom->readDataUART()); + } + + if (sercom->isUARTError()) { + sercom->acknowledgeUARTError(); + // TODO: if (sercom->isBufferOverflowErrorUART()) .... + // TODO: if (sercom->isFrameErrorUART()) .... + // TODO: if (sercom->isParityErrorUART()) .... + sercom->clearStatusUART(); + } +} + +int Uart::available() +{ + return rxBuffer.available(); +} + +int Uart::peek() +{ + return rxBuffer.peek(); +} + +int Uart::read() +{ + return rxBuffer.read_char(); +} + +size_t Uart::write(const uint8_t data) +{ + sercom->writeDataUART(data); + return 1; +} + +SercomNumberStopBit Uart::extractNbStopBit(uint8_t config) +{ + switch(config & HARDSER_STOP_BIT_MASK) + { + case HARDSER_STOP_BIT_1: + default: + return SERCOM_STOP_BIT_1; + + case HARDSER_STOP_BIT_2: + return SERCOM_STOP_BITS_2; + } +} + +SercomUartCharSize Uart::extractCharSize(uint8_t config) +{ + switch(config & HARDSER_DATA_MASK) + { + case HARDSER_DATA_5: + return UART_CHAR_SIZE_5_BITS; + + case HARDSER_DATA_6: + return UART_CHAR_SIZE_6_BITS; + + case HARDSER_DATA_7: + return UART_CHAR_SIZE_7_BITS; + + case HARDSER_DATA_8: + default: + return UART_CHAR_SIZE_8_BITS; + + } +} + +SercomParityMode Uart::extractParity(uint8_t config) +{ + switch(config & HARDSER_PARITY_MASK) + { + case HARDSER_PARITY_NONE: + default: + return SERCOM_NO_PARITY; + + case HARDSER_PARITY_EVEN: + return SERCOM_EVEN_PARITY; + + case HARDSER_PARITY_ODD: + return SERCOM_ODD_PARITY; + } +} diff --git a/hardware/openrov/samd/cores/samd21g18a/Uart.h b/hardware/openrov/samd/cores/samd21g18a/Uart.h new file mode 100644 index 0000000..3c88d67 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/Uart.h @@ -0,0 +1,57 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include "HardwareSerial.h" +#include "SERCOM.h" +#include "RingBuffer.h" + +#include + +class Uart : public HardwareSerial +{ + public: + Uart(SERCOM *_s, uint8_t _pinRX, uint8_t _pinTX, SercomRXPad _padRX, SercomUartTXPad _padTX); + void begin(unsigned long baudRate); + void begin(unsigned long baudrate, uint8_t config); + void end(); + int available(); + int peek(); + int read(); + void flush(); + size_t write(const uint8_t data); + using Print::write; // pull in write(str) and write(buf, size) from Print + + void IrqHandler(); + + operator bool() { return true; } + + private: + SERCOM *sercom; + RingBuffer rxBuffer; + + uint8_t uc_pinRX; + uint8_t uc_pinTX; + SercomRXPad uc_padRX; + SercomUartTXPad uc_padTX; + + SercomNumberStopBit extractNbStopBit(uint8_t config); + SercomUartCharSize extractCharSize(uint8_t config); + SercomParityMode extractParity(uint8_t config); +}; diff --git a/hardware/openrov/samd/cores/samd21g18a/WCharacter.h b/hardware/openrov/samd/cores/samd21g18a/WCharacter.h new file mode 100644 index 0000000..c0cbec7 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WCharacter.h @@ -0,0 +1,179 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Character_h +#define Character_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// WCharacter.h prototypes +#if defined ( __GNUC__ ) +inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); +inline boolean isAlpha(int c) __attribute__((always_inline)); +inline boolean isAscii(int c) __attribute__((always_inline)); +inline boolean isWhitespace(int c) __attribute__((always_inline)); +inline boolean isControl(int c) __attribute__((always_inline)); +inline boolean isDigit(int c) __attribute__((always_inline)); +inline boolean isGraph(int c) __attribute__((always_inline)); +inline boolean isLowerCase(int c) __attribute__((always_inline)); +inline boolean isPrintable(int c) __attribute__((always_inline)); +inline boolean isPunct(int c) __attribute__((always_inline)); +inline boolean isSpace(int c) __attribute__((always_inline)); +inline boolean isUpperCase(int c) __attribute__((always_inline)); +inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); +inline int toAscii(int c) __attribute__((always_inline)); +inline int toLowerCase(int c) __attribute__((always_inline)); +inline int toUpperCase(int c)__attribute__((always_inline)); +#elif defined ( __ICCARM__ ) +#endif + +// Checks for an alphanumeric character. +// It is equivalent to (isalpha(c) || isdigit(c)). +inline boolean isAlphaNumeric(int c) +{ + return ( isalnum(c) == 0 ? false : true); +} + + +// Checks for an alphabetic character. +// It is equivalent to (isupper(c) || islower(c)). +inline boolean isAlpha(int c) +{ + return ( isalpha(c) == 0 ? false : true); +} + + +// Checks whether c is a 7-bit unsigned char value +// that fits into the ASCII character set. +inline boolean isAscii(int c) +{ +/* return ( isascii(c) == 0 ? false : true); */ + return ( (c & ~0x7f) != 0 ? false : true); +} + + +// Checks for a blank character, that is, a space or a tab. +inline boolean isWhitespace(int c) +{ + return ( isblank (c) == 0 ? false : true); +} + + +// Checks for a control character. +inline boolean isControl(int c) +{ + return ( iscntrl (c) == 0 ? false : true); +} + + +// Checks for a digit (0 through 9). +inline boolean isDigit(int c) +{ + return ( isdigit (c) == 0 ? false : true); +} + + +// Checks for any printable character except space. +inline boolean isGraph(int c) +{ + return ( isgraph (c) == 0 ? false : true); +} + + +// Checks for a lower-case character. +inline boolean isLowerCase(int c) +{ + return (islower (c) == 0 ? false : true); +} + + +// Checks for any printable character including space. +inline boolean isPrintable(int c) +{ + return ( isprint (c) == 0 ? false : true); +} + + +// Checks for any printable character which is not a space +// or an alphanumeric character. +inline boolean isPunct(int c) +{ + return ( ispunct (c) == 0 ? false : true); +} + + +// Checks for white-space characters. For the avr-libc library, +// these are: space, formfeed ('\f'), newline ('\n'), carriage +// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). +inline boolean isSpace(int c) +{ + return ( isspace (c) == 0 ? false : true); +} + + +// Checks for an uppercase letter. +inline boolean isUpperCase(int c) +{ + return ( isupper (c) == 0 ? false : true); +} + + +// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7 +// 8 9 a b c d e f A B C D E F. +inline boolean isHexadecimalDigit(int c) +{ + return ( isxdigit (c) == 0 ? false : true); +} + + +// Converts c to a 7-bit unsigned char value that fits into the +// ASCII character set, by clearing the high-order bits. +inline int toAscii(int c) +{ +/* return toascii (c); */ + return (c & 0x7f); +} + + +// Warning: +// Many people will be unhappy if you use this function. +// This function will convert accented letters into random +// characters. + +// Converts the letter c to lower case, if possible. +inline int toLowerCase(int c) +{ + return tolower (c); +} + + +// Converts the letter c to upper case, if possible. +inline int toUpperCase(int c) +{ + return toupper (c); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/WInterrupts.c b/hardware/openrov/samd/cores/samd21g18a/WInterrupts.c new file mode 100644 index 0000000..2936452 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WInterrupts.c @@ -0,0 +1,142 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Arduino.h" +#include "wiring_private.h" + +#include + +static voidFuncPtr callbacksInt[EXTERNAL_NUM_INTERRUPTS]; + +/* Configure I/O interrupt sources */ +static void __initialize() +{ + memset(callbacksInt, 0, sizeof(callbacksInt)); + + NVIC_DisableIRQ(EIC_IRQn); + NVIC_ClearPendingIRQ(EIC_IRQn); + NVIC_SetPriority(EIC_IRQn, 0); + NVIC_EnableIRQ(EIC_IRQn); + + // Enable GCLK for IEC (External Interrupt Controller) + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_EIC)); + +/* Shall we do that? + // Do a software reset on EIC + EIC->CTRL.SWRST.bit = 1 ; + while ((EIC->CTRL.SWRST.bit == 1) && (EIC->STATUS.SYNCBUSY.bit == 1)) { } +*/ + + // Enable EIC + EIC->CTRL.bit.ENABLE = 1; + while (EIC->STATUS.bit.SYNCBUSY == 1) { } +} + +/* + * \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs. + * Replaces any previous function that was attached to the interrupt. + */ +void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode) +{ + static int enabled = 0; + uint32_t config; + uint32_t pos; + + EExt_Interrupts in = digitalPinToInterrupt(pin); + if (in == NOT_AN_INTERRUPT || in == EXTERNAL_INT_NMI) + return; + + if (!enabled) { + __initialize(); + enabled = 1; + } + + // Assign pin to EIC + pinPeripheral(pin, PIO_EXTINT); + + // Assign callback to interrupt + callbacksInt[in] = callback; + + // Look for right CONFIG register to be addressed + if (in > EXTERNAL_INT_7) { + config = 1; + } else { + config = 0; + } + + // Configure the interrupt mode + pos = (in - (8 * config)) << 2; + switch (mode) + { + case LOW: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_LOW_Val << pos; + break; + + case HIGH: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_HIGH_Val << pos; + break; + + case CHANGE: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_BOTH_Val << pos; + break; + + case FALLING: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_FALL_Val << pos; + break; + + case RISING: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_RISE_Val << pos; + break; + } + + // Enable the interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << in); +} + +/* + * \brief Turns off the given interrupt. + */ +void detachInterrupt(uint32_t pin) +{ + EExt_Interrupts in = digitalPinToInterrupt(pin); + if (in == NOT_AN_INTERRUPT || in == EXTERNAL_INT_NMI) + return; + + EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT(1 << in); +} + +/* + * External Interrupt Controller NVIC Interrupt Handler + */ +void EIC_Handler(void) +{ + // Test the 16 normal interrupts + for (uint32_t i=EXTERNAL_INT_0; i<=EXTERNAL_INT_15; i++) + { + if ((EIC->INTFLAG.reg & (1 << i)) != 0) + { + // Call the callback function if assigned + if (callbacksInt[i]) { + callbacksInt[i](); + } + + // Clear the interrupt + EIC->INTFLAG.reg = 1 << i; + } + } +} diff --git a/hardware/openrov/samd/cores/samd21g18a/WInterrupts.h b/hardware/openrov/samd/cores/samd21g18a/WInterrupts.h new file mode 100644 index 0000000..5d2b24a --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WInterrupts.h @@ -0,0 +1,54 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_INTERRUPTS_ +#define _WIRING_INTERRUPTS_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// LOW 0 +// HIGH 1 +#define CHANGE 2 +#define FALLING 3 +#define RISING 4 + +#define DEFAULT 1 +#define EXTERNAL 0 + +typedef void (*voidFuncPtr)(void); + +/* + * \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs. + * Replaces any previous function that was attached to the interrupt. + */ +void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode); + +/* + * \brief Turns off the given interrupt. + */ +void detachInterrupt(uint32_t pin); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/WMath.cpp b/hardware/openrov/samd/cores/samd21g18a/WMath.cpp new file mode 100644 index 0000000..55caddd --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WMath.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +extern "C" { + #include "stdlib.h" + #include "stdint.h" +} +#include "WMath.h" + +extern void randomSeed( uint32_t dwSeed ) +{ + if ( dwSeed != 0 ) + { + srand( dwSeed ) ; + } +} + +extern long random( long howbig ) +{ + if ( howbig == 0 ) + { + return 0 ; + } + + return rand() % howbig; +} + +extern long random( long howsmall, long howbig ) +{ + if (howsmall >= howbig) + { + return howsmall; + } + + long diff = howbig - howsmall; + + return random(diff) + howsmall; +} + +extern long map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +extern uint16_t makeWord( uint16_t w ) +{ + return w ; +} + +extern uint16_t makeWord( uint8_t h, uint8_t l ) +{ + return (h << 8) | l ; +} diff --git a/hardware/openrov/samd/cores/samd21g18a/WMath.h b/hardware/openrov/samd/cores/samd21g18a/WMath.h new file mode 100644 index 0000000..1893955 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WMath.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_MATH_ +#define _WIRING_MATH_ + +extern long random( long ) ; +extern long random( long, long ) ; +extern void randomSeed( uint32_t dwSeed ) ; +extern long map( long, long, long, long, long ) ; + +extern uint16_t makeWord( uint16_t w ) ; +extern uint16_t makeWord( uint8_t h, uint8_t l ) ; + +#define word(...) makeWord(__VA_ARGS__) + + +#endif /* _WIRING_MATH_ */ diff --git a/hardware/openrov/samd/cores/samd21g18a/WString.cpp b/hardware/openrov/samd/cores/samd21g18a/WString.cpp new file mode 100644 index 0000000..e1d60f4 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WString.cpp @@ -0,0 +1,747 @@ +/* + WString.cpp - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "WString.h" +#include "itoa.h" +#include "avr/dtostrf.h" + +/*********************************************/ +/* Constructors */ +/*********************************************/ + +String::String(const char *cstr) +{ + init(); + if (cstr) copy(cstr, strlen(cstr)); +} + +String::String(const String &value) +{ + init(); + *this = value; +} + +String::String(const __FlashStringHelper *pstr) +{ + init(); + *this = pstr; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String::String(String &&rval) +{ + init(); + move(rval); +} +String::String(StringSumHelper &&rval) +{ + init(); + move(rval); +} +#endif + +String::String(char c) +{ + init(); + char buf[2]; + buf[0] = c; + buf[1] = 0; + *this = buf; +} + +String::String(unsigned char value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned char)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(int value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(int)]; + itoa(value, buf, base); + *this = buf; +} + +String::String(unsigned int value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned int)]; + utoa(value, buf, base); + *this = buf; +} + +String::String(long value, unsigned char base) +{ + init(); + char buf[2 + 8 * sizeof(long)]; + ltoa(value, buf, base); + *this = buf; +} + +String::String(unsigned long value, unsigned char base) +{ + init(); + char buf[1 + 8 * sizeof(unsigned long)]; + ultoa(value, buf, base); + *this = buf; +} + +String::String(float value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::String(double value, unsigned char decimalPlaces) +{ + init(); + char buf[33]; + *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); +} + +String::~String() +{ + free(buffer); +} + +/*********************************************/ +/* Memory Management */ +/*********************************************/ + +inline void String::init(void) +{ + buffer = NULL; + capacity = 0; + len = 0; +} + +void String::invalidate(void) +{ + if (buffer) free(buffer); + buffer = NULL; + capacity = len = 0; +} + +unsigned char String::reserve(unsigned int size) +{ + if (buffer && capacity >= size) return 1; + if (changeBuffer(size)) { + if (len == 0) buffer[0] = 0; + return 1; + } + return 0; +} + +unsigned char String::changeBuffer(unsigned int maxStrLen) +{ + char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); + if (newbuffer) { + buffer = newbuffer; + capacity = maxStrLen; + return 1; + } + return 0; +} + +/*********************************************/ +/* Copy and Move */ +/*********************************************/ + +String & String::copy(const char *cstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy(buffer, cstr); + return *this; +} + +String & String::copy(const __FlashStringHelper *pstr, unsigned int length) +{ + if (!reserve(length)) { + invalidate(); + return *this; + } + len = length; + strcpy_P(buffer, (PGM_P)pstr); + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +void String::move(String &rhs) +{ + if (buffer) { + if (capacity >= rhs.len) { + strcpy(buffer, rhs.buffer); + len = rhs.len; + rhs.len = 0; + return; + } else { + free(buffer); + } + } + buffer = rhs.buffer; + capacity = rhs.capacity; + len = rhs.len; + rhs.buffer = NULL; + rhs.capacity = 0; + rhs.len = 0; +} +#endif + +String & String::operator = (const String &rhs) +{ + if (this == &rhs) return *this; + + if (rhs.buffer) copy(rhs.buffer, rhs.len); + else invalidate(); + + return *this; +} + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +String & String::operator = (String &&rval) +{ + if (this != &rval) move(rval); + return *this; +} + +String & String::operator = (StringSumHelper &&rval) +{ + if (this != &rval) move(rval); + return *this; +} +#endif + +String & String::operator = (const char *cstr) +{ + if (cstr) copy(cstr, strlen(cstr)); + else invalidate(); + + return *this; +} + +String & String::operator = (const __FlashStringHelper *pstr) +{ + if (pstr) copy(pstr, strlen_P((PGM_P)pstr)); + else invalidate(); + + return *this; +} + +/*********************************************/ +/* concat */ +/*********************************************/ + +unsigned char String::concat(const String &s) +{ + return concat(s.buffer, s.len); +} + +unsigned char String::concat(const char *cstr, unsigned int length) +{ + unsigned int newlen = len + length; + if (!cstr) return 0; + if (length == 0) return 1; + if (!reserve(newlen)) return 0; + strcpy(buffer + len, cstr); + len = newlen; + return 1; +} + +unsigned char String::concat(const char *cstr) +{ + if (!cstr) return 0; + return concat(cstr, strlen(cstr)); +} + +unsigned char String::concat(char c) +{ + char buf[2]; + buf[0] = c; + buf[1] = 0; + return concat(buf, 1); +} + +unsigned char String::concat(unsigned char num) +{ + char buf[1 + 3 * sizeof(unsigned char)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(int num) +{ + char buf[2 + 3 * sizeof(int)]; + itoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned int num) +{ + char buf[1 + 3 * sizeof(unsigned int)]; + utoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(long num) +{ + char buf[2 + 3 * sizeof(long)]; + ltoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(unsigned long num) +{ + char buf[1 + 3 * sizeof(unsigned long)]; + ultoa(num, buf, 10); + return concat(buf, strlen(buf)); +} + +unsigned char String::concat(float num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(double num) +{ + char buf[20]; + char* string = dtostrf(num, 4, 2, buf); + return concat(string, strlen(string)); +} + +unsigned char String::concat(const __FlashStringHelper * str) +{ + if (!str) return 0; + int length = strlen_P((const char *) str); + if (length == 0) return 1; + unsigned int newlen = len + length; + if (!reserve(newlen)) return 0; + strcpy_P(buffer + len, (const char *) str); + len = newlen; + return 1; +} + +/*********************************************/ +/* Concatenate */ +/*********************************************/ + +StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) +{ + StringSumHelper &a = const_cast(lhs); + if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, char c) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(c)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, float num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, double num) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(num)) a.invalidate(); + return a; +} + +StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs) +{ + StringSumHelper &a = const_cast(lhs); + if (!a.concat(rhs)) a.invalidate(); + return a; +} + +/*********************************************/ +/* Comparison */ +/*********************************************/ + +int String::compareTo(const String &s) const +{ + if (!buffer || !s.buffer) { + if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; + if (buffer && len > 0) return *(unsigned char *)buffer; + return 0; + } + return strcmp(buffer, s.buffer); +} + +unsigned char String::equals(const String &s2) const +{ + return (len == s2.len && compareTo(s2) == 0); +} + +unsigned char String::equals(const char *cstr) const +{ + if (len == 0) return (cstr == NULL || *cstr == 0); + if (cstr == NULL) return buffer[0] == 0; + return strcmp(buffer, cstr) == 0; +} + +unsigned char String::operator<(const String &rhs) const +{ + return compareTo(rhs) < 0; +} + +unsigned char String::operator>(const String &rhs) const +{ + return compareTo(rhs) > 0; +} + +unsigned char String::operator<=(const String &rhs) const +{ + return compareTo(rhs) <= 0; +} + +unsigned char String::operator>=(const String &rhs) const +{ + return compareTo(rhs) >= 0; +} + +unsigned char String::equalsIgnoreCase( const String &s2 ) const +{ + if (this == &s2) return 1; + if (len != s2.len) return 0; + if (len == 0) return 1; + const char *p1 = buffer; + const char *p2 = s2.buffer; + while (*p1) { + if (tolower(*p1++) != tolower(*p2++)) return 0; + } + return 1; +} + +unsigned char String::startsWith( const String &s2 ) const +{ + if (len < s2.len) return 0; + return startsWith(s2, 0); +} + +unsigned char String::startsWith( const String &s2, unsigned int offset ) const +{ + if (offset > len - s2.len || !buffer || !s2.buffer) return 0; + return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; +} + +unsigned char String::endsWith( const String &s2 ) const +{ + if ( len < s2.len || !buffer || !s2.buffer) return 0; + return strcmp(&buffer[len - s2.len], s2.buffer) == 0; +} + +/*********************************************/ +/* Character Access */ +/*********************************************/ + +char String::charAt(unsigned int loc) const +{ + return operator[](loc); +} + +void String::setCharAt(unsigned int loc, char c) +{ + if (loc < len) buffer[loc] = c; +} + +char & String::operator[](unsigned int index) +{ + static char dummy_writable_char; + if (index >= len || !buffer) { + dummy_writable_char = 0; + return dummy_writable_char; + } + return buffer[index]; +} + +char String::operator[]( unsigned int index ) const +{ + if (index >= len || !buffer) return 0; + return buffer[index]; +} + +void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const +{ + if (!bufsize || !buf) return; + if (index >= len) { + buf[0] = 0; + return; + } + unsigned int n = bufsize - 1; + if (n > len - index) n = len - index; + strncpy((char *)buf, buffer + index, n); + buf[n] = 0; +} + +/*********************************************/ +/* Search */ +/*********************************************/ + +int String::indexOf(char c) const +{ + return indexOf(c, 0); +} + +int String::indexOf( char ch, unsigned int fromIndex ) const +{ + if (fromIndex >= len) return -1; + const char* temp = strchr(buffer + fromIndex, ch); + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::indexOf(const String &s2) const +{ + return indexOf(s2, 0); +} + +int String::indexOf(const String &s2, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + const char *found = strstr(buffer + fromIndex, s2.buffer); + if (found == NULL) return -1; + return found - buffer; +} + +int String::lastIndexOf( char theChar ) const +{ + return lastIndexOf(theChar, len - 1); +} + +int String::lastIndexOf(char ch, unsigned int fromIndex) const +{ + if (fromIndex >= len) return -1; + char tempchar = buffer[fromIndex + 1]; + buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( buffer, ch ); + buffer[fromIndex + 1] = tempchar; + if (temp == NULL) return -1; + return temp - buffer; +} + +int String::lastIndexOf(const String &s2) const +{ + return lastIndexOf(s2, len - s2.len); +} + +int String::lastIndexOf(const String &s2, unsigned int fromIndex) const +{ + if (s2.len == 0 || len == 0 || s2.len > len) return -1; + if (fromIndex >= len) fromIndex = len - 1; + int found = -1; + for (char *p = buffer; p <= buffer + fromIndex; p++) { + p = strstr(p, s2.buffer); + if (!p) break; + if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; + } + return found; +} + +String String::substring(unsigned int left, unsigned int right) const +{ + if (left > right) { + unsigned int temp = right; + right = left; + left = temp; + } + String out; + if (left >= len) return out; + if (right > len) right = len; + char temp = buffer[right]; // save the replaced character + buffer[right] = '\0'; + out = buffer + left; // pointer arithmetic + buffer[right] = temp; //restore character + return out; +} + +/*********************************************/ +/* Modification */ +/*********************************************/ + +void String::replace(char find, char replace) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + if (*p == find) *p = replace; + } +} + +void String::replace(const String& find, const String& replace) +{ + if (len == 0 || find.len == 0) return; + int diff = replace.len - find.len; + char *readFrom = buffer; + char *foundAt; + if (diff == 0) { + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + memcpy(foundAt, replace.buffer, replace.len); + readFrom = foundAt + replace.len; + } + } else if (diff < 0) { + char *writeTo = buffer; + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + unsigned int n = foundAt - readFrom; + memcpy(writeTo, readFrom, n); + writeTo += n; + memcpy(writeTo, replace.buffer, replace.len); + writeTo += replace.len; + readFrom = foundAt + find.len; + len += diff; + } + strcpy(writeTo, readFrom); + } else { + unsigned int size = len; // compute size needed for result + while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { + readFrom = foundAt + find.len; + size += diff; + } + if (size == len) return; + if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! + int index = len - 1; + while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { + readFrom = buffer + index + find.len; + memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); + len += diff; + buffer[len] = 0; + memcpy(buffer + index, replace.buffer, replace.len); + index--; + } + } +} + +void String::remove(unsigned int index){ + // Pass the biggest integer as the count. The remove method + // below will take care of truncating it at the end of the + // string. + remove(index, (unsigned int)-1); +} + +void String::remove(unsigned int index, unsigned int count){ + if (index >= len) { return; } + if (count <= 0) { return; } + if (count > len - index) { count = len - index; } + char *writeTo = buffer + index; + len = len - count; + strncpy(writeTo, buffer + index + count,len - index); + buffer[len] = 0; +} + +void String::toLowerCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = tolower(*p); + } +} + +void String::toUpperCase(void) +{ + if (!buffer) return; + for (char *p = buffer; *p; p++) { + *p = toupper(*p); + } +} + +void String::trim(void) +{ + if (!buffer || len == 0) return; + char *begin = buffer; + while (isspace(*begin)) begin++; + char *end = buffer + len - 1; + while (isspace(*end) && end >= begin) end--; + len = end + 1 - begin; + if (begin > buffer) memcpy(buffer, begin, len); + buffer[len] = 0; +} + +/*********************************************/ +/* Parsing / Conversion */ +/*********************************************/ + +long String::toInt(void) const +{ + if (buffer) return atol(buffer); + return 0; +} + +float String::toFloat(void) const +{ + if (buffer) return float(atof(buffer)); + return 0; +} diff --git a/hardware/openrov/samd/cores/samd21g18a/WString.h b/hardware/openrov/samd/cores/samd21g18a/WString.h new file mode 100644 index 0000000..b047980 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WString.h @@ -0,0 +1,224 @@ +/* + WString.h - String library for Wiring & Arduino + ...mostly rewritten by Paul Stoffregen... + Copyright (c) 2009-10 Hernando Barragan. All right reserved. + Copyright 2011, Paul Stoffregen, paul@pjrc.com + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef String_class_h +#define String_class_h +#ifdef __cplusplus + +#include +#include +#include +#include + +// When compiling programs with this class, the following gcc parameters +// dramatically increase performance and memory (RAM) efficiency, typically +// with little or no increase in code size. +// -felide-constructors +// -std=c++0x + +class __FlashStringHelper; +#define F(string_literal) (reinterpret_cast(PSTR(string_literal))) + +// An inherited class for holding the result of a concatenation. These +// result objects are assumed to be writable by subsequent concatenations. +class StringSumHelper; + +// The string class +class String +{ + // use a function pointer to allow for "if (s)" without the + // complications of an operator bool(). for more information, see: + // http://www.artima.com/cppsource/safebool.html + typedef void (String::*StringIfHelperType)() const; + void StringIfHelper() const {} + +public: + // constructors + // creates a copy of the initial value. + // if the initial value is null or invalid, or if memory allocation + // fails, the string will be marked as invalid (i.e. "if (s)" will + // be false). + String(const char *cstr = ""); + String(const String &str); + String(const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String(String &&rval); + String(StringSumHelper &&rval); + #endif + explicit String(char c); + explicit String(unsigned char, unsigned char base=10); + explicit String(int, unsigned char base=10); + explicit String(unsigned int, unsigned char base=10); + explicit String(long, unsigned char base=10); + explicit String(unsigned long, unsigned char base=10); + explicit String(float, unsigned char decimalPlaces=2); + explicit String(double, unsigned char decimalPlaces=2); + ~String(void); + + // memory management + // return true on success, false on failure (in which case, the string + // is left unchanged). reserve(0), if successful, will validate an + // invalid string (i.e., "if (s)" will be true afterwards) + unsigned char reserve(unsigned int size); + inline unsigned int length(void) const {return len;} + + // creates a copy of the assigned value. if the value is null or + // invalid, or if the memory allocation fails, the string will be + // marked as invalid ("if (s)" will be false). + String & operator = (const String &rhs); + String & operator = (const char *cstr); + String & operator = (const __FlashStringHelper *str); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + String & operator = (String &&rval); + String & operator = (StringSumHelper &&rval); + #endif + + // concatenate (works w/ built-in types) + + // returns true on success, false on failure (in which case, the string + // is left unchanged). if the argument is null or invalid, the + // concatenation is considered unsucessful. + unsigned char concat(const String &str); + unsigned char concat(const char *cstr); + unsigned char concat(char c); + unsigned char concat(unsigned char c); + unsigned char concat(int num); + unsigned char concat(unsigned int num); + unsigned char concat(long num); + unsigned char concat(unsigned long num); + unsigned char concat(float num); + unsigned char concat(double num); + unsigned char concat(const __FlashStringHelper * str); + + // if there's not enough memory for the concatenated value, the string + // will be left unchanged (but this isn't signalled in any way) + String & operator += (const String &rhs) {concat(rhs); return (*this);} + String & operator += (const char *cstr) {concat(cstr); return (*this);} + String & operator += (char c) {concat(c); return (*this);} + String & operator += (unsigned char num) {concat(num); return (*this);} + String & operator += (int num) {concat(num); return (*this);} + String & operator += (unsigned int num) {concat(num); return (*this);} + String & operator += (long num) {concat(num); return (*this);} + String & operator += (unsigned long num) {concat(num); return (*this);} + String & operator += (float num) {concat(num); return (*this);} + String & operator += (double num) {concat(num); return (*this);} + String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} + + friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); + friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); + friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); + + // comparison (only works w/ Strings and "strings") + operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } + int compareTo(const String &s) const; + unsigned char equals(const String &s) const; + unsigned char equals(const char *cstr) const; + unsigned char operator == (const String &rhs) const {return equals(rhs);} + unsigned char operator == (const char *cstr) const {return equals(cstr);} + unsigned char operator != (const String &rhs) const {return !equals(rhs);} + unsigned char operator != (const char *cstr) const {return !equals(cstr);} + unsigned char operator < (const String &rhs) const; + unsigned char operator > (const String &rhs) const; + unsigned char operator <= (const String &rhs) const; + unsigned char operator >= (const String &rhs) const; + unsigned char equalsIgnoreCase(const String &s) const; + unsigned char startsWith( const String &prefix) const; + unsigned char startsWith(const String &prefix, unsigned int offset) const; + unsigned char endsWith(const String &suffix) const; + + // character acccess + char charAt(unsigned int index) const; + void setCharAt(unsigned int index, char c); + char operator [] (unsigned int index) const; + char& operator [] (unsigned int index); + void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; + void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const + {getBytes((unsigned char *)buf, bufsize, index);} + const char * c_str() const { return buffer; } + + // search + int indexOf( char ch ) const; + int indexOf( char ch, unsigned int fromIndex ) const; + int indexOf( const String &str ) const; + int indexOf( const String &str, unsigned int fromIndex ) const; + int lastIndexOf( char ch ) const; + int lastIndexOf( char ch, unsigned int fromIndex ) const; + int lastIndexOf( const String &str ) const; + int lastIndexOf( const String &str, unsigned int fromIndex ) const; + String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; + String substring( unsigned int beginIndex, unsigned int endIndex ) const; + + // modification + void replace(char find, char replace); + void replace(const String& find, const String& replace); + void remove(unsigned int index); + void remove(unsigned int index, unsigned int count); + void toLowerCase(void); + void toUpperCase(void); + void trim(void); + + // parsing/conversion + long toInt(void) const; + float toFloat(void) const; + +protected: + char *buffer; // the actual char array + unsigned int capacity; // the array length minus one (for the '\0') + unsigned int len; // the String length (not counting the '\0') +protected: + void init(void); + void invalidate(void); + unsigned char changeBuffer(unsigned int maxStrLen); + unsigned char concat(const char *cstr, unsigned int length); + + // copy and move + String & copy(const char *cstr, unsigned int length); + String & copy(const __FlashStringHelper *pstr, unsigned int length); + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) + void move(String &rhs); + #endif +}; + +class StringSumHelper : public String +{ +public: + StringSumHelper(const String &s) : String(s) {} + StringSumHelper(const char *p) : String(p) {} + StringSumHelper(char c) : String(c) {} + StringSumHelper(unsigned char num) : String(num) {} + StringSumHelper(int num) : String(num) {} + StringSumHelper(unsigned int num) : String(num) {} + StringSumHelper(long num) : String(num) {} + StringSumHelper(unsigned long num) : String(num) {} + StringSumHelper(float num) : String(num) {} + StringSumHelper(double num) : String(num) {} +}; + +#endif // __cplusplus +#endif // String_class_h diff --git a/hardware/openrov/samd/cores/samd21g18a/WVariant.h b/hardware/openrov/samd/cores/samd21g18a/WVariant.h new file mode 100644 index 0000000..8eaf610 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/WVariant.h @@ -0,0 +1,257 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include "sam.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Definitions and types for pins */ +typedef enum _EAnalogChannel +{ + No_ADC_Channel=-1, + ADC_Channel0=0, + ADC_Channel1=1, + ADC_Channel2=2, + ADC_Channel3=3, + ADC_Channel4=4, + ADC_Channel5=5, + ADC_Channel6=6, + ADC_Channel7=7, +#if defined __SAMD21J18A__ + ADC_Channel8=8, + ADC_Channel9=9, +#endif // __SAMD21J18A__ + ADC_Channel10=10, + ADC_Channel11=11, +#if defined __SAMD21J18A__ + ADC_Channel12=12, + ADC_Channel13=13, + ADC_Channel14=14, + ADC_Channel15=15, +#endif // __SAMD21J18A__ + ADC_Channel16=16, + ADC_Channel17=17, + ADC_Channel18=18, + ADC_Channel19=19, + DAC_Channel0, +} EAnalogChannel ; + +// Definitions for TC channels +typedef enum _ETCChannel +{ + NOT_ON_TIMER=-1, + TCC0_CH0 = (0<<8)|(0), + TCC0_CH1 = (0<<8)|(1), + TCC0_CH2 = (0<<8)|(2), + TCC0_CH3 = (0<<8)|(3), + TCC0_CH4 = (0<<8)|(0), // Channel 4 is 0! + TCC0_CH5 = (0<<8)|(1), // Channel 5 is 1! + TCC0_CH6 = (0<<8)|(2), // Channel 6 is 2! + TCC0_CH7 = (0<<8)|(3), // Channel 7 is 3! + TCC1_CH0 = (1<<8)|(0), + TCC1_CH1 = (1<<8)|(1), + TCC1_CH2 = (1<<8)|(0), // Channel 2 is 0! + TCC1_CH3 = (1<<8)|(1), // Channel 3 is 1! + TCC2_CH0 = (2<<8)|(0), + TCC2_CH1 = (2<<8)|(1), + TCC2_CH2 = (2<<8)|(0), // Channel 2 is 0! + TCC2_CH3 = (2<<8)|(1), // Channel 3 is 1! + TC3_CH0 = (3<<8)|(0), + TC3_CH1 = (3<<8)|(1), + TC4_CH0 = (4<<8)|(0), + TC4_CH1 = (4<<8)|(1), + TC5_CH0 = (5<<8)|(0), + TC5_CH1 = (5<<8)|(1), +#if defined __SAMD21J18A__ + TC6_CH0 = (6<<8)|(0), + TC6_CH1 = (6<<8)|(1), + TC7_CH0 = (7<<8)|(0), + TC7_CH1 = (7<<8)|(1), +#endif // __SAMD21J18A__ +} ETCChannel ; + +extern const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM] ; + +#define GetTCNumber( x ) ( (x) >> 8 ) +#define GetTCChannelNumber( x ) ( (x) & 0xff ) +#define GetTC( x ) ( g_apTCInstances[(x) >> 8] ) + +// Definitions for PWM channels +typedef enum _EPWMChannel +{ + NOT_ON_PWM=-1, + PWM0_CH0=TCC0_CH0, + PWM0_CH1=TCC0_CH1, + PWM0_CH2=TCC0_CH2, + PWM0_CH3=TCC0_CH3, + PWM0_CH4=TCC0_CH4, + PWM0_CH5=TCC0_CH5, + PWM0_CH6=TCC0_CH6, + PWM0_CH7=TCC0_CH7, + PWM1_CH0=TCC1_CH0, + PWM1_CH1=TCC1_CH1, + PWM1_CH2=TCC1_CH2, + PWM1_CH3=TCC1_CH3, + PWM2_CH0=TCC2_CH0, + PWM2_CH1=TCC2_CH1, + PWM2_CH2=TCC2_CH2, + PWM2_CH3=TCC2_CH3, + PWM3_CH0=TC3_CH0, + PWM3_CH1=TC3_CH1, + PWM4_CH0=TC4_CH0, + PWM4_CH1=TC4_CH1, + PWM5_CH0=TC5_CH0, + PWM5_CH1=TC5_CH1, +#if defined __SAMD21J18A__ + PWM6_CH0=TC6_CH0, + PWM6_CH1=TC6_CH1, + PWM7_CH0=TC7_CH0, + PWM7_CH1=TC7_CH1, +#endif // __SAMD21J18A__ +} EPWMChannel ; + +typedef enum _EPortType +{ + NOT_A_PORT=-1, + PORTA=0, + PORTB=1, + PORTC=2, +} EPortType ; + +typedef enum +{ + EXTERNAL_INT_0 = 0, + EXTERNAL_INT_1, + EXTERNAL_INT_2, + EXTERNAL_INT_3, + EXTERNAL_INT_4, + EXTERNAL_INT_5, + EXTERNAL_INT_6, + EXTERNAL_INT_7, + EXTERNAL_INT_8, + EXTERNAL_INT_9, + EXTERNAL_INT_10, + EXTERNAL_INT_11, + EXTERNAL_INT_12, + EXTERNAL_INT_13, + EXTERNAL_INT_14, + EXTERNAL_INT_15, + EXTERNAL_INT_NMI, + EXTERNAL_NUM_INTERRUPTS, + NOT_AN_INTERRUPT = -1, + EXTERNAL_INT_NONE = NOT_AN_INTERRUPT, +} EExt_Interrupts ; + +//A B C D E F G H +//EIC REF ADC AC PTC DAC SERCOM SERCOM_ALT TC/TCC TCC COM AC/GCLK + +typedef enum _EPioType +{ + PIO_NOT_A_PIN=-1, /* Not under control of a peripheral. */ + PIO_EXTINT=0, /* The pin is controlled by the associated signal of peripheral A. */ + PIO_ANALOG, /* The pin is controlled by the associated signal of peripheral B. */ + PIO_SERCOM, /* The pin is controlled by the associated signal of peripheral C. */ + PIO_SERCOM_ALT, /* The pin is controlled by the associated signal of peripheral D. */ + PIO_TIMER, /* The pin is controlled by the associated signal of peripheral E. */ + PIO_TIMER_ALT, /* The pin is controlled by the associated signal of peripheral F. */ + PIO_COM, /* The pin is controlled by the associated signal of peripheral G. */ + PIO_AC_CLK, /* The pin is controlled by the associated signal of peripheral H. */ + PIO_DIGITAL, /* The pin is controlled by PORT. */ + PIO_INPUT, /* The pin is controlled by PORT and is an input. */ + PIO_INPUT_PULLUP, /* The pin is controlled by PORT and is an input with internal pull-up resistor enabled. */ + PIO_OUTPUT, /* The pin is controlled by PORT and is an output. */ + + PIO_PWM=PIO_TIMER, + PIO_PWM_ALT=PIO_TIMER_ALT, +} EPioType ; + +/** + * Pin Attributes to be OR-ed + */ +#define PIN_ATTR_NONE (0UL<<0) +#define PIN_ATTR_COMBO (1UL<<0) +#define PIN_ATTR_ANALOG (1UL<<1) +#define PIN_ATTR_DIGITAL (1UL<<2) +#define PIN_ATTR_PWM (1UL<<3) +#define PIN_ATTR_TIMER (1UL<<4) +#define PIN_ATTR_TIMER_ALT (1UL<<5) +#define PIN_ATTR_EXTINT (1UL<<6) + +/* Types used for the table below */ +typedef struct _PinDescription +{ + EPortType ulPort ; + uint32_t ulPin ; + EPioType ulPinType ; + uint32_t ulPinAttribute ; + EAnalogChannel ulADCChannelNumber ; /* ADC Channel number in the SAM device */ + EPWMChannel ulPWMChannel ; + ETCChannel ulTCChannel ; + EExt_Interrupts ulExtInt ; +} PinDescription ; + +/* Pins table to be instantiated into variant.cpp */ +extern const PinDescription g_APinDescription[] ; + +/* Generic Clock Multiplexer IDs */ +#define GCM_DFLL48M_REF (0x00U) +#define GCM_FDPLL96M_INPUT (0x01U) +#define GCM_FDPLL96M_32K (0x02U) +#define GCM_WDT (0x03U) +#define GCM_RTC (0x04U) +#define GCM_EIC (0x05U) +#define GCM_USB (0x06U) +#define GCM_EVSYS_CHANNEL_0 (0x07U) +#define GCM_EVSYS_CHANNEL_1 (0x08U) +#define GCM_EVSYS_CHANNEL_2 (0x09U) +#define GCM_EVSYS_CHANNEL_3 (0x0AU) +#define GCM_EVSYS_CHANNEL_4 (0x0BU) +#define GCM_EVSYS_CHANNEL_5 (0x0CU) +#define GCM_EVSYS_CHANNEL_6 (0x0DU) +#define GCM_EVSYS_CHANNEL_7 (0x0EU) +#define GCM_EVSYS_CHANNEL_8 (0x0FU) +#define GCM_EVSYS_CHANNEL_9 (0x10U) +#define GCM_EVSYS_CHANNEL_10 (0x11U) +#define GCM_EVSYS_CHANNEL_11 (0x12U) +#define GCM_SERCOMx_SLOW (0x13U) +#define GCM_SERCOM0_CORE (0x14U) +#define GCM_SERCOM1_CORE (0x15U) +#define GCM_SERCOM2_CORE (0x16U) +#define GCM_SERCOM3_CORE (0x17U) +#define GCM_SERCOM4_CORE (0x18U) +#define GCM_SERCOM5_CORE (0x19U) +#define GCM_TCC0_TCC1 (0x1AU) +#define GCM_TCC2_TC3 (0x1BU) +#define GCM_TC4_TC5 (0x1CU) +#define GCM_TC6_TC7 (0x1DU) +#define GCM_ADC (0x1EU) +#define GCM_AC_DIG (0x1FU) +#define GCM_AC_ANA (0x20U) +#define GCM_DAC (0x21U) +#define GCM_PTC (0x22U) +#define GCM_I2S_0 (0x23U) +#define GCM_I2S_1 (0x24U) + +#ifdef __cplusplus +} // extern "C" +#endif \ No newline at end of file diff --git a/hardware/openrov/samd/cores/samd21g18a/abi.cpp b/hardware/openrov/samd/cores/samd21g18a/abi.cpp new file mode 100644 index 0000000..bd2f43a --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/abi.cpp @@ -0,0 +1,37 @@ +/* + Copyright (c) 2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); +extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); + +void __cxa_pure_virtual(void) { + // We might want to write some diagnostics to uart in this case + //std::terminate(); + while (1) + ; +} + +void __cxa_deleted_virtual(void) { + // We might want to write some diagnostics to uart in this case + //std::terminate(); + while (1) + ; +} + diff --git a/hardware/openrov/samd/cores/samd21g18a/avr/dtostrf.c b/hardware/openrov/samd/cores/samd21g18a/avr/dtostrf.c new file mode 100644 index 0000000..259caa5 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/avr/dtostrf.c @@ -0,0 +1,28 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2015 Arduino LLC. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { + char fmt[20]; + sprintf(fmt, "%%%d.%df", width, prec); + sprintf(sout, fmt, val); + return sout; +} + diff --git a/hardware/openrov/samd/cores/samd21g18a/avr/dtostrf.h b/hardware/openrov/samd/cores/samd21g18a/avr/dtostrf.h new file mode 100644 index 0000000..762a886 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/avr/dtostrf.h @@ -0,0 +1,30 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2015 Arduino LLC. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +char *dtostrf(double val, signed char width, unsigned char prec, char *sout); + +#ifdef __cplusplus +} +#endif diff --git a/hardware/openrov/samd/variants/trident_alpha/pins_arduino.h b/hardware/openrov/samd/cores/samd21g18a/avr/interrupt.h similarity index 80% rename from hardware/openrov/samd/variants/trident_alpha/pins_arduino.h rename to hardware/openrov/samd/cores/samd21g18a/avr/interrupt.h index db0e40c..950509d 100644 --- a/hardware/openrov/samd/variants/trident_alpha/pins_arduino.h +++ b/hardware/openrov/samd/cores/samd21g18a/avr/interrupt.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Arduino LCC. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,6 +16,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// API compatibility -#include "variant.h" - +/* + Empty file. + This file is here to allow compatibility with sketches (made for AVR) + that includes +*/ diff --git a/hardware/openrov/samd/cores/samd21g18a/avr/pgmspace.h b/hardware/openrov/samd/cores/samd21g18a/avr/pgmspace.h new file mode 100644 index 0000000..68ff497 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/avr/pgmspace.h @@ -0,0 +1,121 @@ +/* + pgmspace.h - Definitions for compatibility with AVR pgmspace macros + + Copyright (c) 2015 Arduino LLC + + Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE +*/ + +#ifndef __PGMSPACE_H_ +#define __PGMSPACE_H_ 1 + +#include + +#define PROGMEM +#define PGM_P const char * +#define PSTR(str) (str) + +#define _SFR_BYTE(n) (n) + +typedef void prog_void; +typedef char prog_char; +typedef unsigned char prog_uchar; +typedef int8_t prog_int8_t; +typedef uint8_t prog_uint8_t; +typedef int16_t prog_int16_t; +typedef uint16_t prog_uint16_t; +typedef int32_t prog_int32_t; +typedef uint32_t prog_uint32_t; +typedef int32_t prog_int64_t; +typedef uint32_t prog_uint64_t; + +typedef const void* int_farptr_t; +typedef const void* uint_farptr_t; + +#define memchr_P(s, c, n) memchr((s), (c), (n)) +#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n)) +#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n)) +#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) +#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen)) +#define memrchr_P(s, c, n) memrchr((s), (c), (n)) +#define strcat_P(dest, src) strcat((dest), (src)) +#define strchr_P(s, c) strchr((s), (c)) +#define strchrnul_P(s, c) strchrnul((s), (c)) +#define strcmp_P(a, b) strcmp((a), (b)) +#define strcpy_P(dest, src) strcpy((dest), (src)) +#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2)) +#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle)) +#define strcspn_P(s, accept) strcspn((s), (accept)) +#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n)) +#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n)) +#define strlen_P(a) strlen((a)) +#define strnlen_P(s, n) strnlen((s), (n)) +#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n)) +#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n)) +#define strncat_P(s1, s2, n) strncat((s1), (s2), (n)) +#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n)) +#define strpbrk_P(s, accept) strpbrk((s), (accept)) +#define strrchr_P(s, c) strrchr((s), (c)) +#define strsep_P(sp, delim) strsep((sp), (delim)) +#define strspn_P(s, accept) strspn((s), (accept)) +#define strstr_P(a, b) strstr((a), (b)) +#define strtok_P(s, delim) strtok((s), (delim)) +#define strtok_rP(s, delim, last) strtok((s), (delim), (last)) + +#define strlen_PF(a) strlen((a)) +#define strnlen_PF(src, len) strnlen((src), (len)) +#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len)) +#define strcpy_PF(dest, src) strcpy((dest), (src)) +#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len)) +#define strcat_PF(dest, src) strcat((dest), (src)) +#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len)) +#define strncat_PF(dest, src, len) strncat((dest), (src), (len)) +#define strcmp_PF(s1, s2) strcmp((s1), (s2)) +#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n)) +#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2)) +#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n)) +#define strstr_PF(s1, s2) strstr((s1), (s2)) +#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n)) +#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n)) + +#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__) + +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned short *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_float(addr) (*(const float *)(addr)) +#define pgm_read_ptr(addr) (*(const void *)(addr)) + +#define pgm_read_byte_near(addr) pgm_read_byte(addr) +#define pgm_read_word_near(addr) pgm_read_word(addr) +#define pgm_read_dword_near(addr) pgm_read_dword(addr) +#define pgm_read_float_near(addr) pgm_read_float(addr) +#define pgm_read_ptr_near(addr) pgm_read_ptr(addr) + +#define pgm_read_byte_far(addr) pgm_read_byte(addr) +#define pgm_read_word_far(addr) pgm_read_word(addr) +#define pgm_read_dword_far(addr) pgm_read_dword(addr) +#define pgm_read_float_far(addr) pgm_read_float(addr) +#define pgm_read_ptr_far(addr) pgm_read_ptr(addr) + +#define pgm_get_far_address(addr) (&(addr)) + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/binary.h b/hardware/openrov/samd/cores/samd21g18a/binary.h new file mode 100644 index 0000000..aec4c73 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/binary.h @@ -0,0 +1,534 @@ +/* + binary.h - Definitions for binary constants + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/cortex_handlers.c b/hardware/openrov/samd/cores/samd21g18a/cortex_handlers.c new file mode 100644 index 0000000..11dad4d --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/cortex_handlers.c @@ -0,0 +1,178 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include + +/* RTOS Hooks */ +extern void svcHook(void); +extern void pendSVHook(void); +extern int sysTickHook(void); + +/* Default empty handler */ +void Dummy_Handler(void) +{ +#if defined DEBUG + __BKPT(3); +#endif + for (;;) { } +} + +/* Cortex-M0+ core handlers */ +void HardFault_Handler(void) __attribute__ ((weak, alias("Dummy_Handler"))); +void Reset_Handler (void); +void NMI_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SVC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void PendSV_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SysTick_Handler (void); + +/* Peripherals handlers */ +void PM_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SYSCTRL_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void WDT_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void RTC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void NVMCTRL_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void USB_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM3_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM4_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM5_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC1_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC2_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC3_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC4_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC5_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC6_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC7_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void ADC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void AC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void DAC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void PTC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); +void I2S_Handler (void) __attribute__ ((weak, alias("Dummy_Handler"))); + +/* Initialize segments */ +extern uint32_t __etext; +extern uint32_t __data_start__; +extern uint32_t __data_end__; +extern uint32_t __bss_start__; +extern uint32_t __bss_end__; +extern uint32_t __StackTop; + +/* Exception Table */ +__attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table = +{ + /* Configure Initial Stack Pointer, using linker-generated symbols */ + (void*) (&__StackTop), + + (void*) Reset_Handler, + (void*) NMI_Handler, + (void*) HardFault_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) SVC_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) PendSV_Handler, + (void*) SysTick_Handler, + + /* Configurable interrupts */ + (void*) PM_Handler, /* 0 Power Manager */ + (void*) SYSCTRL_Handler, /* 1 System Control */ + (void*) WDT_Handler, /* 2 Watchdog Timer */ + (void*) RTC_Handler, /* 3 Real-Time Counter */ + (void*) EIC_Handler, /* 4 External Interrupt Controller */ + (void*) NVMCTRL_Handler, /* 5 Non-Volatile Memory Controller */ + (void*) DMAC_Handler, /* 6 Direct Memory Access Controller */ + (void*) USB_Handler, /* 7 Universal Serial Bus */ + (void*) EVSYS_Handler, /* 8 Event System Interface */ + (void*) SERCOM0_Handler, /* 9 Serial Communication Interface 0 */ + (void*) SERCOM1_Handler, /* 10 Serial Communication Interface 1 */ + (void*) SERCOM2_Handler, /* 11 Serial Communication Interface 2 */ + (void*) SERCOM3_Handler, /* 12 Serial Communication Interface 3 */ + (void*) SERCOM4_Handler, /* 13 Serial Communication Interface 4 */ + (void*) SERCOM5_Handler, /* 14 Serial Communication Interface 5 */ + (void*) TCC0_Handler, /* 15 Timer Counter Control 0 */ + (void*) TCC1_Handler, /* 16 Timer Counter Control 1 */ + (void*) TCC2_Handler, /* 17 Timer Counter Control 2 */ + (void*) TC3_Handler, /* 18 Basic Timer Counter 0 */ + (void*) TC4_Handler, /* 19 Basic Timer Counter 1 */ + (void*) TC5_Handler, /* 20 Basic Timer Counter 2 */ + (void*) TC6_Handler, /* 21 Basic Timer Counter 3 */ + (void*) TC7_Handler, /* 22 Basic Timer Counter 4 */ + (void*) ADC_Handler, /* 23 Analog Digital Converter */ + (void*) AC_Handler, /* 24 Analog Comparators */ + (void*) DAC_Handler, /* 25 Digital Analog Converter */ + (void*) PTC_Handler, /* 26 Peripheral Touch Controller */ + (void*) I2S_Handler /* 27 Inter-IC Sound Interface */ +}; + +extern int main(void); +extern void __libc_init_array(void); + +/* This is called on processor reset to initialize the device and call main() */ +void Reset_Handler(void) +{ + uint32_t *pSrc, *pDest; + + /* Initialize the initialized data section */ + pSrc = &__etext; + pDest = &__data_start__; + + if ((&__data_start__ != &__data_end__) && (pSrc != pDest)) { + for (; pDest < &__data_end__; pDest++, pSrc++) + *pDest = *pSrc; + } + + /* Clear the zero section */ + if ((&__data_start__ != &__data_end__) && (pSrc != pDest)) { + for (pDest = &__bss_start__; pDest < &__bss_end__; pDest++) + *pDest = 0; + } + + /* Initialize the C library */ + __libc_init_array(); + + SystemInit(); + + main(); + + while (1) + ; +} + +/* Default Arduino systick handler */ +extern void SysTick_DefaultHandler(void); + +void SysTick_Handler(void) +{ + if (sysTickHook()) + return; + SysTick_DefaultHandler(); +} diff --git a/hardware/openrov/samd/cores/samd21g18a/delay.c b/hardware/openrov/samd/cores/samd21g18a/delay.c new file mode 100644 index 0000000..ea000ab --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/delay.c @@ -0,0 +1,90 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "delay.h" +#include "Arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Tick Counter united by ms */ +static volatile uint32_t _ulTickCount=0 ; + +uint32_t millis( void ) +{ +// todo: ensure no interrupts + return _ulTickCount ; +} + +// Interrupt-compatible version of micros +// Theory: repeatedly take readings of SysTick counter, millis counter and SysTick interrupt pending flag. +// When it appears that millis counter and pending is stable and SysTick hasn't rolled over, use these +// values to calculate micros. If there is a pending SysTick, add one to the millis counter in the calculation. +uint32_t micros( void ) +{ + uint32_t ticks, ticks2; + uint32_t pend, pend2; + uint32_t count, count2; + + ticks2 = SysTick->VAL; + pend2 = !!(SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) ; + count2 = _ulTickCount ; + + do + { + ticks=ticks2; + pend=pend2; + count=count2; + ticks2 = SysTick->VAL; + pend2 = !!(SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) ; + count2 = _ulTickCount ; + } while ((pend != pend2) || (count != count2) || (ticks < ticks2)); + + return ((count+pend) * 1000) + (((SysTick->LOAD - ticks)*(1048576/(VARIANT_MCK/1000000)))>>20) ; + // this is an optimization to turn a runtime division into two compile-time divisions and + // a runtime multiplication and shift, saving a few cycles +} + +void delay( uint32_t ms ) +{ + if ( ms == 0 ) + { + return ; + } + + uint32_t start = _ulTickCount ; + + do + { + yield() ; + } while ( _ulTickCount - start < ms ) ; +} + +#include "Reset.h" // for tickReset() + +void SysTick_DefaultHandler(void) +{ + // Increment tick count each ms + _ulTickCount++; + tickReset(); +} + +#ifdef __cplusplus +} +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/delay.h b/hardware/openrov/samd/cores/samd21g18a/delay.h new file mode 100644 index 0000000..1df845b --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/delay.h @@ -0,0 +1,104 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _DELAY_ +#define _DELAY_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "variant.h" + +/** + * \brief Returns the number of milliseconds since the Arduino board began running the current program. + * + * This number will overflow (go back to zero), after approximately 50 days. + * + * \return Number of milliseconds since the program started (uint32_t) + */ +extern uint32_t millis( void ) ; + +/** + * \brief Returns the number of microseconds since the Arduino board began running the current program. + * + * This number will overflow (go back to zero), after approximately 70 minutes. On 16 MHz Arduino boards + * (e.g. Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is + * always a multiple of four). On 8 MHz Arduino boards (e.g. the LilyPad), this function has a resolution + * of eight microseconds. + * + * \note There are 1,000 microseconds in a millisecond and 1,000,000 microseconds in a second. + */ +extern uint32_t micros( void ) ; + +/** + * \brief Pauses the program for the amount of time (in miliseconds) specified as parameter. + * (There are 1000 milliseconds in a second.) + * + * \param dwMs the number of milliseconds to pause (uint32_t) + */ +extern void delay( uint32_t dwMs ) ; + +/** + * \brief Pauses the program for the amount of time (in microseconds) specified as parameter. + * + * \param dwUs the number of microseconds to pause (uint32_t) + */ +static __inline__ void delayMicroseconds( uint32_t ) __attribute__((always_inline, unused)) ; +static __inline__ void delayMicroseconds( uint32_t usec ) +{ + if ( usec == 0 ) + { + return ; + } + + /* + * The following loop: + * + * for (; ul; ul--) { + * __asm__ volatile(""); + * } + * + * produce the following assembly code: + * + * loop: + * subs r3, #1 // 1 Core cycle + * bne.n loop // 1 Core cycle + 1 if branch is taken + */ + + // VARIANT_MCK / 1000000 == cycles needed to delay 1uS + // 3 == cycles used in a loop + uint32_t n = usec * (VARIANT_MCK / 1000000) / 3; + __asm__ __volatile__( + "1: \n" + " sub %0, #1 \n" // substract 1 from %0 (n) + " bne 1b \n" // if result is not 0 jump to 1 + : "+r" (n) // '%0' is n variable with RW constraints + : // no input + : // no clobber + ); + // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html + // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile +} + +#ifdef __cplusplus +} +#endif + +#endif /* _DELAY_ */ diff --git a/hardware/openrov/samd/cores/samd21g18a/hooks.c b/hardware/openrov/samd/cores/samd21g18a/hooks.c new file mode 100644 index 0000000..f87c204 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/hooks.c @@ -0,0 +1,58 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + * Empty yield() hook. + * + * This function is intended to be used by library writers to build + * libraries or sketches that supports cooperative threads. + * + * Its defined as a weak symbol and it can be redefined to implement a + * real cooperative scheduler. + */ +static void __empty() { + // Empty +} +void yield(void) __attribute__ ((weak, alias("__empty"))); + +/** + * SysTick hook + * + * This function is called from SysTick handler, before the default + * handler provided by Arduino. + */ +static int __false() { + // Return false + return 0; +} +int sysTickHook(void) __attribute__ ((weak, alias("__false"))); + +/** + * SVC hook + * PendSV hook + * + * These functions are called from SVC handler, and PensSV handler. + * Default action is halting. + */ +static void __halt() { + // Halts + while (1) + ; +} +void svcHook(void) __attribute__ ((weak, alias("__halt"))); +void pendSVHook(void) __attribute__ ((weak, alias("__halt"))); diff --git a/hardware/openrov/samd/cores/samd21g18a/itoa.c b/hardware/openrov/samd/cores/samd21g18a/itoa.c new file mode 100644 index 0000000..55a80e7 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/itoa.c @@ -0,0 +1,170 @@ +/* + Copyright (c) 2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "itoa.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* reverse: reverse string s in place */ +/* +static void reverse( char s[] ) +{ + int i, j ; + char c ; + + for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- ) + { + c = s[i] ; + s[i] = s[j] ; + s[j] = c ; + } +} +*/ + +/* itoa: convert n to characters in s */ +/* +extern void itoa( int n, char s[] ) +{ + int i, sign ; + + if ( (sign = n) < 0 ) // record sign + { + n = -n; // make n positive + } + + i = 0; + do + { // generate digits in reverse order + s[i++] = n % 10 + '0'; // get next digit + } while ((n /= 10) > 0) ; // delete it + + if (sign < 0 ) + { + s[i++] = '-'; + } + + s[i] = '\0'; + + reverse( s ) ; +} +*/ + +extern char* itoa( int value, char *string, int radix ) +{ + return ltoa( value, string, radix ) ; +} + +extern char* ltoa( long value, char *string, int radix ) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v; + int sign; + char *sp; + + if ( string == NULL ) + { + return 0 ; + } + + if (radix > 36 || radix <= 1) + { + return 0 ; + } + + sign = (radix == 10 && value < 0); + if (sign) + { + v = -value; + } + else + { + v = (unsigned long)value; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + if (sign) + *sp++ = '-'; + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} + +extern char* utoa( unsigned long value, char *string, int radix ) +{ + return ultoa( value, string, radix ) ; +} + +extern char* ultoa( unsigned long value, char *string, int radix ) +{ + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v = value; + char *sp; + + if ( string == NULL ) + { + return 0; + } + + if (radix > 36 || radix <= 1) + { + return 0; + } + + while (v || tp == tmp) + { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i+'0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/itoa.h b/hardware/openrov/samd/cores/samd21g18a/itoa.h new file mode 100644 index 0000000..9e4f48d --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/itoa.h @@ -0,0 +1,35 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#ifdef __cplusplus +extern "C"{ +#endif + +//extern void itoa( int n, char s[] ) ; + +extern char* itoa( int value, char *string, int radix ) ; +extern char* ltoa( long value, char *string, int radix ) ; +extern char* utoa( unsigned long value, char *string, int radix ) ; +extern char* ultoa( unsigned long value, char *string, int radix ) ; + +#ifdef __cplusplus +} // extern "C" +#endif + diff --git a/hardware/openrov/samd/cores/samd21g18a/main.cpp b/hardware/openrov/samd/cores/samd21g18a/main.cpp new file mode 100644 index 0000000..8a5dcb0 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/main.cpp @@ -0,0 +1,48 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#define ARDUINO_MAIN + +#include "Arduino.h" + +// Weak empty variant initialization function. +// May be redefined by variant files. +void initVariant() __attribute__((weak)); +void initVariant() { } + +/* + * \brief Main entry point of Arduino application + */ +int main( void ) +{ + init(); + + initVariant(); + + delay(1); + + setup(); + + for (;;) + { + loop(); + if (serialEventRun) serialEventRun(); + } + + return 0; +} diff --git a/hardware/openrov/samd/cores/samd21g18a/new.cpp b/hardware/openrov/samd/cores/samd21g18a/new.cpp new file mode 100644 index 0000000..f189775 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/new.cpp @@ -0,0 +1,36 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +void *operator new(size_t size) { + return malloc(size); +} + +void *operator new[](size_t size) { + return malloc(size); +} + +void operator delete(void * ptr) { + free(ptr); +} + +void operator delete[](void * ptr) { + free(ptr); +} + diff --git a/hardware/openrov/samd/cores/samd21g18a/pulse.c b/hardware/openrov/samd/cores/samd21g18a/pulse.c new file mode 100644 index 0000000..2dd03bf --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/pulse.c @@ -0,0 +1,52 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +// See pulse_asm.S +extern unsigned long countPulseASM(const volatile uint32_t *port, uint32_t bit, uint32_t stateMask, unsigned long maxloops); + +/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH + * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds + * to 3 minutes in length, but must be called at least a few dozen microseconds + * before the start of the pulse. */ +uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout) +{ + // cache the port and bit of the pin in order to speed up the + // pulse width measuring loop and achieve finer resolution. calling + // digitalRead() instead yields much coarser resolution. + PinDescription p = g_APinDescription[pin]; + uint32_t bit = 1 << p.ulPin; + uint32_t stateMask = state ? bit : 0; + + // convert the timeout from microseconds to a number of times through + // the initial loop; it takes (roughly) 13 clock cycles per iteration. + uint32_t maxloops = microsecondsToClockCycles(timeout) / 13; + + uint32_t width = countPulseASM(&(PORT->Group[p.ulPort].IN.reg), bit, stateMask, maxloops); + + // convert the reading to microseconds. The loop has been determined + // to be 13 clock cycles long and have about 16 clocks between the edge + // and the start of the loop. There will be some error introduced by + // the interrupt handlers. + if (width) + return clockCyclesToMicroseconds(width * 13 + 16); + else + return 0; +} + diff --git a/hardware/openrov/samd/cores/samd21g18a/pulse.h b/hardware/openrov/samd/cores/samd21g18a/pulse.h new file mode 100644 index 0000000..9c620f1 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/pulse.h @@ -0,0 +1,39 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * \brief Measures the length (in microseconds) of a pulse on the pin; state is HIGH + * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds + * to 3 minutes in length, but must be called at least a few dozen microseconds + * before the start of the pulse. + */ +uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout); + +#ifdef __cplusplus +// Provides a version of pulseIn with a default argument (C++ only) +uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout = 1000000L); + +} // extern "C" +#endif + diff --git a/hardware/openrov/samd/cores/samd21g18a/pulse_asm.S b/hardware/openrov/samd/cores/samd21g18a/pulse_asm.S new file mode 100644 index 0000000..7b94f15 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/pulse_asm.S @@ -0,0 +1,175 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + +The following function has been compiled to ASM with gcc + + unsigned long countPulseASM(const volatile uint32_t *port, uint32_t bit, uint32_t stateMask, unsigned long maxloops) + { + unsigned long width = 0; + + // wait for any previous pulse to end + while ((*port & bit) == stateMask) + if (--maxloops == 0) + return 0; + + // wait for the pulse to start + while ((*port & bit) != stateMask) + if (--maxloops == 0) + return 0; + + // wait for the pulse to stop + while ((*port & bit) == stateMask) { + if (++width == maxloops) + return 0; + } + return width; + } + +using the command line: + + arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -c -Os -W -ffunction-sections -fdata-sections \ + -nostdlib --param max-inline-insns-single=500 -fno-exceptions -MMD \ + -DF_CPU=48000000L -DARDUINO=10602 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD \ + -D__SAMD21G18A__ -DUSB_VID=0x2341 -DUSB_PID=0x004d -DUSBCON \ + -DUSB_MANUFACTURER="Arduino LLC" -DUSB_PRODUCT="Arduino Zero" \ + -I/Code/arduino/build/linux/work/hardware/tools/CMSIS/CMSIS/Include/ \ + -I/Code/arduino/build/linux/work/hardware/tools/CMSIS/Device/ATMEL/ \ + -I/Code/arduino/build/linux/work/hardware/arduino/samd/cores/arduino \ + -I/Code/arduino/build/linux/work/hardware/arduino/samd/variants/arduino_zero \ + count.c -Wa,-ahlmsd=output.lst -dp -fverbose-asm -S + +The result has been slightly edited to increase readability. + +*/ + + .cpu cortex-m0plus + .fpu softvfp + .eabi_attribute 20, 1 @ Tag_ABI_FP_denormal + .eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions + .eabi_attribute 23, 3 @ Tag_ABI_FP_number_model + .eabi_attribute 24, 1 @ Tag_ABI_align8_needed + .eabi_attribute 25, 1 @ Tag_ABI_align8_preserved + .eabi_attribute 26, 1 @ Tag_ABI_enum_size + .eabi_attribute 30, 4 @ Tag_ABI_optimization_goals + .eabi_attribute 34, 0 @ Tag_CPU_unaligned_access + .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t + .file "count.c" +@ GNU C (GNU Tools for ARM Embedded Processors (Arduino build)) version 4.8.3 20140228 (release) [ARM/embedded-4_8-branch revision 208322] (arm-none-eabi) +@ compiled by GNU C version 4.3.2, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1 +@ GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +@ options passed: +@ -I /Code/arduino/build/linux/work/hardware/tools/CMSIS/CMSIS/Include/ +@ -I /Code/arduino/build/linux/work/hardware/tools/CMSIS/Device/ATMEL/ +@ -I /Code/arduino/build/linux/work/hardware/arduino/samd/cores/arduino +@ -I /Code/arduino/build/linux/work/hardware/arduino/samd/variants/arduino_zero +@ -imultilib armv6-m +@ -iprefix /Code/arduino/build/linux/work/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/ +@ -isysroot /Code/arduino/build/linux/work/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/../arm-none-eabi +@ -MMD count.d -D__USES_INITFINI__ -D F_CPU=48000000L -D ARDUINO=10602 +@ -D ARDUINO_SAMD_ZERO -D ARDUINO_ARCH_SAMD -D __SAMD21G18A__ +@ -D USB_VID=0x2341 -D USB_PID=0x004d -D USBCON +@ -D USB_MANUFACTURER=Arduino LLC -D USB_PRODUCT=Arduino Zero count.c +@ -mcpu=cortex-m0plus -mthumb -Os -Wextra -ffunction-sections +@ -fdata-sections -fno-exceptions -fverbose-asm +@ --param max-inline-insns-single=500 +@ options enabled: -faggressive-loop-optimizations -fauto-inc-dec +@ -fbranch-count-reg -fcaller-saves -fcombine-stack-adjustments -fcommon +@ -fcompare-elim -fcprop-registers -fcrossjumping -fcse-follow-jumps +@ -fdata-sections -fdefer-pop -fdelete-null-pointer-checks -fdevirtualize +@ -fdwarf2-cfi-asm -fearly-inlining -feliminate-unused-debug-types +@ -fexpensive-optimizations -fforward-propagate -ffunction-cse +@ -ffunction-sections -fgcse -fgcse-lm -fgnu-runtime +@ -fguess-branch-probability -fhoist-adjacent-loads -fident -fif-conversion +@ -fif-conversion2 -findirect-inlining -finline -finline-atomics +@ -finline-functions -finline-functions-called-once +@ -finline-small-functions -fipa-cp -fipa-profile -fipa-pure-const +@ -fipa-reference -fipa-sra -fira-hoist-pressure -fira-share-save-slots +@ -fira-share-spill-slots -fivopts -fkeep-static-consts +@ -fleading-underscore -fmath-errno -fmerge-constants -fmerge-debug-strings +@ -fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls +@ -fpartial-inlining -fpeephole -fpeephole2 -fprefetch-loop-arrays +@ -freg-struct-return -fregmove -freorder-blocks -freorder-functions +@ -frerun-cse-after-loop -fsched-critical-path-heuristic +@ -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock +@ -fsched-last-insn-heuristic -fsched-pressure -fsched-rank-heuristic +@ -fsched-spec -fsched-spec-insn-heuristic -fsched-stalled-insns-dep +@ -fschedule-insns2 -fsection-anchors -fshow-column -fshrink-wrap +@ -fsigned-zeros -fsplit-ivs-in-unroller -fsplit-wide-types +@ -fstrict-aliasing -fstrict-overflow -fstrict-volatile-bitfields +@ -fsync-libcalls -fthread-jumps -ftoplevel-reorder -ftrapping-math +@ -ftree-bit-ccp -ftree-builtin-call-dce -ftree-ccp -ftree-ch +@ -ftree-coalesce-vars -ftree-copy-prop -ftree-copyrename -ftree-cselim +@ -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre +@ -ftree-loop-if-convert -ftree-loop-im -ftree-loop-ivcanon +@ -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop -ftree-pre +@ -ftree-pta -ftree-reassoc -ftree-scev-cprop -ftree-sink +@ -ftree-slp-vectorize -ftree-slsr -ftree-sra -ftree-switch-conversion +@ -ftree-tail-merge -ftree-ter -ftree-vect-loop-version -ftree-vrp +@ -funit-at-a-time -fverbose-asm -fzero-initialized-in-bss -mlittle-endian +@ -mpic-data-is-text-relative -msched-prolog -mthumb +@ -mvectorize-with-neon-quad + + .section .text.countPulseASM,"ax",%progbits + .align 1 + .global countPulseASM + .code 16 + .thumb_func + .type countPulseASM, %function +countPulseASM: + push {r4, r5, lr} @ @ 112 *push_multi [length = 2] +.L2: + ldr r4, [r0] @ D.11539, *port_7(D) @ 22 *thumb1_movsi_insn/7 [length = 2] + and r4, r1 @ D.11539, bit @ 24 *thumb1_andsi3_insn [length = 2] + cmp r4, r2 @ D.11539, stateMask @ 25 cbranchsi4_insn/1 [length = 4] + bne .L5 @, + sub r3, r3, #1 @ maxloops, @ 17 *thumb1_addsi3/2 [length = 2] + cmp r3, #0 @ maxloops, @ 18 cbranchsi4_insn/1 [length = 4] + bne .L2 @, + b .L10 @ @ 127 *thumb_jump [length = 2] +.L6: + sub r3, r3, #1 @ maxloops, @ 30 *thumb1_addsi3/2 [length = 2] + cmp r3, #0 @ maxloops, @ 31 cbranchsi4_insn/1 [length = 4] + beq .L10 @, +.L5: + ldr r4, [r0] @ D.11539, *port_7(D) @ 35 *thumb1_movsi_insn/7 [length = 2] + and r4, r1 @ D.11539, bit @ 37 *thumb1_andsi3_insn [length = 2] + cmp r4, r2 @ D.11539, stateMask @ 38 cbranchsi4_insn/1 [length = 4] + bne .L6 @, + mov r4, #0 @ width, @ 7 *thumb1_movsi_insn/2 [length = 2] +.L7: + ldr r5, [r0] @ D.11539, *port_7(D) @ 48 *thumb1_movsi_insn/7 [length = 2] + and r5, r1 @ D.11539, bit @ 50 *thumb1_andsi3_insn [length = 2] + cmp r5, r2 @ D.11539, stateMask @ 51 cbranchsi4_insn/1 [length = 4] + bne .L13 @, + add r4, r4, #1 @ width, @ 43 *thumb1_addsi3/1 [length = 2] + cmp r4, r3 @ width, maxloops @ 44 cbranchsi4_insn/1 [length = 4] + bne .L7 @, + mov r0, #0 @ D.11539, @ 11 *thumb1_movsi_insn/2 [length = 2] + b .L3 @ @ 130 *thumb_jump [length = 2] +.L13: + mov r0, r4 @ D.11539, width @ 9 *thumb1_movsi_insn/1 [length = 2] + b .L3 @ @ 132 *thumb_jump [length = 2] +.L10: + mov r0, r3 @ D.11539, maxloops @ 8 *thumb1_movsi_insn/1 [length = 2] +.L3: + @ sp needed @ @ 115 force_register_use [length = 0] + pop {r4, r5, pc} + .size countPulseASM, .-countPulseASM + .ident "GCC: (GNU Tools for ARM Embedded Processors (Arduino build)) 4.8.3 20140228 (release) [ARM/embedded-4_8-branch revision 208322]" diff --git a/hardware/openrov/samd/cores/samd21g18a/startup.c b/hardware/openrov/samd/cores/samd21g18a/startup.c new file mode 100644 index 0000000..4ffdae2 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/startup.c @@ -0,0 +1,226 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "sam.h" +#include "variant.h" + +#include + +/** + * \brief SystemInit() configures the needed clocks and according Flash Read Wait States. + * At reset: + * - OSC8M clock source is enabled with a divider by 8 (1MHz). + * - Generic Clock Generator 0 (GCLKMAIN) is using OSC8M as source. + * We need to: + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference. + * 2) Put XOSC32K as source of Generic Clock Generator 1 + * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + * 4) Enable DFLL48M clock + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + * 6) Modify PRESCaler value of OSCM to have 8MHz + * 7) Put OSC8M as source for Generic Clock Generator 3 + */ +// Constants for Clock generators +#define GENERIC_CLOCK_GENERATOR_MAIN (0u) +#define GENERIC_CLOCK_GENERATOR_XOSC32K (1u) +#define GENERIC_CLOCK_GENERATOR_OSCULP32K (2u) /* Initialized at reset for WDT */ +#define GENERIC_CLOCK_GENERATOR_OSC8M (3u) +// Constants for Clock multiplexers +#define GENERIC_CLOCK_MULTIPLEXER_DFLL48M (0u) + +void SystemInit( void ) +{ + /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */ + NVMCTRL->CTRLB.bit.RWS = NVMCTRL_CTRLB_RWS_HALF_Val ; + + /* Turn on the digital interface clock */ + PM->APBAMASK.reg |= PM_APBAMASK_GCLK ; + + /* ---------------------------------------------------------------------------------------------- + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator) + */ + SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */ + SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K ; + SYSCTRL->XOSC32K.bit.ENABLE = 1 ; /* separate call, as described in chapter 15.6.3 */ + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY) == 0 ) + { + /* Wait for oscillator stabilization */ + } + + /* Software reset the module to ensure it is re-initialized correctly */ + /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete. + * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1 + */ + GCLK->CTRL.reg = GCLK_CTRL_SWRST ; + + while ( (GCLK->CTRL.reg & GCLK_CTRL_SWRST) && (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) ) + { + /* Wait for reset to complete */ + } + + /* ---------------------------------------------------------------------------------------------- + * 2) Put XOSC32K as source of Generic Clock Generator 1 + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) ; // Generic Clock Generator 1 + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Write Generic Clock Generator 1 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1 + GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator +// GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_GENEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + */ + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GENERIC_CLOCK_MULTIPLEXER_DFLL48M ) | // Generic Clock Multiplexer 0 + GCLK_CLKCTRL_GEN_GCLK1 | // Generic Clock Generator 1 is source + GCLK_CLKCTRL_CLKEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 4) Enable DFLL48M clock + */ + + /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */ + + /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */ + SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0 ; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value + SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value + SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ) ; // External 32KHz is the reference + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* Write full configuration to DFLL control register */ + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */ + SYSCTRL_DFLLCTRL_WAITLOCK | + SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */ + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* Enable the DFLL */ + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 || + (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 ) + { + /* Wait for locks flags */ + } + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_MAIN ) ; // Generic Clock Generator 0 + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Write Generic Clock Generator 0 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0 + GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz +// GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_IDC | // Set 50/50 duty cycle + GCLK_GENCTRL_GENEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 6) Modify PRESCaler value of OSC8M to have 8MHz + */ + SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_1_Val ; + SYSCTRL->OSC8M.bit.ONDEMAND = 0 ; + + /* ---------------------------------------------------------------------------------------------- + * 7) Put OSC8M as source for Generic Clock Generator 3 + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) ; // Generic Clock Generator 3 + + /* Write Generic Clock Generator 3 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3 + GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset) +// GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_GENEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* + * Now that all system clocks are configured, we can set CPU and APBx BUS clocks. + * There values are normally the one present after Reset. + */ + PM->CPUSEL.reg = PM_CPUSEL_CPUDIV_DIV1 ; + PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ; + PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ; + PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ; + + SystemCoreClock=VARIANT_MCK ; + + /* ---------------------------------------------------------------------------------------------- + * 8) Load ADC factory calibration values + */ + + // ADC Bias Calibration + uint32_t bias = (*((uint32_t *) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; + + // ADC Linearity bits 4:0 + uint32_t linearity = (*((uint32_t *) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos; + + // ADC Linearity bits 7:5 + linearity |= ((*((uint32_t *) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5; + + ADC->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | ADC_CALIB_LINEARITY_CAL(linearity); +} diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring.c b/hardware/openrov/samd/cores/samd21g18a/wiring.c new file mode 100644 index 0000000..b076d52 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring.c @@ -0,0 +1,125 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * System Core Clock is at 1MHz (8MHz/8) at Reset. + * It is switched to 48MHz in the Reset Handler (startup.c) + */ +uint32_t SystemCoreClock=1000000ul ; + +/* +void calibrateADC() +{ + volatile uint32_t valeur = 0; + + for(int i = 0; i < 5; ++i) + { + ADC->SWTRIG.bit.START = 1; + while( ADC->INTFLAG.bit.RESRDY == 0 || ADC->STATUS.bit.SYNCBUSY == 1 ) + { + // Waiting for a complete conversion and complete synchronization + } + + valeur += ADC->RESULT.bit.RESULT; + } + + valeur = valeur/5; +}*/ + +/* + * Arduino Zero board initialization + * + * Good to know: + * - At reset, ResetHandler did the system clock configuration. Core is running at 48MHz. + * - Watchdog is disabled by default, unless someone plays with NVM User page + * - During reset, all PORT lines are configured as inputs with input buffers, output buffers and pull disabled. + */ +void init( void ) +{ + + uint32_t ul ; + + // Set Systick to 1ms interval, common to all Cortex-M variants + if ( SysTick_Config( SystemCoreClock / 1000 ) ) + { + // Capture error + while ( 1 ) ; + } + + // Clock PORT for Digital I/O +// PM->APBBMASK.reg |= PM_APBBMASK_PORT ; +// +// // Clock EIC for I/O interrupts +// PM->APBAMASK.reg |= PM_APBAMASK_EIC ; + + // Clock SERCOM for Serial + PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ; + + // Clock TC/TCC for Pulse and Analog + PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 ; + + // Clock ADC/DAC for Analog + PM->APBCMASK.reg |= PM_APBCMASK_ADC | PM_APBCMASK_DAC ; + + // Initialize Analog Controller + // Setting clock + while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); + + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_ADC ) | // Generic Clock ADC + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN ; + + while( ADC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains + + ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV512 | // Divide Clock by 512. + ADC_CTRLB_RESSEL_10BIT; + + ADC->SAMPCTRL.reg = 0x3f; // Set max Sampling Time Length + + while( ADC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains + + ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND; // No Negative input (Internal Ground) + + // Averaging (see datasheet table in AVGCTRL register description) + ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 | // 1 sample only (no oversampling nor averaging) + ADC_AVGCTRL_ADJRES(0x0ul); // Adjusting result by 0 + + analogReference( AR_DEFAULT ) ; // Analog Reference is AREF pin (3.3v) + + // Initialize DAC + // Setting clock + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ); + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_DAC ) | // Generic Clock ADC + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN ; + + while ( DAC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains + DAC->CTRLB.reg = DAC_CTRLB_REFSEL_AVCC | // Using the 3.3V reference + DAC_CTRLB_EOEN ; // External Output Enable (Vout) + +} + +#ifdef __cplusplus +} +#endif diff --git a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.h b/hardware/openrov/samd/cores/samd21g18a/wiring.h similarity index 89% rename from hardware/openrov/samd/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.h rename to hardware/openrov/samd/cores/samd21g18a/wiring.h index 5edb91e..55e4e6a 100644 --- a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.h +++ b/hardware/openrov/samd/cores/samd21g18a/wiring.h @@ -18,7 +18,12 @@ #pragma once -#include +#ifdef __cplusplus +extern "C" { +#endif -void analogReadCorrection (int offset, uint16_t gain); +extern void init(void); +#ifdef __cplusplus +} +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_analog.c b/hardware/openrov/samd/cores/samd21g18a/wiring_analog.c new file mode 100644 index 0000000..a8eb141 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_analog.c @@ -0,0 +1,354 @@ +/* + Copyright (c) 2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Arduino.h" +#include "wiring_private.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static int _readResolution = 10; +static int _ADCResolution = 10; +static int _writeResolution = 8; + +// Wait for synchronization of registers between the clock domains +static __inline__ void syncADC() __attribute__((always_inline, unused)); +static void syncADC() { + while (ADC->STATUS.bit.SYNCBUSY == 1) + ; +} + +// Wait for synchronization of registers between the clock domains +static __inline__ void syncDAC() __attribute__((always_inline, unused)); +static void syncDAC() { + while (DAC->STATUS.bit.SYNCBUSY == 1) + ; +} + +// Wait for synchronization of registers between the clock domains +static __inline__ void syncTC_8(Tc* TCx) __attribute__((always_inline, unused)); +static void syncTC_8(Tc* TCx) { + while (TCx->COUNT8.STATUS.bit.SYNCBUSY); +} + +// Wait for synchronization of registers between the clock domains +static __inline__ void syncTCC(Tcc* TCCx) __attribute__((always_inline, unused)); +static void syncTCC(Tcc* TCCx) { + while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK); +} + +void analogReadResolution( int res ) +{ + _readResolution = res ; + if (res > 10) + { + ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val; + _ADCResolution = 12; + } + else if (res > 8) + { + ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; + _ADCResolution = 10; + } + else + { + ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val; + _ADCResolution = 8; + } + syncADC(); +} + +void analogWriteResolution( int res ) +{ + _writeResolution = res ; +} + +static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to ) +{ + if ( from == to ) + { + return value ; + } + + if ( from > to ) + { + return value >> (from-to) ; + } + else + { + return value << (to-from) ; + } +} + +/* + * Internal Reference is at 1.0v + * External Reference should be between 1v and VDDANA-0.6v=2.7v + * + * Warning : On Arduino Zero board the input/output voltage for SAMD21G18 is 3.3 volts maximum + */ +void analogReference( eAnalogReference ulMode ) +{ + syncADC(); + switch ( ulMode ) + { + case AR_INTERNAL: + case AR_INTERNAL2V23: + ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection + ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297 + break; + + case AR_EXTERNAL: + ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection + ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; + break; + + case AR_INTERNAL1V0: + ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection + ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val; // 1.0V voltage reference + break; + + case AR_INTERNAL1V65: + ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection + ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V + break; + + case AR_DEFAULT: + default: + ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val; + ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V + break; + } +} + +uint32_t analogRead( uint32_t ulPin ) +{ + uint32_t valueRead = 0; + + // TODO: What is this all about + //if ( ulPin < A0 ) + //{ + // ulPin += A0 ; + //} + + pinPeripheral(ulPin, PIO_ANALOG); + + // TODO: We dont use the DAC, check to make sure its ok to keep this commented + //if (ulPin == A0) // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled + //{ + // syncDAC(); + // DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC + // //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off. + // syncDAC(); + //} + + syncADC(); + ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[ulPin].ulADCChannelNumber; // Selection for the positive ADC input + + // Control A + /* + * Bit 1 ENABLE: Enable + * 0: The ADC is disabled. + * 1: The ADC is enabled. + * Due to synchronization, there is a delay from writing CTRLA.ENABLE until the peripheral is enabled/disabled. The + * value written to CTRL.ENABLE will read back immediately and the Synchronization Busy bit in the Status register + * (STATUS.SYNCBUSY) will be set. STATUS.SYNCBUSY will be cleared when the operation is complete. + * + * Before enabling the ADC, the asynchronous clock source must be selected and enabled, and the ADC reference must be + * configured. The first conversion after the reference is changed must not be used. + */ + syncADC(); + ADC->CTRLA.bit.ENABLE = 0x01; // Enable ADC + + // Start conversion + syncADC(); + ADC->SWTRIG.bit.START = 1; + + // Clear the Data Ready flag + ADC->INTFLAG.bit.RESRDY = 1; + + // Start conversion again, since The first conversion after the reference is changed must not be used. + syncADC(); + ADC->SWTRIG.bit.START = 1; + + // Store the value + while ( ADC->INTFLAG.bit.RESRDY == 0 ); // Waiting for conversion to complete + valueRead = ADC->RESULT.reg; + + syncADC(); + ADC->CTRLA.bit.ENABLE = 0x00; // Disable ADC + syncADC(); + + return mapResolution(valueRead, _ADCResolution, _readResolution); +} + + +// Right now, PWM output only works on the pins with +// hardware support. These are defined in the appropriate +// pins_*.c file. For the rest of the pins, we default +// to digital output. +void analogWrite( uint32_t ulPin, uint32_t ulValue ) +{ + uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ; + + if ( (attr & PIN_ATTR_PWM) == PIN_ATTR_PWM ) + { + if (attr & PIN_ATTR_TIMER) + { + + if (g_APinDescription[ulPin].ulPinType == PIO_TIMER_ALT) + { + + pinPeripheral(ulPin, PIO_TIMER_ALT); + } + else + { + + pinPeripheral(ulPin, PIO_TIMER); + } + } + else + { + + // We suppose that attr has PIN_ATTR_TIMER_ALT bit set... + pinPeripheral(ulPin, PIO_TIMER_ALT); + } + + Tc* TCx = 0 ; + Tcc* TCCx = 0 ; + + + uint8_t Channelx = GetTCChannelNumber( g_APinDescription[ulPin].ulPWMChannel ) ; + + if ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) >= TCC_INST_NUM ) + { + + TCx = (Tc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ; + } + else + { + + TCCx = (Tcc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ; + } + + // Enable clocks according to TCCx instance to use + switch ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) ) + { + case 0: // TCC0 + case 1: // TCC1 + // Enable GCLK for TCC0 and TCC1 (timer counter input clock) + + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ; + break ; + + case 2: // TCC2 + case 3: // TC3 + // Enable GCLK for TCC2 and TC3 (timer counter input clock) + + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ; + break ; + + case 4: // TC4 + case 5: // TC5 + // Enable GCLK for TC4 and TC5 (timer counter input clock) + + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )); + break ; + + case 6: // TC6 (not available on Zero) + case 7: // TC7 (not available on Zero) + // Enable GCLK for TC6 and TC7 (timer counter input clock) + + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC6_TC7 )); + break ; + } + + while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) + { + + } + + + ulValue = mapResolution(ulValue, _writeResolution, 8); + + // Set PORT + if ( TCx ) + { + // -- Configure TC + + // Disable TCx + TCx->COUNT8.CTRLA.reg &= ~TC_CTRLA_ENABLE; + syncTC_8(TCx); + // Set Timer counter Mode to 8 bits + TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8; + // Set TCx as normal PWM + TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; + // Set TCx in waveform mode Normal PWM + TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue; + syncTC_8(TCx); + // Set PER to maximum counter value (resolution : 0xFF) + TCx->COUNT8.PER.reg = 0xFF; + syncTC_8(TCx); + // Enable TCx + TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE; + syncTC_8(TCx); + + + } + else + { + + // -- Configure TCC + // Disable TCCx + TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE; + + + syncTCC(TCCx); + + + // Set TCx as normal PWM + TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; + + syncTCC(TCCx); + + + // Set TCx in waveform mode Normal PWM + TCCx->CC[Channelx].reg = (uint32_t)ulValue; + + syncTCC(TCCx); + + // Set PER to maximum counter value (resolution : 0xFF) + TCCx->PER.reg = 0xFF; + + syncTCC(TCCx); + + // Enable TCCx + TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ; + + syncTCC(TCCx); + + } + + + return ; + } +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_analog.h b/hardware/openrov/samd/cores/samd21g18a/wiring_analog.h new file mode 100644 index 0000000..f17a7c9 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_analog.h @@ -0,0 +1,85 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include "Arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * \brief SAMD products have only one reference for ADC + */ +typedef enum _eAnalogReference +{ + AR_DEFAULT, + AR_INTERNAL, + AR_EXTERNAL, + AR_INTERNAL1V0, + AR_INTERNAL1V65, + AR_INTERNAL2V23 +} eAnalogReference ; + + +/* + * \brief Configures the reference voltage used for analog input (i.e. the value used as the top of the input range). + * This function is kept only for compatibility with existing AVR based API. + * + * \param ulMmode Should be set to AR_DEFAULT. + */ +extern void analogReference( eAnalogReference ulMode ) ; + +/* + * \brief Writes an analog value (PWM wave) to a pin. + * + * \param ulPin + * \param ulValue + */ +extern void analogWrite( uint32_t ulPin, uint32_t ulValue ) ; + +/* + * \brief Reads the value from the specified analog pin. + * + * \param ulPin + * + * \return Read value from selected pin, if no error. + */ +extern uint32_t analogRead( uint32_t ulPin ) ; + +/* + * \brief Set the resolution of analogRead return values. Default is 10 bits (range from 0 to 1023). + * + * \param res + */ +extern void analogReadResolution(int res); + +/* + * \brief Set the resolution of analogWrite parameters. Default is 8 bits (range from 0 to 255). + * + * \param res + */ +extern void analogWriteResolution(int res); + +extern void analogOutputInit( void ) ; + +#ifdef __cplusplus +} +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_constants.h b/hardware/openrov/samd/cores/samd21g18a/wiring_constants.h new file mode 100644 index 0000000..e8573ae --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_constants.h @@ -0,0 +1,63 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_CONSTANTS_ +#define _WIRING_CONSTANTS_ + +#ifdef __cplusplus +extern "C"{ +#endif // __cplusplus + +#define LOW (0x0) +#define HIGH (0x1) + +#define INPUT (0x0) +#define OUTPUT (0x1) +#define INPUT_PULLUP (0x2) +#define INPUT_PULLDOWN (0x3) + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 +#define EULER 2.718281828459045235360287471352 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +enum BitOrder { + LSBFIRST = 0, + MSBFIRST = 1 +}; + +// moved to WInterrupts.h +//// LOW 0 +//// HIGH 1 +//#define CHANGE 2 +//#define FALLING 3 +//#define RISING 4 +// +//#define DEFAULT 1 +//#define EXTERNAL 0 + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif /* _WIRING_CONSTANTS_ */ diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_digital.c b/hardware/openrov/samd/cores/samd21g18a/wiring_digital.c new file mode 100644 index 0000000..e4cba73 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_digital.c @@ -0,0 +1,116 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Arduino.h" + +#ifdef __cplusplus + extern "C" { +#endif + +void pinMode( uint32_t ulPin, uint32_t ulMode ) +{ + // Handle the case the pin isn't usable as PIO + if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN ) + { + return ; + } + + // Set pin mode according to chapter '22.6.3 I/O Pin Configuration' + switch ( ulMode ) + { + case INPUT: + // Set pin to input mode + PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN) ; + PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ; + PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (uint32_t)(1<Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ; + PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (uint32_t)(1<Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg&=~(uint8_t)(PORT_PINCFG_INEN) ; + PORT->Group[g_APinDescription[ulPin].ulPort].DIRSET.reg = (uint32_t)(1<Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_PULLEN) ; + + switch ( ulVal ) + { + case LOW: + PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (1ul << g_APinDescription[ulPin].ulPin) ; + break ; + + default: + PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (1ul << g_APinDescription[ulPin].ulPin) ; + break ; + } + + return ; +} + +int digitalRead( uint32_t ulPin ) +{ + // Handle the case the pin isn't usable as PIO + if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN ) + { + return LOW ; + } + + if ( (PORT->Group[g_APinDescription[ulPin].ulPort].IN.reg & (1ul << g_APinDescription[ulPin].ulPin)) != 0 ) + { + return HIGH ; + } + + return LOW ; +} + +#ifdef __cplusplus +} +#endif + diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_digital.h b/hardware/openrov/samd/cores/samd21g18a/wiring_digital.h new file mode 100644 index 0000000..9895390 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_digital.h @@ -0,0 +1,71 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_DIGITAL_ +#define _WIRING_DIGITAL_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "WVariant.h" + +/** + * \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details. + * + * \param ulPin The number of the pin whose mode you wish to set + * \param ulMode Can be INPUT, OUTPUT, INPUT_PULLUP or INPUT_PULLDOWN + */ +extern void pinMode( uint32_t dwPin, uint32_t dwMode ) ; + +/** + * \brief Write a HIGH or a LOW value to a digital pin. + * + * If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set to the + * corresponding value: 5V (or 3.3V on 3.3V boards) for HIGH, 0V (ground) for LOW. + * + * If the pin is configured as an INPUT, writing a HIGH value with digitalWrite() will enable an internal + * 20K pullup resistor (see the tutorial on digital pins). Writing LOW will disable the pullup. The pullup + * resistor is enough to light an LED dimly, so if LEDs appear to work, but very dimly, this is a likely + * cause. The remedy is to set the pin to an output with the pinMode() function. + * + * \note Digital pin PIN_LED is harder to use as a digital input than the other digital pins because it has an LED + * and resistor attached to it that's soldered to the board on most boards. If you enable its internal 20k pull-up + * resistor, it will hang at around 1.7 V instead of the expected 5V because the onboard LED and series resistor + * pull the voltage level down, meaning it always returns LOW. If you must use pin PIN_LED as a digital input, use an + * external pull down resistor. + * + * \param dwPin the pin number + * \param dwVal HIGH or LOW + */ +extern void digitalWrite( uint32_t dwPin, uint32_t dwVal ) ; + +/** + * \brief Reads the value from a specified digital pin, either HIGH or LOW. + * + * \param ulPin The number of the digital pin you want to read (int) + * + * \return HIGH or LOW + */ +extern int digitalRead( uint32_t ulPin ) ; + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_DIGITAL_ */ diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_private.c b/hardware/openrov/samd/cores/samd21g18a/wiring_private.c new file mode 100644 index 0000000..aca5175 --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_private.c @@ -0,0 +1,101 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Arduino.h" +#include "wiring_private.h" + +int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral ) +{ + // Handle the case the pin isn't usable as PIO + if ( g_APinDescription[ulPin].ulPinType == PIO_NOT_A_PIN ) + { + return -1 ; + } + + switch ( ulPeripheral ) + { + case PIO_DIGITAL: + case PIO_INPUT: + case PIO_INPUT_PULLUP: + case PIO_OUTPUT: + // Disable peripheral muxing, done in pinMode +// PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].bit.PMUXEN = 0 ; + + // Configure pin mode, if requested + if ( ulPeripheral == PIO_INPUT ) + { + pinMode( ulPin, INPUT ) ; + } + else + { + if ( ulPeripheral == PIO_INPUT_PULLUP ) + { + pinMode( ulPin, INPUT_PULLUP ) ; + } + else + { + if ( ulPeripheral == PIO_OUTPUT ) + { + pinMode( ulPin, OUTPUT ) ; + } + else + { + // PIO_DIGITAL, do we have to do something as all cases are covered? + } + } + } + break ; + + case PIO_ANALOG: + case PIO_SERCOM: + case PIO_SERCOM_ALT: + case PIO_TIMER: + case PIO_TIMER_ALT: + case PIO_EXTINT: + case PIO_COM: + case PIO_AC_CLK: + + if ( g_APinDescription[ulPin].ulPin & 1 ) // is pin odd? + { + uint32_t temp ; + + // Get whole current setup for both odd and even pins and remove odd one + temp = (PORT->Group[g_APinDescription[ulPin].ulPort].PMUX[g_APinDescription[ulPin].ulPin >> 1].reg) & PORT_PMUX_PMUXE( 0xF ) ; + // Set new muxing + PORT->Group[g_APinDescription[ulPin].ulPort].PMUX[g_APinDescription[ulPin].ulPin >> 1].reg = temp|PORT_PMUX_PMUXO( ulPeripheral ) ; + // Enable port mux + PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg |= PORT_PINCFG_PMUXEN ; + } + else // even pin + { + uint32_t temp ; + + temp = (PORT->Group[g_APinDescription[ulPin].ulPort].PMUX[g_APinDescription[ulPin].ulPin >> 1].reg) & PORT_PMUX_PMUXO( 0xF ) ; + PORT->Group[g_APinDescription[ulPin].ulPort].PMUX[g_APinDescription[ulPin].ulPin >> 1].reg = temp|PORT_PMUX_PMUXE( ulPeripheral ) ; + PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg |= PORT_PINCFG_PMUXEN ; // Enable port mux + } + break ; + + case PIO_NOT_A_PIN: + return -1l ; + break ; + } + + return 0l ; +} + diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_private.h b/hardware/openrov/samd/cores/samd21g18a/wiring_private.h new file mode 100644 index 0000000..ce64e2d --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_private.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Includes Atmel CMSIS +#include "sam.h" + +#include "wiring_constants.h" + +int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral ); + +#ifdef __cplusplus +} // extern "C" + +#include "HardwareSerial.h" + +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_shift.c b/hardware/openrov/samd/cores/samd21g18a/wiring_shift.c new file mode 100644 index 0000000..3260d2b --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_shift.c @@ -0,0 +1,74 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include "wiring_shift.h" +#include "wiring_digital.h" +#include "wiring_private.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +uint32_t shiftIn( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder ) +{ + uint8_t value = 0 ; + uint8_t i ; + + for ( i=0 ; i < 8 ; ++i ) + { + digitalWrite( ulClockPin, HIGH ) ; + + if ( ulBitOrder == LSBFIRST ) + { + value |= digitalRead( ulDataPin ) << i ; + } + else + { + value |= digitalRead( ulDataPin ) << (7 - i) ; + } + + digitalWrite( ulClockPin, LOW ) ; + } + + return value ; +} + +void shiftOut( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder, uint32_t ulVal ) +{ + uint8_t i ; + + for ( i=0 ; i < 8 ; i++ ) + { + if ( ulBitOrder == LSBFIRST ) + { + digitalWrite( ulDataPin, !!(ulVal & (1 << i)) ) ; + } + else + { + digitalWrite( ulDataPin, !!(ulVal & (1 << (7 - i))) ) ; + } + + digitalWrite( ulClockPin, HIGH ) ; + digitalWrite( ulClockPin, LOW ) ; + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/hardware/openrov/samd/cores/samd21g18a/wiring_shift.h b/hardware/openrov/samd/cores/samd21g18a/wiring_shift.h new file mode 100644 index 0000000..6026bdc --- /dev/null +++ b/hardware/openrov/samd/cores/samd21g18a/wiring_shift.h @@ -0,0 +1,42 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WIRING_SHIFT_ +#define _WIRING_SHIFT_ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * \brief + */ +extern uint32_t shiftIn( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder ) ; + + +/* + * \brief + */ +extern void shiftOut( uint32_t ulDataPin, uint32_t ulClockPin, uint32_t ulBitOrder, uint32_t ulVal ) ; + + +#ifdef __cplusplus +} +#endif + +#endif /* _WIRING_SHIFT_ */ diff --git a/hardware/openrov/samd/extras/pack.hourlybuild.bash b/hardware/openrov/samd/extras/pack.hourlybuild.bash deleted file mode 100755 index 6eea332..0000000 --- a/hardware/openrov/samd/extras/pack.hourlybuild.bash +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -ex - -BUILD_NUMBER=$1 -CURR_TIME=`date "+%Y-%m-%d %H:%M"` -CURR_TIME_SED=`date "+%Y\\-%m\\-%d %H:%M"` -VERSION=9.9.9-Hourly - -PWD=`pwd` -FOLDERNAME=`basename $PWD` -THIS_SCRIPT_NAME=`basename $0` -FILENAME=package_samd-hourly-b${BUILD_NUMBER}.tar.bz2 - -rm -f $FILENAME - -# Change name in platform.txt -sed -i "s/name=.*/name=SAMD Hourly Build ${BUILD_NUMBER} (${CURR_TIME})/" platform.txt - -cd .. -tar --transform "s|$FOLDERNAME|samd-hourly_b${BUILD_NUMBER}|g" --exclude=extras/** --exclude=.git* --exclude=.idea -cjf $FILENAME $FOLDERNAME -cd - - -mv ../$FILENAME . - -CHKSUM=`sha256sum $FILENAME | awk '{ print $1 }'` -SIZE=`wc -c $FILENAME | awk '{ print $1 }'` - -cat extras/package_index.json.Hourly.template | -sed "s/%%BUILD_NUMBER%%/${BUILD_NUMBER}/" | -sed "s/%%CURR_TIME%%/${CURR_TIME_SED}/" | -sed "s/%%VERSION%%/${VERSION}/" | -sed "s/%%FILENAME%%/${FILENAME}/" | -sed "s/%%CHECKSUM%%/${CHKSUM}/" | -sed "s/%%SIZE%%/${SIZE}/" > package_samd-hourly-build_index.json - diff --git a/hardware/openrov/samd/extras/pack.pullrequest.bash b/hardware/openrov/samd/extras/pack.pullrequest.bash deleted file mode 100755 index 36d4d9c..0000000 --- a/hardware/openrov/samd/extras/pack.pullrequest.bash +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -ex - -PR_NUMBER=$1 -BUILD_NUMBER=$2 -VERSION=`grep version= platform.txt | sed 's/version=//g'` - -PWD=`pwd` -FOLDERNAME=`basename $PWD` -THIS_SCRIPT_NAME=`basename $0` -FILENAME=package_samd-b${BUILD_NUMBER}.tar.bz2 - -rm -f $FILENAME - -# Change name in platform.txt -sed -i "s/name=.*/name=SAMD Pull request #${PR_NUMBER} (Build ${BUILD_NUMBER})/" platform.txt - -cd .. -tar --transform "s|$FOLDERNAME|samd-PR${PR_NUMBER}_b${BUILD_NUMBER}|g" --exclude=extras/** --exclude=.git* --exclude=.idea -cjf $FILENAME $FOLDERNAME -cd - - -mv ../$FILENAME . - -CHKSUM=`sha256sum $FILENAME | awk '{ print $1 }'` -SIZE=`wc -c $FILENAME | awk '{ print $1 }'` - -cat extras/package_index.json.PR.template | -sed s/%%PR_NUMBER%%/${PR_NUMBER}/ | -sed s/%%BUILD_NUMBER%%/${BUILD_NUMBER}/ | -sed s/%%VERSION%%/${VERSION}-build-${BUILD_NUMBER}/ | -sed s/%%FILENAME%%/${FILENAME}/ | -sed s/%%CHECKSUM%%/${CHKSUM}/ | -sed s/%%SIZE%%/${SIZE}/ > package_samd-b${BUILD_NUMBER}_index.json - diff --git a/hardware/openrov/samd/extras/pack.release.bash b/hardware/openrov/samd/extras/pack.release.bash deleted file mode 100755 index 6ccb131..0000000 --- a/hardware/openrov/samd/extras/pack.release.bash +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -ex - -VERSION=`grep version= platform.txt | sed 's/version=//g'` - -PWD=`pwd` -FOLDERNAME=`basename $PWD` -THIS_SCRIPT_NAME=`basename $0` - -rm -f samd-$VERSION.tar.bz2 - -cd .. -tar --transform "s|$FOLDERNAME|$FOLDERNAME-$VERSION|g" --exclude=extras/** --exclude=.git* --exclude=.idea -cjf samd-$VERSION.tar.bz2 $FOLDERNAME -cd - - -mv ../samd-$VERSION.tar.bz2 . - diff --git a/hardware/openrov/samd/extras/package_index.json.Hourly.template b/hardware/openrov/samd/extras/package_index.json.Hourly.template deleted file mode 100644 index 19b1caa..0000000 --- a/hardware/openrov/samd/extras/package_index.json.Hourly.template +++ /dev/null @@ -1,54 +0,0 @@ -{ - "packages": [ - { - "name": "arduino-beta", - "maintainer": "Arduino Betatesting", - "websiteURL": "http://www.arduino.cc/", - "email": "packages@arduino.cc", - "help": { - "online": "http://www.arduino.cc/en/Reference/HomePage" - }, - "platforms": [ - { - "name": "Arduino SAMD core - Hourly build", - "architecture": "samd", - "version": "%%VERSION%%", - "category": "Arduino", - "url": "http://downloads.arduino.cc/Hourly/samd/%%FILENAME%%", - "archiveFileName": "%%FILENAME%%", - "checksum": "SHA-256:%%CHECKSUM%%", - "size": "%%SIZE%%", - "boards": [ - { - "name": "Arduino Zero" - } - ], - "toolsDependencies": [ - { - "packager": "arduino", - "name": "arm-none-eabi-gcc", - "version": "4.8.3-2014q1" - }, - { - "packager": "arduino", - "name": "bossac", - "version": "1.6-arduino" - }, - { - "packager": "arduino", - "name": "openocd", - "version": "0.9.0-arduino" - }, - { - "packager": "arduino", - "name": "CMSIS", - "version": "4.0.0-atmel" - } - ] - } - ], - "tools": [ - ] - } - ] -} diff --git a/hardware/openrov/samd/extras/package_index.json.PR.template b/hardware/openrov/samd/extras/package_index.json.PR.template deleted file mode 100644 index 45da70a..0000000 --- a/hardware/openrov/samd/extras/package_index.json.PR.template +++ /dev/null @@ -1,54 +0,0 @@ -{ - "packages": [ - { - "name": "arduino-beta", - "maintainer": "Arduino Betatesting", - "websiteURL": "http://www.arduino.cc/", - "email": "packages@arduino.cc", - "help": { - "online": "http://www.arduino.cc/en/Reference/HomePage" - }, - "platforms": [ - { - "name": "Arduino SAMD core - Pull request #%%PR_NUMBER%% (build %%BUILD_NUMBER%%)", - "architecture": "samd", - "version": "%%VERSION%%", - "category": "Arduino", - "url": "http://downloads.arduino.cc/PR/samd/%%FILENAME%%", - "archiveFileName": "%%FILENAME%%", - "checksum": "SHA-256:%%CHECKSUM%%", - "size": "%%SIZE%%", - "boards": [ - { - "name": "Arduino Zero" - } - ], - "toolsDependencies": [ - { - "packager": "arduino", - "name": "arm-none-eabi-gcc", - "version": "4.8.3-2014q1" - }, - { - "packager": "arduino", - "name": "bossac", - "version": "1.6-arduino" - }, - { - "packager": "arduino", - "name": "openocd", - "version": "0.9.0-arduino" - }, - { - "packager": "arduino", - "name": "CMSIS", - "version": "4.0.0-atmel" - } - ] - } - ], - "tools": [ - ] - } - ] -} diff --git a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/examples/CorrectADCResponse/CorrectADCResponse.ino b/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/examples/CorrectADCResponse/CorrectADCResponse.ino deleted file mode 100644 index 2b74538..0000000 --- a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/examples/CorrectADCResponse/CorrectADCResponse.ino +++ /dev/null @@ -1,210 +0,0 @@ -/* - This sketch easily and quickly finds the right ADC correction values for a particular Arduino ZERO board. - The correction values that are found are only valid for the board where the sketch is executed. - - This example code is in the public domain. - - Written 6 May 2015 by Claudio Indellicati -*/ - -/* - How to use this sketch - - 1) Remove any connection cable, shield or jumper from your Arduino ZERO - 2) Connect pin A1 to the nearest GND pin using the shortest jumper possible - 3) Connect pin A2 to the 3.3V pin using the shortest jumper possible - 4) Connect the Arduino ZERO to your PC using a USB cable plugged in the USB programming port of the board - 5) Upload this sketch and leave the board powered on for at least one minute - 6) Open the Serial Monitor and press the reset button on the Arduino ZERO - 7) At the and of the procedure you can find logged - - the offset and gain values for the board where the sketch has been just executed - - the instruction line to copy/paste in the final sketch -*/ - -#include "SAMD_AnalogCorrection.h" - -#define ADC_GND_PIN A1 -#define ADC_3V3_PIN A2 - -#define ADC_READS_SHIFT 8 -#define ADC_READS_COUNT (1 << ADC_READS_SHIFT) - -#define ADC_MIN_GAIN 0x0400 -#define ADC_UNITY_GAIN 0x0800 -#define ADC_MAX_GAIN (0x1000 - 1) -#define ADC_RESOLUTION_BITS 12 -#define ADC_RANGE (1 << ADC_RESOLUTION_BITS) -#define ADC_TOP_VALUE (ADC_RANGE - 1) - -#define MAX_TOP_VALUE_READS 10 - -void setup() -{ - Serial.begin(9600); - - Serial.println("\r\nCalibrating ADC with factory values"); - - analogReadResolution(ADC_RESOLUTION_BITS); - - Serial.println("\r\nReading GND and 3.3V ADC levels"); - Serial.print(" "); - readGndLevel(); - Serial.print(" "); - read3V3Level(); - - int offsetCorrectionValue = 0; - uint16_t gainCorrectionValue = ADC_UNITY_GAIN; - - Serial.print("\r\nOffset correction (@gain = "); - Serial.print(gainCorrectionValue); - Serial.println(" (unity gain))"); - - // Set default correction values and enable correction - analogReadCorrection(offsetCorrectionValue, gainCorrectionValue); - - for (int offset = 0; offset < (int)(ADC_OFFSETCORR_MASK >> 1); ++offset) - { - analogReadCorrection(offset, gainCorrectionValue); - - Serial.print(" Offset = "); - Serial.print(offset); - Serial.print(", "); - - if (readGndLevel() == 0) - { - offsetCorrectionValue = offset; - break; - } - } - - Serial.println("\r\nGain correction"); - - uint8_t topValueReadsCount = 0U; - - uint16_t minGain = 0U, - maxGain = 0U; - - analogReadCorrection(offsetCorrectionValue, gainCorrectionValue); - Serial.print(" Gain = "); - Serial.print(gainCorrectionValue); - Serial.print(", "); - uint16_t highLevelRead = read3V3Level(); - - if (highLevelRead < ADC_TOP_VALUE) - { - for (uint16_t gain = ADC_UNITY_GAIN + 1; gain <= ADC_MAX_GAIN; ++gain) - { - analogReadCorrection(offsetCorrectionValue, gain); - - Serial.print(" Gain = "); - Serial.print(gain); - Serial.print(", "); - highLevelRead = read3V3Level(); - - if (highLevelRead == ADC_TOP_VALUE) - { - if (minGain == 0U) - minGain = gain; - - if (++topValueReadsCount >= MAX_TOP_VALUE_READS) - { - maxGain = minGain; - break; - } - - maxGain = gain; - } - - if (highLevelRead > ADC_TOP_VALUE) - break; - } - } - else if (highLevelRead >= ADC_TOP_VALUE) - { - if (highLevelRead == ADC_TOP_VALUE) - maxGain = ADC_UNITY_GAIN; - - for (uint16_t gain = ADC_UNITY_GAIN - 1; gain >= ADC_MIN_GAIN; --gain) - { - analogReadCorrection(offsetCorrectionValue, gain); - - Serial.print(" Gain = "); - Serial.print(gain); - Serial.print(", "); - highLevelRead = read3V3Level(); - - if (highLevelRead == ADC_TOP_VALUE) - { - if (maxGain == 0U) - maxGain = gain; - - minGain = gain; - } - - if (highLevelRead < ADC_TOP_VALUE) - break; - } - } - - gainCorrectionValue = (minGain + maxGain) >> 1; - - analogReadCorrection(offsetCorrectionValue, gainCorrectionValue); - - Serial.println("\r\nReadings after corrections"); - Serial.print(" "); - readGndLevel(); - Serial.print(" "); - read3V3Level(); - - Serial.println("\r\n=================="); - Serial.println("\r\nCorrection values:"); - Serial.print(" Offset = "); - Serial.println(offsetCorrectionValue); - Serial.print(" Gain = "); - Serial.println(gainCorrectionValue); - Serial.println("\r\nAdd the next line to your sketch:"); - Serial.print(" analogReadCorrection("); - Serial.print(offsetCorrectionValue); - Serial.print(", "); - Serial.print(gainCorrectionValue); - Serial.println(");"); - Serial.println("\r\n=================="); -} - -void loop() -{ -} - -uint16_t readGndLevel() -{ - uint32_t readAccumulator = 0; - - for (int i = 0; i < ADC_READS_COUNT; ++i) - readAccumulator += analogRead(ADC_GND_PIN); - - uint16_t readValue = readAccumulator >> ADC_READS_SHIFT; - - Serial.print("ADC(GND) = "); - Serial.println(readValue); - - return readValue; -} - -uint16_t read3V3Level() -{ - uint32_t readAccumulator = 0; - - for (int i = 0; i < ADC_READS_COUNT; ++i) - readAccumulator += analogRead(ADC_3V3_PIN); - - uint16_t readValue = readAccumulator >> ADC_READS_SHIFT; - - if (readValue < (ADC_RANGE >> 1)) - readValue += ADC_RANGE; - - Serial.print("ADC(3.3V) = "); - Serial.println(readValue); - - return readValue; -} - diff --git a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/library.properties b/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/library.properties deleted file mode 100644 index b8ba59a..0000000 --- a/hardware/openrov/samd/libraries/SAMD_AnalogCorrection/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=SAMD_AnalogCorrection -version=1.0 -author=Arduino -maintainer=Arduino -sentence=Sets and enables the digital correction logic of the SAMD ADC. -paragraph=Useful to correct the values returned by the ADC. -category=Other -url= -architectures=samd diff --git a/hardware/openrov/samd/platform.txt b/hardware/openrov/samd/platform.txt index 2dd7a09..bb677b2 100644 --- a/hardware/openrov/samd/platform.txt +++ b/hardware/openrov/samd/platform.txt @@ -105,44 +105,4 @@ recipe.output.save_file={build.project_name}.{build.variant}.bin ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -recipe.size.regex=\.text\s+([0-9]+).* - - -# Uploader tools -# -------------- - -# -# BOSSA -# -tools.bossac.path={runtime.tools.bossac-1.6-arduino.path} -tools.bossac.cmd=bossac -tools.bossac.cmd.windows=bossac.exe - -tools.bossac.upload.params.verbose=-i -d -tools.bossac.upload.params.quiet= -tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -i -e -w -v "{build.path}/{build.project_name}.bin" -R - -# -# OpenOCD sketch upload -# - -tools.openocd.path={runtime.tools.openocd.path} -tools.openocd.cmd=bin/openocd -tools.openocd.cmd.windows=bin/openocd.exe - -tools.openocd.upload.params.verbose=-d2 -tools.openocd.upload.params.quiet=-d0 -tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.bin}} verify reset 0x00002000; shutdown" - -tools.openocd.program.params.verbose=-d2 -tools.openocd.program.params.quiet=-d0 -tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.elf}} verify reset; shutdown" - -tools.openocd.erase.params.verbose=-d3 -tools.openocd.erase.params.quiet=-d0 -tools.openocd.erase.pattern= - -tools.openocd.bootloader.params.verbose=-d2 -tools.openocd.bootloader.params.quiet=-d0 -tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{{runtime.platform.path}/bootloaders/{bootloader.file}}} verify reset; shutdown" - +recipe.size.regex=\.text\s+([0-9]+).* \ No newline at end of file diff --git a/hardware/openrov/samd/programmers.txt b/hardware/openrov/samd/programmers.txt index fd7471b..3c121e3 100644 --- a/hardware/openrov/samd/programmers.txt +++ b/hardware/openrov/samd/programmers.txt @@ -14,23 +14,3 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -edbg.name=Atmel EDBG -edbg.communication=USB -edbg.protocol= -edbg.program.protocol= -edbg.program.tool=openocd -edbg.program.extra_params= - -atmel_ice.name=Atmel-ICE -atmel_ice.communication=USB -atmel_ice.protocol= -atmel_ice.program.protocol= -atmel_ice.program.tool=openocd -atmel_ice.program.extra_params= - -sam_ice.name=Atmel SAM-ICE -sam_ice.communication=USB -sam_ice.protocol= -sam_ice.program.protocol= -sam_ice.program.tool=openocd -sam_ice.program.extra_params= diff --git a/hardware/openrov/samd/variants/trident/debug_scripts/variant.gdb b/hardware/openrov/samd/variants/trident/debug_scripts/variant.gdb deleted file mode 100644 index 3c37ffd..0000000 --- a/hardware/openrov/samd/variants/trident/debug_scripts/variant.gdb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Arduino Zero OpenOCD script. -# -# Copyright (c) 2014-2015 Arduino LLC. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -# Define 'reset' command -define reset - -info reg - -break main - -# End of 'reset' command -end - -target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/hardware/openrov/samd/variants/trident/linker_scripts/gcc/flash_with_bootloader.ld b/hardware/openrov/samd/variants/trident/linker_scripts/gcc/flash_with_bootloader.ld deleted file mode 100644 index 4475f95..0000000 --- a/hardware/openrov/samd/variants/trident/linker_scripts/gcc/flash_with_bootloader.ld +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* Linker script to configure memory regions. - * Need modifying for a specific board. - * FLASH.ORIGIN: starting address of flash - * FLASH.LENGTH: length of flash - * RAM.ORIGIN: starting address of RAM bank 0 - * RAM.LENGTH: length of RAM bank 0 - */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 -} - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * Reset_Handler : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __copy_table_start__ - * __copy_table_end__ - * __zero_table_start__ - * __zero_table_end__ - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __end__ - * end - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - */ -ENTRY(Reset_Handler) - -SECTIONS -{ - .text : - { - KEEP(*(.isr_vector)) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - KEEP(*(.eh_frame*)) - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* To copy multiple ROM to RAM sections, - * uncomment .copy.table section and, - * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ - /* - .copy.table : - { - . = ALIGN(4); - __copy_table_start__ = .; - LONG (__etext) - LONG (__data_start__) - LONG (__data_end__ - __data_start__) - LONG (__etext2) - LONG (__data2_start__) - LONG (__data2_end__ - __data2_start__) - __copy_table_end__ = .; - } > FLASH - */ - - /* To clear multiple BSS sections, - * uncomment .zero.table section and, - * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ - /* - .zero.table : - { - . = ALIGN(4); - __zero_table_start__ = .; - LONG (__bss_start__) - LONG (__bss_end__ - __bss_start__) - LONG (__bss2_start__) - LONG (__bss2_end__ - __bss2_start__) - __zero_table_end__ = .; - } > FLASH - */ - - __etext = .; - - .data : AT (__etext) - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP(*(SORT(.fini_array.*))) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - KEEP(*(.jcr*)) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (COPY): - { - __end__ = .; - PROVIDE(end = .); - *(.heap*) - __HeapLimit = .; - } > RAM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") -} diff --git a/hardware/openrov/samd/variants/trident/openocd_scripts/sodaq_autonomo.cfg b/hardware/openrov/samd/variants/trident/openocd_scripts/sodaq_autonomo.cfg deleted file mode 100644 index 083166b..0000000 --- a/hardware/openrov/samd/variants/trident/openocd_scripts/sodaq_autonomo.cfg +++ /dev/null @@ -1,30 +0,0 @@ -# -# Arduino Zero OpenOCD script. -# -# Copyright (c) 2014-2015 Arduino LLC. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91samd21j18 -set ENDIAN little - -# choose a port here -set telnet_port 0 - -source [find target/at91samdXX.cfg] diff --git a/hardware/openrov/samd/variants/trident/variant.cpp b/hardware/openrov/samd/variants/trident/variant.cpp index c5908a6..acc3149 100644 --- a/hardware/openrov/samd/variants/trident/variant.cpp +++ b/hardware/openrov/samd/variants/trident/variant.cpp @@ -37,103 +37,68 @@ const PinDescription g_APinDescription[] = // NOTE! // DUM(MY) pins should not be used. Their purpose is to make the array index of these pin descriptors match the pin numbers on the board. // Some of them describe actual pins, just not GPIO pins, such as the oscillator, power, ground, debug, etc pins. Just FYI. - // They are set up to redundantly describe the EN_PROGRAM pin, which will be safe, just in case you don't see this and try. - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 0 -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 1 | XOSCIN32 -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 2 | XOSCOUT32 - - { PORTA , 2 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel0 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 3 | A0 - { PORTA , 3 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel1 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 4 | A1 - { PORTB , 4 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel12 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 5 | A12 - { PORTB , 5 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel13 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 6 | A13 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 7 | GNDANA -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 8 | VDDANA - - { PORTB , 6 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel14 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 9 | A14 - { PORTB , 7 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel15 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 10 | A15 - { PORTB , 8 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel2 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 11 | A2 - { PORTB , 9 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel3 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 12 | A3 - - { PORTA , 4 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 13 | SERCOM0/PAD[0], UART0 TX - { PORTA , 5 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 14 | SERCOM0/PAD[1], UART0 RX - { PORTA , 6 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 15 | SERCOM0/PAD[2], UART0 RTS - { PORTA , 7 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 16 | SERCOM0/PAD[3], UART0 CTS - - { PORTA , 8 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 17 | SERCOM2/PAD[0], I2C1 SDA - { PORTA , 9 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 18 | SERCOM2/PAD[1], I2C1 SCL - - { PORTA , 10 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel0 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 19 | A18 - { PORTA , 11 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel0 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 20 | A19 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 21 | VDDIO -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 22 | GND - - { PORTB , 10 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 23 | Servo1 TC5 0 - { PORTB , 11 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 24 | Servo2 TC5 1 - { PORTB , 12 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 25 | Servo3 TC4 0 - { PORTB , 13 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 26 | GPIO0 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 27 | N/A - - { PORTB , 15 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 28 | GPIO1, LED_1 - - { PORTA , 12 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 29 | SERCOM4/PAD[0], UART1_TX - { PORTA , 13 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 30 | SERCOM4/PAD[1], UART1_RX - - { PORTA , 14 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 31 | GPIO2 LED_0 - { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 32 | GPIO3 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 33 | GND -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 34 | VDDIO - - { PORTA , 16 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 35 | SERCOM1/PAD[0], UART2_TX - { PORTA , 17 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 36 | SERCOM1/PAD[1], UART2_RX - - { PORTA , 18 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 37 | GPIO4 - { PORTA , 19 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 38 | GPIO5 - - { PORTB , 16 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 39 | GPIO6 - { PORTB , 17 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 40 | GPIO7 - { PORTA , 20 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 41 | GPIO8 - - { PORTA , 21 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 42 | GPIO9 - - { PORTA , 22 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 43 | SERCOM3/PAD[0], UART3 TX - { PORTA , 23 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 44 | SERCOM3/PAD[1], UART3 RX - - { PORTA , 24 , PIO_TIMER_ALT , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM1_CH2 , TCC1_CH2 , EXTERNAL_INT_NONE }, // 45 | TCC1_2, PWM0 - - { PORTA , 25 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 46 | GPIO10 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 47 | GND -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 48 | VDDIO - - { PORTB , 22 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 49 | GPIO11 - { PORTB , 23 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 50 | GPIO12 - { PORTA , 27 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 51 | GPIO13 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 52 | RESETN -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 53 | SPARE -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 54 | GND -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 55 | VDDCORE -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 56 | VDDIN -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 57 | DEBUG SWCLK -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 58 | DEBUG SWDIO - - { PORTB , 30 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 59 | SERCOM5/PAD[0], UART4 TX - { PORTB , 31 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 60 | SERCOM5/PAD[1], UART4 RX - - { PORTB , 0 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel8 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 61 | A8 - { PORTB , 1 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel9 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 62 | A9 - { PORTB , 2 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel10 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 63 | A10 - { PORTB , 3 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel11 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE } // 64 | A11 + // They are set up to redundantly describe the unused PA28 pin, which will be safe, just in case you don't see this and try. + +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 0 | DOES NOT EXIST +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 1 | XOSCIN32 +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 2 | XOSCOUT32 + { PORTA , 2 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 3 | N/A + { PORTA , 3 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 4 | N/A +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 5 | GNDANA +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 6 | VDDANA + { PORTB , 8 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 7 | N/A + { PORTB , 9 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 8 | N/A + { PORTA , 4 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 9 | SERCOM0/PAD[0], UART0 TX + { PORTA , 5 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 10 | SERCOM0/PAD[1], UART0 RX + { PORTA , 6 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 11 | N/A + { PORTA , 7 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 12 | N/A + + + { PORTA , 8 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 13 | SERCOM2/PAD[0], I2C1 SDA + { PORTA , 9 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 14 | SERCOM2/PAD[1], I2C1 SCL + { PORTA , 10 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 15 | I2C0_INT (Unused) + { PORTA , 11 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 16 | I2C0_PWR +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 17 | VDDIO +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 18 | GND + { PORTB , 10 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 19 | N/A + { PORTB , 11 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 20 | N/A + { PORTA , 12 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 21 | SERCOM4/PAD[0], UART1_TX + { PORTA , 13 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 22 | SERCOM4/PAD[1], UART1_RX + { PORTA , 14 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 23 | N/A + { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 24 | N/A + + + { PORTA , 16 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 25 | SERCOM1/PAD[0], UART2_TX + { PORTA , 17 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 26 | SERCOM1/PAD[1], UART2_RX + { PORTA , 18 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 27 | N/A + { PORTA , 19 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 28 | N/A + { PORTA , 20 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 29 | N/A + { PORTA , 21 , PIO_TIMER_ALT , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM0_CH7 , TCC0_CH7 , EXTERNAL_INT_NONE }, // 30 | TCC0_7, LED_PWM + { PORTA , 22 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 31 | SERCOM3/PAD[0], UART3 TX + { PORTA , 23 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 32 | SERCOM3/PAD[1], UART3 RX + { PORTA , 24 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 33 | N/A + { PORTA , 25 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 34 | N/A +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 35 | GND +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 36 | VDDIO + + + { PORTB , 22 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 37 | LED2 + { PORTB , 23 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 38 | LED1 + { PORTA , 27 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 39 | LED0 +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 40 | RESETN +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 41 | N/A +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 42 | GND +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 43 | VDDCORE +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 44 | VDDIN +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 45 | DEBUG SWCLK +/*DUM*/ { PORTA , 28 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 46 | DEBUG SWDIO + { PORTB , 2 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 47 | SERCOM5/PAD[0], UART4 TX + { PORTB , 3 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 48 | SERCOM5/PAD[1], UART4 RX }; const void* g_apTCInstances[ TCC_INST_NUM+TC_INST_NUM ]= { TCC0, TCC1, TCC2, TC3, TC4, TC5, TC6, TC7 }; -// Multi-serial objects instantiation +// Instantiate the sercom objects SERCOM sercom0( SERCOM0 ); SERCOM sercom1( SERCOM1 ); SERCOM sercom2( SERCOM2 ); @@ -141,43 +106,43 @@ SERCOM sercom3( SERCOM3 ); SERCOM sercom4( SERCOM4 ); SERCOM sercom5( SERCOM5 ); -// Instantiate Serial object -Uart Serial( &sercom0, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ); +// Instantiate SerialDebug object +Uart SerialDebug( &sercom0, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ); void SERCOM0_Handler() { - Serial.IrqHandler(); + SerialDebug.IrqHandler(); } -// Instantiate Serial1 object -Uart Serial1( &sercom4, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ); +// Instantiate SerialMotorB object +Uart SerialMotorA( &sercom4, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ); void SERCOM4_Handler() { - Serial1.IrqHandler(); + SerialMotorA.IrqHandler(); } // Instantiate Serial2 object -Uart Serial2( &sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX ); +Uart SerialMotorB( &sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX ); void SERCOM1_Handler() { - Serial2.IrqHandler(); + SerialMotorB.IrqHandler(); } -// Instantiate Serial3 object -Uart Serial3( &sercom3, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX ); +// Instantiate SerialCpu object +Uart SerialCpu( &sercom3, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX ); void SERCOM3_Handler() { - Serial3.IrqHandler(); + SerialCpu.IrqHandler(); } // Instantiate Serial4 object -Uart Serial4( &sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX ); +Uart SerialMotorC( &sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX ); void SERCOM5_Handler() { - Serial4.IrqHandler(); + SerialMotorC.IrqHandler(); } diff --git a/hardware/openrov/samd/variants/trident/variant.h b/hardware/openrov/samd/variants/trident/variant.h index 70a8765..89cef73 100644 --- a/hardware/openrov/samd/variants/trident/variant.h +++ b/hardware/openrov/samd/variants/trident/variant.h @@ -1,113 +1,75 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - #pragma once -/*---------------------------------------------------------------------------- - * Definitions - *----------------------------------------------------------------------------*/ - -/** Frequency of the board main oscillator */ -#define VARIANT_MAINOSC (32768ul) - -/** Master clock frequency */ -#define VARIANT_MCK (48000000ul) - -/*---------------------------------------------------------------------------- - * Headers - *----------------------------------------------------------------------------*/ +// Defines +#define VARIANT_MAINOSC (32768ul) // Frequency of the board main oscillator +#define VARIANT_MCK (48000000ul) // Master clock frequency +// Includes #include "WVariant.h" #ifdef __cplusplus -#include "SERCOM.h" -#include "Uart.h" -#endif // __cplusplus + #include "SERCOM.h" + #include "Uart.h" +#endif #ifdef __cplusplus -extern "C" -{ -#endif // __cplusplus + extern "C" + { +#endif -/*---------------------------------------------------------------------------- - * Pins - *----------------------------------------------------------------------------*/ +// Pin setup // Number of pins defined in PinDescription array -#define PINS_COUNT (65u) // There are actually 64 pins, but the first pin in the pin descriptors is a dummy used to offset the pins to be 1-based -#define NUM_DIGITAL_PINS (14u) -#define NUM_ANALOG_INPUTS (14u) -#define NUM_ANALOG_OUTPUTS (0u) - -#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) -#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) -#define portOutputRegister(port) ( &(port->OUT.reg) ) -#define portInputRegister(port) ( &(port->IN.reg) ) -#define portModeRegister(port) ( &(port->DIR.reg) ) -#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) - -// Interrupts -#define digitalPinToInterrupt(P) ( g_APinDescription[P].ulExtInt ) - -// LEDs -#define PIN_LED_0 (31u) -#define PIN_LED_1 (28u) - -#define PIN_LED PIN_LED_0 -#define LED_BUILTIN PIN_LED_0 - -#define ADC_RESOLUTION 10 +#define PINS_COUNT (65u) // There are actually 64 pins, but the first pin in the pin descriptors is a dummy used to offset the pins to be 1-based +#define NUM_DIGITAL_PINS (14u) +#define NUM_ANALOG_INPUTS (14u) +#define NUM_ANALOG_OUTPUTS (0u) + +// Helpers for pin operations +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) +#define digitalPinToInterrupt(P) ( g_APinDescription[P].ulExtInt ) + +// ADC Configuration +#define ADC_RESOLUTION 10 // UART Interfaces -// UART0 (Primary Serial Port wth CTS+RTS) -#define PIN_SERIAL_RX (14u) -#define PIN_SERIAL_TX (13u) -#define PIN_SERIAL_RTS (15u) -#define PIN_SERIAL_CTS (16u) -#define PAD_SERIAL_TX (UART_TX_RTS_CTS_PAD_0_2_3) +// UART0 (Debug) +#define PIN_SERIAL_RX (10u) +#define PIN_SERIAL_TX (9u) +#define PAD_SERIAL_TX (UART_TX_PAD_0) #define PAD_SERIAL_RX (SERCOM_RX_PAD_1) -// UART1 (Programming/aux serial port) -#define PIN_SERIAL1_RX (30u) -#define PIN_SERIAL1_TX (29u) +// UART1 (ESCA) +#define PIN_SERIAL1_RX (22u) +#define PIN_SERIAL1_TX (21u) #define PAD_SERIAL1_TX (UART_TX_PAD_0) #define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) -// UART2 (Programming/aux serial port) -#define PIN_SERIAL2_RX (36u) -#define PIN_SERIAL2_TX (35u) +// UART2 (ESCB) +#define PIN_SERIAL2_RX (26u) +#define PIN_SERIAL2_TX (25u) #define PAD_SERIAL2_TX (UART_TX_PAD_0) #define PAD_SERIAL2_RX (SERCOM_RX_PAD_1) -// UART3 (Programming/aux serial port) -#define PIN_SERIAL3_RX (44u) -#define PIN_SERIAL3_TX (43u) +// UART3 (PI) +#define PIN_SERIAL3_RX (32u) +#define PIN_SERIAL3_TX (31u) #define PAD_SERIAL3_TX (UART_TX_PAD_0) #define PAD_SERIAL3_RX (SERCOM_RX_PAD_1) -// UART4 (Programming/aux serial port) -#define PIN_SERIAL4_RX (60u) -#define PIN_SERIAL4_TX (59u) +// UART4 (ESCC) +#define PIN_SERIAL4_RX (48u) +#define PIN_SERIAL4_TX (47u) #define PAD_SERIAL4_TX (UART_TX_PAD_0) #define PAD_SERIAL4_RX (SERCOM_RX_PAD_1) -// SPI interfaces +// SPI interfaces (None) #define SPI_INTERFACES_COUNT 0 // I2C Interfaces @@ -126,63 +88,30 @@ extern "C" } #endif -/*---------------------------------------------------------------------------- - * Arduino objects - C++ only - *----------------------------------------------------------------------------*/ +// C++ Object declarations #ifdef __cplusplus -/* ========================= - * ===== SERCOM DEFINITION - * ========================= -*/ -extern SERCOM sercom0; -extern SERCOM sercom1; -extern SERCOM sercom2; -extern SERCOM sercom3; -extern SERCOM sercom4; -extern SERCOM sercom5; - -extern Uart Serial; -extern Uart Serial1; -extern Uart Serial2; -extern Uart Serial3; -extern Uart Serial4; - + // SERCOM declarations + extern SERCOM sercom0; + extern SERCOM sercom1; + extern SERCOM sercom2; + extern SERCOM sercom3; + extern SERCOM sercom4; + extern SERCOM sercom5; + + // UART Declarations + extern Uart SerialDebug; + extern Uart SerialMotorA; + extern Uart SerialMotorB; + extern Uart SerialCpu; + extern Uart SerialMotorC; + + // I2C Declarations made in I2C library + // I2C interface and interrupt handler + #define PERIPH_WIRE sercom2 + #define WIRE_IT_HANDLER SERCOM2_Handler #endif -// These serial port names are intended to allow libraries and architecture-neutral -// sketches to automatically default to the correct port name for a particular type -// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, -// the first hardware serial port whose RX/TX pins are not dedicated to another use. -// -// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor -// -// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial -// -// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library -// -// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. -// -// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX -// pins are NOT connected to anything by default. - -// Serial has no physical pins broken out, so it's not listed as HARDWARE port -#define SERIAL_PORT_HARDWARE Serial -#define SERIAL_PORT_HARDWARE_OPEN Serial - -#define SERIAL_PORT_HARDWARE1 Serial1 -#define SERIAL_PORT_HARDWARE_OPEN1 Serial1 - -#define SERIAL_PORT_HARDWARE2 Serial2 -#define SERIAL_PORT_HARDWARE_OPEN2 Serial2 - -#define SERIAL_PORT_HARDWARE3 Serial3 -#define SERIAL_PORT_HARDWARE_OPEN3 Serial3 - -#define SERIAL_PORT_HARDWARE4 Serial4 -#define SERIAL_PORT_HARDWARE_OPEN4 Serial4 - -#define PERIPH_WIRE sercom2 -#define WIRE_IT_HANDLER SERCOM2_Handler + diff --git a/hardware/openrov/samd/variants/trident_alpha/debug_scripts/variant.gdb b/hardware/openrov/samd/variants/trident_alpha/debug_scripts/variant.gdb deleted file mode 100644 index 3c37ffd..0000000 --- a/hardware/openrov/samd/variants/trident_alpha/debug_scripts/variant.gdb +++ /dev/null @@ -1,31 +0,0 @@ -# -# Arduino Zero OpenOCD script. -# -# Copyright (c) 2014-2015 Arduino LLC. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -# Define 'reset' command -define reset - -info reg - -break main - -# End of 'reset' command -end - -target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/hardware/openrov/samd/variants/trident_alpha/linker_scripts/gcc/flash_with_bootloader.ld b/hardware/openrov/samd/variants/trident_alpha/linker_scripts/gcc/flash_with_bootloader.ld deleted file mode 100644 index 4475f95..0000000 --- a/hardware/openrov/samd/variants/trident_alpha/linker_scripts/gcc/flash_with_bootloader.ld +++ /dev/null @@ -1,211 +0,0 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* Linker script to configure memory regions. - * Need modifying for a specific board. - * FLASH.ORIGIN: starting address of flash - * FLASH.LENGTH: length of flash - * RAM.ORIGIN: starting address of RAM bank 0 - * RAM.LENGTH: length of RAM bank 0 - */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 -} - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * Reset_Handler : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __copy_table_start__ - * __copy_table_end__ - * __zero_table_start__ - * __zero_table_end__ - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __end__ - * end - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - */ -ENTRY(Reset_Handler) - -SECTIONS -{ - .text : - { - KEEP(*(.isr_vector)) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - KEEP(*(.eh_frame*)) - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* To copy multiple ROM to RAM sections, - * uncomment .copy.table section and, - * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ - /* - .copy.table : - { - . = ALIGN(4); - __copy_table_start__ = .; - LONG (__etext) - LONG (__data_start__) - LONG (__data_end__ - __data_start__) - LONG (__etext2) - LONG (__data2_start__) - LONG (__data2_end__ - __data2_start__) - __copy_table_end__ = .; - } > FLASH - */ - - /* To clear multiple BSS sections, - * uncomment .zero.table section and, - * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ - /* - .zero.table : - { - . = ALIGN(4); - __zero_table_start__ = .; - LONG (__bss_start__) - LONG (__bss_end__ - __bss_start__) - LONG (__bss2_start__) - LONG (__bss2_end__ - __bss2_start__) - __zero_table_end__ = .; - } > FLASH - */ - - __etext = .; - - .data : AT (__etext) - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP(*(SORT(.fini_array.*))) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - KEEP(*(.jcr*)) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (COPY): - { - __end__ = .; - PROVIDE(end = .); - *(.heap*) - __HeapLimit = .; - } > RAM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") -} diff --git a/hardware/openrov/samd/variants/trident_alpha/linker_scripts/gcc/flash_without_bootloader.ld b/hardware/openrov/samd/variants/trident_alpha/linker_scripts/gcc/flash_without_bootloader.ld deleted file mode 100644 index 0162f07..0000000 --- a/hardware/openrov/samd/variants/trident_alpha/linker_scripts/gcc/flash_without_bootloader.ld +++ /dev/null @@ -1,212 +0,0 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* Linker script to configure memory regions. - * Need modifying for a specific board. - * FLASH.ORIGIN: starting address of flash - * FLASH.LENGTH: length of flash - * RAM.ORIGIN: starting address of RAM bank 0 - * RAM.LENGTH: length of RAM bank 0 - */ -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 -} - -/* Linker script to place sections and symbol values. Should be used together - * with other linker script that defines memory regions FLASH and RAM. - * It references following symbols, which must be defined in code: - * Reset_Handler : Entry of reset handler - * - * It defines following symbols, which code can use without definition: - * __exidx_start - * __exidx_end - * __copy_table_start__ - * __copy_table_end__ - * __zero_table_start__ - * __zero_table_end__ - * __etext - * __data_start__ - * __preinit_array_start - * __preinit_array_end - * __init_array_start - * __init_array_end - * __fini_array_start - * __fini_array_end - * __data_end__ - * __bss_start__ - * __bss_end__ - * __end__ - * end - * __HeapLimit - * __StackLimit - * __StackTop - * __stack - * __ram_end__ - */ -ENTRY(Reset_Handler) - -SECTIONS -{ - .text : - { - KEEP(*(.isr_vector)) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - KEEP(*(.eh_frame*)) - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* To copy multiple ROM to RAM sections, - * uncomment .copy.table section and, - * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ - /* - .copy.table : - { - . = ALIGN(4); - __copy_table_start__ = .; - LONG (__etext) - LONG (__data_start__) - LONG (__data_end__ - __data_start__) - LONG (__etext2) - LONG (__data2_start__) - LONG (__data2_end__ - __data2_start__) - __copy_table_end__ = .; - } > FLASH - */ - - /* To clear multiple BSS sections, - * uncomment .zero.table section and, - * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ - /* - .zero.table : - { - . = ALIGN(4); - __zero_table_start__ = .; - LONG (__bss_start__) - LONG (__bss_end__ - __bss_start__) - LONG (__bss2_start__) - LONG (__bss2_end__ - __bss2_start__) - __zero_table_end__ = .; - } > FLASH - */ - - __etext = .; - - .data : AT (__etext) - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP(*(SORT(.fini_array.*))) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - KEEP(*(.jcr*)) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (COPY): - { - __end__ = .; - PROVIDE(end = .); - *(.heap*) - __HeapLimit = .; - } > RAM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") -} diff --git a/hardware/openrov/samd/variants/trident_alpha/openocd_scripts/sodaq_autonomo.cfg b/hardware/openrov/samd/variants/trident_alpha/openocd_scripts/sodaq_autonomo.cfg deleted file mode 100644 index 083166b..0000000 --- a/hardware/openrov/samd/variants/trident_alpha/openocd_scripts/sodaq_autonomo.cfg +++ /dev/null @@ -1,30 +0,0 @@ -# -# Arduino Zero OpenOCD script. -# -# Copyright (c) 2014-2015 Arduino LLC. All right reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# - -source [find interface/cmsis-dap.cfg] - -# chip name -set CHIPNAME at91samd21j18 -set ENDIAN little - -# choose a port here -set telnet_port 0 - -source [find target/at91samdXX.cfg] diff --git a/hardware/openrov/samd/variants/trident_alpha/variant.cpp b/hardware/openrov/samd/variants/trident_alpha/variant.cpp deleted file mode 100644 index 206fefc..0000000 --- a/hardware/openrov/samd/variants/trident_alpha/variant.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -/* - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * + Pin number + Trident pin | PIN | Label/Name | Comments (* is for default peripheral in use) - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | Digital Low | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - */ - - -#include "variant.h" - -// Shorthand to collapse the table some more -#define PIN_ATTRIBUTE_PWM (PIN_ATTR_DIGITAL | PIN_ATTR_PWM | PIN_ATTR_TIMER) - -// Pin Descriptions for Rovduino -const PinDescription g_APinDescription[] = -{ - // | PORT | PIN | PIN_TYPE | PIN_ATTRIBUTES | ADC_CHANNEL | PWM_CHANNEL | TIMER_CHANNEL | EXT. INTERRUPT | // Pin | Description - - // NOTE! - // DUM(MY) pins should not be used. Their purpose is to make the array index of these pin descriptors match the pin numbers on the board. - // Some of them describe actual pins, just not GPIO pins, such as the oscillator, power, ground, debug, etc pins. Just FYI. - // They are set up to redundantly describe the EN_PROGRAM pin, which will be safe, just in case you don't see this and try. - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 0 -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 1 | XOSCIN32 -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 2 | XOSCOUT32 - - { PORTA , 2 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel0 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 3 | A0, Batt1_V - { PORTA , 3 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel1 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 4 | A1, Batt2_V - { PORTB , 4 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel12 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 5 | A12, ExtLoad_I - { PORTB , 5 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel13 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 6 | A13, ESC1_I - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 7 | GNDANA -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 8 | VDDANA - - { PORTB , 6 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel14 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 9 | A14, BattBus_V - { PORTB , 7 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel15 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 10 | A15, ESC2_I - { PORTB , 8 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel2 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 11 | A2, NonESC_I - { PORTB , 9 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel3 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 12 | A3, ESC3_I - - { PORTA , 4 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 13 | SERCOM0/PAD[0], UART0 TX - { PORTA , 5 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 14 | SERCOM0/PAD[1], UART0 RX - { PORTA , 6 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 15 | SERCOM0/PAD[2], UART0 RTS - { PORTA , 7 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 16 | SERCOM0/PAD[3], UART0 CTS - - { PORTA , 8 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 17 | SERCOM2/PAD[0], I2C1 SDA - { PORTA , 9 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 18 | SERCOM2/PAD[1], I2C1 SCL - - { PORTA , 10 , PIO_TIMER_ALT , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM0_CH2 , TCC0_CH2 , EXTERNAL_INT_NONE }, // 19 | TCC1_0, PWM5 // TCC0 2 - { PORTA , 11 , PIO_TIMER_ALT , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM0_CH3 , TCC0_CH3 , EXTERNAL_INT_NONE }, // 20 | TCC1_1, PWM6 // TCC0 3 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 21 | VDDIO -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 22 | GND - - { PORTB , 10 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 23 | Servo1 (Motor1) // TC5 0 - { PORTB , 11 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 24 | Servo2 (Motor2) // TC5 1 - { PORTB , 12 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 25 | Servo3 (Motor3) // TC4 0 - { PORTB , 13 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 26 | Servo4 (Motor4) // TC4 1 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 27 | N/A - - { PORTB , 15 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 28 | GPIO6, LED_1 - - { PORTA , 12 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 29 | SERCOM4/PAD[0], I2C0 SDA - { PORTA , 13 , PIO_SERCOM_ALT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 30 | SERCOM4/PAD[1], I2C0 SCL - - { PORTA , 14 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 31 | GPIO5, LED_0 - { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 32 | GPIO4, EN_PROGRAM - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 33 | GND -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 34 | VDDIO - - { PORTA , 16 , PIO_TIMER , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM2_CH0 , TCC2_CH0 , EXTERNAL_INT_NONE }, // 35 | TCC2_0, PWM1 (IntLights) // TCC0 6 - { PORTA , 17 , PIO_TIMER , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM2_CH1 , TCC2_CH1 , EXTERNAL_INT_NONE }, // 36 | TCC2_1, PWM2 (Lasers) // TCC0 7 - - { PORTA , 18 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 37 | Servo5 (Motor5) // TC3 0 - { PORTA , 19 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 38 | Servo6 (Motor6) // TC3 1 - - { PORTB , 16 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 39 | SERCOM5/PAD[0], SPI0 MOSI - { PORTB , 17 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 40 | SERCOM5/PAD[1], SPI0 SCK - { PORTA , 20 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 41 | SERCOM5/PAD[2], SPI0 MISO - - { PORTA , 21 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 42 | GPIO3, EN_ESC - - { PORTA , 22 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 43 | SERCOM3/PAD[0], UART1 TX - { PORTA , 23 , PIO_SERCOM , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 44 | SERCOM3/PAD[1], UART1 RX - - { PORTA , 24 , PIO_TIMER_ALT , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM1_CH2 , TCC1_CH2 , EXTERNAL_INT_NONE }, // 45 | TCC1_2, PWM3 (ExtLights) // TC5 0 - { PORTA , 25 , PIO_TIMER_ALT , PIN_ATTRIBUTE_PWM , No_ADC_Channel , PWM1_CH3 , TCC1_CH3 , EXTERNAL_INT_NONE }, // 46 | TCC1_3, PWM4 // TC5 1 - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 47 | GND -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 48 | VDDIO - - { PORTB , 22 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 49 | GPIO2, ESC_PRECHARGE - { PORTB , 23 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 50 | GPIO1, EN_EXTI2C - { PORTA , 27 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 51 | GPIO0, EN_INTI2C - -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 52 | RESETN -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 53 | SPARE -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 54 | GND -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 55 | VDDCORE -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 56 | VDDIN -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 57 | DEBUG SWCLK -/*DUM*/ { PORTA , 15 , PIO_INPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 58 | DEBUG SWDIO - - { PORTB , 30 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 59 | Servo7 (CamTilt) // TCC0 0 - { PORTB , 31 , PIO_OUTPUT , PIN_ATTR_DIGITAL , No_ADC_Channel , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 60 | Servo8 (ExtServo) // TCC0 1 - - { PORTB , 0 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel8 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 61 | A8, BattTube1_I - { PORTB , 1 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel9 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 62 | A9, BattTube2_I - { PORTB , 2 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel10 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE }, // 63 | A10, HUMIDITY - { PORTB , 3 , PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel11 , NOT_ON_PWM , NOT_ON_TIMER , EXTERNAL_INT_NONE } // 64 | A11, BoardTemp -}; - -const void* g_apTCInstances[ TCC_INST_NUM+TC_INST_NUM ]= { TCC0, TCC1, TCC2, TC3, TC4, TC5, TC6, TC7 }; - -// Multi-serial objects instantiation -SERCOM sercom0( SERCOM0 ); -SERCOM sercom1( SERCOM1 ); -SERCOM sercom2( SERCOM2 ); -SERCOM sercom3( SERCOM3 ); -SERCOM sercom4( SERCOM4 ); -SERCOM sercom5( SERCOM5 ); - -// Instantiate Serial object -Uart Serial( &sercom0, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ); - -void SERCOM0_Handler() -{ - Serial.IrqHandler(); -} - -// Instantiate Serial1 object -Uart Serial1( &sercom3, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ); - -void SERCOM3_Handler() -{ - Serial1.IrqHandler(); -} - diff --git a/hardware/openrov/samd/variants/trident_alpha/variant.h b/hardware/openrov/samd/variants/trident_alpha/variant.h deleted file mode 100644 index 5d52c48..0000000 --- a/hardware/openrov/samd/variants/trident_alpha/variant.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - Copyright (c) 2014-2015 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#pragma once - -/*---------------------------------------------------------------------------- - * Definitions - *----------------------------------------------------------------------------*/ - -/** Frequency of the board main oscillator */ -#define VARIANT_MAINOSC (32768ul) - -/** Master clock frequency */ -#define VARIANT_MCK (48000000ul) - -/*---------------------------------------------------------------------------- - * Headers - *----------------------------------------------------------------------------*/ - -#include "WVariant.h" - -#ifdef __cplusplus -#include "SERCOM.h" -#include "Uart.h" -#endif // __cplusplus - -#ifdef __cplusplus -extern "C" -{ -#endif // __cplusplus - -/*---------------------------------------------------------------------------- - * Pins - *----------------------------------------------------------------------------*/ - -// Number of pins defined in PinDescription array -#define PINS_COUNT (65u) // There are actually 64 pins, but the first pin in the pin descriptors is a dummy used to offset the pins to be 1-based -#define NUM_DIGITAL_PINS (7u) -#define NUM_ANALOG_INPUTS (12u) -#define NUM_ANALOG_OUTPUTS (0u) - -#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) -#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) -#define portOutputRegister(port) ( &(port->OUT.reg) ) -#define portInputRegister(port) ( &(port->IN.reg) ) -#define portModeRegister(port) ( &(port->DIR.reg) ) -#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) - -// Interrupts -#define digitalPinToInterrupt(P) ( g_APinDescription[P].ulExtInt ) - -// LEDs -#define PIN_LED_0 (31u) -#define PIN_LED_1 (28u) - -#define PIN_LED PIN_LED_0 -#define LED_BUILTIN PIN_LED_0 - - -#define ADC_RESOLUTION 12 - -// UART Interfaces - -// UART0 (Primary Serial Port wth CTS+RTS) -#define PIN_SERIAL_RX (14u) -#define PIN_SERIAL_TX (13u) -#define PIN_SERIAL_RTS (15u) -#define PIN_SERIAL_CTS (16u) -#define PAD_SERIAL_TX (UART_TX_RTS_CTS_PAD_0_2_3) -#define PAD_SERIAL_RX (SERCOM_RX_PAD_1) - -// UART1 (Programming/aux serial port) -#define PIN_SERIAL1_RX (44u) -#define PIN_SERIAL1_TX (43u) -#define PAD_SERIAL1_TX (UART_TX_PAD_0) -#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) - -// SPI interfaces -#define SPI_INTERFACES_COUNT 1 - -#define PIN_SPI_MISO (41u) -// #define PIN_SPI_SS (43u) -#define PIN_SPI_MOSI (39u) -#define PIN_SPI_SCK (40u) - -static const uint8_t MISO = PIN_SPI_MISO; -// static const uint8_t SS = PIN_SPI_SS ; -static const uint8_t MOSI = PIN_SPI_MOSI ; -static const uint8_t SCK = PIN_SPI_SCK ; - - -// I2C Interfaces -#define WIRE_INTERFACES_COUNT 2 - -// SERCOM4 -#define PIN_WIRE_SDA (29u) -#define PIN_WIRE_SCL (30u) - -// SERCOM2 -#define PIN_WIRE1_SDA (17u) -#define PIN_WIRE1_SCL (18u) - -// Unused USB pins -#define PIN_USB_DM 0 -#define PIN_USB_DP 0 -#define PIN_USB_HOST_ENABLE 0 - -#ifdef __cplusplus -} -#endif - -/*---------------------------------------------------------------------------- - * Arduino objects - C++ only - *----------------------------------------------------------------------------*/ - -#ifdef __cplusplus - -/* ========================= - * ===== SERCOM DEFINITION - * ========================= -*/ -extern SERCOM sercom0; -extern SERCOM sercom1; -extern SERCOM sercom2; -extern SERCOM sercom3; -extern SERCOM sercom4; -extern SERCOM sercom5; - -extern Uart Serial; -extern Uart Serial1; - -#endif - -// These serial port names are intended to allow libraries and architecture-neutral -// sketches to automatically default to the correct port name for a particular type -// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, -// the first hardware serial port whose RX/TX pins are not dedicated to another use. -// -// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor -// -// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial -// -// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library -// -// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. -// -// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX -// pins are NOT connected to anything by default. - -// Serial has no physical pins broken out, so it's not listed as HARDWARE port -#define SERIAL_PORT_HARDWARE Serial -#define SERIAL_PORT_HARDWARE_OPEN Serial - -#define SERIAL_PORT_HARDWARE1 Serial1 -#define SERIAL_PORT_HARDWARE_OPEN1 Serial1 - -#define PERIPH_WIRE sercom4 -#define WIRE_IT_HANDLER SERCOM4_Handler - -#define PERIPH_WIRE1 sercom2 -#define WIRE1_IT_HANDLER SERCOM2_Handler