diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/bin/openblt_xmc4700.srec b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/bin/openblt_xmc4700.srec index 7af398d3..b9ce455a 100644 --- a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/bin/openblt_xmc4700.srec +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/bin/openblt_xmc4700.srec @@ -1,528 +1,1706 @@ -S31508000000D0130020A1020008AD020008AD020008C6 -S31508000010AD020008AD020008AD02000800000000AD -S31508000020000000000000000000000000AD0200080B -S31508000030AD02000800000000AD020008AD0200088D -S31508000040AD020008AD020008AD020008AD020008C6 -S31508000050AD020008AD020008AD020008AD020008B6 -S31508000060AD020008000000000000000000000000CB -S31508000070AD02000800000000AD020008AD0200084D -S31508000080AD020008AD020008AD020008AD02000886 -S31508000090AD020008AD020008AD020008AD02000876 -S315080000A0AD020008AD020008AD020008AD02000866 -S315080000B0AD020008AD020008AD020008AD02000856 -S315080000C0AD020008AD020008AD020008AD02000846 -S315080000D0AD020008AD020008AD020008AD02000836 -S315080000E0AD020008AD020008AD020008AD02000826 -S315080000F0AD020008AD020008AD020008AD02000816 -S31508000100AD020008AD020008AD020008AD02000805 -S31508000110AD020008AD020008AD020008AD020008F5 -S31508000120AD020008AD020008AD020008AD020008E5 -S31508000130AD020008AD020008AD020008AD020008D5 -S31508000140AD020008AD020008AD020008AD020008C5 -S31508000150AD020008AD020008AD020008AD020008B5 +S31508000000A01E0020B1020008BD020008BD020008BB +S31508000010BD020008BD020008BD020008000000007D +S31508000020000000000000000000000000BD020008FB +S31508000030BD02000800000000BD020008BD0200085D +S31508000040BD020008BD020008BD020008BD02000886 +S31508000050BD020008BD020008BD020008BD02000876 +S31508000060BD020008000000000000000000000000BB +S31508000070BD02000800000000BD020008BD0200081D +S31508000080BD020008BD020008BD020008BD02000846 +S31508000090BD020008BD020008BD020008BD02000836 +S315080000A0BD020008BD020008BD020008BD02000826 +S315080000B0BD020008BD020008BD020008BD02000816 +S315080000C0BD020008BD020008BD020008BD02000806 +S315080000D0BD020008BD020008BD020008BD020008F6 +S315080000E0BD020008BD020008BD020008BD020008E6 +S315080000F0BD020008BD020008BD020008BD020008D6 +S31508000100BD020008BD020008BD020008BD020008C5 +S31508000110BD020008BD020008BD020008BD020008B5 +S31508000120BD020008BD020008BD020008BD020008A5 +S31508000130BD020008BD020008BD020008BD02000895 +S31508000140BD020008BD020008BD020008BD02000885 +S31508000150BD020008BD020008BD020008BD02000875 S315080001600000000000000000000000000000000081 -S31508000170AD020008AD020008AD020008AD02000895 -S31508000180AD020008AD020008AD020008AD02000885 -S31508000190AD020008AD020008AD020008AD02000875 -S315080001A0AD020008AD020008AD020008AD02000865 -S315080001B0AD020008AD020008AD020008AD02000855 -S315080001C0AD020008AD020008AD020008AD02000845 -S315080001D0AD020008AD020008AD02000800000000EC -S315080001E0AD020008AD020008AD020008AD02000825 -S315080001F0AD02000800000000AD0200080000000083 -S3150800020000F002F800F03CF80AA090E8000C8244DE -S315080002108344AAF10107DA4501D100F031F8AFF2BB +S31508000170BD020008BD020008BD020008BD02000855 +S31508000180BD020008BD020008BD020008BD02000845 +S31508000190BD020008BD020008BD020008BD02000835 +S315080001A0BD020008BD020008BD020008BD02000825 +S315080001B0BD020008BD020008BD020008BD02000815 +S315080001C0BD020008BD020008BD020008BD02000805 +S315080001D0BD020008BD020008BD02000800000000BC +S315080001E0BD020008BD020008251A0008BD02000865 +S315080001F0BD02000800000000BD0200080000000063 +S3150800020000F002F800F045F80AA090E8000C8244D5 +S315080002108344AAF10107DA4501D100F03AF8AFF2B2 S31508000220090EBAE80F0013F0010F18BFFB1A43F0C6 -S3150800023001031847441E0000641E0000103A24BF3C +S31508000230010318474C6600006C660000103A24BF9C S3150800024078C878C1FAD8520724BF30C830C144BF2D S3150800025004680C607047000000230024002500266F S31508000260103A28BF78C1FBD8520728BF30C148BF0B -S315080002700B6070471FB501F0A7FE1FBD10B510BD76 -S3150800028000F0A4F81146FFF7F5FF01F094FE00F020 -S31508000290C2F803B4FFF7F2FF03BC00F0C9F8000088 -S315080002A0DFF818D00648804706480047FEE70000F2 -S315080002B005480649064A074B70470000D013002038 -S315080002C0E911000801020008D0090020D013002017 -S315080002D0D00B0020D00B0020032A40F2308010F00B -S315080002E0030C00F0158011F8013BBCF1020F6244C3 -S315080002F098BF11F801CB00F8013B38BF11F8013B54 -S31508000300A2F1040298BF00F801CB38BF00F8013B00 -S3150800031011F0030300F02880083AC0F0088051F86D -S31508000320043B083A51F804CBA0E80810F5E7121D7B -S315080003305CBF51F8043B40F8043BAFF30080D2079A -S3150800034024BF11F8013B11F801CB48BF11F8012B66 -S3150800035024BF00F8013B00F801CB48BF00F8012B89 -S31508000360704770477047704710B5203AC0F00B8049 -S31508000370B1E81850203AA0E81850B1E81850A0E89B -S315080003801850BFF4F5AF5FEA027C24BFB1E81850F5 -S31508000390A0E8185044BF18C918C0BDE810405FEA65 -S315080003A0827C24BF51F8043B40F8043B08BF7047E1 -S315080003B0D20728BF31F8023B48BF11F8012B28BFE6 -S315080003C020F8023B48BF00F8012B7047754600F03D -S315080003D02BF8AE4605006946534620F007008546C9 -S315080003E018B020B5FFF764FFBDE820404FF00006BF -S315080003F04FF000074FF000084FF0000B21F00701FF -S31508000400AC46ACE8C009ACE8C009ACE8C009ACE841 -S31508000410C0098D46704710B50446AFF300802046E4 -S31508000420BDE81040FFF735BF004870476C0900204B -S3150800043001491820ABBEFEE726000200704700F00F -S31508000440C4F9FCE710B500F07BF9012812D00A4C74 -S31508000450207801280ED100F0D5FED4E90112114406 -S3150800046001F5FA71884205D300202070BDE81040D6 -S3150800047000F0C4B910BD00000800002010B50449FA -S315080004800120087000F006F8BDE81040FFF7DABF53 -S315080004900800002010B5044C2078012802D100F08D -S315080004A0B1FEA06010BD00000800002010B500F0E5 -S315080004B090F900F085F900F0ADFE00F023FC00F09D -S315080004C02FF9BDE81040FFF7D9BF10B500F07DF948 -S315080004D000F0BAFE00F03CF9BDE81040FFF7B2BFE5 -S315080004E02DE9FE4301F058F90446484D02E0640040 -S315080004F000F06BF9AC42FAD3454D02E0640800F00F -S3150800050064F9AC42FAD8DFF80C812246012140464C -S3150800051000F0E4FE0094404801904FF4FA50ADF81C -S3150800052008004FF00109ADF80A903C4E694670681C -S3150800053000F0FEFF7068016841F040010160016843 -S3150800054041F001010160374C35482060606820F0B1 -S31508000550404000F1004040F2E17161F31C00A268DE -S3150800056061F31C02A26020F000506060204600F093 -S31508000570FBFE082727730020002503E021180D74C9 -S31508000580401CC0B2217B8142F8D884F818902548CF -S3150800059000F0F4FE00220121404600F061FE2048EA -S315080005A0204C203020342060606820F0404000F164 -S315080005B0004040F2676161F31C00A26861F31C0207 -S315080005C0A26020F000506060204600F0CDFE277340 -S315080005D0002103E060180574491CC9B2207B8842D3 -S315080005E0F8D825760F48203000F0C8FE01221146BB -S315080005F0404600F035FE7068016821F04001016050 -S31508000600016821F001010160BDE8FE83001BB70007 -S31508000610000E27070040014820A107001800002007 -S3150800062000500148E00000202DE9F04106460F463B -S3150800063000250E4C2068C069C00713D0204600F07C -S31508000640EBFE60B9207B3870002105E06018007C5D -S3150800065070540125491CC9B2207B8842F6D801206E -S315080006602168C8612846BDE8F08100000001002025 -S3150800067070B5124C2173002104E06318425C1A74A9 -S31508000680491CC9B2227B8A42F7D80C4800F034FFCD -S3150800069002202168C861094800F01AFF00F0B2FD7F -S315080006A000F1320505E000F090F800F0ABFDA84235 -S315080006B003D82068C0698007F5D470BDE000002023 -S315080006C0FFF7E8BE7047000009480078002807D001 -S315080006D0012807D0022807D0032807D040207047F2 -S315080006E04020704708207047002070474020704718 -S315080006F01400002009480078002807D0012807D0F0 -S31508000700022807D0032807D04020704740207047AA -S3150800071008207047002070474020704714000020CA -S3150800072010B501F091FBFFF7DBFE044C01202070A9 -S3150800073000F03EFB0020207010BD000014000020D1 -S3150800074010B5002401F08CFB00B10124204610BD31 -S3150800075038B569460C48FFF767FF0C4C012805D1E8 -S3150800076020709DF80010084801F086FB6946064887 -S3150800077000F05EFB012806D1002020709DF80010CD -S31508000780014801F079FB38BD540000201400002010 -S3150800079070B506460C46094D2878012803D1E1B202 -S315080007A03046FFF765FF287818B9E1B2304600F001 -S315080007B0ABFBBDE8704001F0CDBB00001400002083 -S315080007C0AFF30080642000F06BBAAFF3008000F04E -S315080007D06DBAAFF3008072B6704762B6704770B5EF -S315080007E005460C46164605E014F8010B05F8010BFC -S315080007F0FFF7EBFF761EB6B2F6D270BD10B500F065 -S3150800080083FAB0B100F022F8B8B1FFF75BFF00F049 -S3150800081013FD00F075FA0B4908400B49086000F013 -S315080008206FFA4468FFF7D9FFA047BDE81040FFF705 -S3150800083047BFBDE81040FFF743BFBDE81040FFF7CC -S315080008403FBF000080FFFF1F08ED00E010B5064817 -S31508000850406AC0F34030002803D000F019FA01209E -S3150800086010BD002010BD0000008F02482DE9F0479A -S3150800087004460D4616461F464FEA95294FEA89292A -S315080008802068401C04D14946204600F0F7F838B3E2 -S315080008902068484505D04946204600F001F9044637 -S315080008A004B32068281A05192D1D4FF4806809F528 -S315080008B08069FFF78AFF281B001F404506D3494673 -S315080008C0204600F0EDF8044674B1251D16F8010B14 -S315080008D005F8010B7F1E002FEBD10120BDE8F0873C -S315080008E00020FBE70020F9E70020F7E710B50B48E2 -S315080008F00068401C03D0094800F04EF948B1084882 -S315080009000068401C03D0064800F046F918B10120DB -S3150800091010BD002010BD002010BD000024050020D9 -S315080009202001002070B50D4600F0DCF804460D489D -S31508000930011B681E814201D2002070BD204600F0CE -S3150800094051F806466019401E00F04CF80146FF2E85 -S3150800095006D0FF2904D03046BDE8704000F004B840 -S31508000960002070BDFFFF1F0C2DE9F0410F46B8426D -S3150800097002D90020BDE8F081032801D30F2F01D941 -S315080009800020F7E7044629E0FFF71FFF204600F09E -S3150800099049F80546681C08D000F034FC41F6C81131 -S315080009A04618284600F046FE09E00020E2E700F077 -S315080009B029FCB04201D90020DCE7FFF706FF00F06A -S315080009C047FEC0F300000028F1D100F041FE20F0F8 -S315080009D0200008B10020CDE7641CE4B2BC42D3D99C -S315080009E00120C7E770B5054600240D4EFFF7EDFE5A -S315080009F004EB440156F82120AA420BD806EB8100E5 -S31508000A0040681044A84205D904EB440006EB800070 -S31508000A10007A70BD641CE4B20D2CE7D3FF2070BDCC -S31508000A20DC1F00082DE9F04106464FF0FF37002489 -S31508000A300A4DFFF7CAFE04EB440005EB8000007A76 -S31508000A40B04204D104EB440055F8207003E0641C5E -S31508000A50E4B20D2CEDD33846BDE8F081DC1F000862 -S31508000A600048704700C0000C03494FF0FF3008608B -S31508000A7001F20441086070472001002010B58A057C -S31508000A8001D0002010BD02688A4201D1012010BDA4 -S31508000A9002C04FF48062FFF7A2FE012010BD0000DD -S31508000AA070B504460D460D48844202D1A0F20444AE -S31508000AB009E00B48854202D1084C054603E020466A -S31508000AC000F06AF830B129462046FFF7D7FF18B17B -S31508000AD0204670BD002070BD002070BD2405002092 -S31508000AE000C0000C0821B1EB106F01D100F1806045 -S31508000AF0704700000B480168426811448268114437 -S31508000B00C268114402691144426911448269114458 -S31508000B10C943D0F80002814201D101207047002064 -S31508000B207047000000C0000C70B50D461646FFF76A -S31508000B30D9FF04461448011B681E814201D20020D1 -S31508000B4070BD2046FFF74EFFFF2812D06019401EE1 -S31508000B50FFF748FFFF280CD0A00A80020B498842FD -S31508000B6009D12B4632462146BDE870400848FFF7B2 -S31508000B707DBE002070BD2B4632462146BDE870403A -S31508000B800448FFF773BE0000FFFF1F0C00C0000CEF -S31508000B9024050020200100202DE9F0410646306892 -S31508000BA0FFF720FFFF2811D00024FFF70EFE30685C -S31508000BB000EB042806EB04273F1D00F023FB00F199 -S31508000BC00D053946404600F049FD0AE00020BDE81B -S31508000BD0F08100F017FBA84201D90020F7E7FFF7DC -S31508000BE0F4FD00F035FDC0F300000028F1D100F057 -S31508000BF02FFD20F0100008B10020E8E7002018F8C3 -S31508000C0000103A5C914201D00020E0E7401CFF2822 -S31508000C10F5D9641C042CC8D30120D8E708B50020F0 -S31508000C2000900D480168491C14D041688268114437 -S31508000C30C268114402691144426911448269114427 -S31508000C40C0690844C04300906A4604210348FFF778 -S31508000C506BFF08BD012008BD2405002000C2000C5A -S31508000C6010B500F05BFA80220921074800F084FDE0 -S31508000C70064C00220D21204600F07EFD216E21F44F -S31508000C800051216610BD000000850248008F024809 -S31508000C9002494FF00070486070470000008502481E -S31508000CA001494880704700000000002010B500F098 -S31508000CB0A9FA0B4C616888420CD32178094851B1CE -S31508000CC0002121704FF00071416000F09BFA6188A5 -S31508000CD00844606010BD0121217049024160F4E7B3 -S31508000CE0000000200085024810B5FFF797FF18B1ED -S31508000CF0BDE81040FFF7FABD002010BDFFF712BE91 -S31508000D00FFF7AEBEFFF7B0BEFFF7F4BEFFF70CBFA6 -S31508000D1000487047001BB7002DE9F0418CB000274A -S31508000D208DF8247001250A9502248DF82C40DFF8E9 -S31508000D30748009AA0421404600F0E2FC90268DF84A -S31508000D40186007958DF8204006AA0521404600F050 -S31508000D50D7FC1549C86920F0070040F00100C861B2 -S31508000D608DF80C7003AA0D21404600F0C9FC8DF8D9 -S31508000D70006001958DF808406A460C21404600F04F -S31508000D80BFFC0A48016841F040010160C16864F38C -S31508000D900201C160016821F0400101600CB0BDE8A4 -S31508000DA0F08100000081024800000340004301482A -S31508000DB03EB54FF46140009008208DF805008DF887 -S31508000DC0060001208DF8070010208DF80800002085 -S31508000DD0ADF80A000B4C6946206800F035FD012382 -S31508000DE004221021206800F059FE01230422002164 -S31508000DF0206800F0B5FD2068016C21F00F01891C00 -S31508000E0001643EBD3800002010B504460748006856 -S31508000E10D0F81411C1F3C001002901D0002010BD7B -S31508000E2000F006FD2070012010BD000038000020EB -S31508000E302DE9F04180460F461B4C00251B4E607875 -S31508000E40002810D020783044401CFFF7DDFF012829 -S31508000E5019D000F0D7F961686431884200D9657005 -S31508000E600020BDE8F0811148FFF7CEFF0128F7D131 -S31508000E703078401E3F28F3D800F0C4F9606025702A -S31508000E8001206070ECE72078401CC2B222703078EE -S31508000E9031469042E4D1491C4046FFF7A0FC6570F4 -S31508000EA0207838700120DCE730000020280900206F -S31508000EB070B501460126134D2868D0F81421C2F3EF -S31508000EC00032002A01D0002070BD00F0FEFC00F0C0 -S31508000ED099F900F10A0407E0FFF777FC00F092F9A8 -S31508000EE0A04201D9002606E02868D0F8140100F4CB -S31508000EF04070C005F0D528684FF48071C0F8181105 -S31508000F00304670BD3800002070B505460E46402EA6 -S31508000F1003D97A210EA0FFF792FA3046FFF7C8FFE9 -S31508000F20012803D07E210AA0FFF789FA00240CE0E5 -S31508000F30FFF74BFC285DFFF7BBFF012803D087218D -S31508000F4003A0FFF77CFA641CA4B2B442F0D370BDC8 -S31508000F502E2E5C2E2E5C2E2E5C2E2E5C536F7572FA -S31508000F6063655C41524D434D345F584D43345C7262 -S31508000F70733233322E63000070B55948D0F8001228 -S31508000F80C90709D1D0F8041241F00101C0F80412CA -S31508000F90D0F80012C907FBD052480068800509D569 -S31508000FA050480830016841F40071016041F64C5020 -S31508000FB000F0F5FF4C4C206840F40020206040F615 -S31508000FC0C41000F0ECFF2068484908402060464EEF -S31508000FD0103E3068A4F1040510F0300F1CD03068BC -S31508000FE0434908403060FFF793FE4249B0FBF1F0F1 -S31508000FF03168401E41EA004030603B4808300168CD -S3150800100021F001010160206820F400302060286882 -S31508001010C0F3C2100728FAD1206840F0010020600A -S31508001020206840F0100020602F4E3348361D30608F -S31508001030206840F040002060206820F01000206002 -S31508001040206840F48020206028684007FCD5206886 -S3150800105020F0010020602868C007FCD127494FF01E -S31508001060011008602548002508300560001F056046 -S31508001070224814300560001D056020480321103001 -S315080010800160001F1E4901601C491E481C3108608A -S31508001090206820F0400020601B4830604FF416603E -S315080010A000F07DFF194830604FF4616000F077FF6B -S315080010B0174830604FF4965000F071FF15483060BD -S315080010C041F2707000F06BFF134830604FF4E15046 -S315080010D000F065FF09480838056000F01FF870BD84 -S315080010E0004000500044005014470050FDFFFEFF2A -S315080010F0CFFFF0FFA0252600002F0B010C4600505D -S315080011000500010003002001002F0501002F03013F -S31508001110002F0201002F0101002F000110B51C4C01 -S315080011202068C1031B4823D51B490968C90701D193 -S31508001130FFF7EEFD18490C3909684A07174911D512 -S315080011400A68C2F303635B1C0A68C2F30622521CD0 -S315080011500968C1F30641491C13FB01F1B0FBF1F024 -S31508001160504305E0096801F07F01491CB0FBF1F026 -S315080011702168C9B2491CB0FBF1F00549091D096887 -S3150800118001F00101491CB0FBF1F00549086010BDEA -S315080011900C46005000366E011C4700501847005098 -S315080011A0C0FF032072B60D480D490860BFF34F8F84 -S315080011B062B60B488030016841F470010160084846 -S315080011C00C30016821F0080101600649486920F0E1 -S315080011D00F0040F004004861704700000000000856 -S315080011E008ED00E00020005810B51022510604480A -S315080011F0FFF772F8FFF7D6FFFFF7BEFE10BD000037 -S31508001200C4FF032000B500F01FF80148006800BDC0 -S315080012105000002000B500F00FF84FF0E020044918 -S31508001220416100218161052202610248016000BD19 -S315080012307F320200500000204FF0E02000210161BB -S3150800124041618161704700004FF0E0200069C003EA -S3150800125003D502480168491C016070475000002008 -S31508001260D0F8C43113F4407F0BD00023002BF7D0FD -S315080012700223491C43EA024242EA0161C0F8C4114A -S3150800128070470123F2E7000070B50446074D28466B -S3150800129000F0A0FA284600F0ABFA206820F001001A -S315080012A0206020688007FCD470BD00001000001084 -S315080012B010B500F00EF8012803D0022805D000204A -S315080012C010BDBDE8104000F067BABDE81040FFF752 -S315080012D01FBDD0F8C80100F00F0070472DE9F04196 -S315080012E004460E4615462046FFF7CEFF31462046F1 -S315080012F000F097F92046FFF7DBFFB0FBF5F1C1F5E3 -S31508001300806140F2FF36B14200D33146C1F58062B2 -S31508001310B0FBF2F7AB0982099802B0FBF2F3B342CD -S3150800132000D3334618464243920A9201EB1BAA1A87 -S31508001330934201D8012200E00022002A00D0084684 -S3150800134002D04FF0010101E04FF00201E2684CF2D1 -S31508001350FF3322EA0302E260E26840EA813042EAA9 -S315080013600002E260BDE8F081816841F000518160C9 -S315080013700068C16841F00051C160704710B5044665 -S3150800138022482168084440094209520300F01F0018 -S3150800139042EA0022886820F47F40886020688168D5 -S315080013A011438160207E002801D0012822D12168BE -S315080013B02020C861606881000DD400F0604141EAD0 -S315080013C0804021688861A06800F0604141EA804059 -S315080013D02168C86004E0216888612168A068C8603F -S315080013E0207E012807D021684FF40060C861216873 -S315080013F00748C86110BD204600F07EF821684FF006 -S315080014000060C86121680348C86110BD00B0FEB716 -S315080014104006A000C000200610B50168CA69C2F3DC -S31508001420C022C969C1F38001002A01D0032010BD7A -S3150800143001291FD008230168CB6101688A699200D7 -S315080014401FD4426822F0005242608C69C4F38A4471 -S3150800145064F31C024260CA68540F826864F35D72C2 -S315080014608260940008D5CC68C4F38A4464F31C02ED -S31508001470826018E0022010BDCC6864F31C0282600A -S3150800148011E0426842F0005242608C6964F31C0223 -S315080014904260CC68826864F31C028260CC68640F80 -S315080014A064F35D7282600A68C2F3036202730A69B2 -S315080014B002614A694261CA69C2F38002C969C1F315 -S315080014C0C0010AB10029B6D100210176002010BD5D -S315080014D00068C169C1F34012C169C1F30021002A3D -S315080014E006D0012906D04FF0E061C161002070479F -S315080014F004207047022070470321027E012A12D178 -S3150800150002682021D1610168037B0A6863F31B62C4 -S315080015100A600268016911610268416951610068DF -S315080015200249C161002108467047000040002800B2 -S315080015302DE9F04F4FF000094FF00108002642F25E -S31508001540107EF44601220B680A2703EB83034FEA51 -S31508001550430B4B68BBFBF2F4B4FBF3F5B5FBF7FAA8 -S3150800156007FB1A5ABAF1050F03D9B5FBF7F56D1C37 -S3150800157001E0B5FBF7F535B105EB850A4FEA4A0AEE -S31508001580B4FBFAF402E0B4FBF7F40125A34201D850 -S31508001590E41A00E01C1B142D07D8A44505D991466A -S315080015A02E46A446B4F57A7F02D3521C402AD1D9D6 -S315080015B040220C89531C42F210756B43B3FBF6F3B9 -S315080015C09C4201D81D1B00E0E51AAE4501D990469C -S315080015D0AE469C4202D8521E032AEBD2A6EB08025C -S315080015E0036843F040030360921E897A4FF4E04390 -S315080015F0491E03EA0232890742EA1162A8F1010884 -S315080016004FF4706101EA08210A43A9F1010909F0BA -S315080016103F010A430261016821F040010160BDE80B -S31508001620F08FD0F8C82122F00F020A43C0F8C8216B -S315080016307047000000B5024600F02CF8104600F08E -S3150800164035F802480169C907FCD100BD00200058D9 -S3150800165001480069704700000020005830B505466B -S315080016600C4600F017F800F01BF80023581C54F835 -S31508001670201054F8230000F02BF89B1C402BF5D3C0 -S31508001680284600F02DF802480169C907FCD130BD8B -S31508001690002000580148F521016070475455000C98 -S315080016A001485021016070475455000C30B5064971 -S315080016B0AA240C60054B55221A6080250D600C6023 -S315080016C01A603021016030BD5455000CA8AA000CE0 -S315080016D0024A1060101D016070470000F055000CAA -S315080016E010B5054BAA211960044A55241460A02296 -S315080016F01A60016010BD00005455000CA8AA000C21 -S31508001700F0B521F0030303441D698C07E40EF8269F -S31508001710A640B5431D61456F4F000326BE40B5433D -S315080017204567134DA84202D0124DA84205D1056E51 -S3150800173001268E40B543056614E015782D0611D5A9 -S3150800174055688D404560CD0800EB8500056C490756 -S31508001750C90E07268E40B5430564157A8D40016C7F -S315080017600D43056410781969A04008431861F0BD57 -S31508001770008E0248008F024810B521F00303184472 -S3150800178003698907C90EF8248C40A34303610369DA -S315080017908A401343036110BD03480068034909687A -S315080017A001F00101C8407047C0FF032014460050ED -S315080017B0010F20F07040064A01EB410102EB81015E -S315080017C0D1F84016014201D0012070470020704729 -S315080017D000400050010F20F07040044A01EB41011F -S315080017E002EB8101C1F8480670470000004000502E -S315080017F0010F20F07040044A01EB410102EB810120 -S31508001800C1F814047047000000400050010F20F092 -S315080018107040064A01EB410102EB8101D1F80C1434 -S31508001820014201D001207047002070470040005057 -S31508001830D0F80C1111F0E06F03D0D0F81C0180B27B -S315080018407047406D80B2704770B504460D46102645 -S31508001850204600F04DF8287A00B10646287928B1C6 -S3150800186032462046296800F0D5F804E0324620467C -S31508001870296800F08BF8E8790121401E400001EB49 -S31508001880560140EA0120401C40F44030E063687984 -S315080018904FF48171401E41EA00606063A87928B15F -S315080018A0616B401E41EA0040606305E0616B687940 -S315080018B0401E41EA004060634FF4A060A0634FF009 -S315080018C0FF30E0646889206470BDD0F8082112F002 -S315080018D0E06F02D0C0F880117047826B02F0800278 -S315080018E0802AFAD04FF40052C264C0F880107047BC -S315080018F010B504461448844202D01448844204D1E0 -S315080019001148083000F0DEF814E01148844202D08D -S315080019101048844204D10E48083000F0D3F809E094 -S315080019200D48844202D00D48844203D10A48083043 -S3150800193000F0C8F80320E060E068C007FCD0206C1F -S3150800194020F00F00206410BD000003400002034091 -S3150800195000000248000202480040024800420248CD -S3150800196010B500F58670046824F0E064046041EA66 -S31508001970032141EA02610268034B1A40114341F010 -S315080019808051016010BD0000C0C0FFEF2DE9F0478F -S3150800199081460C469046642C38D3B8F1000F35D0F2 -S315080019A0FFF7FAFE01466420B1FBF0FCB4FBF0F247 -S315080019B00120012740F2FF36314602FB08F24FF4B8 -S315080019C0806A0CFB01F3B3FBF2F5AC0AC5F3090315 -S315080019D0544504D2B34202D21E4627460846491E3B -S315080019E00029EED140F40040C9F81000D9F81400D7 -S315080019F00749A8F10108084040EA88207F1E40EA06 -S31508001A000740C9F814000020BDE8F0870120FBE76D -S31508001A10EF8000FC2DE9F041074688461646FFF799 -S31508001A20BBFE08FB06F20124904233DD90FBF2F37D -S31508001A3040F2FF3104E0641C02FB04F590FBF5F369 -S31508001A408B42F8D203FB06F16143B0FBF1F15A1C55 -S31508001A5072436243B0FBF2F2A8EB0100B8EB020155 -S31508001A6000D54942002800DA4042814200DA5B1C70 -S31508001A70C3F5806040F48040386178690649761E6F -S31508001A80084040EA8620641E40EA04407861002047 -S31508001A90BDE8F0810120FBE7EF8000FC10B500F5FA -S31508001AA08470046824F0E064046041EA032141EA92 -S31508001AB002610268024B1A401143016010BD000022 -S31508001AC0C0C0FFF810B52049884211D1C414204679 -S31508001AD0FFF780FE2046FFF76BFE0028FAD1204666 -S31508001AE0FFF786FE2046FFF791FE0028FAD110BDC3 -S31508001AF01649884211D1164C2046FFF76BFE204640 -S31508001B00FFF756FE0028FAD12046FFF771FE204659 -S31508001B10FFF77CFE0028FAD110BD0E498842FBD19A -S31508001B200B4C80342046FFF755FE2046FFF740FE53 -S31508001B300028FAD12046FFF75BFE2046FFF766FE2F -S31508001B400028FAD110BD000008000340080002482A -S31508001B50800000100840024838B5002500950B4C57 -S31508001B60FF212170001D00F063F901466A46A06C4A -S31508001B7000F04AF96070211D009800F005FAA5707A -S31508001B80E5700820A4F8440038BD00009400002041 -S31508001B9070B500F0E7F90E4C012584F84050FF2097 -S31508001BA02070002010216170A070FEF78DFDE07096 -S31508001BB0FEF7A0FD2071FEF79DFD000A6071A57174 -S31508001BC0E5710820A4F84400BDE87040FFF79AB80C -S31508001BD09400002010B5064C002084F8400000F060 -S31508001BE0C1F9FF2020700120A4F8440010BD0000B0 -S31508001BF09400002010B5084CFF2020700748A06408 -S31508001C0000206070A070E0700720211D00F0BCF96C -S31508001C100820A4F8440010BD94000020D21F000834 -S31508001C200748FF2101700021417090F84120827019 -S31508001C30C170017141710621A0F844107047000077 -S31508001C409400002070B50446FEF73EFD6178801EBC -S31508001C50884204DABDE87040222000F08BB9104DA6 -S31508001C60FF2028700120A5F84400617849B1A21C1C -S31508001C70A86CFFF74BF868B16178A86C0844A864AB -S31508001C8070BDFFF731F80028FAD1BDE87040312061 -S31508001C9000F070B9BDE87040312000F06BB9000063 -S31508001CA09400002070B50A4DAC6C001D00F0C0F819 -S31508001CB001462046FFF722F828B1FF2028700120A8 -S31508001CC0A5F8440070BDBDE87040312000F052B957 -S31508001CD09400002070B50546FEF7F6FC0B4C411E35 -S31508001CE06A1CA06CFFF712F858B1FF202070FEF7A7 -S31508001CF0EBFCA16C401E0844A0640120A4F8440033 -S31508001D0070BDBDE87040312000F034B99400002061 -S31508001D10312000F02FB9000010B5FEF76FFD03481B -S31508001D20FF2101700121A0F8441010BD9400002085 -S31508001D3070B5084CFF20207000256570A570FEF769 -S31508001D40C3FCE07025716571A5710720A4F84400ED -S31508001D5070BD00009400002010B5054CFF212170CD -S31508001D60001D00F065F8A0640120A4F8440010BD29 -S31508001D709400002070B50446FEF7A6FC6178401E64 -S31508001D80884204DABDE87040222000F0F3B8201D2E -S31508001D9000F04EF8094DA86462786B1C0146184697 -S31508001DA0FEF71DFDFF2028706178A86C0844A8641A -S31508001DB06078401CA5F8440070BD0000940000201F -S31508001DC0002000F0D7B8000070B50546FEF77CFC89 -S31508001DD06A78401E904204DABDE87040222000F07E -S31508001DE0C9B8084C601CA16CFEF7F9FCFF202070EE -S31508001DF06978A06C0844A0646878401CA4F844007C -S31508001E0070BD0000940000202DE9F04104460E46FE -S31508001E101746002505E014F8010B2844C5B2FEF75D -S31508001E20D4FC761E701CF6D13D600120BDE8F08119 -S31508001E300178427841EA0221827841EA0241C07873 -S31508001E4041EA006070470000044800210170816083 -S31508001E50C17081808170417070470000D4000020F5 -S31508001E60044890F84000002801D00120704700205F -S31508001E70704700009400002010B50178344CFF2903 -S31508001E8010D094F84020012A60D1F42921D013DC1F -S31508001E90D02936D009DCC92930D0CC293DD0CF2964 -S31508001EA03ED137E0FFF774FE3DE0D1292FD0D22985 -S31508001EB02AD0F32934D112E0F5390A2930D2DFE8DD -S31508001EC001F0050B2F2F2F112F14171AFFF77CFF80 -S31508001ED029E0FFF74FFF26E0FFF73EFF23E0FFF775 -S31508001EE03BFE20E0FFF786FE1DE0FFF769FF1AE0DC -S31508001EF0FFF796FE17E0FFF76DFE14E0FFF7EAFE20 -S31508001F0011E0FFF79FFE0EE0FFF712FF0BE0FFF769 -S31508001F10C9FE08E0FFF700FF05E0FFF7F9FE02E05B -S31508001F20202000F027F894F84300012802D1102059 -S31508001F3000F020F8B4F94410002907DD012084F8E0 -S31508001F404300BDE81040024800F026B810BD000066 -S31508001F50940000200249002081F8430070470000E1 -S31508001F60940000200249002081F8410070470000D3 -S31508001F70940000200349FE220A7048700220A1F846 -S31508001F8044007047940000200870020A4A70020C48 -S31508001F908A70000EC870704789B2FEF7F9BB08B59B -S31508001FA00021009103E000BF0099491C00910099A7 -S31508001FB08142F8D308BDFEF753FEFEF777FAFEF71F -S31508001FC0ABFEFEF782FAFCE74FF04070E1EE100A2E -S31508001FD070474F70656E424C5400000000C0000CFC -S31508001FE000400000030000000000010C0040000053 -S31508001FF0040000000040010C00400000050000003D -S315080020000080010C004000000600000000C0010C22 -S3150800201000400000070000000000020C000002005B -S31508002020080000000000040C00000400090000007D -S315080020300000080C000004000A00000000000C0C58 -S31508002040000004000B0000000000100C0000040053 -S315080020500C0000000000140C000004000D00000035 -S315080020600000180C000004000E00000000001C0C04 -S31508002070000004000F00000098200008000000205F -S31508002080540000003C020008EC2000085400002020 -S315080020907C13000058020008000000000000000041 -S315080020A0000000000000000000000000040000001E -S315080020B000420148004301480044014800450148E0 -S315080020C000460148004701480000000000000000E3 -S315080020D000000340000203400000024800020248D4 -S311080020E0004002480042024800000000D0 +S315080002700B6070471FB506F011F800F0EDF80400A2 +S315080002800020002105F0F4FF401C60601FBD10B57A +S3150800029010BD00F029F91146FFF7ECFF05F09BFDAC +S315080002A000F047F903B4FFF7F2FF03BC00F04AF980 +S315080002B0DFF818D00648804706480047FEE70000E2 +S315080002C005480649064A074B70470000A01E00204D +S315080002D0BD36000801020008A0140020A01E002058 +S315080002E0A0160020A016002010B500F0B5F8001DD5 +S315080002F010BD00BF7D5F000010B50446FFF7F4FF90 +S315080003000068005D000704D5DF2C02D0A4F12000A8 +S3150800031010BD204610BD032A40F2308010F0030CB1 +S3150800032000F0158011F8013BBCF1020F624498BF3A +S3150800033011F801CB00F8013B38BF11F8013BA2F1D7 +S31508000340040298BF00F801CB38BF00F8013B11F052 +S31508000350030300F02580083AC0F0088051F8043BF2 +S31508000360083A51F804CBA0E80810F5E7121D5CBF5F +S3150800037051F8043B40F8043BAFF30080D20724BF92 +S3150800038011F8013B11F801CB48BF11F8012B24BF26 +S3150800039000F8013B00F801CB48BF00F8012B704775 +S315080003A010B5203AC0F00B80B1E81850203AA0E802 +S315080003B01850B1E81850A0E81850BFF4F5AF5FEA36 +S315080003C0027C24BFB1E81850A0E8185044BF18C9E9 +S315080003D018C0BDE810405FEA827C24BF51F8043B90 +S315080003E040F8043B08BF7047D20728BF31F8023BE4 +S315080003F048BF11F8012B28BF20F8023B48BF00F878 +S31508000400012B70474FF0000200B5134694469646F6 +S31508000410203922BFA0E80C50A0E80C50B1F1200109 +S31508000420BFF4F7AF090728BFA0E80C5048BF0CC0B7 +S315080004305DF804EB890028BF40F8042B08BF704715 +S3150800044048BF20F8022B11F0804F18BF00F8012B87 +S315080004507047704770477047004870475C14002023 +S31508000460004870473C1400204FF0013C50F8042B1C +S3150800047051F8043B9A4221D1A2EB0C03934313EAA9 +S31508000480CC1317D150F8042B51F8043B9A4215D1D6 +S31508000490A2EB0C03934313EACC130BD150F8042BAD +S315080004A051F8043B9A4209D1A2EB0C03934313EA91 +S315080004B0CC13DBD04FF00000704700BFD01A01BA4A +S315080004C0B1FA81F101F0180122FA01F0CB40C1F12D +S315080004D02001DBB2C0B2C01A2CFA01F3D11A91433B +S315080004E011EAC311E6D170477546FFF7B9FFAE4664 +S315080004F005006946534620F00700854618B020B522 +S31508000500FFF7DEFEBDE820404FF000064FF000077B +S315080005104FF000084FF0000B21F00701AC46ACE89D +S31508000520C009ACE8C009ACE8C009ACE8C0098D460A +S31508000530704710B50446AFF300802046BDE810406A +S31508000540FFF7B0BE01491820ABBEFEE72600020041 +S31508000550704700F0D0F9FCE710B500F087F90128DC +S315080005601AD000F0E3FA002816D00C4C207801289F +S3150800057012D103F0B1F8D4E90112114401F5FA7168 +S31508000580884209D30020207000F078FA002803D1A9 +S31508000590BDE8104000F0C8B910BD00007800002082 +S315080005A010B504490120087000F006F8BDE81040AF +S315080005B0FFF7D2BF7800002010B5044C2078012838 +S315080005C002D103F089F8A06010BD00007800002071 +S315080005D010B500F094F900F089F903F085F801F0F8 +S315080005E0E7F800F063FA00F031F9BDE81040FFF7CC +S315080005F0D7BF10B500F07FF903F090F800F0E6FBDE +S3150800060000F03CF9BDE81040FFF7A6BF2DE9FE4310 +S3150800061003F03EFB0446484D02E0640000F06BF927 +S31508000620AC42FAD3454D02E0640800F064F9AC42E6 +S31508000630FAD8DFF80C8122460121404603F0B8F8C3 +S315080006400094404801904FF4FA50ADF808004FF076 +S315080006500109ADF80A903C4E6946706803F0D2F974 +S315080006607068016841F040010160016841F00101CC +S315080006700160374C35482060606820F0404000F142 +S31508000680004040F2E17161F31C00A26861F31C02AC +S31508000690A26020F000506060204603F0CFF80827DB +S315080006A027730020002503E021180D74401CC0B2F2 +S315080006B0217B8142F8D884F81890254803F0C8F8B9 +S315080006C000220121404603F035F82048204C20300E +S315080006D020342060606820F0404000F1004040F27D +S315080006E0676161F31C00A26861F31C02A26020F036 +S315080006F000506060204603F0A1F82773002103E04C +S3150800070060180574491CC9B2207B8842F8D825763A +S315080007100F48203003F09CF801221146404603F0AA +S3150800072009F87068016821F040010160016821F04C +S3150800073001010160BDE8FE83001BB700000E270714 +S315080007400040014820A107009400002000500148FD +S31508000750B00900202DE9F04106460F4600250E4C4B +S315080007602068C069C00713D0204603F0BFF860B9F7 +S31508000770207B3870002105E06018007C7054012544 +S31508000780491CC9B2207B8842F6D801202168C86175 +S315080007902846BDE8F0810000D009002070B5124C4B +S315080007A02173002104E06318425C1A74491CC9B21B +S315080007B0227B8A42F7D80C4803F008F90220216800 +S315080007C0C861094803F0EEF802F086FF00F1320529 +S315080007D005E000F090F802F07FFFA84203D82068F1 +S315080007E0C0698007F5D470BDB0090020FFF7E4BEE4 +S315080007F07047000009480078002807D0012807D06C +S31508000800022807D0032807D04020704740207047A9 +S315080008100820704700207047402070478400002059 +S3150800082009480078002807D0012807D0022807D0F1 +S31508000830032807D04020704740207047082070479B +S3150800084000207047402070478400002010B503F050 +S3150800085005FEFFF7DBFE044C0120207000F0FEFFCA +S315080008600020207010BD00008400002010B5002470 +S3150800087003F000FE00B10124204610BD38B56946D4 +S315080008800C48FFF767FF0C4C012805D120709DF82E +S315080008900010084803F0FAFD6946064801F01EF8FC +S315080008A0012806D1002020709DF80010014803F0A9 +S315080008B0EDFD38BD040300208400002070B506460F +S315080008C00C46094D2878012803D1E1B23046FFF7D6 +S315080008D065FF287818B9E1B2304601F06BF8BDE833 +S315080008E0704003F041BE000084000020AFF3008092 +S315080008F0642000F02BBFAFF3008000F02DBFAFF3EC +S31508000900008072B6704762B6704770B505460C46E9 +S31508000910164605E014F8010B05F8010BFFF7EBFF87 +S31508000920761EB6B2F6D270BD10B500F043FFB0B170 +S3150800093000F022F8B8B1FFF75BFF02F0E7FE00F01F +S3150800094035FF0B4908400B49086000F02FFF446843 +S31508000950FFF7D9FFA047BDE81040FFF747BFBDE83E +S315080009601040FFF743BFBDE81040FFF73FBF000048 +S3150800097080FFFF1F08ED00E010B50648406AC0F387 +S315080009804030002803D000F0D9FE012010BD002019 +S3150800099010BD0000008F024810B5064890F82802DE +S315080009A0012802D1034804F0B7FABDE8104002480E +S315080009B004F0ACBDD8000020A6620008044890F8F0 +S315080009C02802012802D1024804F0A6BA704700009E +S315080009D0D800002070B50446174D95F8280201285E +S315080009E00BD12946204604F04FFC002805DA0020E2 +S315080009F085F82802284604F08FFA104D18E0284694 +S31508000A0003F065FA02F068FE00F10A0605E0FFF752 +S31508000A1072FF02F061FEB04205D8D5F8140100F461 +S31508000A204070C005F3D54FF48070C5F81801641CF2 +S31508000A3021780029E3D170BDD800002000000340CA +S31508000A4010B5074C002084F828020A2205A1204682 +S31508000A5004F06EFB002802D1012084F8280210BD9C +S31508000A60D80000202F626F6F746C6F672E747874CD +S31508000A700000000000487047A662000810B5FFF79E +S31508000A80F5FE012804D0084C207818B1002010BDC6 +S31508000A90002010BD00F030F8012801D0002010BD5C +S31508000AA00120207010BD00008800002010B50849FC +S31508000AB000200870002207A1074804F013FB00284D +S31508000AC005D0BDE81040772104A0FFF742BD10BD50 +S31508000AD088000020303A0000440300202E2E5C2EA9 +S31508000AE02E5C2E2E5C2E2E5C536F757263655C66CB +S31508000AF0696C652E6300000000B5C7B04FF48C71B1 +S31508000B0001A8FFF77FFC01A9074804F093FC40B948 +S31508000B10019830B19DF80C00C00602D4012047B0F8 +S31508000B2000BD0020FBE70000A66200080348007825 +S31508000B30002801D000207047012070478800002057 +S31508000B4010B5014601F00F003030092902D9C01D41 +S31508000B50C0B210BDFFF7D0FBC0B210BD70B50546D8 +S31508000B600C462809FFF7ECFF207005F00F00FFF789 +S31508000B70E7FF60700020A070204670BD70B506467D +S31508000B8000250024305DFFF7B7FBC1B2A1F13002A2 +S31508000B90172A02D23A39072901D2002070BDD1B2EC +S31508000BA0092901D9C91FC9B201EB0510C5B2641CD0 +S31508000BB0E4B2022CE6D3284670BD02460846114622 +S31508000BC00A23401CB1FBF3F10029FAD10170401E3B +S31508000BD0B2FBF3F103FB112130310170B2FBF3F2E2 +S31508000BE0002AF4D1704710B504462078FFF784FB35 +S31508000BF0532806D1FFF778FB01686078095C20293D +S31508000C0001D0032010BD312805D0322805D033285D +S31508000C1005D0032010BD002010BD012010BD022004 +S31508000C2010BD00002DE9F04107460C461646002582 +S31508000C30002C00D027B940F263214EA0FFF789FCAB +S31508000C403846FFF7D0FF8046B8F1030F0DD0384677 +S31508000C5000F09EF860B1B8F1000F0CD0B8F1010FA2 +S31508000C602BD0B8F1020F27D150E00020BDE8F08163 +S31508000C704FF0FF30FAE7BF1C3846FFF77FFF0546FF +S31508000C80BF1C3846FFF77AFF00022060BF1C3846B3 +S31508000C90FFF774FF216808442060BF1CED1E002E74 +S31508000CA065D0002406E03846FFF768FF3055BF1CBC +S31508000CB0641CA4B2AC42F6DB59E0BF1C3846FFF709 +S31508000CC05DFF0546BF1C3846FFF758FF0004206045 +S31508000CD0BF1C3846FFF752FF216801EB0020206051 +S31508000CE0BF1C3846FFF74AFF216808442060BF1C2E +S31508000CF02D1F96B3002406E03846FFF73FFF305510 +S31508000D00BF1C641CA4B2AC42F6DB30E0BF1C3846FC +S31508000D10FFF734FF0546BF1C3846FFF72FFF0006CE +S31508000D202060BF1C3846FFF729FF216801EB004009 +S31508000D302060BF1C3846FFF721FF216801EB002021 +S31508000D402060BF1C3846FFF719FF21680844206059 +S31508000D50BF1C6D1F0EB1002407E008E03846FFF7F8 +S31508000D600DFF3055BF1C641CA4B2AC42F6DB284606 +S31508000D707CE700002E2E5C2E2E5C2E2E5C2E2E5C22 +S31508000D80536F757263655C66696C652E6300000057 +S31508000D9070B5861C3046FFF7F1FE04462546B61C9C +S31508000DA03046FFF7EBFE2844C5B2641EA4B2B61C53 +S31508000DB0012CF5D8E843C4B23046FFF7DFFEA0425F +S31508000DC001D0002070BD012070BD00002DE9F84F4C +S31508000DD00024E34F3878002851D000253E1DDFF85F +S31508000DE084A3012823D00AF50A7808F5C0714FF4C0 +S31508000DF0807308F5C279A8F58B6B0091022840D05C +S31508000E0003283CD152461946404604F095F89BF80B +S31508000E104112002970D03D70D3A0FFF7DBFD0220F8 +S31508000E20FFF7CCFD5046BDE8F84F04F075B800F062 +S31508000E30BFFCFFF705FED5A0FFF7CCFDDCA0FFF74A +S31508000E40C9FDFFF717FE01460122504604F070F966 +S31508000E5040B13D70E0A0FFF7BDFDBDE8F84F0120A9 +S31508000E60FFF7ACBDDEA0FFF7B5FDDFA0FFF7B2FDCB +S31508000E70E6A0FFF7AFFD3560756002203870BDE863 +S31508000E80F88F52461946ED4804F056F89BF8411279 +S31508000E9059B13D70D0A0FFF79DFD0220FFF78EFDEA +S31508000EA05046BDE8F84F04F037B838B10022E34899 +S31508000EB00099FFF7B7FE0446601C0CD0002C59DDDC +S31508000EC07068A0B13168D8F880210144914214D1E4 +S31508000ED0204470604EE03D70BFA0FFF77BFD032005 +S31508000EE0FFF76CFD5046BDE8F84F04F015B8D8F882 +S31508000EF08001306074603DE0A6E0B9A0FFF76AFDA6 +S31508000F00CFA0FFF767FDD1497068FFF756FECF48B7 +S31508000F10FFF760FDCEA0FFF75DFD3068CB49000EF8 +S31508000F20FFF71CFE306809F10201C0F30740FFF71E +S31508000F3015FE308809F10401C0F30720FFF70EFEFD +S31508000F40307809F10601FFF709FEC048FFF742FDB0 +S31508000F50B9A0FFF73FFDD6E9000100F025FC08B36C +S31508000F609FA0FFF737FDA9A0FFF734FDD8F8800149 +S31508000F7030607460DBF83C12DBF8440288427FF488 +S31508000F807EAF0021504603F0FBFFB8B13D7092A03A +S31508000F90FFF720FD0420FFF711FD5046BDE8F84F86 +S31508000FA003F0BABF3D708CA0FFF714FD0520FFF7CC +S31508000FB005FD5046BDE8F84F03F0AEBF706888B32C +S31508000FC087A0FFF707FD9EA0FFF704FD9F497068FD +S31508000FD0FFF7F3FD9D48FFF7FDFC9DA0FFF7FAFC20 +S31508000FE030689A49000EFFF7B9FD306809F1020129 +S31508000FF0C0F30740FFF7B2FD308809F10401C0F3DA +S315080010000720FFF7ABFD307809F10601FFF7A6FDCB +S315080010108E48FFF7DFFC88A0FFF7DCFC03CE00F064 +S31508001020C3FB28B16EA0FFF7D5FC0320387026E76E +S315080010303D7069A0FFF7CEFC0520FFF7BFFC5046C0 +S31508001040BDE8F84F03F068BF804E843E38B132469B +S315080010507A480099FFF7E6FD0446601C5BD0002C31 +S3150800106039DD82A0FFF7B6FC78492046FFF7A5FDD3 +S315080010707648FFF7AFFC81A0FFF7ACFCD8F88001F3 +S315080010807249000EFFF76AFDD8F8800109F10201DE +S31508001090C0F30740FFF762FDB8F8800109F10401C3 +S315080010A0C0F30720FFF75AFD98F8800109F10601F9 +S315080010B0FFF754FD6548FFF78DFC5FA0FFF78AFC34 +S315080010C032462146D8F8800100F076FB00282ED05B +S315080010D043A0FFF77FFCDBF83C12DBF844028842AA +S315080010E0A5D16CA0FFF776FC00F054FB00282AD0A7 +S315080010F03BA0FFF76FFC6EA0FFF76CFC504603F0B1 +S315080011000BFF71A0FFF766FC3D70FFF745FCBDE8D5 +S31508001110F84FFFF709BC3D7076A0FFF75BFC03208C +S31508001120FFF74CFC5046BDE8F84F03F0F5BE3D709E +S3150800113029A0FFF74FFC0620FFF740FC5046BDE804 +S31508001140F84F03F0E9BE3D7023A0FFF743FC0720E4 +S31508001150FFF734FC5046BDE8F84F03F0DDBE00004B +S31508001160880000207405002052656164696E672056 +S315080011706C696E652066726F6D2066696C652E2EC9 +S315080011802E4552524F520A0D000000004669726DF4 +S315080011907761726520757064617465207265717512 +S315080011A06573742064657465637465640A0D00006C +S315080011B04F70656E696E67206669726D77617265D4 +S315080011C02066696C6520666F722072656164696E57 +S315080011D0672E2E2E000000004552524F520A0D006F +S315080011E04F4B0A0D000000005374617274696E67F4 +S315080011F0207468652070726F6772616D6D696E67BD +S315080012002073657175656E63650A0D0050617273AA +S31508001210696E67206669726D776172652066696CAA +S315080012206520746F206465746563742065726173E4 +S315080012306520626C6F636B732E2E2E009C07002050 +S3150800124045726173696E672000000000200900205E +S315080012502062797465732066726F6D206D656D6F97 +S3150800126072792061742030780000000050726F6730 +S3150800127072616D6D696E67200000000020627974E6 +S31508001280657320746F206D656D6F727920617420A7 +S315080012903078000057726974696E672070726F67DC +S315080012A072616D20636865636B73756D2E2E2E00F3 +S315080012B0436C6F73696E67206669726D77617265D4 +S315080012C02066696C650A0D004669726D77617265FC +S315080012D020757064617465207375636365737366DE +S315080012E0756C6C7920636F6D706C657465640A0D36 +S315080012F000000000496E76616C6964206368656366 +S315080013006B73756D20666F756E642E2E2E45525260 +S315080013104F520A0D000000002DE9F04704460D461D +S3150800132016461F464FEA95294FEA89292068401C28 +S3150800133004D14946204600F0F7F838B320684845F6 +S3150800134005D04946204600F001F9044604B3206852 +S31508001350281A05192D1D4FF4806809F58069FFF7CD +S31508001360CAFA281B001F404506D34946204600F006 +S31508001370EDF8044674B1251D16F8010B05F8010BA6 +S315080013807F1E002FEBD10120BDE8F0870020FBE788 +S315080013900020F9E70020F7E710B50B480068401C65 +S315080013A003D0094800F04EF948B108480068401CC7 +S315080013B003D0064800F046F918B1012010BD0020F8 +S315080013C010BD002010BD0000F40D0020F00900201B +S315080013D070B50D4600F0DCF804460D48011B681E82 +S315080013E0814201D2002070BD204600F051F8064621 +S315080013F06019401E00F04CF80146FF2E06D0FF2962 +S3150800140004D03046BDE8704000F004B8002070BD36 +S31508001410FFFF1F0C2DE9F0410F46B84202D9002004 +S31508001420BDE8F081032801D30F2F01D90020F7E783 +S31508001430044629E0FFF75FFA204600F049F805461A +S31508001440681C08D002F048F941F6C8114618284623 +S3150800145002F05AFB09E00020E2E702F03DF9B0424B +S3150800146001D90020DCE7FFF746FA02F05BFBC0F380 +S3150800147000000028F1D102F055FB20F0200008B149 +S315080014800020CDE7641CE4B2BC42D3D90120C7E7EB +S3150800149070B5054600240D4EFFF72DFA04EB4401FE +S315080014A056F82120AA420BD806EB81004068104462 +S315080014B0A84205D904EB440006EB8000007A70BD0B +S315080014C0641CE4B20D2CE7D3FF2070BDA8630008A6 +S315080014D02DE9F04106464FF0FF3700240A4DFFF785 +S315080014E00AFA04EB440005EB8000007AB04204D106 +S315080014F004EB440055F8207003E0641CE4B20D2C9C +S31508001500EDD33846BDE8F081A86300080048704767 +S3150800151000C0000C03494FF0FF30086001F2044197 +S3150800152008607047F009002010B58A0501D0002030 +S3150800153010BD02688A4201D1012010BD02C04FF4D5 +S315080015408062FFF7E2F9012010BD000070B504467D +S315080015500D460D48844202D1A0F2044409E00B4826 +S31508001560854202D1084C054603E0204600F06AF899 +S3150800157030B129462046FFF7D7FF18B1204670BD7F +S31508001580002070BD002070BDF40D002000C0000CC6 +S315080015900821B1EB106F01D100F18060704700009F +S315080015A00B4801684268114482681144C2681144B4 +S315080015B0026911444269114482691144C943D0F849 +S315080015C00002814201D101207047002070470000C7 +S315080015D000C0000C70B50D461646FFF7D9FF044645 +S315080015E01448011B681E814201D2002070BD2046A6 +S315080015F0FFF74EFFFF2812D06019401EFFF748FF7D +S31508001600FF280CD0A00A80020B49884209D12B4634 +S3150800161032462146BDE870400848FFF77DBE0020E7 +S3150800162070BD2B4632462146BDE870400448FFF798 +S3150800163073BE0000FFFF1F0C00C0000CF40D002055 +S31508001640F00900202DE9F04106463068FFF720FF33 +S31508001650FF2811D00024FFF74EF9306800EB042864 +S3150800166006EB04273F1D02F037F800F10D05394651 +S31508001670404602F05DFA0AE00020BDE8F08102F07B +S315080016802BF8A84201D90020F7E7FFF734F902F052 +S3150800169049FAC0F300000028F1D102F043FA20F01D +S315080016A0100008B10020E8E7002018F800103A5C9E +S315080016B0914201D00020E0E7401CFF28F5D9641CC0 +S315080016C0042CC8D30120D8E708B5002000900D489F +S315080016D00168491C14D0416882681144C2681144E3 +S315080016E0026911444269114482691144C069084477 +S315080016F0C04300906A4604210348FFF76BFF08BD04 +S31508001700012008BDF40D002000C2000C10B501F040 +S315080017106FFF80220921074802F0A4FA064C00222E +S315080017200D21204602F09EFA216E21F40051216611 +S3150800173010BD000000850248008F024802494FF09C +S3150800174000704860704700000085024801494880DB +S31508001750704700000000002010B501F0BDFF0B4CDB +S31508001760616888420CD32178094851B1002121705B +S315080017704FF00071416001F0AFFF61880844606076 +S3150800178010BD0121217049024160F4E700000020E4 +S315080017900085024810B5FFF797FF18B1BDE810405D +S315080017A0FFF7FABD002010BDFFF712BEFFF7AEBE69 +S315080017B0FFF7B0BEFFF7F4BEFFF70CBF004870474F +S315080017C0001BB7002DE9F0418CB000278DF8247076 +S315080017D001250A9502248DF82C40DFF8748009AAA1 +S315080017E00421404602F0F6F990268DF81860079510 +S315080017F08DF8204006AA0521404602F0EBF9154966 +S31508001800C86920F0070040F00100C8618DF80C7027 +S3150800181003AA0D21404602F0DDF98DF80060019516 +S315080018208DF808406A460C21404602F0D3F90A486A +S31508001830016841F040010160C16864F30201C160BA +S31508001840016821F0400101600CB0BDE8F08100009C +S315080018500081024800000340004301483EB54FF4AA +S315080018606140009008208DF805008DF806000120DB +S315080018708DF8070010208DF808000020ADF80A0042 +S315080018800B4C6946206802F0E1FA01230422102174 +S31508001890206802F005FC012304220021206802F0DA +S315080018A061FB2068016C21F00F01891C01643EBDB3 +S315080018B0B400002010B5044607480068D0F8141193 +S315080018C0C1F3C001002901D0002010BD02F0B2FA10 +S315080018D02070012010BD0000B40000202DE9F04161 +S315080018E080460F461B4C00251B4E6078002810D0FA +S315080018F020783044401CFFF7DDFF012819D001F09D +S31508001900EBFE61686431884200D965700020BDE845 +S31508001910F0811148FFF7CEFF0128F7D13078401E35 +S315080019203F28F3D801F0D8FE60602570012060706A +S31508001930ECE72078401CC2B22270307831469042DB +S31508001940E4D1491C4046FEF7E0FF65702078387000 +S315080019500120DCE7AC000020F811002070B5014634 +S315080019600126134D2868D0F81421C2F30032002A44 +S3150800197001D0002070BD02F0AAFA01F0ADFE00F118 +S315080019800A0407E0FEF7B7FF01F0A6FEA04201D958 +S31508001990002606E02868D0F8140100F44070C00557 +S315080019A0F0D528684FF48071C0F81811304670BD1C +S315080019B0B400002070B505460E46402E03D97A219C +S315080019C00EA0FEF7C6FD3046FFF7C8FF012803D074 +S315080019D07E210AA0FEF7BDFD00240CE0FEF78BFF72 +S315080019E0285DFFF7BBFF012803D0872103A0FEF778 +S315080019F0B0FD641CA4B2B442F0D370BD2E2E5C2E8A +S31508001A002E5C2E2E5C2E2E5C536F757263655C41C0 +S31508001A10524D434D345F584D43345C727332333202 +S31508001A202E63000010B50D4800680068018E0B4C47 +S31508001A30241F2180408E60802088000403D5618899 +S31508001A40201D00F0F5FA2088400405D02188BDE85D +S31508001A501040024800F0DABC10BD00006800002003 +S31508001A6070B52B4C206840F001002060206820F0FB +S31508001A70F00040F080002060274D264A05212846C0 +S31508001A8002F0A8F801220521284602F0DFF8214ACB +S31508001A9006211032284602F09DF801220621284622 +S31508001AA002F0D4F81B4A1D4D403A0021284602F0A0 +S31508001AB091F801220021284602F0C8F8154A184E66 +S31508001AC0303A0621304602F085F8012206213046D2 +S31508001AD002F0BCF80F4A0721203A304602F07AF89D +S31508001AE001220721304602F0B1F80A4A0121103ACC +S31508001AF0284602F06FF801221146284602F0A6F899 +S31508001B00A06940F4803040F48010A06170BD0000E8 +S31508001B109C4000500863000800830248008402487D +S31508001B2000810248014600200A7B002A02D10846A5 +S31508001B3000F002BC704770B5044600260025607B9D +S31508001B4001280FD0606800B18047207B18B920466D +S31508001B5000F0F6FB05461DB101260020607301E082 +S31508001B6001206073304670BD10B50146002001247F +S31508001B700A7B002A02D1084600F08DF900B9002434 +S31508001B80204610BD2DE9F04389B004460E46174697 +S31508001B904FF0000800254FF0010924216846FEF79A +S31508001BA031FC207AC00713D0A9464FF00308B9F1D3 +S31508001BB0000F40D00D2E73D01BDC0D2E30D2DFE87F +S31508001BC006F03E4B425D542F2FF42F2F6670790096 +S31508001BD02046FFF7A7FF0007E9D54FF005082EB105 +S31508001BE00D2E03D00E2E01D0042EE0D14FF00009A1 +S31508001BF0DDE768460DF1020807F11009222E74D0B8 +S31508001C0008DC0E2E68D01F2E76D0202E6FD0212EFF +S31508001C1006D1A5E0232E6BD0242E6AD0252E69D0B6 +S31508001C200A25002D67D00F2D7DD00A2D7CD0332DA7 +S31508001C30FCD04FF0010809B04046BDE8F0832046C5 +S31508001C4001F001FCEDE7207B0028EAD13946204661 +S31508001C5000F06DFB0546E4E7207B0028E1D1394614 +S31508001C60204600F033FB0546DBE7207B0028D8D169 +S31508001C7006CF204600F06CF90546D2E7207B0028FF +S31508001C80CFD13946204600F067FA0546C9E7207BDA +S31508001C900028C6D13946204600F080FA0546C0E736 +S31508001CA011E0207B0028BCD13946204600F0ACFA6A +S31508001CB00546B6E7207B0028B3D13946204600F012 +S31508001CC071FA0546ADE7207B0028AAD13946204699 +S31508001CD000F0CAFA0546A4E7207B0028A1D13946B8 +S31508001CE0204600F0C7FA05469BE761E004E01EE0DF +S31508001CF077E09DE0A5E0B9E004218DF800103946AB +S31508001D0091F82020102A10D88DF80120801CFEF7A3 +S31508001D1002FB207B002884D101226946204600F078 +S31508001D2021FB05467DE7A4E0A6E00A2579E7002120 +S31508001D308DF80010394691F82020102A0ED88DF813 +S31508001D400120801CFEF7E7FA207B00288CD10022B0 +S31508001D506946204600F006FB054662E70A2560E765 +S31508001D6001218DF8001097F82020102A1ED897F820 +S31508001D70211010291AD811448DF8011097F820203F +S31508001D803946801CFEF7C7FA2037494638787A78EC +S31508001D904044FEF7C0FA207B00288AD10022694613 +S31508001DA0204600F0DFFA05463BE757E00A2538E704 +S31508001DB002218DF80010394691F82020102A0ED8F5 +S31508001DC08DF80120801CFEF7A6FA207B00288BD10F +S31508001DD000226946204600F0C5FA054621E70A258D +S31508001DE01FE705218DF8001097F82020102A1DD826 +S31508001DF097F82110102919D811448DF8011097F871 +S31508001E0020203946801CFEF786FA2037494638785E +S31508001E107A784044FEF77FFA207B002886D1012293 +S31508001E206946204600F09EFA0546FAE60A25F8E6CF +S31508001E30207B002891D13946204600F0EFF9054667 +S31508001E40EFE608208DF80000207B002885D10022C7 +S31508001E506946204600F086FA0546E2E6207B002819 +S31508001E60A2D1204600F054F80546DAE64FF00008FD +S31508001E70E1E64FF00208DEE64FF00408DBE630B490 +S31508001E8004460020257B002D03D1204630BC00F0F7 +S31508001E9001BB30BC704770B50546012401F01CFC37 +S31508001EA000F2E93601F018FCB04201D92E2408E008 +S31508001EB0FEF721FD28680068808DC0F340000028E1 +S31508001EC0F0D02E2C22D028680068818D41F00401BC +S31508001ED081852868006810F8291F41F00101017002 +S31508001EE0286890F85A0088B9284600F0F9FE044692 +S31508001EF0200001D02B2C09D1284600F077FB044698 +S31508001F00200003D12968012081F85A00204670BDB7 +S31508001F10F8B5044601250020217A890713D42168DB +S31508001F20B1F84C1040EA01420026334607492046DC +S31508001F30009601F0E5F805462DB9204600F084FB29 +S31508001F40206880F85A602846F8BD00003E630008FD +S31508001F502DE9F04F9BB0054688469146282233491D +S31508001F6011A8FEF71DFA402101A8FEF74BFA2968C9 +S31508001F70012048762968087629688876287A4007ED +S31508001F8001D50F2441E0A9EB0806761C32464146E6 +S31508001F90284600F0C4FC0446200036D101A928468C +S31508001FA000F068F9044620002FD10498C0F30121F7 +S31508001FB00498C0F385230498039AC0B202F07F42BE +S31508001FC040EA1240039AC2F30352B3FBF0F303EB61 +S31508001FD0010A11A951F8227047430CE008EB0702E1 +S31508001FE0934653464146284600F0BCFE0446200068 +S31508001FF003D1D846F61BBE42F0D236B153464A46FE +S315080020004146284600F0AEFE04462868006801F0FE +S31508002010DFFE0028F9D12868006801F0D5FE0028FF +S31508002020F3D11BB02046BDE8F08F000078630008A6 +S315080020302DE9F04104460D46012720688580E8070A +S315080020403E460DD0216802204876207A00F0EF003F +S31508002050207220683104006801F066FE20688671E7 +S31508002060A8070ED5216803204876207A00F0EF00ED +S31508002070207220684FF40031006801F055FE206890 +S31508002080867168070ED5216804204876207A00F004 +S31508002090EF00207220684FF48021006801F044FEAA +S315080020A02068867128070ED5216805204876207A8B +S315080020B000F0EF00207220684FF40021006801F05C +S315080020C033FE20688671E8060ED521680620087654 +S315080020D0207A00F0DF00207220684FF48011006833 +S315080020E001F022FE2068C671A8060ED521680720D1 +S315080020F00876207A00F0DF00207220684FF400117D +S31508002100006801F011FE2068C67168060ED52168C0 +S3150800211008200876207A00F0DF00207220684FF445 +S315080021208001006801F000FE2068C671E80510D538 +S3150800213021680920C876207A00F0EF0000F0DF0059 +S31508002140207220684FF08071006801F0EDFD20686C +S3150800215086713846BDE8F0811FB50C46417A4FF0C6 +S31508002160000249070DD50092019202920392694630 +S3150800217000F04AF80199C1F3C611491C216004B060 +S3150800218010BD0092019202920392694600F03CF853 +S315080021900199C1F3C611491C2160F0E7407A08602D +S315080021A0002070470268928CC2F30B020A8002680C +S315080021B0138D526A1B0443EA12424A600268926A05 +S315080021C0120C0A720268D26A120E4A720268D26A3F +S315080021D0120C8A720268928D120ACA72026892F802 +S315080021E02C200A730268926A120E4A730268128ECB +S315080021F0120A8A73026892F83020CA730068006B64 +S31508002200000C08740020704710B50B4601680F22B1 +S315080022103431581CFEF77FF8002010BD7CB5044603 +S315080022200D46002601962068B0F84C0046EA0042A2 +S3150800223001A8009001230B49204600F061FF002801 +S3150800224008D10199890106D501212970217A41F021 +S31508002250080121727CBD2E70217A01F0F7012172E6 +S315080022607CBD00003C6300080068006A0860002026 +S3150800227070470000FEB504460E4600250020029071 +S31508002280204601F071F800281CD12068B0F84C00EF +S3150800229045EA004202A8009001230B49204600F0B7 +S315080022A02FFF00280ED120680121006801F099FD52 +S315080022B00120CDE90060044940230022891D2046FB +S315080022C000F0B4FFFEBD00005A6300081FB50C46B7 +S315080022D0417A4FF00002490712D500920192029204 +S315080022E003926946FFF790FF002807D10299019AE1 +S315080022F0090441EA1241491C8902216004B010BD53 +S3150800230000920192029203926946FFF77DFF002828 +S31508002310F4D10199C1F3C231891C029A019B920535 +S31508002320120D42EA9372521C8A402260E6E74FF485 +S315080023300070088000207047007A00F00F00704790 +S3150800234010B504462068006801F0FAFC022001F086 +S3150800235099FC204600F064FC2046BDE8104000F0D9 +S31508002360C3B800002DE9FE4F04468A4616462046A5 +S3150800237000F0FAFF0546280042D1206800210068CF +S3150800238001F02FFD9AF80100401C20F0010909F11F +S3150800239002091D4902AF01234A468846204600978E +S315080023A000F0AEFE054628002AD10220CDE900A09D +S315080023B015491FFA89F300221831204600F036FF26 +S315080023C02068006801F004FD0028F9D101235A02AB +S315080023D041462046009700F093FE054620680068AF +S315080023E001F0F6FC0028F9D12068006801F0ECFC41 +S315080023F00028F3D125B93146204600F07FFA054674 +S315080024002846BDE8FE8F0000406300082DE9F0412C +S3150800241004460D460027A8064FF01E084FF0010691 +S3150800242009D5206880F8188020682021006801F006 +S315080024307BFC2068C671E80609D5206880F81880F4 +S3150800244020681021006801F06FFC2068C671A80793 +S315080024500DD521681F20887620680221006801F0C2 +S3150800246063FC207A00F0DF00207220680672E80715 +S315080024700DD021681C20487620680121006801F0EB +S3150800248053FC207A00F0EF002072206886713846E7 +S31508002490BDE8F08170B50546287AC40701D0032443 +S315080024A00CE0000701D5052408E0012B14D02846C6 +S315080024B000F0E8F8A0B1332814D001242868006891 +S315080024C001F086FC0028F9D12868006801F07CFC38 +S315080024D00028F3D1204670BD284600F0FDF8E9E74C +S315080024E00024EBE70424E9E701462C200A7A520681 +S315080024F002D4084600F0A4BB704770B50546287A92 +S31508002500C40701D0032412E0040701D505240EE010 +S31508002510400701D502240AE0012B16D0284600F010 +S3150800252001F9B0B11E2814D0332814D00124286824 +S31508002530006801F04DFC0028F9D12868006801F010 +S3150800254043FC0028F3D1204670BD284600F016F952 +S31508002550E7E70024EBE70424E9E700002DE9FC415E +S31508002560044600250020019020680121006801F03A +S315080025700AFC1D4E01AFE0B12068007F242807D170 +S315080025800123002231462046009700F0B9FD054692 +S31508002590002D0CD0252D0AD00421204600F090FDF0 +S315080025A0002804D120688021006801F0ECFBBDE812 +S315080025B0FC810221204600F083FD0028F7D1012383 +S315080025C0002231462046009700F09AFD2528EED0D5 +S315080025D00421204600F074FD0028E8D120688021F7 +S315080025E0006801F0D0FBE2E73A6300087CB50446D0 +S315080025F0207A00F00805204600F08EFC38B901A8BC +S31508002600012300905A020F49204600F079FD50EA4E +S31508002610050115D1204600F03FFE20B120680021B3 +S31508002620006801F0FEFB204600F06CFE002807D08B +S315080026302068006810F8281F01F0FB0101700020CF +S315080026407CBD00004063000810B5044630212068B0 +S315080026502030FDF7D7FE00216172206880F85010FF +S315080026602268012050762268107622681077226840 +S315080026709076217220680068818D21F00401818599 +S3150800268010BD0000FFB583B004460E461F462A203B +S31508002690216801254D7621680D7621688D76216899 +S315080026A091F85A10012913D13A462046059900F0A7 +S315080026B036F900280CD120680121006801F091FB49 +S315080026C0CDE90065034B3A4605A9204600F098FB7C +S315080026D007B0F0BD446300087CB504460E461546AF +S315080026E02A200122216891F85A10012917D1294672 +S315080026F0204600F014F9002811D1607A000700D4AA +S315080027006D0220680121006801F06BFB0120CDE90C +S31508002710006043022A460249204600F087FD7CBD38 +S3150800272042630008FFB583B004460E461F462A20BA +S31508002730216801254D7621680D7621688D762168F8 +S3150800274091F85A10012914D13A462046059900F005 +S31508002750E6F800280DD120680021006801F041FB49 +S315080027600220CDE90060044B3A4605A9204600F050 +S3150800277047FB07B0F0BD0000486300087CB5044677 +S315080027800E4615462A200122216891F85A10012979 +S3150800279017D12946204600F0C2F8002811D1607AE0 +S315080027A0000700D46D0220680021006801F019FBBB +S315080027B00220CDE9006003022A460249204600F0BD +S315080027C035FD7CBD4663000803680122002B00DA4C +S315080027D00A7003685B0000D50A7003689B0000D581 +S315080027E00A700068400100D50A70704702689302B3 +S315080027F04FF0010200D50A700368DB0200D50A70A3 +S315080028000068000300D50A7070472DE9F0410446B8 +S315080028100F461A2500F060FF00F2E93600F05CFF6B +S31508002820B04201D92E250DE0FEF765F8206800684C +S3150800283001F0CEFA0028F1D12068006801F0C4FA48 +S315080028400028EBD12068006801F0BEFA00BB00251D +S315080028503888810606D4C0F305210D2902D0C04365 +S31508002860800710D12068006801F0B2FA08B11B256C +S3150800287009E03888810602D4C043800703D1207A4C +S3150800288040F0200020721DB9207A40F01000207216 +S315080028902846BDE8F0810268D3004FF0010200D552 +S315080028A00A7003681B0100D50A700088000400D569 +S315080028B00A70704738B5054600240020009069461E +S315080028C02846FFF781FF69462846FFF7E4FF694671 +S315080028D02846FFF78BFF29684FF00102C80100D58B +S315080028E00092C80300D50092080700D500929DF80B +S315080028F00000012800D10124204638BD38B50C4611 +S315080029006946FFF78BFC002808D19DF80020012AAC +S3150800291001D1012C02D0224300D0102038BD38B591 +S315080029200C461546002300936946FFF7CFFC00289E +S3150800293004D1009A6119914200D9332038BD2DE996 +S31508002940F04104460D4600262268012082F8580008 +S3150800295000F0C2FE4FF47A71B5FBF1F145186D1C13 +S315080029604FF40047FFF75EF800F0B6FEA84201D91B +S315080029702E260EE0FDF7BFFF22689079012808D0C1 +S31508002980D079012805D03946106801F001FA0028E7 +S31508002990E8D12168002088712168C8713046BDE8F1 +S315080029A0F08170B586B004460D461E460020059097 +S315080029B0607A000702D42868400228604FF4007045 +S315080029C00290039222208DF8100001208DF8110044 +S315080029D0206802A9006801F00BFA20684FF08071A0 +S315080029E0006801F0B9F905A8009001233146204690 +S315080029F02A6800F085FB06B070BDF0B585B00546BF +S31508002A000E4617460024049401938DF80C408DF861 +S31508002A100D40286801A9006801F0EAF904A80090A9 +S31508002A2001233A463146284600F06AFB05B0F0BD58 +S31508002A302DE9F04104460D461646984600F04CFE30 +S31508002A4000F2E937FEF7EEFF00F046FEB84205D879 +S31508002A50FDF751FF2068C0790028F3D021680020CF +S31508002A60C8712068017E1E2907D0012180F85110FF +S31508002A702046BDE8F04100F029B800200DE0012EFF +S31508002A8003D121680968096A2960022E03D12168E1 +S31508002A9009682A680A622D1D401C4045EFD30020AC +S31508002AA0BDE8F08110B50C4600F016FE4FF47A71B9 +S31508002AB0B4FBF1F14418641C01E0FDF71CFF00F0BB +S31508002AC00BFEA042F9D3002010BD00002DE9F0410D +S31508002AD004463A4E2525002739492068006801F042 +S31508002AE027F920680179090703D1006801F06CF914 +S31508002AF020B10221204600F0E3FA05462068017954 +S31508002B0011F0700F03D1006801F062F920B10421B9 +S31508002B10204600F0D5FA0546DFF8A8802068414629 +S31508002B20006801F001F9206890F85110012904D0D5 +S31508002B30006801F044F970B336E0006800223146B7 +S31508002B4001F04AF920492046FFF7F9FE0546280014 +S31508002B5013D12068006801F032F970B12525206884 +S31508002B603946006801F0E0F820684146006801F03F +S31508002B70DBF80621204600F0A3FA2068006801F079 +S31508002B801EF988B92068006801F010F908B12425F3 +S31508002B900AE0252508E0FFE72068006801F006F945 +S31508002BA008B1242500E0252508492068006801F0B9 +S31508002BB0D3F8206805772846BDE8F0813A6300080F +S31508002BC00000FF100080FF0040420F000080FF1049 +S31508002BD08B01017A05D5032A03D041F00801017259 +S31508002BE0704701F0F7010172704710B590B00446BE +S31508002BF040216846FDF706FC69462046FFF73AFB82 +S31508002C0000280BD100990A0E01F47F0142EA11212E +S31508002C10002903D0217A41F00401217210B010BDB9 +S31508002C2010B504460120217A490608D52046FFF743 +S31508002C300BFD2046BDE81040012100F041BA10BD49 +S31508002C4038B504462C20217A490646D40121204667 +S31508002C5000F036FA002840D1216809688A8D22F0EA +S31508002C6001028A852168012209688B8D62F31F2378 +S31508002C708B85216809688A8D42F001028A85226857 +S31508002C80F3211268918622684EF2FF011268D186F6 +S31508002C90236833221B681A872268126851872168BD +S31508002CA0096811F82E2F22F00F0242F00E020A7060 +S31508002CB02168096811F8292F42F00E020A70217A54 +S31508002CC041F04301217200210091044902E0009A73 +S31508002CD0521C0092009A8A42F9D338BDA086010098 +S31508002CE07CB505460024002600231A461C492846BA +S31508002CF0009600F005FA40B9284600F0B5F8641CBD +S31508002D00E4B2022C01D21928EED0002827D128686F +S31508002D10B0F84C10284600F0D1F800281FD12868D2 +S31508002D200F492430009003230022891C284600F00E +S31508002D30E7F9002813D1284600F04CF900280ED1EF +S31508002D4001A92846FFF76AFA002808D19DF8041059 +S31508002D50012900D12B20297A01F0FC0129727CBDBA +S31508002D60286300082DE9FC41054690461E460020CA +S31508002D700190687A000702D449024FEA482801AF51 +S31508002D800A4601231D492846009700F0B9F904466A +S31508002D90200008D1194901234246891C2846009774 +S31508002DA000F0AEF904462CBB144902230022091D83 +S31508002DB02846009700F0A4F9044600F08DFC06EBBF +S31508002DC04601C1EBC61100EBC106761C00F084FC77 +S31508002DD0B04201D92E240DE0FDF78DFD2868006864 +S31508002DE000F0F6FF0028F1D12868006800F0ECFF33 +S31508002DF00028EBD12046BDE8FC810000526300089C +S31508002E002DE9F0410746DDE906680C46154639689E +S31508002E10012088762A4621463846FFF7C2FD044631 +S31508002E2020000BD01BE08023424631463846FFF788 +S31508002E30FFFD044624B96D1E06F50076002DF2D175 +S31508002E406CB90849384600F0B5FA0446200006D1A0 +S31508002E503868C07E092802D13846FFF77FFB20462E +S31508002E60BDE8F08140420F007CB504460025019577 +S31508002E7001A8009006234FF4D5720F49204600F0AA +S31508002E803FF938B121684A7E022A02D181F85050AA +S31508002E9000207CBD0199CAB2AA2A01D019207CBD9E +S31508002EA0C1F30321012901D019207CBD2268012123 +S31508002EB082F850107CBD0000346300087CB50546D6 +S31508002EC00E460020019001A80090012332461149C0 +S31508002ED0284600F015F90446286890F8501009B9F4 +S31508002EE0122C00D0A4B920300A4900900423324697 +S31508002EF00C31284600F004F90446122C00D03CB9DF +S31508002F00284600F051F9044614B9284600F07AFA22 +S31508002F1020467CBD5A63000870B586B00546002178 +S31508002F20059103910491287A00F008042868B0F8FE +S31508002F304C2041EA024634300090032332462449A5 +S31508002F40284600F0DDF820430BD0284600F00CFA9E +S31508002F50044628680121006800F043FF06B02046B1 +S31508002F6070BD2846FFF741FE0446002CF6D1687A64 +S31508002F70C006F3D4284600F0F7F90446002CEDD134 +S31508002F802868B0F84C0046EA004205A810490090A7 +S31508002F9001232431284600F0B3F80446002CDDD17D +S31508002FA028680121006800F01CFF012003A9CDE96B +S31508002FB000100749082300223431284600F036F964 +S31508002FC004462868DDE90312C0E91112C6E70000C5 +S31508002FD03663000808B5016805234C3100910022C4 +S31508002FE0014900F08DF808BD2C6300082DE9FC4165 +S31508002FF080460E4617461C46002001900090002584 +S31508003000308810F47C5F54D0C0F305200F2850D0C8 +S31508003010D8F800000068016901913088C0F30522DC +S315080030204046FFF7D5FD072F42D2DFE807F04204F6 +S315080030300B19303633000198206001A8FFF73AFCD7 +S31508003040054636E00198206001A8FFF733FC0546DF +S3150800305028002ED01849404600F0ACF9054628E06D +S3150800306016490869000220600869000E4A6940EAA4 +S31508003070022060604869000E8A6940EA0220A06062 +S315080030808869000EC96940EA0120A06011E001982C +S3150800309020600EE0019820600BE0019880B2009055 +S315080030A06846FFF707FC05460198000C206000E01B +S315080030B001252846BDE8FC8140420F0000C00148B2 +S315080030C02DE9F04106460C4600273068006810F8DE +S315080030D02F1F2143017000F0FFFA00F2F51500F0EA +S315080030E0FBFAA84201D92E2707E0FDF704FC306851 +S315080030F0026892F82F202242F1D13846BDE8F081C5 +S315080031002DE9F0470446DDF820900D46924698468C +S315080031102068002780F851702068012646762068C6 +S31508003120067629462046FFF770FBC0B21B2838D022 +S315080031301A2836D0206852462946006800F04CFE08 +S3150800314000F0CAFA00F2E93AFEF76CFC00F0C4FA9D +S31508003150504505D8FDF7CFFB206880790028F3D0C5 +S31508003160206887712068417E1C2902D0022908D070 +S315080031700CE04B46424629462046BDE8F047FFF795 +S3150800318035BF2988C1F30521082909D02978890678 +S3150800319001D580F851602046BDE8F047FFF796BC98 +S315080031A00220BDE8F08700002DE9FC47064600200E +S315080031B001900025306890F8500000281AD0194F61 +S315080031C0DFF864900DF104080123002249463046D1 +S315080031D0CDF80080FFF794FF044674B164252846AD +S315080031E06D1C322803D23068006A0028ECDA2046C3 +S315080031F0BDE8FC874FF48017E2E730680A492030BB +S31508003200009004233A460C313046FFF779FF04460E +S315080032100CB1122CEBD1002444F620613046FFF79E +S3150800322041FCDCE7000010405A6300082DE9F04134 +S315080032300446DDE90667D81C85082046FFF7DDFB4E +S31508003240002827D12B463A4631462046FFF7F0FBA1 +S3150800325000281FD100F040FA00F2E935FEF7E2FB3C +S3150800326000F03AFAA84205D8FDF745FB2068007A2F +S315080032700028F3D02168002008722068817E1F2963 +S3150800328007D0012180F851102046BDE8F041FFF72C +S315080032901DBC0020BDE8F0817CB50546002600204F +S315080032A00190284600F060F8044634BB286840219F +S315080032B0006800F03DFD2868B0F84410090A49077F +S315080032C015D5B0F84C0046EA004201AE01230C4978 +S315080032D028460096FFF714FF044644B90849012317 +S315080032E00222091D28460096FFF70AFF044624B95C +S315080032F028680221006800F094FD20467CBD000085 +S315080033005A63000810B592B00446402102A8FDF79A +S3150800331079F80120216891F8441009071ED0204643 +S3150800332000F022F8002819D1012002A9CDE90010E1 +S3150800333040230B4A0B492046FFF778FF28B9069920 +S3150800334001F00F01012900D00120002806D12168CB +S31508003350096811F8282F42F004020A7012B010BD4D +S3150800336001000080306300087CB505460020019006 +S315080033702968B1F84C1040EA014601AC01233246EF +S315080033800B4928460094FFF7BBFE00280ED1019989 +S31508003390042201F4E851B2EB512F07D00449022365 +S315080033A032460A3928460094FFF7AAFE7CBD00007B +S315080033B03C63000870B504460D46002622680120C5 +S315080033C082F8580000F088F94FF47A71B5FBF1F1EC +S315080033D045186D1CFEF726FB00F07EF9A84201D9B8 +S315080033E02E2605E0FDF787FA2068007A0028F1D036 +S315080033F02168002008722068817E1F2900D0067E79 +S31508003400304670BD0268417A92F85030002B06D0DB +S31508003410126A520007D541F00C014172704741F01B +S3150800342002014172704741F001014172704730B4A0 +S3150800343004460020257B002D03D1204630BCFFF72B +S315080034405CB830BC704700207047000070B559481A +S31508003450D0F80012C90709D1D0F8041241F00101C9 +S31508003460C0F80412D0F80012C907FBD05248006809 +S31508003470800509D550480830016841F4007101609B +S3150800348041F64C5001F070FA4C4C206840F400208C +S31508003490206040F6C41001F067FA206848490840E1 +S315080034A02060464E103E3068A4F1040510F0300F37 +S315080034B01CD03068434908403060FEF77FF942491E +S315080034C0B0FBF1F03168401E41EA004030603B48ED +S315080034D00830016821F001010160206820F40030FD +S315080034E020602868C0F3C2100728FAD1206840F087 +S315080034F001002060206840F0100020602F4E3348FD +S31508003500361D3060206840F040002060206820F0BA +S3150800351010002060206840F480202060286840075A +S31508003520FCD5206820F0010020602868C007FCD17F +S3150800353027494FF001100860254800250830056026 +S31508003540001F0560224814300560001D05602048EC +S31508003550032110300160001F1E4901601C491E48E6 +S315080035601C310860206820F0400020601B4830604D +S315080035704FF4166001F0F8F9194830604FF46160AD +S3150800358001F0F2F9174830604FF4965001F0ECF963 +S315080035901548306041F2707001F0E6F91348306062 +S315080035A04FF4E15001F0E0F909480838056000F0E9 +S315080035B01FF870BD004000500044005014470050EA +S315080035C0FDFFFEFFCFFFF0FFA0252600002F0B0111 +S315080035D00C4600500500010003002001002F0501DC +S315080035E0002F0301002F0201002F0101002F000107 +S315080035F010B51C4C2068C1031B4823D51B49096814 +S31508003600C90701D1FEF7DAF818490C3909684A07DB +S31508003610174911D50A68C2F303635B1C0A68C2F32B +S315080036200622521C0968C1F30641491C13FB01F125 +S31508003630B0FBF1F0504305E0096801F07F01491C31 +S31508003640B0FBF1F02168C9B2491CB0FBF1F005499D +S31508003650091D096801F00101491CB0FBF1F0054993 +S31508003660086010BD0C46005000366E011C4700501D +S3150800367018470050C0FF032072B60D480D49086070 +S31508003680BFF34F8F62B60B488030016841F4700172 +S31508003690016008480C30016821F0080101600649FC +S315080036A0486920F00F0040F00400486170470000A8 +S315080036B00000000808ED00E00020005810B51022B0 +S315080036C051060448FCF727FEFFF7D6FFFFF7BEFEB4 +S315080036D010BD0000C4FF032000B500F01FF8014824 +S315080036E0006800BDCC00002000B500F00FF84FF0D0 +S315080036F0E0200449416100218161052202610248F6 +S31508003700016000BD7F320200CC0000204FF0E020AF +S315080037100021016141618161704700004FF0E0209E +S315080037200069C00303D502480168491C0160704757 +S31508003730CC000020D0F8C43113F4407F0BD000230E +S31508003740002BF7D00223491C43EA024242EA0161F0 +S31508003750C0F8C41170470123F2E7000070B50446AB +S31508003760074D284600F0B2FA284600F0BDFA206850 +S3150800377020F00100206020688007FCD470BD00009E +S315080037801000001010B500F00EF8012803D002282A +S3150800379005D0002010BDBDE8104000F079BABDE89C +S315080037A01040FEF70BB8D0F8C80100F00F007047BC +S315080037B02DE9F04104460E4615462046FFF7CEFF92 +S315080037C03146204600F097F92046FFF7DBFFB0FBAD +S315080037D0F5F1C1F5806140F2FF36B14200D33146BA +S315080037E0C1F58062B0FBF2F7AB0982099802B0FB1B +S315080037F0F2F3B34200D3334618464243920A920183 +S31508003800EB1BAA1A934201D8012200E00022002AE3 +S3150800381000D0084602D04FF0010101E04FF0020146 +S31508003820E2684CF2FF3322EA0302E260E26840EA09 +S31508003830813042EA0002E260BDE8F081816841F029 +S31508003840005181600068C16841F00051C16070474D +S3150800385010B5044622482168084440094209520323 +S3150800386000F01F0042EA0022886820F47F40886042 +S315080038702068816811438160207E002801D00128D4 +S3150800388022D121682020C861606881000DD400F02B +S31508003890604141EA804021688861A06800F0604183 +S315080038A041EA80402168C86004E02168886121688F +S315080038B0A068C860207E012807D021684FF4006000 +S315080038C0C86121680748C86110BD204600F07EF827 +S315080038D021684FF00060C86121680348C86110BDBF +S315080038E000B0FEB74006A000C000200610B501686B +S315080038F0CA69C2F3C022C969C1F38001002A01D08E +S31508003900032010BD01291FD008230168CB61016877 +S315080039108A6992001FD4426822F0005242608C697C +S31508003920C4F38A4464F31C024260CA68540F82686E +S3150800393064F35D728260940008D5CC68C4F38A4447 +S3150800394064F31C02826018E0022010BDCC6864F3A0 +S315080039501C02826011E0426842F0005242608C69A3 +S3150800396064F31C024260CC68826864F31C028260BD +S31508003970CC68640F64F35D7282600A68C2F30362FE +S3150800398002730A6902614A694261CA69C2F380021E +S31508003990C969C1F3C0010AB10029B6D1002101766F +S315080039A0002010BD0068C169C1F34012C169C1F3A6 +S315080039B00021002A06D0012906D04FF0E061C16136 +S315080039C00020704704207047022070470321027EBA +S315080039D0012A12D102682021D1610168037B0A6895 +S315080039E063F31B620A600268016911610268416932 +S315080039F0516100680249C16100210846704700000C +S31508003A00400028002DE9F04F4FF000094FF001085B +S31508003A10002642F2107EF44601220B680A2703EBC1 +S31508003A2083034FEA430B4B68BBFBF2F4B4FBF3F595 +S31508003A30B5FBF7FA07FB1A5ABAF1050F03D9B5FB16 +S31508003A40F7F56D1C01E0B5FBF7F535B105EB850A11 +S31508003A504FEA4A0AB4FBFAF402E0B4FBF7F401258C +S31508003A60A34201D8E41A00E01C1B142D07D8A4456C +S31508003A7005D991462E46A446B4F57A7F02D3521C40 +S31508003A80402AD1D940220C89531C42F210756B4347 +S31508003A90B3FBF6F39C4201D81D1B00E0E51AAE45C0 +S31508003AA001D99046AE469C4202D8521E032AEBD252 +S31508003AB0A6EB0802036843F040030360921E897A66 +S31508003AC04FF4E043491E03EA0232890742EA1162CB +S31508003AD0A8F101084FF4706101EA08210A43A9F127 +S31508003AE0010909F03F010A430261016821F040011A +S31508003AF00160BDE8F08FD0F8C82122F00F020A4312 +S31508003B00C0F8C8217047000000B5024600F02CF83E +S31508003B10104600F035F802480169C907FCD100BD16 +S31508003B20002000580148006970470000002000582E +S31508003B3030B505460C4600F017F800F01BF80023D0 +S31508003B40581C54F8201054F8230000F02BF89B1C3E +S31508003B50402BF5D3284600F02DF802480169C9071D +S31508003B60FCD130BD002000580148F521016070479E +S31508003B705455000C01485021016070475455000CFB +S31508003B8030B50649AA240C60054B55221A608025D3 +S31508003B900D600C601A603021016030BD5455000C70 +S31508003BA0A8AA000C024A1060101D016070470000A8 +S31508003BB0F055000C10B5054BAA211960044A552486 +S31508003BC01460A0221A60016010BD00005455000C54 +S31508003BD0A8AA000CF0B521F0030303441D698C075D +S31508003BE0E40EF826A640B5431D61456F4F0003262F +S31508003BF0BE40B5434567134DA84202D0124DA842B0 +S31508003C0005D1056E01268E40B543056614E0157884 +S31508003C102D0611D555688D404560CD0800EB850009 +S31508003C20056C4907C90E07268E40B5430564157A03 +S31508003C308D40016C0D43056410781969A04008434E +S31508003C401861F0BD008E0248008F024810B5436F18 +S31508003C50490003248C40A3434367436F8A401343B8 +S31508003C60436710BD10B521F003031844036989079B +S31508003C70C90EF8248C40A343036103698A401343A1 +S31508003C80036110BD014908607047000004460050F2 +S31508003C90034800680349096801F00101C8407047F4 +S31508003CA0C0FF032014460050010F20F07040064A5A +S31508003CB001EB410102EB8101D1F84016014201D026 +S31508003CC0012070470020704700400050010F20F087 +S31508003CD07040044A01EB410102EB8101C1F8480634 +S31508003CE07047000000400050010F20F07040044A61 +S31508003CF001EB410102EB8101C1F814047047000091 +S31508003D0000400050010F20F07040064A01EB4101C7 +S31508003D1002EB8101D1F80C14014201D00120704751 +S31508003D2000207047004000500186090C4186704704 +S31508003D30028F8A430287428F22EA114141877047E0 +S31508003D4010B5044C2046FFF7C1FF2046BDE81040D9 +S31508003D50FFF7CABF4000001010B503460C462146BF +S31508003D60184600F008F8188F20431887588F40EA3D +S31508003D701440588710BD828E0A438286C28E42EA54 +S31508003D801141C1867047808F084000D001207047D6 +S31508003D90B1F5803F04D2008E084000D0012070475C +S31508003DA0408E10EA1140FAD001207047406AC0F3ED +S31508003DB003500F2801D00020704701207047408E1D +S31508003DC0002800D001207047406AC0F30000704701 +S31508003DD0406AC0F34000704782600988C1810020AC +S31508003DE07047828922F0100242EA011181817047E8 +S31508003DF00A8882808A88C28082890B7A22F0200209 +S31508003E001A4382810A7A002A03D1828922F00202A1 +S31508003E1082818289497A22F00C0242EA81018181F3 +S31508003E20704710F8282F02F0DD02027002780A4364 +S31508003E3002707047D0F80C1111F0E06F03D0D0F87B +S31508003E401C0180B27047406D80B2704770B5044659 +S31508003E500D461026204600F04DF8287A00B1064691 +S31508003E60287928B132462046296800F0D5F804E0BA +S31508003E7032462046296800F08BF8E8790121401E71 +S31508003E80400001EB560140EA0120401C40F4403056 +S31508003E90E06368794FF48171401E41EA006060630F +S31508003EA0A87928B1616B401E41EA0040606305E0CD +S31508003EB0616B6879401E41EA004060634FF4A06078 +S31508003EC0A0634FF0FF30E0646889206470BDD0F8C5 +S31508003ED0082112F0E06F02D0C0F880117047826B9B +S31508003EE002F08002802AFAD04FF40052C264C0F869 +S31508003EF08010704710B504461448844202D014480E +S31508003F00844204D11148083000F0DEF814E0114864 +S31508003F10844202D01048844204D10E48083000F08A +S31508003F20D3F809E00D48844202D00D48844203D1F3 +S31508003F300A48083000F0C8F80320E060E068C007C7 +S31508003F40FCD0206C20F00F00206410BD0000034058 +S31508003F5000020340000002480002024800400248EE +S31508003F600042024810B500F58670046824F0E06443 +S31508003F70046041EA032141EA02610268034B1A40E0 +S31508003F80114341F08051016010BD0000C0C0FFEF31 +S31508003F902DE9F04781460C469046642C38D3B8F193 +S31508003FA0000F35D0FFF774FE01466420B1FBF0FC24 +S31508003FB0B4FBF0F20120012740F2FF36314602FB3E +S31508003FC008F24FF4806A0CFB01F3B3FBF2F5AC0A76 +S31508003FD0C5F30903544504D2B34202D21E46274606 +S31508003FE00846491E0029EED140F40040C9F81000E1 +S31508003FF0D9F814000749A8F10108084040EA8820C2 +S315080040007F1E40EA0740C9F814000020BDE8F08783 +S315080040100120FBE7EF8000FC2DE9F04107468846C2 +S315080040201646FFF735FE08FB06F20124904233DDFB +S3150800403090FBF2F340F2FF3104E0641C02FB04F546 +S3150800404090FBF5F38B42F8D203FB06F16143B0FB14 +S31508004050F1F15A1C72436243B0FBF2F2A8EB01007D +S31508004060B8EB020100D54942002800DA40428142F5 +S3150800407000DA5B1CC3F5806040F4804038617869DB +S315080040800649761E084040EA8620641E40EA044037 +S3150800409078610020BDE8F0810120FBE7EF8000FC95 +S315080040A010B500F58470046824F0E064046041EA01 +S315080040B0032141EA02610268024B1A40114301607A +S315080040C010BD0000C0C0FFF810B52049884211D1C4 +S315080040D0C4142046FFF7FAFD2046FFF7E5FD002841 +S315080040E0FAD12046FFF700FE2046FFF70BFE002810 +S315080040F0FAD110BD1649884211D1164C2046FFF751 +S31508004100E5FD2046FFF7D0FD0028FAD12046FFF747 +S31508004110EBFD2046FFF7F6FD0028FAD110BD0E4943 +S315080041208842FBD10B4C80342046FFF7CFFD204652 +S31508004130FFF7BAFD0028FAD12046FFF7D5FD20463D +S31508004140FFF7E0FD0028FAD110BD00000800034083 +S3150800415008000248800000100840024838B50025CB +S3150800416000950B4CFF212170001D00F06BF90146EC +S315080041706A46A06C00F052F96070211D009800F0A4 +S315080041800DFAA570E5700820A4F8440038BD0000B3 +S315080041906009002070B5FCF7C9FCF0B100F0ECF935 +S315080041A0104C012584F84050FF2020700020102173 +S315080041B06170A070FCF71EFBE070FCF731FB207104 +S315080041C0FCF72EFB000A6071A571E5710820A4F8BA +S315080041D04400BDE87040FDF7EBBABDE8704010201A +S315080041E000F0D2B96009002010B5064C002084F80A +S315080041F0400000F0C1F9FF2020700120A4F8440017 +S3150800420010BD00006009002010B5084CFF20207082 +S315080042100748A06400206070A070E0700720211D88 +S3150800422000F0BCF90820A4F8440010BD600900207D +S31508004230A06300080748FF2101700021417090F82B +S3150800424041208270C170017141710621A0F84410A5 +S31508004250704700006009002070B50446FCF7CAFAEA +S315080042606178801E884204DABDE87040222000F09A +S315080042708BB9104DFF2028700120A5F844006178FD +S3150800428049B1A21CA86CFDF797FA68B16178A86CC9 +S315080042900844A86470BDFDF77DFA0028FAD1BDE888 +S315080042A07040312000F070B9BDE87040312000F050 +S315080042B06BB900006009002070B50A4DAC6C001D92 +S315080042C000F0C0F801462046FDF76EFA28B1FF2037 +S315080042D028700120A5F8440070BDBDE87040312063 +S315080042E000F052B96009002070B50546FCF782FA5D +S315080042F00B4C411E6A1CA06CFDF75EFA58B1FF20F4 +S315080043002070FCF777FAA16C401E0844A0640120CF +S31508004310A4F8440070BDBDE87040312000F034B9FF +S3150800432060090020312000F02FB9000010B5FCF715 +S31508004330FBFA0348FF2101700121A0F8441010BDC3 +S315080043406009002070B5084CFF20207000256570B4 +S31508004350A570FCF74FFAE07025716571A571072005 +S31508004360A4F8440070BD00006009002010B5054C93 +S31508004370FF212170001D00F065F8A0640120A4F853 +S31508004380440010BD6009002070B50446FCF732FAF7 +S315080043906178401E884204DABDE87040222000F0A9 +S315080043A0F3B8201D00F04EF8094DA86462786B1C1E +S315080043B001461846FCF7A9FAFF2028706178A86C10 +S315080043C00844A8646078401CA5F8440070BD000045 +S315080043D060090020002000F0D7B8000070B5054637 +S315080043E0FCF708FA6A78401E904204DABDE8704085 +S315080043F0222000F0C9B8084C601CA16CFCF785FAAD +S31508004400FF2020706978A06C0844A0646878401C76 +S31508004410A4F8440070BD0000600900202DE9F041B1 +S3150800442004460E461746002505E014F8010B2844F5 +S31508004430C5B2FCF760FA761E701CF6D13D60012005 +S31508004440BDE8F0810178427841EA0221827841EAA2 +S315080044500241C07841EA0060704700000448002124 +S3150800446001708160C1708180817041707047000061 +S31508004470A0090020044890F84000002801D0012037 +S3150800448070470020704700006009002010B50178C9 +S31508004490344CFF2910D094F84020012A60D1F42921 +S315080044A021D013DCD02936D009DCC92930D0CC2953 +S315080044B03DD0CF293ED137E0FFF76CFE3DE0D1294C +S315080044C02FD0D2292AD0F32934D112E0F5390A2976 +S315080044D030D2DFE801F0050B2F2F2F112F14171AF2 +S315080044E0FFF77CFF29E0FFF74FFF26E0FFF73EFFC7 +S315080044F023E0FFF733FE20E0FFF786FE1DE0FFF717 +S3150800450069FF1AE0FFF796FE17E0FFF76DFE14E065 +S31508004510FFF7EAFE11E0FFF79FFE0EE0FFF712FF36 +S315080045200BE0FFF7C9FE08E0FFF700FF05E0FFF71D +S31508004530F9FE02E0202000F027F894F8430001284D +S3150800454002D1102000F020F8B4F94410002907DD44 +S31508004550012084F84300BDE81040024800F026B860 +S3150800456010BD0000600900200249002081F84300C0 +S3150800457070470000600900200249002081F84100C8 +S3150800458070470000600900200349FE220A7048703F +S315080045900220A1F844007047600900200870020A4A +S315080045A04A70020C8A70000EC870704789B2FCF710 +S315080045B085B9000070B504460020E070401EE06230 +S315080045C0204601F02CFC08B1042070BD04F22E2010 +S315080045D001F0FCFBA0F52A41553901D0032070BD36 +S315080045E004F1660001F0E7FB084DB5EB002F01D199 +S315080045F0002070BD04F1820001F0DDFBB5EB002F51 +S3150800460001D1002070BD022070BD00000046415453 +S3150800461000E0401C02780AB18A42FAD10078704755 +S31508004620891E4269921E8A4201D800207047826A12 +S31508004630408901FB002070472DE9F04781468846EE +S3150800464008F11A0001F0C2FB10B10020BDE8F0879E +S3150800465098F8000000F03F00401E00EB800101EBD7 +S31508004660C00401270025DFF860A01AF805004044B9 +S3150800467001F0ACFB06468FB1FF2C0BD2304601F099 +S3150800468089F807462046641C39F8100001F082F8BC +S31508004690874201D00020D9E7374605E0A6F57F40D6 +S315080046A0FF3801D00020D1E76D1C0D2DDDD398F819 +S315080046B00000400605D527B139F8140008B10020D6 +S315080046C0C4E70120C2E70000C46400082DE9F041F0 +S315080046D080460F46D8F80050002F08D03946404685 +S315080046E001F05CFA022809D20120BDE8F081EE68E3 +S315080046F016B16869B04207D8012605E0411CF4D016 +S3150800470069698142F1D83E463446641C6869A0420C +S3150800471004D80224022E01D20020E6E721464046AC +S3150800472001F03CFA38B10128DFD0411CDDD0B44293 +S31508004730EBD10020D9E74FF0FF363246214628460E +S3150800474001F0CAFB28B927B122463946284601F0A6 +S31508004750C3FB20B101280FD001242046C5E7EC6031 +S31508004760D5E90401891E884201D2401E28612879AC +S3150800477040F001002871F0E73446EEE72DE9F35FD3 +S315080047808846D8F800700098D0F828900024254666 +S3150800479028466D1C385C202809D32F2807D05C28AA +S315080047A005D0FF2C0FD30620BDE8FC9F6D1C795D54 +S315080047B02F29FBD05C29F9D07919C8F800102028D0 +S315080047C017D204261FE0C0B2012100F0C9FF064631 +S315080047D046B1802E08D231465DA0FFF719FF18B101 +S315080047E00620E1E70620DFE72046641C29F810606A +S315080047F0CEE7002607E0601E39F81000202801D011 +S315080048002E2802D1641E002CF5D1002029F81400A8 +S315080048103CB100980B222021006A01F0FAFA002721 +S3150800482002E00620C0E77F1C39F817002028FAD0D6 +S315080048302E28F8D01FB146F0030600E0641E24B106 +S31508004840601E39F810002E28F8D14FF00008C2462D +S315080048504FF0080B38467F1C39F8105005B3202D49 +S3150800486003D02E2D04D1A74202D046F00306F1E765 +S31508004870DA4501D2A74219D1BBF10B0F0ED0A742D8 +S3150800488001D046F003060BD827464FF0080A4FF02A +S315080048900B0B4FEA88604FEA1068DBE746F0030621 +S315080048A00098006A0178E5292ED02FE0802D0BD3D9 +S315080048B00021284600F054FF05461DB12748284424 +S315080048C010F8805C46F0020625B1294624A0FFF7B9 +S315080048D09FFE18B15F2546F003060EE0A5F14100DC +S315080048E0192802D848F0020807E0A5F1610019283E +S315080048F003D848F00108203DADB20098016A504639 +S315080049000AF1010A0D54A5E705210170BBF1080F4C +S3150800491003D14FEA88604FEA1068C8F3810003287C +S3150800492003D06FEA0801890701D146F00206B107EC +S3150800493009D408F00301012901D146F0100601281F +S3150800494001D146F008060098006AC67200202BE7D7 +S31508004950222A3A3C3E3F7C7F00000000446400085F +S315080049602B2C3B3D5B5D000008B50021009103E060 +S3150800497000BF0099491C009100998142F8D308BDEF +S315080049802DE9F04105460E462F680021284600F01D +S315080049901EFA88B900243846A96901F040FA58B9C0 +S315080049A0E9690A78E52A0CD05AB10024012128467B +S315080049B000F06EF80028EED0042800D10720BDE8E4 +S315080049C0F081641CB442F7D0F0E72DE9F0470446BD +S315080049D0D4F800A00021204600F0F9F9002855D1A6 +S315080049E0FF26B0464FF0FF39C4F824905046A16917 +S315080049F001F015FA0746380047D1E06905786DB128 +S31508004A00C17A01F03F01A171E52D03D00A0707D548 +S31508004A100F2905D0FF26C4F824902FE0042734E098 +S31508004A200F2901D0D6B11DE0A26A3AB3690606D5A8 +S31508004A3090F80D8025F040052E4621696162B54241 +S31508004A4009D1417B414506D101461046FFF7F4FDE1 +S31508004A5008B1761E00E0FF26F6B20FE001F072FB01 +S31508004A60404512D0216AC87AC00704D10B22E069F2 +S31508004A7001F0BAF948B1FF26C4F82490002120466F +S31508004A8000F006F807463800B0D03846BDE8F0878B +S31508004A902DE9F04705460F462C68D5F8108008F131 +S31508004AA02008A869002802D0B8F5001F02D3042000 +S31508004AB0BDE8F0875FEAC85166D1401CA8616969FC +S31508004AC04FF0000929B16089401E10EA582F08D016 +S31508004AD05AE02089B0EB581F56D8C5F8189004201C +S31508004AE0E6E7284601F05AF80646012E01D80220C4 +S31508004AF0DEE7701C14D06069B0423FD897B12846EB +S31508004B006969FFF7E3FD064630000FD0012E0FD086 +S31508004B10701C0FD0204601F067FB68B10120C7E77B +S31508004B200120C5E7C5F818900420C1E70720BFE7AC +S31508004B300220BDE70120BBE74FF40072002104F113 +S31508004B40300001F066F9002731462046FFF768FD78 +S31508004B50E0624FF001090BE084F80390204601F06B +S31508004B6043FB08B10120A3E77F1CE06A401CE06212 +S31508004B706089B842F0D8E06AC01BE0626E613146CF +S31508004B802046FFF74DFDA861C5F81080C8F3080058 +S31508004B9020443030E86100208AE72DE9F0470546D1 +S31508004BA089460427D5F800A0FF26B04649E05046B6 +S31508004BB001F035F90746380046D1E869047884B12A +S31508004BC0C17A01F03F01A971E52C08D02E2C06D038 +S31508004BD021F02002082A06D000224A4505D0FF26E1 +S31508004BE01FE0042730E00122F7E70F2901D026BB92 +S31508004BF01FE0610606D590F80D8024F0400426468D +S31508004C0029696962B4420AD1417B414507D1AA6A3A +S31508004C100146104601F01EF908B1761E00E0FF268F +S31508004C20F6B200212846FFF733FF0746380008D0BA +S31508004C300AE001F087FA404506D04FF0FF30686277 +S31508004C4002E0A9690029B2D10FB10020A86138464F +S31508004C50BDE8F0872DE9FE4304462768D4F820808E +S31508004C60D4F8289098F80B0010F0A00F02D0062070 +S31508004C70BDE8FE83002600E0761C39F816000028F9 +S31508004C80FAD10C224146684601F0BAF89DF80B00A5 +S31508004C90C0071BD0002088F80B00A06201252B4610 +S31508004CA04A466946404600F035FF2046FFF78DFE26 +S31508004CB010B96D1C642DF2D3642D11D00428D7D1F8 +S31508004CC09DF80B0088F80B00C4F828909DF80B0097 +S31508004CD0800707D50C360D20B6FBF0F6761C02E0E9 +S31508004CE00720C5E7012631462046FFF749FE054657 +S31508004CF04FF001082DBB761E23D02069714200EBC8 +S31508004D004111204600F063F80546280019D1206AAB +S31508004D1001F018FA81463846A16901F080F805467F +S31508004D207DB9F2B24B46E169A06A01F053F987F8FA +S31508004D30038000212046FFF7ABFE05460DB9761E17 +S31508004D40E9D1C5B93846A16901F069F805462800D0 +S31508004D5011D120220021E06901F05BF8D4E90701AE +S31508004D600B2201F04DF8206AE169C07A00F01800BC +S31508004D70087387F8038028467AE72DE9F041044648 +S31508004D8025682669616A481C0DD0204600F01FF880 +S31508004D9000281AD1E5274FF001082846A16901F035 +S31508004DA03EF878B901E00020F2E7E1690F7085F86E +S31508004DB003802169B14205D200212046FFF768FE2B +S31508004DC00028EAD0042800D10220BDE8F0812DE9A8 +S31508004DD0F04106460D463768B5F5001F01D2E806CC +S31508004DE002D00220BDE8F0813561B4681CB9387874 +S31508004DF0032800D37C6A1CB178894FEA40281AE058 +S31508004E003889B0EB551F01D80220EBE7786AB06104 +S31508004E1018E02146304600F0C1FE0446601C06D064 +S31508004E20022C02D37869A04203D80220DAE70120CF +S31508004E30D8E7A5EB08054545EBD221463846FFF7E6 +S31508004E40EFFBB0617461B06948B100EB5520B06101 +S31508004E50C5F3080038443030F0610020C2E702206C +S31508004E60C0E7000010B504460548FCF764FE0CB11F +S31508004E70032010BD0248FCF777FE0249085C10BD06 +S31508004E8068000020BD62000810B5002801D0042083 +S31508004E9010BD0348FCF776FE0249085C10BD000009 +S31508004EA068000020C162000810B5002801D004205F +S31508004EB010BD33B1DBB20448FCF7E1FF0349085CD7 +S31508004EC010BD042010BD000068000020C162000863 +S31508004ED010B5002801D0032010BD0348FCF722FEB8 +S31508004EE00249085C10BD000068000020BD62000889 +S31508004EF010B5002801D0042010BD33B1DBB2044838 +S31508004F00FEF795FA0349085C10BD042010BD0000A1 +S31508004F1068000020C162000838B50446204600F043 +S31508004F20ADFA002807D16946204601F087F900281E +S31508004F3001D10021216038BD2DE9FC410746904684 +S31508004F4000253C464E1E11E06B46012201A940464B +S31508004F5000F0BDF9009801280AD19DF804000D2833 +S31508004F6004D004F8010B6D1C0A2801D0B542EBDB0E +S31508004F700020207015B13846BDE8FC810020FBE70B +S31508004F802DE9F84F04460D466946204601F056F9C4 +S31508004F9080465FEA080004D194F81180B8F1000F42 +S31508004FA002D04046BDE8F88FE068A84203D2217CCB +S31508004FB0890700D405466069002767614FF0010933 +S31508004FC00DB3009949894E024FF0020A68B1691E6D +S31508004FD0401EB1FBF6F1B0FBF6F2914205D3711E05 +S31508004FE0884360612D1AA1690CE0A16849B90021BE +S31508004FF02046FFF76BFB0146012905D0481C07D060 +S31508005000A160A16159BB37E084F811A00220C9E765 +S3150800501084F811900120C5E7207C800706D5204634 +S31508005020FFF754FB014629B935461AE0204600F039 +S31508005030B5FD0146481C09D0012903D900984069E5 +S31508005040884207D884F811A00220ABE784F81190AB +S315080050500120A7E7A161606930446061AD1BB542D4 +S31508005060DAD8606928446061E80505D00098FFF73A +S31508005070D7FAB8B100EB5527A08AC00527D0E26950 +S31508005080BA4224D0207C04F12805400612D500989F +S31508005090012329464078FFF72BFF38B184F8119091 +S315080050A001207FE784F811A002207BE7207C20F00E +S315080050B040002074009801233A4640782946FFF7B5 +S315080050C0F3FE18B184F8119001206BE7E761E168F7 +S315080050D06069884204D9E060207C40F02000207492 +S315080050E040465FE717B581B01446029800906846B7 +S315080050F000F02DFE002802DA0B2004B010BD0B4B81 +S3150800510053F82010002201B10A700199002900D035 +S315080051100A7043F8201001D0012C01D00020ECE7DA +S31508005120002201A902A800F07BFBE6E7D4000020D4 +S315080051302DE9F74390B00546002D0CD000272F60C7 +S3150800514002F01F06324604A911A800F069FB0446BE +S31508005150200004D092E0092013B0BDE8F08304983B +S31508005160059001A80D9046480F9005A8119900F0E2 +S3150800517093FC0446200004D10D98C07A000600D599 +S31508005180062416F01C0F4FD044B1042C03D105A8F1 +S31508005190FFF760FD044646F0080609E09DF81A0088 +S315080051A010F0110F01D0072402E0700700D508247B +S315080051B0CCBB300744D5DFF8CC800C9841460E307E +S315080051C000F0B4FF0C984146163000F0AFFF0C997A +S315080051D02020C8720C99049800F0DAFD8046002257 +S315080051E00C99049800F08EFF0C9800211C3000F0F2 +S315080051F09DFF04980121C170B8F1000F20D0D0F8A6 +S315080052002C900022414605A800F042FF04462000E3 +S3150800521016D14946049800F002FE04460498A8F1FF +S315080052200108C0F80C800BE054B99DF81A00C106B5 +S3150800523001D5042404E0B10702D5C00700D007242D +S3150800524044B9300701D546F020060498C06A28629A +S315080052500C98686294B90C99049800F099FDA860B6 +S315080052600C981C3000F0A7FDE8606F746F61EF6161 +S315080052702E74049828600498C088A88020466BE796 +S315080052803A1200200000614810B594B00446019116 +S3150800529000200290039003E0641C01A800F0D4FEED +S315080052A021780029F8D1029800280DDBDDE90102F2 +S315080052B06B4604A900F082F930B900990298884231 +S315080052C002D1039814B010BD4FF0FF30FAE72DE96C +S315080052D0FC5F04460F46164698460020C8F80000AC +S315080052E06946204600F0AAFF002812D1607C0028F3 +S315080052F00FD1207CC0070BD06169E068401A86424E +S3150800530000D9064604F128004FF0010901908BE008 +S315080053100720BDE8FC9F6069C1056DD100994989E0 +S31508005320491E01EA502ABAF1000F0ED140B12046B3 +S31508005330A16900F033FC022804D202206074E8E771 +S31508005340A068F8E7411C1CD0A061A1690098FFF786 +S3150800535067F9D0B100EB0A0B750A55B300980AEB4A +S31508005360050241898A4201D9A1EB0A0540782B46F4 +S315080053705A463946FFF798FD50B184F81190012036 +S31508005380C7E784F811900120C3E702206074C0E7DC +S31508005390207C40060BD5E069A0EB0B00A84206D29C +S315080053A007EB40204FF40072019900F029FD6D02C9 +S315080053B030E0E2695A451DD0207C40060ED500989B +S315080053C0012301994078FFF793FD18B184F81190ED +S315080053D001209EE7207C20F04000207400980123DD +S315080053E05A4640780199FFF75FFD18B184F8119085 +S315080053F001208EE7C4F81CB0A08AC0F30800C0F5E7 +S315080054000075B54200D93546011928312A4638466D +S3150800541000F0F6FC2F44606928446061D8F8000063 +S315080054202844C8F80000761B002E7FF474AF0020CD +S315080054306FE7000033B58FB00D46002204A90FA808 +S3150800544000F0EEF90446A4B901A80C900A480E909B +S3150800545004A80F9900F020FB044654B90C98C07AAA +S31508005460000601D5062404E01DB1294604A800F06B +S31508005470F7FB11B0204630BD3A120020F8B50446B5 +S315080054806946204600F0DAFE00280ED1217C8A06FD +S315080054900BD548060ED50098E2690123407804F139 +S315080054A02801FFF725FD08B10120F8BD207C20F072 +S315080054B040002074144E216A009800F0B0FC0028C1 +S315080054C0F3D1656AE87A40F02000E8722946A268B6 +S315080054D0206800F017FE05F11C00E16800F026FEC2 +S315080054E0314605F1160000F021FE002105F11200F3 +S315080054F000F024FE00980121C17000F031FE217CE5 +S3150800550021F020012174F8BD0000614831B59AB038 +S315080055100025022203A91AA800F082F90446039876 +S315080055200F90E4BBCDF85CD0234819900FA81A99C0 +S3150800553000F0B2FA044694BB1798C07A000601D563 +S31508005540062404E09DF84200C00700D00724DCB911 +S315080055501699039800F01CFC05469DF84200C00603 +S3150800556012D5039804900695002104A8FFF72FFC8E +S3150800557004464CB9002104A8FFF70FFB044604B9FA +S315080055800724042C00D100244CB90FA8FFF7F5FB1B +S31508005590044644B93DB1002229460FA800E007E0B9 +S315080055A000F076FD04461CB9039800F0D9FD0446C0 +S315080055B01BB0204630BD00003A1200202DE9FC5FE2 +S315080055C004460F46164698460020C8F80000694665 +S315080055D0204600F033FE002806D1607C002803D15F +S315080055E0207C800702D40720BDE8FC9F60698119EA +S315080055F000D3C64304F128004FF001090190A5E045 +S315080056006069C1057DD100994989491E01EA502A78 +S31508005610BAF1000F1ED168B12046A169FFF756F806 +S3150800562000286FD001280DD0411C0ED0A061A168BA +S3150800563079B10FE0A0680028F2D100212046FFF7D3 +S3150800564045F8EDE702206074CEE784F81190012052 +S31508005650CAE7A060207C40060FD50098E2690123BE +S3150800566040780199FFF744FC18B184F8119001209D +S31508005670BAE7207C20F040002074A1690098FEF764 +S31508005680CFFFB0B100EB0A0B750A3DB300980AEBE1 +S31508005690050241898A4201D9A1EB0A0540782B46C1 +S315080056A05A463946FFF724FC30B184F81190012098 +S315080056B09AE70220607497E7E069A0EB0B00A8421E +S315080056C00AD207EB40214FF40072019800F098FBCC +S315080056D0207C20F0400020746D0228E0E0695845DF +S315080056E011D0E168606988420DD2009801235A46B4 +S315080056F040780199FFF7D8FB28B184F8119001206A +S3150800570072E702E025E0C4F81CB0A08AC0F30800DE +S31508005710C0F50075B54200D93546204428302A46DA +S31508005720394600F06DFB207C40F0400020742F4481 +S31508005730606928446061E168884200D80846E060EC +S31508005740D8F800002844C8F80000761B002E7FF41D +S3150800575057AF207C40F020002074002044E700006A +S31508005760802804D30A4A39B1FF2801D90020704796 +S31508005770803832F810007047002132F81130834221 +S3150800578003D0491C89B28029F7D38031C8B2704743 +S31508005790D264000830B5B0F5805F01D21E4900E03A +S315080057A01E4931F8022B002A14D0904212D331F840 +S315080057B0023B1C0ADBB2D518854228D9092C09D226 +S315080057C0DFE804F005090F1215181B1E2100801AC0 +S315080057D031F8100030BD811A01F00101401A80B27B +S315080057E030BD103880B230BD203880B230BD303878 +S315080057F080B230BD1A3880B230BD083080B230BDB4 +S31508005800503880B230BDA0F5E35080B230BD002CD0 +S31508005810C7D101EB4301C4E7D2650008C467000895 +S315080058202DE9FF410E4690460027376000F08FFAB3 +S315080058300546280003D50B2004B0BDE8F08193483F +S3150800584050F8254094B1346028F00106207820B13C +S315080058506078FFF73DFBC1070AD02770E8B2607091 +S31508005860FFF700FBC1070AD00320E5E70C20E3E7B2 +S315080058701EB1400701D50A20DEE70020DCE71EB18D +S31508005880400701D50A20D7E7002529462046FEF716 +S3150800589091FE02281FD1E84604EB051000F5F770C3 +S315080058A0017919B1083000F086FA00E0002048F8BE +S315080058B025006D1C042DEFD3002658F8265025B177 +S315080058C029462046FEF776FE00E00320022802D38A +S315080058D0761C042EF1D3042803D0022803D30D2006 +S315080058E0AAE70120A8E704F13B0000F06FFAB0F53B +S315080058F0007F01D00D209FE704F1460000F066FA0C +S3150800590018B904F1540000F056FAA06194F84080E2 +S3150800591084F80280B8F1010F04D0B8F1020F01D063 +S315080059200D2089E708FB00F894F83D00608110B166 +S31508005930411E084201D00D207EE704F1410000F027 +S3150800594045FA2081000701D00D2075E704F14300D0 +S3150800595000F03CFA0646300004D104F1500000F08D +S315080059602AFA064604F13E0000F030FA014641B133 +S31508005970238901EB080000EB1312964203D20D208F +S315080059805AE70D2058E7B01A6689B0FBF6F030B32F +S31508005990012640F6F67C604500D302264FF6F67CD3 +S315080059A0604500D30326801C6061E56129442162B5 +S315080059B02A44A262032E14D033B341446162022EF4 +S315080059C024D000F0010100EB400001EB5000A16972 +S315080059D000F2FF10B1EB502F1AD20D202CE70D2044 +S315080059E02AE704F15A0000F0F1F908B10D2023E77F +S315080059F0208908B10D201FE704F15C0000F0DBF9EF +S31508005A00606260698000E2E70D2015E74000DEE786 +S31508005A104FF0FF302061E06080202071032E2BD1EB +S31508005A2004F1600000F0D2F9012825D1691C20464E +S31508005A3000F0F5F900BB277104F22E2000F0C6F934 +S31508005A40A0F52A41553917D104F1300000F0B3F911 +S31508005A500F49884210D104F5057000F0ACF90D49DC +S31508005A60884209D104F5067000F0A5F9206104F50D +S31508005A70077000F0A0F9E06026700449091F08883D +S31508005A80401C0880E0800020D6E60000D4000020F4 +S31508005A90525261417272416173B50446256801E04C +S31508005AA0401C0190019801782F29F9D05C29F7D07C +S31508005AB00021A16001980078202807D2216A802059 +S31508005AC0C87200212046FFF782F97CBD01A920464D +S31508005AD0FEF754FE0028F8D12046FEF776FF216A25 +S31508005AE0C97A28B10428F0D14907EED405207CBD2F +S31508005AF04907FCD4A079C00601D405207CBD208ABC +S31508005B00C0F3080041193031284600F041F9A06079 +S31508005B10DCE700007CB5054616461C460B222846DF +S31508005B2000F06EF9052C11D91B480CE0B61C0023B1 +S31508005B3022460C4662F35F044908E20300D5444056 +S31508005B405B1C102BF4D331880029EFD107216B4653 +S31508005B5004F00F023032392A01D9D21DD2B20846D2 +S31508005B60491E1A542409002CF2D17E2058540022CA +S31508005B7000E0521C8A4202D2A85C2028F9D10829E2 +S31508005B8003D20846491C185C00E020201446521C23 +S31508005B902855082AF3D37CBD211001002DE9F047CA +S31508005BA00D460468022D02D36069A84201D8012671 +S31508005BB009E04FF0FF362078012807D002282CD0BC +S31508005BC003283AD001263046BDE8F08705EB55078D +S31508005BD0206A00EB5721204600F021F90028F2D16F +S31508005BE0C7F30800204407F1010890F83090206AAE +S31508005BF000EB5821204600F012F90028E3D1C8F33B +S31508005C000800204490F8300049EA0020E90701D04E +S31508005C100609D8E7C0F30B06D5E7206A00EB15217D +S31508005C20204600F0FCF80028CDD1E8B204EB40008D +S31508005C30303000F0CBF80646C5E7206A00EBD511F0 +S31508005C40204600F0ECF80028BDD140F2FF1000EA2B +S31508005C5085002044303000F0AEF820F07046B2E7F8 +S31508005C602DE9F04705460C464FF0000884F81680E3 +S31508005C70A869002869D0686A401C17D00026AF6A50 +S31508005C800DE00021FFF76CFD18B1FF2E03D30026A7 +S31508005C9009E0002607E031462144761C887537F866 +S31508005CA0020B0028EDD1A01980F8168000210A46BB +S31508005CB0A07D4FF02E0C29E0EE690B46491CF35CDB +S31508005CC0202B23D0052B00D1E523092908D110B9AB +S31508005CD0A61886F816C016462644521C86F809C029 +S31508005CE0A618737288B9A3F14107192F0CD8EF6962 +S31508005CF0092997F80C9001D3102700E0082719EA1C +S31508005D00070F01D02033DBB2B375521C0B29D3D34E +S31508005D1030B9A01880F81680E869007B00B900221F +S31508005D20A01880F80980E869C07A2072E8691C30F2 +S31508005D3000F041F82060E869183000F047F8A080C4 +S31508005D40E869163000F042F8E080BDE8F08710B543 +S31508005D5004464FF0FF302368002B0BD0194600E0AD +S31508005D60491C0A78202A01D33A2AF9D10A783A2A0C +S31508005D7001D0002010BD13F8012B303A0A2AF9D2B7 +S31508005D808B42F7D1002AF5D11046491C216010BD77 +S31508005D9070B506460D4605F11A0000F017F80446D8 +S31508005DA03078032805D105F1140000F00FF844EA0D +S31508005DB00044204670BDC178827842EA01214278C3 +S31508005DC042EA0121007840EA0120704741780078CC +S31508005DD040EA01207047FBF799FCFAF7F9FBFBF755 +S31508005DE0F1FCFAF706FCFCE710B510F8013B11F8D0 +S31508005DF0014B1B1B521E01D0002BF6D0184610BDB6 +S31508005E00002A05D011F8013B00F8013B521EF9D1D2 +S31508005E107047C9B200F8011B521EFBD1704770B516 +S31508005E2004460E460025E06AB04210D0204600F02F +S31508005E30DBF905465DB960780123324604F1300185 +S31508005E40FFF732F810B14FF0FF360125E662284613 +S31508005E5070BD00002DE9F04707460E4606F11A0008 +S31508005E60FFF7B4FF10B10020BDE8F087307800F0E6 +S31508005E703F00401E00EB800101EBC0044FF0010A11 +S31508005E800025DFF850804FF6FF7918F805003044F2 +S31508005E90FFF79CFFBAF1000F09D0FF2C01D30020B1 +S31508005EA0E2E721468246641C27F8110003E04845CC +S31508005EB001D00020D8E76D1C0D2DE6D330784006BA +S31508005EC006D5FF2C01D30020CEE7002027F81400C2 +S31508005ED00120C9E7C46400082DE9F04704460D46C9 +S31508005EE017460226022D71D36069A8426ED920781A +S31508005EF04FF0010A012804D002283AD0032865D1B8 +S31508005F004AE005EB5508206A00EB58212046FFF7C2 +S31508005F1086FF0646300059D1C8F30800204408F128 +S31508005F2001093030E90704D00178FAB262F31F118B +S31508005F3000E03946017084F803A0206A00EB592175 +S31508005F402046FFF76CFF064630003FD1C9F308002C +S31508005F5020443030E90702D0C7F3071105E001787D +S31508005F60C7F3032201F0F0011143017084F803A07E +S31508005F702CE0206A00EB15212046FFF750FF064665 +S31508005F80300023D1E8B204EB4000B9B2303000F05B +S31508005F90D5F884F803A019E0206A00EBD51120464D +S31508005FA0FFF73DFF0646300010D140F2FF1000EA29 +S31508005FB08500204430300546FFF7FDFE67F31B00D9 +S31508005FC00146284600F0B2F884F803A03046BDE83A +S31508005FD0F08700002DE9F05F81460E469046737300 +S31508005FE00F20F07200203073002106F11A0000F02D +S31508005FF0A5F8A8F1010000EB800101EBC00500241B +S315080060002746DFF840B04FF6FF7A544503D02846B6 +S315080060106D1C39F810401BF807002146304400F083 +S315080060208DF804B954467F1C0D2FEED3544502D083 +S3150800603039F8150008B948F0400886F80080BDE828 +S31508006040F09F0000C4640008F8B504460E460A2E00 +S3150800605003D10D212046FFF7F7FF6068002816DBFD +S31508006060451C204406733D2D0DDB6B462A4604F17C +S315080060700C012068FFF7A2FA0098A84201D1002572 +S3150800608001E04FF0FF356560A068401CA060F8BDD0 +S315080060902DE9F0410E46074611463C68022E02D30A +S315080060A06069B04202D80220BDE8F08131B14FF0F4 +S315080060B0FF322046FFF710FF0028F5D13146384653 +S315080060C0FFF76CFD0546BDB1012D17D0681C17D02A +S315080060D0002231462046FFF7FFFE0028E4D120695A +S315080060E0411C05D0401C2061207940F00100207138 +S315080060F02E466069B042E1D80020D5E70220D3E7F2 +S315080061000120D1E770B506460C461546A9B204F13A +S315080061101A0000F013F83078032806D1290C04F188 +S315080061201400BDE8704000F009B870BD0170090A96 +S315080061304170090A8170090AC17070470170090A1D +S3150800614041707047014600200B22430803EBC0103C +S3150800615011F8013B1844C0B2521EF6D17047000030 +S3150800616070B50446204600F03FF80546B5BB2078D2 +S3150800617003282CD12079012829D1420204F13000C4 +S3150800618000210646FFF745FE4AF6552104F22E2061 +S31508006190FFF7D4FF12493046FFF7C8FF114904F547 +S315080061A00570FFF7C3FF04F506702169FFF7BEFF08 +S315080061B004F50770E168FFF7B9FFE269521CE2626D +S315080061C0607801233146FEF793FE002020710022F5 +S315080061D060781146FEF758FE00B10125284670BDC5 +S315080061E052526141727241612DE9F041044600271D +S315080061F0E07800281FD0E66A04F1300160780123B0 +S3150800620032468846FEF774FE08B1012713E00020DF +S31508006210E070206AA169301A88420CD2A57808E095 +S31508006220A06906446078012332464146FEF760FEBF +S315080062306D1E022DF4D23846BDE8F08170B50D46C4 +S31508006240044600280CD0206850B1017841B1C188B5 +S31508006250A288914204D14078FEF73AFEC00703D0DF +S3150800626000202860092070BD20682860002070BDC5 +S3150800627010B500290AD00878002807D005487844C0 +S31508006280FAF7F2F8002801D0002010BD0248784439 +S3150800629010BD0000220600001A0600004FF04070EC +S315080062A0E1EE100A70472F64656D6F70726F675F55 +S315080062B0786D63343730302E7372656300000102DF +S315080062C00400010203040000800000000000010031 +S315080062D0010000000100000080000000000001002D +S315080062E0010000000100000080000000000001001D +S315080062F0010000000100000080000000000001000D +S3150800630001000000010000008000000000000100FC +S3150800631001000000010000008000000000000100EC +S315080063200100000001000000000009021A03000431 +S315080063303A061B071A080909090A1B0C1A0D000F49 +S315080063401A103A113A123A183A193A1B1A1C1A1D17 +S315080063503A1E1A201A211B263A2A1A373A381A06DA +S315080063603A0D3A161A1702291A2A3A3312011B0548 +S315080063701B063A081A231A24000000002000000011 +S31508006380400000008000000000010000000200003C +S3150800639000040000000800000010000000200000B3 +S315080063A04F70656E424C540000C0000C004000005F +S315080063B0030000000000010C00400000040000007B +S315080063C00040010C00400000050000000080010CA0 +S315080063D0004000000600000000C0010C004000005C +S315080063E0070000000000020C000002000800000080 +S315080063F00000040C00000400090000000000080C5E +S31508006400000004000A00000000000C0C0000040054 +S315080064100B0000000000100C000004000C00000037 +S315080064200000140C000004000D0000000000180C09 +S31508006430000004000E00000000001C0C0000040010 +S315080064400F000000809A45418E418F804545454999 +S3150800645049498E8F9092924F994F555559999A9BC3 +S315080064609C9D9E9F41494F55A5A5A6A7A8A9AAAB3D +S31508006470ACADAEAFB0B1B2B3B4B5B6B7B8B9BABBD6 +S31508006480BCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBC6 +S31508006490CCCDCECFD0D1D2D3D4D5D6D7D8D9DADBB6 +S315080064A0DCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBA6 +S315080064B0ECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFB96 +S315080064C0FCFDFEFF01030507090E10121416181C21 +S315080064D01E00C700FC00E900E200E400E000E50059 +S315080064E0E700EA00EB00E800EF00EE00EC00C4006D +S315080064F0C500C900E600C600F400F600F200FB007D +S31508006500F900FF00D600DC00A200A300A500A72022 +S315080065109201E100ED00F300FA00F100D100AA00B3 +S31508006520BA00BF001023AC00BD00BC00A100AB0040 +S31508006530BB009125922593250225242561256225F0 +S31508006540562555256325512557255D255C255B254B +S315080065501025142534252C251C2500253C255E25CB +S315080065605F255A25542569256625602550256C25FD +S3150800657067256825642565255925582552255325F7 +S315080065806B256A2518250C25882584258C259025B4 +S315080065908025B103DF009303C003A303C303B5003B +S315080065A0C403A6039803A903B4031E22C603B503AE +S315080065B029226122B1006522642220232123F700C3 +S315080065C04822B0001922B7001A227F20B200A0255F +S315080065D0A00061001A03E0001703F8000703FF0094 +S315080065E0010078010001300132010601390110016C +S315080065F04A012E017901060180014D0043028101FD +S31508006600820182018401840186018701870189014B +S315080066108A018B018B018D018E018F0190019101F9 +S31508006620910193019401F601960197019801980149 +S315080066303D029B019C019D0120029F01A001A00132 +S31508006640A201A201A401A401A601A701A701A9010B +S31508006650AA01AB01AC01AC01AE01AF01AF01B101BA +S31508006660B201B301B301B501B501B701B801B8016B +S31508006670BA01BB01BC01BC01BE01F701C001C101E1 +S31508006680C201C301C401C501C401C701C801C701CC +S31508006690CA01CB01CA01CD011001DD0101008E013D +S315080066A0DE011201F3010300F101F401F401F8011E +S315080066B02801220212013A020900652C3B023B021C +S315080066C03D02662C3F0240024102410246020A018F +S315080066D05302400081018601550289018A01580248 +S315080066E08F015A0290015C025D025E025F0293010D +S315080066F061026202940164026502660267029701FA +S3150800670096016A02622C6C026D026E029C0170028E +S3150800671071029D01730274029F0176027702780264 +S3150800672079027A027B027C02642C7E027F02A60131 +S3150800673081028202A9018402850286028702AE01CD +S315080067404402B101B20145028D028E028F02900207 +S315080067509102B7017B030300FD03FE03FF03AC03AD +S3150800676004008603880389038A03B1031103C2035D +S315080067700200A303A303C4030803CC0303008C038A +S315080067808E038F03D8031801F2030A00F903F303F3 +S31508006790F403F503F603F703F703F903FA03FA0319 +S315080067A03004200350041007600422018A043601CD +S315080067B0C1040E01CF040100C004D00444016105E0 +S315080067C0260400007D1D0100632C001E9601A01EF4 +S315080067D05A01001F0806101F0606201F0806301F4C +S315080067E00806401F0606511F0700591F521F5B1F48 +S315080067F0541F5D1F561F5F1F601F0806701F0E007F +S31508006800BA1FBB1FC81FC91FCA1FCB1FDA1FDB1F32 +S31508006810F81FF91FEA1FEB1FFA1FFB1F801F080648 +S31508006820901F0806A01F0806B01F0400B81FB91F4E +S31508006830B21FBC1FCC1F0100C31FD01F0206E01FDA +S315080068400206E51F0100EC1FF21F0100FC1F4E2186 +S315080068500100322170211002842101008321D024F5 +S315080068601A05302C2F04602C0201672C0601752CA2 +S315080068700201802C6401002D260841FF1A0300003E +S31508006880B069000800000020D80000003C0200089B +S31508006890886A0008D8000020C81D000058020008B1 +S315080068A01001000043000000F8FFFFFF00404040D1 +S315080068B040404040404041414141414040404040C5 +S315080068C04040404040404040404040404005020271 +S315080068D00202020202020202020202020220202030 +S315080068E0202020202020200202020202020290908C +S315080068F0909090901010101010101010101010108A +S3150800690010101010101010100202020202028888DD +S3150800691088888888080808080808080808080808E9 +S3150800692008080808080808080202020240000000D1 +S315080069300000000000000000000000000000000049 +S315080069400000000000000000000000000000000039 +S315080069500000000000000000000000000000000029 +S315080069600000000000000000000000000000000019 +S315080069700000000000000000000000000000000009 +S3150800698000000000000000000000000000000000F9 +S3150800699000000000000000000000000000000000E9 +S315080069A000000000000000000000000000000000D9 +S315080069B0000000000000000000C0014800000000C0 +S315080069C0000000003F00000000000000000000007A +S315080069D000000000000000000000000000000000A9 +S315080069E00000000000000000000000000000000099 +S315080069F00000000000000000000000000000000089 +S31508006A000000000000000000000000000000000078 +S31508006A10000000000000000008000020611A0008BD +S31508006A200300000000000000000000000000000055 +S31508006A300000000004000000000000000000000044 +S31508006A400000000000420148004301480044014894 +S31508006A50004501480046014800470148000000007B +S31508006A600000000000000340000203400000024846 +S31508006A7000020248004002480042024800000000A6 +S30D08006A80000000000000000000 S70508000201EF diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/blt_conf.h b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/blt_conf.h index 47b23aeb..a3b7ec69 100644 --- a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/blt_conf.h +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/blt_conf.h @@ -185,7 +185,7 @@ * firmware update is completed by the bootloader. */ /** \brief Enable/disable support for firmware updates from a locally attached storage.*/ -#define BOOT_FILE_SYS_ENABLE (0) +#define BOOT_FILE_SYS_ENABLE (1) /** \brief Enable/disable logging messages during firmware updates. */ #define BOOT_FILE_LOGGING_ENABLE (1) /** \brief Enable/disable a hook function that is called upon detection of an error. */ diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvoptx b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvoptx index c3b94d4c..423336b2 100644 --- a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvoptx +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvoptx @@ -135,7 +135,7 @@ 0 DLGUARM - + d 0 @@ -1679,32 +1679,32 @@ - Core - 0 + Lib/FatFS + 1 0 0 0 5 122 - 1 + 5 0 0 0 - ..\..\..\..\Source\asserts.c - asserts.c + ..\lib\FatFS\ffconf.h + ffconf.h 0 0 5 123 - 5 + 1 0 0 0 - ..\..\..\..\Source\asserts.h - asserts.h + ..\lib\FatFS\mmc.c + mmc.c 0 0 @@ -1715,8 +1715,8 @@ 0 0 0 - ..\..\..\..\Source\backdoor.c - backdoor.c + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block.c + sdmmc_block.c 0 0 @@ -1727,8 +1727,8 @@ 0 0 0 - ..\..\..\..\Source\backdoor.h - backdoor.h + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block.h + sdmmc_block.h 0 0 @@ -1739,8 +1739,8 @@ 0 0 0 - ..\..\..\..\Source\boot.c - boot.c + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_conf.c + sdmmc_block_conf.c 0 0 @@ -1751,8 +1751,8 @@ 0 0 0 - ..\..\..\..\Source\boot.h - boot.h + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_conf.h + sdmmc_block_conf.h 0 0 @@ -1763,8 +1763,8 @@ 0 0 0 - ..\..\..\..\Source\can.h - can.h + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_extern.h + sdmmc_block_extern.h 0 0 @@ -1775,8 +1775,8 @@ 0 0 0 - ..\..\..\..\Source\com.c - com.c + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_private_sd.c + sdmmc_block_private_sd.c 0 0 @@ -1787,14 +1787,130 @@ 0 0 0 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_private_sd.h + sdmmc_block_private_sd.h + 0 + 0 + + + + + Core + 0 + 0 + 0 + 0 + + 6 + 131 + 1 + 0 + 0 + 0 + ..\..\..\..\Source\asserts.c + asserts.c + 0 + 0 + + + 6 + 132 + 5 + 0 + 0 + 0 + ..\..\..\..\Source\asserts.h + asserts.h + 0 + 0 + + + 6 + 133 + 1 + 0 + 0 + 0 + ..\..\..\..\Source\backdoor.c + backdoor.c + 0 + 0 + + + 6 + 134 + 5 + 0 + 0 + 0 + ..\..\..\..\Source\backdoor.h + backdoor.h + 0 + 0 + + + 6 + 135 + 1 + 0 + 0 + 0 + ..\..\..\..\Source\boot.c + boot.c + 0 + 0 + + + 6 + 136 + 5 + 0 + 0 + 0 + ..\..\..\..\Source\boot.h + boot.h + 0 + 0 + + + 6 + 137 + 5 + 0 + 0 + 0 + ..\..\..\..\Source\can.h + can.h + 0 + 0 + + + 6 + 138 + 1 + 0 + 0 + 0 + ..\..\..\..\Source\com.c + com.c + 0 + 0 + + + 6 + 139 + 5 + 0 + 0 + 0 ..\..\..\..\Source\com.h com.h 0 0 - 5 - 131 + 6 + 140 1 0 0 @@ -1805,8 +1921,8 @@ 0 - 5 - 132 + 6 + 141 5 0 0 @@ -1817,8 +1933,8 @@ 0 - 5 - 133 + 6 + 142 5 0 0 @@ -1829,8 +1945,8 @@ 0 - 5 - 134 + 6 + 143 1 0 0 @@ -1841,8 +1957,8 @@ 0 - 5 - 135 + 6 + 144 5 0 0 @@ -1853,8 +1969,8 @@ 0 - 5 - 136 + 6 + 145 1 0 0 @@ -1865,8 +1981,8 @@ 0 - 5 - 137 + 6 + 146 5 0 0 @@ -1877,8 +1993,8 @@ 0 - 5 - 138 + 6 + 147 5 0 0 @@ -1889,8 +2005,8 @@ 0 - 5 - 139 + 6 + 148 5 0 0 @@ -1901,8 +2017,8 @@ 0 - 5 - 140 + 6 + 149 5 0 0 @@ -1913,8 +2029,8 @@ 0 - 5 - 141 + 6 + 150 5 0 0 @@ -1925,8 +2041,8 @@ 0 - 5 - 142 + 6 + 151 5 0 0 @@ -1937,8 +2053,8 @@ 0 - 5 - 143 + 6 + 152 1 0 0 @@ -1949,8 +2065,8 @@ 0 - 5 - 144 + 6 + 153 5 0 0 @@ -1969,8 +2085,8 @@ 0 0 - 6 - 145 + 7 + 154 1 0 0 @@ -1981,8 +2097,8 @@ 0 - 6 - 146 + 7 + 155 1 0 0 @@ -1993,8 +2109,8 @@ 0 - 6 - 147 + 7 + 156 1 0 0 @@ -2005,8 +2121,8 @@ 0 - 6 - 148 + 7 + 157 5 0 0 @@ -2017,8 +2133,8 @@ 0 - 6 - 149 + 7 + 158 1 0 0 @@ -2029,8 +2145,8 @@ 0 - 6 - 150 + 7 + 159 1 0 0 @@ -2041,8 +2157,8 @@ 0 - 6 - 151 + 7 + 160 1 0 0 @@ -2053,8 +2169,8 @@ 0 - 6 - 152 + 7 + 161 5 0 0 @@ -2065,8 +2181,8 @@ 0 - 6 - 153 + 7 + 162 1 0 0 @@ -2078,4 +2194,72 @@ + + Core/third_party/fatfs + 0 + 0 + 0 + 0 + + 8 + 163 + 5 + 0 + 0 + 0 + ..\..\..\..\Source\third_party\fatfs\src\diskio.h + diskio.h + 0 + 0 + + + 8 + 164 + 1 + 0 + 0 + 0 + ..\..\..\..\Source\third_party\fatfs\src\ff.c + ff.c + 0 + 0 + + + 8 + 165 + 5 + 0 + 0 + 0 + ..\..\..\..\Source\third_party\fatfs\src\ff.h + ff.h + 0 + 0 + + + 8 + 166 + 5 + 0 + 0 + 0 + ..\..\..\..\Source\third_party\fatfs\src\integer.h + integer.h + 0 + 0 + + + 8 + 167 + 1 + 0 + 0 + 0 + ..\..\..\..\Source\third_party\fatfs\src\option\unicode.c + unicode.c + 0 + 0 + + + diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvprojx b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvprojx index 33f06857..63363110 100644 --- a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvprojx +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/ide/xmc4700.uvprojx @@ -339,7 +339,7 @@ --diag_suppress=111 XMC4700_F144x2048 - ..\..\Boot;..\lib;..\lib\cmsis;..\lib\xmclib\inc;..\..\..\..\Source;..\..\..\..\Source\ARMCM4_XMC4 + ..\..\Boot;..\lib;..\lib\cmsis;..\lib\xmclib\inc;..\lib\FatFS;..\lib\FatFS\SDMMC_BLOCK;..\..\..\..\Source;..\..\..\..\Source\ARMCM4_XMC4;..\..\..\..\Source\third_party\fatfs\src @@ -1005,6 +1005,56 @@ + + Lib/FatFS + + + ffconf.h + 5 + ..\lib\FatFS\ffconf.h + + + mmc.c + 1 + ..\lib\FatFS\mmc.c + + + sdmmc_block.c + 1 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block.c + + + sdmmc_block.h + 5 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block.h + + + sdmmc_block_conf.c + 1 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_conf.c + + + sdmmc_block_conf.h + 5 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_conf.h + + + sdmmc_block_extern.h + 5 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_extern.h + + + sdmmc_block_private_sd.c + 1 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_private_sd.c + + + sdmmc_block_private_sd.h + 5 + ..\lib\FatFS\SDMMC_BLOCK\sdmmc_block_private_sd.h + + + Core @@ -1175,6 +1225,36 @@ + + Core/third_party/fatfs + + + diskio.h + 5 + ..\..\..\..\Source\third_party\fatfs\src\diskio.h + + + ff.c + 1 + ..\..\..\..\Source\third_party\fatfs\src\ff.c + + + ff.h + 5 + ..\..\..\..\Source\third_party\fatfs\src\ff.h + + + integer.h + 5 + ..\..\..\..\Source\third_party\fatfs\src\integer.h + + + unicode.c + 1 + ..\..\..\..\Source\third_party\fatfs\src\option\unicode.c + + + diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block.c b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block.c new file mode 100644 index 00000000..ed5b061e --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block.c @@ -0,0 +1,780 @@ + +/** + * @file sdmmc_block.c + * @date 2016-08-24 + * + * NOTE: + * This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. + * + * @cond + *********************************************************************************************************************** + * SDMMC_BLOCK v4.0.22 - The SDMMC_BLOCK APP is a generic SD/MMC card block device driver designed to drive SDMMC cards + * with all relevant functionalities like writing or reading blocks of data from the card. + * + * Copyright (c) 2016-2017, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 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. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes + * with Infineon Technologies AG (dave@infineon.com). + *********************************************************************************************************************** + * + * Change History + * -------------- + * + * 2016-01-20: + * - Initial version.
+ * + * 2016-02-05: + * - RTOS support added.
+ * - Bug fixes done.
+ * + * 2016-02-08: + * - Help Doc updated.
+ * - Bug fixes done.
+ * + * 2016-04-05: + * - Remove dead code
+ * - MISRA fixes
+ * + * @endcond + */ + +/*********************************************************************************************************************** + * HEADER FILES + **********************************************************************************************************************/ + +#include "sdmmc_block.h" + +#ifdef SDMMC_BLOCK_SD +# if SDMMC_BLOCK_RTOS_MODE_SELECT +# include "sdmmc_block_private_sd_rtos.h" +#else +# include "sdmmc_block_private_sd.h" +# endif /* SDMMC_BLOCK_RTOS_MODE_SELECT */ +#endif /* SDMMC_BLOCK_SD */ + +#ifdef SDMMC_BLOCK_SPI +# if SDMMC_BLOCK_RTOS_MODE_SELECT +# include "sdmmc_block_private_spi_rtos.h" +#else +# include "sdmmc_block_private_spi.h" +# endif /* SDMMC_BLOCK_RTOS_MODE_SELECT */ +#endif /* SDMMC_BLOCK_SPI */ + +/*********************************************************************************************************************** + * MACROS + **********************************************************************************************************************/ + +#define SDMMC_BLOCK_LOCK (0x4U) /* Lock the card */ +#define SDMMC_BLOCK_UNLOCK (0x0U) /* Unlock the card */ +#define SDMMC_BLOCK_SET_PASSWD (0x1U) /* Set the password for the card */ +#define SDMMC_BLOCK_CLR_PASSWD (0x2U) /* Clears the password */ +#define SDMMC_BLOCK_SET_PASSWD_AND_LOCK (0x5U) /* Set the password and locks the card */ +#define SDMMC_BLOCK_FORCE_ERASE (0x8U) /* Force erase the password data */ + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * LOCAL ROUTINES + **********************************************************************************************************************/ + +static SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_lFlushDiskWriteCache(SDMMC_BLOCK_t *obj); + +/********************************************************************************************************************** + * API IMPLEMENTATION + **********************************************************************************************************************/ + +/* SDMMC_BLOCK initialization function */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_Init(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_STATUS_t status = SDMMC_BLOCK_STATUS_SUCCESS; + SDMMC_BLOCK_MODE_STATUS_t mode_status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + + XMC_ASSERT("SDMMC_BLOCK_Init:Null obj is passed as input" , (obj != NULL)) + + if (obj->init_flag == 1U) + { + status = SDMMC_BLOCK_STATUS_SUCCESS; + } + else + { + /* Setup pins */ + if (obj->init_pins != NULL) + { + obj->init_pins(); + } + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_Init(obj); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_Init(obj); + } +#endif + + if (mode_status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + status = SDMMC_BLOCK_STATUS_FAILURE; + obj->init_flag = 0U; + } + else + { + obj->init_flag = 1U; + } + } + + return status; +} + +/* Initialize the card identification process */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_Initialize(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t mode_status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + SDMMC_BLOCK_STATUS_t status = SDMMC_BLOCK_STATUS_FAILURE; + + XMC_ASSERT("SDMMC_BLOCK_Initialize:Null obj is passed as input" , (obj != NULL)) + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_CardIdentificationProcess(obj); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_CardIdentificationProcess(obj); + } +#endif + + if (mode_status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + status = SDMMC_BLOCK_STATUS_SUCCESS; + } + + return status; +} + +/* Read the specified number of sectors of data from the specified address */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_ReadBlock(SDMMC_BLOCK_t *const obj, + uint8_t* read_buf, + const uint32_t sector_number, + const uint8_t sector_count) +{ + SDMMC_BLOCK_STATUS_t status = SDMMC_BLOCK_STATUS_SUCCESS; + + XMC_ASSERT("SDMMC_BLOCK_ReadBlock:Null obj is passed as input" , (obj != NULL)) + XMC_ASSERT("SDMMC_BLOCK_ReadBlock:Read buffer address is invalid" , (read_buf != NULL)) + XMC_ASSERT("SDMMC_BLOCK_ReadBlock:Sector count to be read is zero" , (sector_count != 0U)) + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + status = SDMMC_BLOCK_SPI_ReadBlock(obj, read_buf, sector_number, (uint32_t)sector_count); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + status = SDMMC_BLOCK_SD_ReadBlock(obj, read_buf, sector_number, sector_count); + } +#endif + + return status; +} + +/* Write the specified number of sectors of data from the specified address */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_WriteBlock(SDMMC_BLOCK_t *const obj, + uint8_t* write_buf, + const uint32_t sector_number, + const uint8_t sector_count) +{ + SDMMC_BLOCK_STATUS_t status = SDMMC_BLOCK_STATUS_SUCCESS; + + XMC_ASSERT("SDMMC_BLOCK_WriteBlock:Null obj is passed as input" , (obj != NULL)) + XMC_ASSERT("SDMMC_BLOCK_WriteBlock:Write buffer address is invalid" , (write_buf != NULL)) + XMC_ASSERT("SDMMC_BLOCK_WriteBlock:Sector count to be written is zero" , (sector_count != 0U)) + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + status = SDMMC_BLOCK_SPI_WriteBlock(obj, write_buf, sector_number, (uint32_t)sector_count); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + status = SDMMC_BLOCK_SD_WriteBlock(obj, write_buf, sector_number, sector_count); + } +#endif + + return status; +} + +/* Get the current status of the card */ +uint8_t SDMMC_BLOCK_GetStatus(SDMMC_BLOCK_t *const obj) +{ + uint8_t disk_status = 0U; + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + disk_status = SDMMC_BLOCK_SPI_GetState(obj); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + disk_status = SDMMC_BLOCK_SD_GetState(obj); + } +#endif + + return disk_status; +} + +/* I/O control */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_Ioctl(SDMMC_BLOCK_t *const obj, const uint8_t command, void *buffer) +{ + SDMMC_BLOCK_STATUS_t status = SDMMC_BLOCK_STATUS_SUCCESS; + SDMMC_BLOCK_MODE_STATUS_t mode_status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + uint8_t card_status; + bool valid_command = true; + SDMMC_BLOCK_ERASE_ADDRESS_t *erase_ptr; + SDMMC_BLOCK_LOCK_STRUCTURE_t lock = {0U}; + const SDMMC_BLOCK_PASSWORD_t *password; + + XMC_ASSERT("SDMMC_BLOCK_WriteBlock:Null obj is passed as input" , (obj != NULL)) + + /* If card is not initialized or inserted */ + if ((obj->card_state & (uint8_t)SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED) == (uint8_t)0) + { + card_status = SDMMC_BLOCK_GetStatus(obj); + + if ((card_status & (uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED) != 0U) + { + status = SDMMC_BLOCK_STATUS_LOCKED; + if ((command == (uint8_t)SDMMC_BLOCK_CTRL_SYNC) || + (command == (uint8_t)SDMMC_BLOCK_MMC_GET_OCR) || + (command == (uint8_t)SDMMC_BLOCK_MMC_GET_SDSTAT) || + (command == (uint8_t)SDMMC_BLOCK_CTRL_TRIM)) + { + valid_command = false; + } + } + } + else + { + valid_command = false; + status = SDMMC_BLOCK_STATUS_NOTRDY; + } + + if (valid_command == true) + { + /* Switch to the respective IOCTL command */ + switch (command) + { + /* + * Control sync + */ + case SDMMC_BLOCK_CTRL_SYNC: + status = SDMMC_BLOCK_lFlushDiskWriteCache(obj); + break; + + /* + * Get sector size + */ + case SDMMC_BLOCK_GET_SECTOR_SIZE: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetSectorSize(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetSectorSize(obj, buffer); + } +#endif + + break; + + /* + * Get sector count + */ + case SDMMC_BLOCK_GET_SECTOR_COUNT: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetSectorCount(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetSectorCount(obj, buffer); + } +#endif + break; + + /* + * Control trim. Erase the content in the specified sectors + */ + case SDMMC_BLOCK_CTRL_TRIM: + erase_ptr = (SDMMC_BLOCK_ERASE_ADDRESS_t *) buffer; +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_EraseBlock(obj, (erase_ptr->start_address), (erase_ptr->end_address)); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_EraseBlock(obj, (erase_ptr->start_address), (erase_ptr->end_address)); + } +#endif + break; + + /* + * Get block size + */ + case SDMMC_BLOCK_GET_BLOCK_SIZE: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetBlockSize(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetBlockSize(obj, buffer); + } +#endif + break; + + /* + * Get the type of the card + */ + case SDMMC_BLOCK_MMC_GET_TYPE: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetCardType(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetCardType(obj, buffer); + } +#endif + break; + + /* + * Get CSD + */ + case SDMMC_BLOCK_MMC_GET_CSD: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetCsd(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetCsd(obj, buffer); + } +#endif + break; + + /* + * Get CID + */ + case SDMMC_BLOCK_MMC_GET_CID: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetCid(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetCid(obj, buffer); + } +#endif + break; + + /* + * Get OCR + */ + case SDMMC_BLOCK_MMC_GET_OCR: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetOcr(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetOcr(obj, buffer); + } +#endif + break; + + /* + * Get SD status + */ + case SDMMC_BLOCK_MMC_GET_SDSTAT: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetSdStatus(obj, buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetSdStatus(obj, buffer); + } +#endif + break; + + /* + * Lock card + */ + case SDMMC_BLOCK_MMC_LOCK_CARD: + lock.mode = (uint8_t)SDMMC_BLOCK_LOCK; + password = (const SDMMC_BLOCK_PASSWORD_t *)buffer; + + /* Check password length doesn't exceeds the permitted length */ + if (password->old_pwd_len <= (uint8_t)SDMMC_BLOCK_MAX_PASSWORD_LENGTH) + { + lock.pwd_len = password->old_pwd_len; + memcpy(lock.pwd_data, password->old_pwd, lock.pwd_len); + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED); + } +#endif + } + else + { + mode_status = SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR; + } + break; + + /* + * Unlock card + */ + case SDMMC_BLOCK_MMC_UNLOCK_CARD: + lock.mode = (uint8_t)SDMMC_BLOCK_UNLOCK; + password = (const SDMMC_BLOCK_PASSWORD_t *)buffer; + + if (password->old_pwd_len <= (uint8_t)SDMMC_BLOCK_MAX_PASSWORD_LENGTH) + { + lock.pwd_len = password->old_pwd_len; + memcpy(lock.pwd_data, password->old_pwd, lock.pwd_len); + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } +#endif + } + else + { + mode_status = SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR; + } + break; + + /* + * Set card password + */ + case SDMMC_BLOCK_MMC_SET_PASSWD: + lock.mode = (uint8_t)SDMMC_BLOCK_SET_PASSWD; + password = (const SDMMC_BLOCK_PASSWORD_t *)buffer; + + if ((password->old_pwd_len <= (uint8_t)SDMMC_BLOCK_MAX_PASSWORD_LENGTH) && + (password->new_pwd_len <= (uint8_t)SDMMC_BLOCK_MAX_PASSWORD_LENGTH)) + { + lock.pwd_len = password->old_pwd_len + password->new_pwd_len; + memcpy(lock.pwd_data, password->old_pwd, password->old_pwd_len); + memcpy(&lock.pwd_data[password->old_pwd_len], password->new_pwd, password->new_pwd_len); + + #ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } + #endif + + #ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } + #endif + } + else + { + mode_status = SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR; + } + break; + + /* + * Clear card password + */ + case SDMMC_BLOCK_MMC_CLEAR_PASSWD: + lock.mode = (uint8_t)SDMMC_BLOCK_CLR_PASSWD; + password = (const SDMMC_BLOCK_PASSWORD_t *)buffer; + if (password->old_pwd_len <= (uint8_t)SDMMC_BLOCK_MAX_PASSWORD_LENGTH) + { + lock.pwd_len = password->old_pwd_len; + memcpy(lock.pwd_data, password->old_pwd, lock.pwd_len); + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } +#endif + } + else + { + mode_status = SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR; + } + break; + + /* + * Set card lock + */ + case SDMMC_BLOCK_MMC_SET_LOCK: + lock.mode = (uint8_t)SDMMC_BLOCK_SET_PASSWD_AND_LOCK; + password = (const SDMMC_BLOCK_PASSWORD_t *)buffer; + + if ((password->old_pwd_len <= (uint8_t)SDMMC_BLOCK_MAX_PASSWORD_LENGTH) && + (password->new_pwd_len <= (uint8_t)SDMMC_BLOCK_MAX_PASSWORD_LENGTH)) + { + lock.pwd_len = password->old_pwd_len + password->new_pwd_len; + memcpy(lock.pwd_data, password->old_pwd, password->old_pwd_len); + memcpy(&lock.pwd_data[password->old_pwd_len], password->new_pwd, password->new_pwd_len); + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED); + } +#endif + } + else + { + mode_status = SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR; + } + break; + + /* + * Read lock status + */ + case SDMMC_BLOCK_MMC_READ_LOCK_STATUS: + +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_GetLockStatus(obj, (SDMMC_BLOCK_CARD_LOCK_STATUS_t *)buffer); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_GetLockStatus(obj, (SDMMC_BLOCK_CARD_LOCK_STATUS_t *)buffer); + } +#endif + break; + + /* + * Force card erase + */ + case SDMMC_BLOCK_MMC_FORCE_ERASE: + lock.mode = (uint8_t)SDMMC_BLOCK_FORCE_ERASE; +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_LockUnlockCard(obj, &lock, SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED); + } +#endif + break; + + /* + * Eject card + */ + case SDMMC_BLOCK_CTRL_EJECT: +#ifdef SDMMC_BLOCK_SPI + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SPI) + { + mode_status = SDMMC_BLOCK_SPI_EjectCard(obj); + } +#endif + +#ifdef SDMMC_BLOCK_SD + if (obj->interface_mode == SDMMC_BLOCK_CARD_INTERFACE_SD) + { + mode_status = SDMMC_BLOCK_SD_EjectCard(obj); + } +#endif + break; + + default: + mode_status = SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR; + break; + } + + if (mode_status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + status = SDMMC_BLOCK_STATUS_SUCCESS; + } + else if (mode_status == SDMMC_BLOCK_MODE_STATUS_WP_VIOLATION_ERROR) + { + status = SDMMC_BLOCK_STATUS_WRPRT; + } + else if ((mode_status == SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR) || + (mode_status == SDMMC_BLOCK_MODE_STATUS_SECTOR_OUT_OF_BOUND)) + { + status = SDMMC_BLOCK_STATUS_PARERR; + } + else + { + status = SDMMC_BLOCK_STATUS_FAILURE; + } + } + + return status; +} + +#if SDMMC_BLOCK_SD_CARD_DETECTION_SUPPORT + +#ifdef SDMMC_BLOCK_SD + +/* + * Registers the callback function for the card detection + * mechanism. + */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_RegisterCallback(SDMMC_BLOCK_t *const obj, + void (*cb)(SDMMC_BLOCK_SD_INTERRUPT_t)) +{ + SDMMC_BLOCK_STATUS_t status = SDMMC_BLOCK_STATUS_PARERR; + + /* Check if the callback is not NULL */ + if (cb != NULL) + { + obj->sdmmc_sd->callback = cb; + status = SDMMC_BLOCK_STATUS_SUCCESS; + } + + return status; +} + +#endif /* SDMMC_BLOCK_SD */ + +#endif /* SDMMC_BLOCK_SD_CARD_DETECTION_SUPPORT */ + +/*********************************************************************************************************************** + * LOCAL ROUTINES IMPLEMENTATION + **********************************************************************************************************************/ + +/* Flush disk cache */ +static SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_lFlushDiskWriteCache(SDMMC_BLOCK_t *obj) +{ + /* + * A flush is generally meant for writing filled buffers/cache to the + * media. We're already ensuring that a write block(s) operation completes + * before it exits WriteBlock(). + * So, this function does nothing at the moment. We are simply going to + * return success + */ + return SDMMC_BLOCK_STATUS_SUCCESS; +} diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block.h b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block.h new file mode 100644 index 00000000..1535dba2 --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block.h @@ -0,0 +1,1321 @@ + +/** + * @file sdmmc_block.h + * @date 2017-02-14 + * + * NOTE: + * This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. + * + * @cond + *********************************************************************************************************************** + * SDMMC_BLOCK v4.0.22 - The SDMMC_BLOCK APP is a generic SD/MMC card block device driver designed to drive SDMMC cards + * with all relevant functionalities like writing or reading blocks of data from the card. + * + * Copyright (c) 2016-2017, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 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. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes + * with Infineon Technologies AG (dave@infineon.com). + *********************************************************************************************************************** + * + * Change History + * -------------- + * + * 2016-01-20: + * - Initial version.
+ * + * 2016-02-05: + * - RTOS support added.
+ * - Bug fixes done.
+ * + * 2016-02-08: + * - Help Doc updated.
+ * - Bug fixes done.
+ * + * 2016-04-05: + * - Remove dead code
+ * - MISRA fixes
+ * + * 2017-02-14: + * - Update minimum required XMCLib version
+ * + * @endcond + */ + +#ifndef SDMMC_BLOCK_H +#define SDMMC_BLOCK_H + +/*********************************************************************************************************************** + * HEADER FILES + **********************************************************************************************************************/ + +#include "sdmmc_block_conf.h" +#include "xmc_gpio.h" + +#if (!((XMC_LIB_MAJOR_VERSION == 2U) && \ + (XMC_LIB_MINOR_VERSION >= 1U) && \ + (XMC_LIB_PATCH_VERSION >= 10U))) +#error "SDMMC_BLOCK requires XMC Peripheral Library v2.1.10 or higher" +#endif + +/********************************************************************************************************************** + * MACROS + **********************************************************************************************************************/ + +#define SDMMC_BLOCK_NORMAL_INT_STATUS_BITS (0x7FFFU) /**< Normal interrupt status bits */ +#define SDMMC_BLOCK_BLOCK_ADDRESSING (8U) /**< Card supports block addressing. It means address will be + taken in terms of sector numbers */ + +#define SDMMC_BLOCK_IN_IDLE_STATE (0x01U) /**< Idle State */ +#define SDMMC_BLOCK_ILLEGAL_COMMAND (0x04U) /**< Illegal Command */ + +/**< Some Command's static Arguments */ +#define SDMMC_BLOCK_ARGUMENT0 (0x00000000U) +#define SDMMC_BLOCK_SD_CMD8_ARG (0x000001AAU) +#define SDMMC_BLOCK_SD_ACMD41_F80_ARG (0x00100000U) +#define SDMMC_BLOCK_SD_ACMD41_F81_ARG (0x40100000U) +#define SDMMC_BLOCK_MMC_CMD1_ARG (0x40FF8000U) +#define SDMMC_BLOCK_MMC_4BUS_WIDTH_ARG (0x03B70100U) +#define SDMMC_BLOCK_SD_4BUS_WIDTH_ARG (0x00000002U) +#define SDMMC_BLOCK_MMC_HIGH_SPEED_ARG (0x03B90100U) +#define SDMMC_BLOCK_SD_HIGH_SPEED_ARG (0x80000001U) + +/**< RCA Register */ +#define SDMMC_BLOCK_MMC_DEFAULT_RCA (0x0001U) +#define SDMMC_BLOCK_ARG_RCA_BITPOS (0x10U) + +#define SDMMC_BLOCK_SD_CARD_TYPE_BITMASK (0xFFFFU) /**< Card type mask */ + +/* SCR Register Bitmask */ +#define SDMMC_BLOCK_SCR_BUS_WIDTH4_BITMASK (0x4U) /**< Bus width mask */ + +/**< SD Card's CMD8 response R7 bit positions */ +#define SDMMC_BLOCK_SD_CMD8_CHECK_PATTERN_VALUE (0xAAU) +#define SDMMC_BLOCK_SD_CMD8_CHECK_PATTERN_BITMASK (0xFFU) +#define SDMMC_BLOCK_SD_CMD8_CHECK_PATTERN_BITPOS (0x00U) +#define SDMMC_BLOCK_SD_CMD8_VHS_BITPOS (0x8U) +#define SDMMC_BLOCK_SD_CMD8_VHS_BITMASK (0xFU) +#define SDMMC_BLOCK_SD_VHS_PATTERN_2_7_3_6_VALUE (0x1U) + +/**< Card's OCR register */ +#define SDMMC_BLOCK_OCR_POWER_STATUS_BITMASK (0x80000000U) +#define SDMMC_BLOCK_OCR_CCS_BITMASK (0x40000000U) +#define SDMMC_BLOCK_MMC_OCR_ACCESS_MODE_BITMASK (0x60000000U) +#define SDMMC_BLOCK_MMC_OCR_ACCESS_MODE_BITPOS (0x1DU) + +/* + * Command code for disk_ioctrl function + */ + +/* Generic command (defined for FatFs) */ +#define SDMMC_BLOCK_CTRL_SYNC (0U) /**< Flush disk cache (for write functions) */ +#define SDMMC_BLOCK_GET_SECTOR_COUNT (1U) /**< Get media size */ +#define SDMMC_BLOCK_GET_SECTOR_SIZE (2U) /**< Get sector size */ +#define SDMMC_BLOCK_GET_BLOCK_SIZE (3U) /**< Get erase block size */ +#define SDMMC_BLOCK_CTRL_TRIM (4U) /**< Inform device that the data on the block of sectors is + no longer used. */ + +/* Generic command */ +#define SDMMC_BLOCK_CTRL_EJECT (7U) /**< Eject media */ + +/* MMC/SDC specific ioctl command */ +#define SDMMC_BLOCK_MMC_GET_TYPE (10U) /**< Get card type i.e. Standard Capacity v2/v1x or + High Capacity card. */ +#define SDMMC_BLOCK_MMC_GET_CSD (11U) /**< Get Card's Specific Data register */ +#define SDMMC_BLOCK_MMC_GET_CID (12U) /**< Get Card's Identification register */ +#define SDMMC_BLOCK_MMC_GET_OCR (13U) /**< Get Card's Operating Condition Register */ +#define SDMMC_BLOCK_MMC_GET_SDSTAT (14U) /**< Get SD card status information. */ + +/* + * NAND specific ioctl command + */ + +/* Create physical format */ +#define SDMMC_BLOCK_NAND_FORMAT (30U) +#define SDMMC_BLOCK_MMC_LOCK_CARD (31U) /**< Locks the card. */ +#define SDMMC_BLOCK_MMC_UNLOCK_CARD (32U) /**< Unlocks the card. */ +#define SDMMC_BLOCK_MMC_SET_PASSWD (33U) /**< Set/replace the password. */ +#define SDMMC_BLOCK_MMC_CLEAR_PASSWD (34U) /**< Clears the password. */ +#define SDMMC_BLOCK_MMC_SET_LOCK (35U) /**< Sets the password and locks the card, + in the same power cycle. */ +#define SDMMC_BLOCK_MMC_READ_LOCK_STATUS (36U) /**< Reads the current lock status of the card. */ +#define SDMMC_BLOCK_MMC_FORCE_ERASE (37U) /**< Force erase the password. It is useful when user forgets + the password. */ + +#define SDMMC_BLOCK_MAX_PASSWORD_LENGTH (16U) /* Max. password length: lock/unlock */ + +/********************************************************************************************************************** + * ENUMERATIONS + **********************************************************************************************************************/ +/** + * @ingroup SDMMC_BLOCK_enumerations + * @{ + */ + +/** + * @brief Return status of SDMMC_BLOCK APP functions + */ +typedef enum SDMMC_BLOCK_MODE_STATUS +{ + SDMMC_BLOCK_MODE_STATUS_SUCCESS = 0U, /**< Success */ + SDMMC_BLOCK_MODE_STATUS_FAILURE, /**< Failure */ + SDMMC_BLOCK_MODE_STATUS_COMMAND_TIMEOUT_ERROR, /**< Timeout error */ + SDMMC_BLOCK_MODE_STATUS_COMMAND_CRC_ERROR, /**< CRC error */ + SDMMC_BLOCK_MODE_STATUS_COMMAND_ENDBIT_ERROR, /**< End bit error */ + SDMMC_BLOCK_MODE_STATUS_COMMAND_INDEX_ERROR, /**< Command index error */ + SDMMC_BLOCK_MODE_STATUS_DATA_TIMEOUT_ERROR, /**< Data timeout error */ + SDMMC_BLOCK_MODE_STATUS_DATA_CRC_ERROR, /**< Data CRC error */ + SDMMC_BLOCK_MODE_STATUS_DATA_ENDBIT_ERROR, /**< Data end-bit error */ + SDMMC_BLOCK_MODE_STATUS_ACMD12_ERROR, /**< ACMD12 error */ + SDMMC_BLOCK_MODE_STATUS_OUT_OF_RANGE_ERROR, /**< Out of range error */ + SDMMC_BLOCK_MODE_STATUS_ADDRESS_ERROR, /**< Address error */ + SDMMC_BLOCK_MODE_STATUS_BLOCK_LEN_ERROR, /**< Length error */ + SDMMC_BLOCK_MODE_STATUS_ERASE_SEQ_ERROR, /**< Sequence error */ + SDMMC_BLOCK_MODE_STATUS_ERASE_PARAM_ERROR, /**< Erase parameter error */ + SDMMC_BLOCK_MODE_STATUS_WP_VIOLATION_ERROR, /**< Write protect violation error */ + SDMMC_BLOCK_MODE_STATUS_LOCK_UNLOCK_ERROR, /**< Lock/Unlock error */ + SDMMC_BLOCK_MODE_STATUS_COM_CRC_ERROR, /**< Command CRC error */ + SDMMC_BLOCK_MODE_STATUS_ILLEGAL_COMMAND_ERROR, /**< Illegal command error */ + SDMMC_BLOCK_MODE_STATUS_CARD_ECC_ERROR, /**< ECC error */ + SDMMC_BLOCK_MODE_STATUS_CC_ERROR, /**< CC error */ + SDMMC_BLOCK_MODE_STATUS_UNKNOWN_ERROR, /**< Unknown error */ + SDMMC_BLOCK_MODE_STATUS_CSD_OVERWRITE, /**< CSD overwrite */ + SDMMC_BLOCK_MODE_STATUS_WP_ERASE_SKIP_ERROR, /**< Write protect erase skip error */ + SDMMC_BLOCK_MODE_STATUS_ASK_SEQ_ERROR, /**< Ask sequence error */ + SDMMC_BLOCK_MODE_STATUS_BAD_RESPONSE, /**< Bad response */ + SDMMC_BLOCK_MODE_STATUS_CMD_LINE_BUSY, /**< Command line busy */ + SDMMC_BLOCK_MODE_STATUS_DATA_LINE_BUSY, /**< Data line busy */ + SDMMC_BLOCK_MODE_STATUS_COMMAND_COMPLETE, /**< Command complete */ + SDMMC_BLOCK_MODE_STATUS_SENDCOMMAND_ERROR, /**< Send command error */ + SDMMC_BLOCK_MODE_STATUS_BUFFER_READY, /**< Buffer ready */ + SDMMC_BLOCK_MODE_STATUS_TRANSFER_COMPLETE, /**< Transfer complete */ + SDMMC_BLOCK_MODE_STATUS_CARD_IS_LOCKED, /**< Card is locked */ + SDMMC_BLOCK_MODE_STATUS_CARD_UNLOCKED, /**< Card unlocked */ + SDMMC_BLOCK_MODE_STATUS_READ_ERROR, /**< Read error */ + SDMMC_BLOCK_MODE_STATUS_WRITE_ERROR, /**< Write error */ + SDMMC_BLOCK_MODE_STATUS_RECOVERABLE_ERROR, /**< Recoverable error */ + SDMMC_BLOCK_MODE_STATUS_NONRECOVERABLE_ERROR, /**< Non-recoverable error */ + SDMMC_BLOCK_MODE_STATUS_ACMD_CMD_WO_DAT_ERROR, /**< Command without data error */ + SDMMC_BLOCK_MODE_STATUS_ACMD_BOTH_ERROR, /**< ACMD both error */ + SDMMC_BLOCK_MODE_STATUS_ACMD_SD_TRANSFER_ERROR, /**< ACMD SD transfer error */ + SDMMC_BLOCK_MODE_STATUS_ACMD_CMD_WO_DAT_NOT_ISSUED, /**< Command without data not issued */ + SDMMC_BLOCK_MODE_STATUS_INIT_FAIL, /**< Init failed */ + SDMMC_BLOCK_MODE_STATUS_INITIALIZED_BUT_LOCKED, /**< Initialized but locked */ + SDMMC_BLOCK_MODE_STATUS_HOST_CONTROLLER_INITIALIZED, /**< Host controller initialized */ + SDMMC_BLOCK_MODE_STATUS_NULL_POINTER, /**< NULL pointer */ + SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED, /**< Timeout occured */ + SDMMC_BLOCK_MODE_STATUS_CREATE_TIMER_FAILED, /**< Create timer failed */ + SDMMC_BLOCK_MODE_STATUS_DELETE_TIMER_FAILED, /**< Delete timer failed */ + SDMMC_BLOCK_MODE_STATUS_START_TIMER_FAILED, /**< Start timer failed */ + SDMMC_BLOCK_MODE_STATUS_STOP_TIMER_FAILED, /**< Stop timer failed */ + SDMMC_BLOCK_MODE_STATUS_SECTOR_OUT_OF_BOUND, /**< Sector out of bound */ + SDMMC_BLOCK_MODE_STATUS_VOLTAGE_ERROR, /**< Voltage error */ + SDMMC_BLOCK_MODE_STATUS_PATTERN_ERROR, /**< Pattern error */ + SDMMC_BLOCK_MODE_STATUS_COMMUNICATION_ERROR /**< Communication error */ +} SDMMC_BLOCK_MODE_STATUS_t; + +/** + * @brief SDMMC_BLOCK status + */ +typedef enum SDMMC_BLOCK_STATUS +{ + SDMMC_BLOCK_STATUS_SUCCESS = 0U, /**< Success */ + SDMMC_BLOCK_STATUS_FAILURE, /**< Failure */ + SDMMC_BLOCK_STATUS_WRPRT, /**< Write protected */ + SDMMC_BLOCK_STATUS_NOTRDY, /**< Not ready */ + SDMMC_BLOCK_STATUS_PARERR, /**< Parameter error */ + SDMMC_BLOCK_STATUS_LOCKED /**< Locked */ +} SDMMC_BLOCK_STATUS_t; + +/** + * @brief Card lock/unlock + */ +typedef enum SDMMC_BLOCK_CARD_LOCK_STATUS +{ + SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED = 0U, /**< Card is not locked */ + SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED /**< Card is locked */ +} SDMMC_BLOCK_CARD_LOCK_STATUS_t; + +/** + * @brief Card types + */ +typedef enum SDMMC_BLOCK_CARD_TYPE +{ + SDMMC_BLOCK_CARD_TYPE_STANDARD_CAPACITY_V2 = 1U, /**< Capacity V2 */ + SDMMC_BLOCK_CARD_TYPE_STANDARD_CAPACITY_V1X = 2U, /**< Capacity V1X */ + SDMMC_BLOCK_CARD_TYPE_HIGH_CAPACITY = 4U, /**< High capacity */ + SDMMC_BLOCK_CARD_TYPE_BLOCK_ADDRESSING = 8U, /**< Block addressing */ + SDMMC_BLOCK_CARD_TYPE_MMC = 16U /**< MMC type */ +} SDMMC_BLOCK_CARD_TYPE_t; + +/** + * @brief Card states + */ +typedef enum SDMMC_BLOCK_CARD_STATE +{ + SDMMC_BLOCK_CARD_STATE_INITIALIZED = 0U, /**< Card initialized */ + SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED = 1U, /**< Card initialized */ + SDMMC_BLOCK_CARD_STATE_NO_CARD = 2U, /**< No card available */ + SDMMC_BLOCK_CARD_STATE_WRITE_PROTECTED = 4U, /**< Card write protected */ + SDMMC_BLOCK_CARD_STATE_LOCKED = 8U, /**< Card locked */ + SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE = 16U, /**< Command line in use */ + SDMMC_BLOCK_CARD_STATE_DATA_ACTIVE = 32U, /**< Data line in use */ + SDMMC_BLOCK_CARD_STATE_HC_INITIALIZED = 64U /**< Host controller initialized */ +} SDMMC_BLOCK_CARD_STATE_t; + +/** + * @brief Card types + */ +typedef enum SDMMC_BLOCK_CARD_CAPACITY +{ + SDMMC_BLOCK_CARD_CAPACITY_UNKNOWN = 0U, /**< Unknown */ + SDMMC_BLOCK_CARD_CAPACITY_MMC = 1U, /**< MMC */ + SDMMC_BLOCK_CARD_CAPACITY_SD = 2U, /**< SD */ + SDMMC_BLOCK_CARD_CAPACITY_SDHC = 3U /**< SDHC */ +} SDMMC_BLOCK_CARD_CAPACITY_t; + +/** + * @brief Card interface (SPI OR native SD?) + */ +typedef enum SDMMC_BLOCK_CARD_INTERFACE +{ + SDMMC_BLOCK_CARD_INTERFACE_SD = 0U, /**< SD interface */ + SDMMC_BLOCK_CARD_INTERFACE_SPI = 1U /**< SPI interface */ +} SDMMC_BLOCK_CARD_INTERFACE_t; + +/** + * @brief RTOS mode + */ +typedef enum SDMMC_BLOCK_RTOS_MODE +{ + SDMMC_BLOCK_RTOS_MODE_DISABLED = 0U, /**< RTOS mode is not selected */ + SDMMC_BLOCK_RTOS_MODE_ENABLED = 1U /**< RTOS mode is selected */ +} SDMMC_BLOCK_RTOS_MODE_t; + +#ifdef SDMMC_BLOCK_SD + +/** + * @brief This enumerates some of the SDMMC interrupts + */ +typedef enum SDMMC_BLOCK_SD_INTERRUPT +{ + SDMMC_BLOCK_SD_INTERRUPT_CARD_REMOVAL = 0U, /**< Card removal interrupt */ + SDMMC_BLOCK_SD_INTERRUPT_CARD_INSERTION /**< Card insertion interrupt */ +} SDMMC_BLOCK_SD_INTERRUPT_t; + +/** + * @brief Data transfer direction + */ +typedef enum SDMMC_BLOCK_SD_DATA_TRANSFER +{ + SDMMC_BLOCK_SD_DATA_TRANSFER_READ_BUFFER = 1U, /**< Read from card */ + SDMMC_BLOCK_SD_DATA_TRANSFER_WRITE_BUFFER /**< Write to card */ +} SDMMC_BLOCK_SD_DATA_TRANSFER_t; + +#endif + +typedef void (*SDMMC_BLOCK_Config_Init)(void); + +/** + * @} + */ +/********************************************************************************************************************** + * DATA STRUCTURES + **********************************************************************************************************************/ + +/** + * @ingroup SDMMC_BLOCK_datastructures + * @{ + */ + +/** + * @brief This structure stores the SD Card's SCR register content. + */ +typedef struct SDMMC_BLOCK_SCR +{ + uint32_t sd_spec : 4; /**< Physical Layer Specification Version supported by the card */ + uint32_t scr_structure : 4; /**< SCR version */ + uint32_t sd_bus_width : 4; /**< DAT bus widths that are supported by card */ + uint32_t sd_security : 3; /**< CPRM security specification version for each capacity card */ + uint32_t data_erase_stat : 1; /**< Data status after erase (0 or 1) */ + uint32_t : 3; /**< Reserved bits */ + uint32_t ext_security : 4; /**< Extended security */ + uint32_t sd_spec_3 : 1; /**< SD specification version */ + uint32_t cmd_support : 2; /**< Support bit of new commands are defined to bit 33-32 of SCR */ + uint32_t : 6; /**< Reserved bits */ + uint32_t manuf_resvd : 32; /**< Reserved: Manufacturer's use */ +} SDMMC_BLOCK_SCR_t; + +/** + * @brief Stores SD card CID register content + */ +typedef struct SDMMC_BLOCK_CID +{ + uint16_t manufacturing_date; /**< 12 bit Manufacturing date (MDT) */ + uint32_t product_serial_num; /**< 32 bit serial number (PSN) */ + uint8_t product_rev; /**< 32 bit Product revision (PRV) */ + uint8_t product_name[5]; /**< 40 bit product name (PNM) */ + uint8_t app_oem_id[2]; /**< 16 bit OEM/Application ID (OID) */ + uint8_t manufacturer_id; /**< 8 bit Manufacturer ID (MID) */ +} SDMMC_BLOCK_CID_t; + +/** + * @brief Stores SD (v1) card's CSD register content + */ +typedef struct SDMMC_BLOCK_SDV1_CSD +{ + uint32_t fixed : 1; /**< Always fixed to 1 */ + uint32_t crc : 7; /**< CRC bits */ + uint32_t : 2; /**< Reserved bits */ + uint32_t file_fmt : 2; /**< Indicates file format on the card */ + uint32_t temp_write_prot : 1; /**< Temporarily protects card content from being overwritten or erased */ + uint32_t perm_write_prot : 1; /**< Permanently protects card content against overwriting or erasing */ + uint32_t copy : 1; /**< Defines if content is original (= 0) or has been copied (= 1) */ + uint32_t file_fmt_grp : 1; /**< Indicates selected group of file formats */ + uint32_t : 5; /**< Reserved bits */ + uint32_t write_blk_partial : 1; /**< Defines if partial block sizes can be used in block write commands */ + uint32_t write_blk_len : 4; /**< Maximum write data block length is computed as 2WRITE_BL_LEN */ + uint32_t write_speed_factor : 3; /**< Defines typical block program time as a multiple of the read access time */ + uint32_t : 2; /**< Reserved bits */ + uint32_t write_prot_grp_en : 1; /**< A value of 0 means no group write protection possible */ + uint32_t write_prot_grp_size : 7; /**< Size of a write protected group; Indexed from 0 */ + uint32_t erase_sector_size : 7; /**< Size of an erasable sector */ + uint32_t erase_blk_en : 1; /**< ERASE_BLK_EN defines granularity of unit size of erasable data */ + uint32_t dev_size_mult : 3; /**< Multiplier for total size of device (Check C_SIZE) */ + uint32_t max_write_current : 3; /**< Maximum write current at maximum VDD */ + uint32_t min_write_current : 3; /**< Maximum write current at minimum VDD */ + uint32_t max_read_current : 3; /**< Maximum read current at maximum VDD */ + uint32_t min_read_current : 3; /**< Maximum read current at minimum VDD */ + uint32_t dev_size_low : 2; /**< Total size of data card */ + uint32_t dev_size_high : 10;/**< Total size of data card */ + uint32_t : 2; /**< Reserved bits */ + uint32_t dsr_imp : 1; /**< Is configurable driver stage is integrated with card? */ + uint32_t read_blk_misalign : 1; /**< Can read block occupy more than 1 physical block on card? */ + uint32_t write_blk_misalign : 1; /**< Can written block occupy more than 1 physical block on card? */ + uint32_t read_blk_partial : 1; /**< Can a block be read partially? : Always valid in SD */ + uint32_t read_blk_len : 4; /**< Maximum read data block length is computed as 2READ_BL_LEN */ + uint32_t ccc : 12; /**< Card command class register specifies supported command classes */ + uint32_t tran_speed : 8; /**< Defines maximum data transfer rate per one data line */ + uint32_t nsac : 8; /**< Defines worst case for clock-dependent factor of the data access time */ + uint32_t taac : 8; /**< Defines asynchronous part of data access time */ + uint32_t : 6; /**< Reserved bits */ + uint32_t csd_struct : 2; /**< Describes version of the CSD structure */ +} SDMMC_BLOCK_SDV1_CSD_t; + +/** + * @brief Stores SD (v2) card's CSD register content + */ +typedef struct SDMMC_BLOCK_SDV2_CSD +{ + uint32_t fixed : 1; /**< Always fixed to 1 */ + uint32_t crc : 7; /**< CRC bits */ + uint32_t : 2; /**< Reserved bits */ + uint32_t file_fmt : 2; /**< Indicates file format on the card */ + uint32_t temp_write_prot : 1; /**< Temporarily protects card content from being overwritten or erased */ + uint32_t perm_write_prot : 1; /**< Permanently protects card content against overwriting or erasing */ + uint32_t copy : 1; /**< Defines if content is original (= 0) or has been copied (= 1) */ + uint32_t file_fmt_grp : 1; /**< Indicates selected group of file formats */ + uint32_t : 5; /**< Reserved bits */ + uint32_t write_blk_partial : 1; /**< Defines if partial block sizes can be used in block write commands */ + uint32_t write_blk_len : 4; /**< Maximum write data block length is computed as 2WRITE_BL_LEN */ + uint32_t write_speed_factor : 3; /**< Defines typical block program time as a multiple of the read access time */ + uint32_t : 2; /**< Reserved bits */ + uint32_t write_prot_grp_en : 1; /**< A value of 0 means no group write protection possible */ + uint32_t write_prot_grp_size : 7; /**< Size of a write protected group; Indexed from 0 */ + uint32_t erase_sector_size : 7; /**< Size of an erasable sector */ + uint32_t erase_blk_en : 1; /**< If 1, host can erase one or multiple units of 512 bytes */ + uint32_t : 1; /**< Reserved bits */ + uint32_t dev_size_low : 16;/**< Total size of data card */ + uint32_t dev_size_high : 6; /**< Total size of data card */ + uint32_t : 6; /**< Reserved bits */ + uint32_t dsr_imp : 1; /**< Is configurable driver stage is integrated with card? */ + uint32_t read_blk_misalign : 1; /**< When 0, read crossing block boundaries is disabled in high capacity SD cards */ + uint32_t write_blk_misalign : 1; /**< When 0, write crossing block boundaries is disabled in high capacity SD cards*/ + uint32_t read_blk_partial : 1; /**< Fixed to 0; Only unit of block access is permitted */ + uint32_t read_blk_len : 4; /**< Fixed at 0x09; Indicates READ_BL_LEN = 512 bytes */ + uint32_t ccc : 12; /**< Card command class register specifies supported command classes */ + uint32_t tran_speed : 8; /**< Defines maximum data transfer rate per one data line */ + uint32_t nsac : 8; /**< Fixed at 0x00 */ + uint32_t taac : 8; /**< Fixed at 0x0E; Indicates asynchronous part of data access time as 1 ms */ + uint32_t : 6; /**< Reserved bits */ + uint32_t csd_struct : 2; /**< Describes version of the CSD structure */ +} SDMMC_BLOCK_SDV2_CSD_t; + +/** + * @brief SDMMC_BLOCK GPIO configuration + */ +typedef struct SDMMC_BLOCK_GPIO_CONFIG +{ + XMC_GPIO_CONFIG_t config; /**< Pin configuration structure */ + XMC_GPIO_HWCTRL_t hw_control; /**< HW control setting for pins */ +} SDMMC_BLOCK_GPIO_CONFIG_t; + +/** + * @brief SDMMC pin configuration + */ +typedef struct SDMMC_BLOCK_PIN_CONFIG +{ + XMC_GPIO_PORT_t *const port; /**< Pointer to the GPIO port base address */ + const uint8_t pin; /**< Pin number in the port */ + const SDMMC_BLOCK_GPIO_CONFIG_t *config; /**< Reference to pin configuration structure */ +} SDMMC_BLOCK_PIN_CONFIG_t; + +#if SDMMC_BLOCK_RTOS_MODE_SELECT + +/** + * @brief Resources for SDMMC RTOS mode + */ +typedef struct SDMMC_BLOCK_CMSIS_RTOS +{ + uint32_t os_mutex_cb_cmd_mut_handle[4]; /**< Command mutex handle */ + osMutexDef_t os_mutex_def_cmd_mut_handle; /**< Command mutex definition */ + osMutexId cmd_mut_id; /**< Command mutex id */ + + uint32_t os_mutex_cb_data_mut_handle[4]; /**< Data mutex handle */ + const osMutexDef_t os_mutex_def_data_mut_handle; /**< Data mutex definition */ + osMutexId data_mut_id; /**< Data mutex id */ + + uint32_t os_semaphore_cb_cmd_sem[2]; /**< Semaphore for commands */ + const osSemaphoreDef_t os_semaphore_def_cmd_sem; /**< Command semaphore definition */ + osSemaphoreId cmd_sem_id; /**< Command semaphore id */ + int32_t cmd_sem_index; /**< Command semaphore index */ + + uint32_t os_semaphore_cb_data_sem[2]; /**< Semaphore for data */ + const osSemaphoreDef_t os_semaphore_def_data_sem; /**< Data semaphore definition */ + osSemaphoreId data_sem_id; /**< Data semaphore id */ + int32_t data_sem_index; /**< Data semaphore index */ + +#ifdef SDMMC_BLOCK_SD + uint32_t os_semaphore_cb_transfer_sem[2]; /**< Semaphore for transfer */ + const osSemaphoreDef_t os_semaphore_def_transfer_sem; /**< Transfer semaphore definition */ + osSemaphoreId transfer_sem_id; /**< Transfer semaphore id */ + int32_t transfer_sem_index; /**< Transfer semaphore index */ +#endif + +#ifdef SDMMC_BLOCK_SPI + uint32_t os_mutex_cb_init_mut_handle[4]; /**< Command mutex handle */ + osMutexDef_t os_mutex_def_init_mut_handle; /**< Command mutex definition */ + osMutexId init_mut_id; /**< Command mutex id */ +#endif + + bool os_resources_created; /**< Semaphore and mutex created successfully */ +} SDMMC_BLOCK_CMSIS_RTOS_t; + +#endif /* #if SDMMC_BLOCK_RTOS_MODE_SELECT */ + +#ifdef SDMMC_BLOCK_SPI +/** + * @brief This structure stores the card's register content information + */ +typedef struct SDMMC_BLOCK_SPI_CARD_INFORMATION +{ + uint8_t ocr[4]; /**< OCR register contents */ + uint8_t cid[16]; /**< CID register contents */ + uint8_t csd[16]; /**< CSD register contents */ + SDMMC_BLOCK_SCR_t scr; /**< SCR register content */ + uint8_t sd_status[64]; /**< SD_STATUS */ +} SDMMC_BLOCK_SPI_CARD_INFORMATION_t; + +/** + * @brief configuration in SPI mode + */ +typedef struct SDMMC_BLOCK_SPI +{ + SPI_MASTER_t *spi_master_handle; /**< Pointer to the SPI_MASTER configuration handler */ + SDMMC_BLOCK_SPI_CARD_INFORMATION_t card_info; /**< Card information */ +#if SDMMC_BLOCK_RTOS_MODE_SELECT + SDMMC_BLOCK_CMSIS_RTOS_t *rtos; /**< Resources specific to RTOS mode */ +#endif + uint8_t cmd_response; /**< Command response value */ + bool mode_init_flag; /**< Flag indicating initialization return value */ +} SDMMC_BLOCK_SPI_t; + +#endif + +#ifdef SDMMC_BLOCK_SD + +/** + * @brief This structure stores the card's register content information + */ +typedef struct SDMMC_BLOCK_SD_CARD_INFORMATION +{ + uint32_t ocr; /**< OCR register contents */ + uint32_t cid[4]; /**< CID register contents */ + uint32_t csd[4]; /**< CSD register contents */ + SDMMC_BLOCK_SCR_t scr; /**< SCR register contents */ + uint16_t rca; /**< Card's relative address */ +} SDMMC_BLOCK_SD_CARD_INFORMATION_t; + +/** + * @brief This structure stores the Interrupt Context Information. + */ +typedef struct SDMMC_BLOCK_INTERRUPT_CONTEXT +{ + uint16_t int_status_shadow; /**< Stores interrupt status register status bits */ + uint8_t cmd_flag; /**< Set when command specific interrupt occurs */ + uint8_t data_flag; /**< Set when data transfer error interrupt occurs */ + uint8_t transfer_flag; /**< Set when transfer complete interrupt occurs */ +} SDMMC_BLOCK_INTERRUPT_CONTEXT_t; + +/** + * @brief configuration in SD mode + */ +typedef struct SDMMC_BLOCK_SD +{ + XMC_SDMMC_t *sdmmc; /**< Base SDMMC pointer */ + SDMMC_BLOCK_INTERRUPT_CONTEXT_t isr_context; /**< Interrupt context */ + uint32_t int_priority; /**< Interrupt priority */ + uint32_t int_sub_priority; /**< Interrupt sub-priority */ + uint32_t buf_ready_int; /**< Buffer ready interrupt */ + SDMMC_BLOCK_MODE_STATUS_t data_int_err; /**< Interrupt error in data transfer */ + SDMMC_BLOCK_MODE_STATUS_t cmd_int_err; /**< Interrupt error in cmd issuance */ + SDMMC_BLOCK_MODE_STATUS_t transfer_int_err; /**< Interrupt status if transfer successful */ + SDMMC_BLOCK_MODE_STATUS_t acmd_int_err; /**< Interrupt status in issuance of ACMD12 Command */ + SDMMC_BLOCK_MODE_STATUS_t err_recovery_stat; /**< Error recovery status of a failed transaction */ +#if SDMMC_BLOCK_SD_CARD_DETECTION_SUPPORT + void (*callback)(SDMMC_BLOCK_SD_INTERRUPT_t); /**< call-back function */ + uint32_t card_detect_state; /**< Card detect state */ +#endif + SDMMC_BLOCK_SD_CARD_INFORMATION_t card_info; /**< Card information */ + uint8_t f8; /**< Flag used in card initialization to identify card type */ + uint8_t issue_abort; /**< Issue abort */ +#if !SDMMC_BLOCK_RTOS_MODE_SELECT + volatile uint32_t tmr_id; /**< SYSTIMER identifier */ +#endif + volatile bool tmr_expire; /**< Timeout (expiration) flag */ + XMC_SDMMC_DATA_LINES_t bus_width; /**< Bus width */ + bool mode_init_flag; /**< Flag indicating initialization return value */ +#if SDMMC_BLOCK_RTOS_MODE_SELECT + uint32_t *buf; /**< Data buffer */ + uint32_t block_count; /**< Block count */ + uint32_t transfer_quad_bytes; /**< Number of quad bytes to transfer */ + SDMMC_BLOCK_CMSIS_RTOS_t *rtos; /**< Resources specific to RTOS mode */ +#endif + +} SDMMC_BLOCK_SD_t; + +#endif + +/** + * @brief Store local lock structure information + */ +typedef struct SDMMC_BLOCK_LOCK_STRUCTURE +{ + uint8_t mode; /**< 8-bit card lock/unlock mode */ + uint8_t pwd_len; /**< Password length; Also the length of new and old passwords in case of change */ + uint8_t pwd_data[SDMMC_BLOCK_MAX_PASSWORD_LENGTH * 2U]; /**< New password OR old + new in case of change */ +} SDMMC_BLOCK_LOCK_STRUCTURE_t; + +/** + * @brief Password structure + */ +typedef struct SDMMC_BLOCK_PASSWORD +{ + uint8_t old_pwd[SDMMC_BLOCK_MAX_PASSWORD_LENGTH]; /**< Old password */ + uint8_t new_pwd[SDMMC_BLOCK_MAX_PASSWORD_LENGTH]; /**< New password */ + uint8_t old_pwd_len; /**< Old password length */ + uint8_t new_pwd_len; /**< New password length. Set to 0 if password not set */ +} SDMMC_BLOCK_PASSWORD_t; + +/** + * @brief Erase Address details. + */ +typedef struct SDMMC_BLOCK_ERASE_ADDRESS +{ + uint32_t start_address; /**< Erase Block Start Address */ + uint32_t end_address; /**< Erase Block Start Address */ +} SDMMC_BLOCK_ERASE_ADDRESS_t; + +/* Anonymous structure/union guard start */ +#if defined (__CC_ARM) +# pragma push +# pragma anon_unions +#elif defined (__TASKING__) +# pragma warning 586 +#endif + +/** + * @brief SDMMC_BLOCK APP instance + */ +typedef struct SDMMC_BLOCK +{ + union + { +#ifdef SDMMC_BLOCK_SPI + SDMMC_BLOCK_SPI_t *sdmmc_spi; /**< SPI instance */ +#endif + +#ifdef SDMMC_BLOCK_SD + SDMMC_BLOCK_SD_t *sdmmc_sd; /**< SD instance */ +#endif + }; + +# ifdef SDMMC_BLOCK_CARD_WRITE_PROTECT_SIGNAL + const SDMMC_BLOCK_PIN_CONFIG_t *sdwc; /**< Card write protect signal */ +# endif + +#ifdef SDMMC_BLOCK_SPI + +# ifdef SDMMC_BLOCK_SPI_CARD_LED_SIGNAL + const SDMMC_BLOCK_PIN_CONFIG_t *led; /**< LED signal, used in SPI mode */ +# endif + +#endif /* SDMMC_BLOCK_SPI */ + +#if SDMMC_BLOCK_RTOS_MODE_SELECT + CMSIS_RTOS_t *const cmsis_rtos; /**< specific to RTOS mode */ +#endif /* SDMMC_BLOCK_RTOS_MODE_SELECT */ + + SDMMC_BLOCK_Config_Init init_pins; /**< Pins initialization function */ + uint8_t card_state; /**< Card state */ + uint8_t card_type; /**< Card type */ + uint8_t card_capacity; /**< Capacity of the card */ + SDMMC_BLOCK_RTOS_MODE_t rtos_mode; /**< RTOS mode */ + SDMMC_BLOCK_CARD_INTERFACE_t interface_mode; /**< Card interface mode */ + bool init_flag; /**< Flag indicating initialization return value */ +} SDMMC_BLOCK_t; + +/** + * @} + */ + +/* Anonymous structure/union guard end */ +#if defined (__CC_ARM) +# pragma pop +#elif defined (__TASKING__) +# pragma warning restore +#endif + +/* Support for C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/*********************************************************************************************************************** + * API PROTOTYPES + **********************************************************************************************************************/ + +/** + * @ingroup SDMMC_BLOCK_apidoc + * @{ + */ + +/** + * @brief Initialize the the SDMMC_BLOCK APP with the configuration done in the GUI. + * @param obj A pointer to SDMMC_BLOCK_t, pointing to the SDMMC_BLOCK handle configuration + * @return SDMMC_BLOCK_STATUS_t: Status of SDMMC_BLOCK APP initialization.\n + * SDMMC_BLOCK_STATUS_SUCCESS - on successful initialization.\n + * SDMMC_BLOCK_STATUS_FAILURE - if initialization fails.\n + * + * \parDescription:
+ * + * + * Example Usage: + * SDMMC_BLOCK_Init() function is called in DAVE_Init(). If SDMMC_BLOCK_Init() is not successful, other + * functionalities are not supposed to be called. + * + * @code + * #include + * int main(void) + * { + * DAVE_STATUS_t status; + * DAVE_APP_VERSION_t app_version; + * + * status = DAVE_Init(); // SDMMC_BLOCK_Init() is called from DAVE_Init() + * + * if(status == DAVE_STATUS_FAILURE) + * { + * // Placeholder for error handler code. The while loop below can be replaced with an user error handler. + * XMC_DEBUG("DAVE APPs initialization failed\n"); + * + * while(1U) + * { + * + * } + * } + * + * // Placeholder for user application code. The while loop below can be replaced with user application code. + * while(1U) + * { + * + * } + * } + * @endcode
+ */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_Init(SDMMC_BLOCK_t *const obj); + +/** + * @brief Initialize the SD/MMC card and return the initialization status of the card + * @param obj A pointer to SDMMC_BLOCK_t, pointing to the SDMMC_BLOCK handle configuration + * @return SDMMC_BLOCK_STATUS_t: Status of SDMMC_BLOCK APP initialization.\n + * SDMMC_BLOCK_STATUS_SUCCESS: on successful initialization.\n + * SDMMC_BLOCK_STATUS_FAILURE: If initialization fails.\n + * SDMMC_BLOCK_STATUS_NOTRDY : Card is not available or not initialized\n + * + * \parDescription:
+ *
    + *
  • Initialize the card and update the card information like card type and card state. Initialization + * flag is set to 1 if the card is initialized properly.
  • + *
+ * + * Example Usage: + * This will initialize the card and update the card related properties and returns successful if card is + * initialized successfully. + * + * @code + * #include + * int main(void) + * { + * DAVE_STATUS_t status; + * DAVE_APP_VERSION_t app_version; + * SDMMC_BLOCK_STATUS_t sdmmc_status; + * + * status = DAVE_Init(); // SDMMC_BLOCK_Init() is called from DAVE_Init() + * + * sdmmc_status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + * + * if(status == DAVE_STATUS_FAILURE) + * { + * // Placeholder for error handler code. The while loop below can be replaced with an user error handler. + * XMC_DEBUG("DAVE APPs initialization failed\n"); + * + * while(1U) + * { + * + * } + * } + * + * // Placeholder for user application code. The while loop below can be replaced with user application code. + * while(1U) + * { + * + * } + * } + * @endcode
+ */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_Initialize(SDMMC_BLOCK_t *const obj); + +/** + * @brief Get the card's current status + * @param obj A pointer to SDMMC_BLOCK_t, pointing to the SDMMC_BLOCK handle configuration + * @return uint8_t \n + * * SDMMC_BLOCK_CARD_STATE_INITIALIZED: If initialization is successful without any errors.\n + * SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED: If initialization fails.\n + * SDMMC_BLOCK_CARD_STATE_NO_CARD : Card is not available\n + * SDMMC_BLOCK_CARD_STATE_WRITE_PROTECTED : Card is write protected\n + * + * \parDescription:
+ * Card state (initialization state, card availability and write protection state and the like) + * is returned as a logically OR'd value indicating various states. The user may then use an + * appropriate mask to take measures based on the states. + * + * Example Usage: + * This will initialize the card. Post initialization, the current status of the card is requested. + * + * @code + * #include + * int main(void) + * { + * DAVE_STATUS_t status; + * DAVE_APP_VERSION_t app_version; + * uint8_t card_status; + * + * status = DAVE_Init(); // SDMMC_BLOCK_Init() is called from DAVE_Init() + * + * sdmmc_status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + * + * card_status = SDMMC_BLOCK_GetStatus(&SDMMC_BLOCK_0); + * + * if(status == DAVE_STATUS_FAILURE) + * { + * // Placeholder for error handler code. The while loop below can be replaced with an user error handler. + * XMC_DEBUG("DAVE APPs initialization failed\n"); + * + * while(1U) + * { + * + * } + * } + * + * // Placeholder for user application code. The while loop below can be replaced with user application code. + * while(1U) + * { + * + * } + * } + * @endcode
+ */ +uint8_t SDMMC_BLOCK_GetStatus(SDMMC_BLOCK_t *const obj); + +/** + * @brief Reads the specified number of blocks of data from the card + * @param obj A pointer to SDMMC_BLOCK_t, pointing to the SDMMC_BLOCK handle configuration + * @param read_buf Read aligned buffer pointer to store data read from the card. + * @param sector_number Specifies the card sector address from which the read operation has to be started. + * @param sector_count Specifies the number of sectors of data that has to be read (1 sector = 512 bytes) + * @return SDMMC_BLOCK_STATUS_t: Status of SDMMC_BLOCK APP read operation.\n + * SDMMC_BLOCK_STATUS_SUCCESS: on successful read operation.\n + * SDMMC_BLOCK_STATUS_FAILURE: If read operation fails.\n + * SDMMC_BLOCK_STATUS_NOTRDY : Card is not available or not initialized.\n + * SDMMC_BLOCK_STATUS_LOCKED : Card is locked with password.\n + * SDMMC_BLOCK_STATUS_WRPRT : Card is write protected.\n + * \parDescription:
+ * Block read can be single or multiple blocks. It is mandatory to pass an aligned buffer to store the data read + * from the card. + * + * Example Usage: + * This will initialize the card. If initialization is successful data will be written, read and then + * erased from the card. Post these functions, the card is finally ejected. + * + * @code + * uint8_t send_data[1024]; + * uint8_t read_data[1024]; + * volatile uint32_t count; + * + * SDMMC_BLOCK_ERASE_ADDRESS_t erase_address = + * { + * .start_address = 1004U, + * .end_address = 1005U + * }; + * + * #include + * int main(void) + * { + * DAVE_STATUS_t status; + * DAVE_APP_VERSION_t app_version; + * SDMMC_BLOCK_CARD_STATE_t card_status; + * + * status = DAVE_Init(); // SDMMC_BLOCK_Init() is called from DAVE_Init() + * + * sdmmc_status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + * + * if (sdmmc_status == SDMMC_BLOCK_STATUS_SUCCESS) + * { + * do + * { + * send_data[count] = count; + * } while (count++ < 1024); + * + * sdmmc_status = SDMMC_BLOCK_WriteBlock(&SDMMC_BLOCK_0, send_data, 1004U, 2U); + * + * if (sdmmc_status == SDMMC_BLOCK_STATUS_SUCCESS) + * { + * sdmmc_status = SDMMC_BLOCK_ReadBlock(&SDMMC_BLOCK_0, read_data, 1004U, 2U); + * + * for (count = 0; count < 1024; count++) + * { + * if(read_data[count] != send_data[count]) + * status = DAVE_STATUS_FAILURE; + * } + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_CTRL_TRIM, &erase_address); + * + * sdmmc_status = SDMMC_BLOCK_ReadBlock(&SDMMC_BLOCK_0, read_data, 1004U, 2U); + * + * for (count = 0; count < 1024; count++) + * { + * if(read_data[count] != 0U) + * status = DAVE_STATUS_FAILURE; + * } + * } + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_CTRL_EJECT, &buffer); + * } + * + * if(status == DAVE_STATUS_FAILURE) + * { + * // Placeholder for error handler code. The while loop below can be replaced with an user error handler. + * XMC_DEBUG("DAVE APPs initialization failed\n"); + * + * while(1U) + * { + * + * } + * } + * + * // Placeholder for user application code. The while loop below can be replaced with user application code. + * while(1U) + * { + * + * } + * } + * @endcode
+ */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_ReadBlock(SDMMC_BLOCK_t *const obj, + uint8_t *read_buf, + const uint32_t sector_number, + const uint8_t sector_count); + +/** + * @brief Write data blocks onto the card from the host system. + * @param obj A pointer to SDMMC_BLOCK_t, pointing to the SDMMC_BLOCK handle configuration + * @param write_buf Buffer pointer for the data to be stored into card. + * @param sector_number Specifies the card sector address from which the write operation has to be started. + * @param sector_count Specifies the number of sectors of data that has to be written. (1 sector = 512 bytes) + * @return SDMMC_BLOCK_STATUS_t: Status of SDMMC_BLOCK APP write operation.\n + * SDMMC_BLOCK_STATUS_SUCCESS: on successful read operation.\n + * SDMMC_BLOCK_STATUS_FAILURE: If read operation fails.\n + * SDMMC_BLOCK_STATUS_NOTRDY : Card is not available or not initialized\n + * SDMMC_BLOCK_STATUS_LOCKED : Card is locked with password\n + * SDMMC_BLOCK_STATUS_WRPRT : Card is write protected.\n + * + * \parDescription:
+ * Write operation may be for single or multiple blocks. + * + * Example Usage: + * This will initialize the card. If initialization is successful data will be written, read and then + * erased from the card. Post these functions, the card is finally ejected. + * + * @code + * uint8_t send_data[1024]; + * uint8_t read_data[1024]; + * volatile uint32_t count; + * + * SDMMC_BLOCK_ERASE_ADDRESS_t erase_address = + * { + * .start_address = 1004U, + * .end_address = 1005U + * }; + * + * #include + * int main(void) + * { + * DAVE_STATUS_t status; + * DAVE_APP_VERSION_t app_version; + * SDMMC_BLOCK_CARD_STATE_t card_status; + * + * status = DAVE_Init(); // SDMMC_BLOCK_Init() is called from DAVE_Init() + * + * sdmmc_status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + * + * if (sdmmc_status == SDMMC_BLOCK_STATUS_SUCCESS) + * { + * do + * { + * send_data[count] = count; + * } while (count++ < 1024); + * + * sdmmc_status = SDMMC_BLOCK_WriteBlock(&SDMMC_BLOCK_0, send_data, 1004U, 2U); + * + * if (sdmmc_status == SDMMC_BLOCK_STATUS_SUCCESS) + * { + * sdmmc_status = SDMMC_BLOCK_ReadBlock(&SDMMC_BLOCK_0, read_data, 1004U, 2U); + * + * for (count = 0; count < 1024; count++) + * { + * if(read_data[count] != send_data[count]) + * status = DAVE_STATUS_FAILURE; + * } + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_CTRL_TRIM, &erase_address); + * + * sdmmc_status = SDMMC_BLOCK_ReadBlock(&SDMMC_BLOCK_0, read_data, 1004U, 2U); + * + * for (count = 0; count < 1024; count++) + * { + * if(read_data[count] != 0U) + * status = DAVE_STATUS_FAILURE; + * } + * } + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_CTRL_EJECT, &buffer); + * } + * + * if(status == DAVE_STATUS_FAILURE) + * { + * // Placeholder for error handler code. The while loop below can be replaced with an user error handler. + * XMC_DEBUG("DAVE APPs initialization failed\n"); + * + * while(1U) + * { + * + * } + * } + * + * // Placeholder for user application code. The while loop below can be replaced with user application code. + * while(1U) + * { + * + * } + * } + * @endcode
+ */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_WriteBlock(SDMMC_BLOCK_t *const obj, + uint8_t *write_buf, + const uint32_t sector_number, + const uint8_t sector_count); + +/** + * @brief Control the specified SDMMC device features and the miscellaneous device independent functions + * other than disk read/write. + * @param obj A pointer to SDMMC_BLOCK_t, pointing to the SDMMC_BLOCK handle configuration + * @param command Specifies the command code. + * @param buffer Pointer to the parameter buffer depends on the command code.\n + * When it is not used, specify a NULL pointer. + * @return SDMMC_BLOCK_STATUS_t: Status of SDMMC_BLOCK APP operation.\n + * SDMMC_BLOCK_STATUS_SUCCESS: on successful operation.\n + * SDMMC_BLOCK_STATUS_FAILURE: If the specified operation fails.\n + * SDMMC_BLOCK_STATUS_NOTRDY : Card is not available or not initialized\n + * SDMMC_BLOCK_STATUS_LOCKED : Card is locked with password\n + * SDMMC_BLOCK_STATUS_PARERR : If invalid parameter is passed as argument.\n + * SDMMC_BLOCK_STATUS_WRPRT : Card is write protected.\n + * + * \parDescription:
+ * For Locking features, the user must provide the password information in the SDMMC_BLOCK_PASSWORD_t structure. + *

+ * The IOCTL commands used are: \n\n + * Generic IOCTL commands: \n\n + * SDMMC_BLOCK_CTRL_SYNC: Flush disk cache (for write functions). \n ('buffer' can be NULL). \n\n + * SDMMC_BLOCK_GET_SECTOR_COUNT: Get media size. \n ('buffer' must refer to a uint32_t) \n\n + * SDMMC_BLOCK_GET_SECTOR_SIZE: Get sector size. \n ('buffer' must refer to a uint32_t) \n\n + * SDMMC_BLOCK_GET_BLOCK_SIZE: Get erase block size. \n ('buffer' must refer to a uint32_t) \n\n + * SDMMC_BLOCK_CTRL_TRIM: Inform device that the data on the block of sectors is no longer used. \n + * ('buffer must refer to a value of type SDMMC_BLOCK_ERASE_ADDRESS_t). \n\n + * SDMMC_BLOCK_CTRL_EJECT: Eject media. \n ('buffer' can be NULL). \n\n + * MMC/SD card specific IOCTL commands: \n\n + * SDMMC_BLOCK_MMC_GET_TYPE: Get card type i.e. Standard Capacity v2/v1x or High Capacity card. \n + * ('buffer' must refer to a value of type SDMMC_BLOCK_CARD_TYPE_t). \n\n + * SDMMC_BLOCK_MMC_GET_CSD: Get Card's Specific Data register. \n ('buffer' must refer to a value of type SDMMC_BLOCK_SDV2_CSD_t). \n\n + * SDMMC_BLOCK_MMC_GET_CID: Get Card's Identification Number. \n ('buffer' must refer to a value of type SDMMC_BLOCK_CID_t). \n\n + * SDMMC_BLOCK_MMC_GET_OCR: Get Card's Operating Condition Register \n ('buffer' must refer to a uint32_t). \n\n + * SDMMC_BLOCK_MMC_GET_SDSTAT: Get SD bus status information. \n ('buffer' must refer to a uin8_t array of size 64 bytes) \n\n + * SDMMC_BLOCK_MMC_LOCK_CARD: Locks the card. \n ('buffer' must refer to a value of type SDMMC_BLOCK_PASSWORD_t). \n\n + * SDMMC_BLOCK_MMC_UNLOCK_CARD: Unlocks the card. \n ('buffer' must refer to a value of type SDMMC_BLOCK_PASSWORD_t). \n\n + * SDMMC_BLOCK_MMC_SET_PASSWD: Set/replace the password. \n ('buffer' must refer to a value of type SDMMC_BLOCK_PASSWORD_t). \n\n + * SDMMC_BLOCK_MMC_CLEAR_PASSWD: Clear the password. \n ('buffer' must refer to a value of type SDMMC_BLOCK_PASSWORD_t). \n\n + * SDMMC_BLOCK_MMC_SET_LOCK: Sets the password and locks the card in the same power cycle. \n ('buffer' must refer to a value of type SDMMC_BLOCK_PASSWORD_t). \n\n + * SDMMC_BLOCK_MMC_READ_LOCK_STATUS: Reads the current lock status of the card. \n ('buffer' must refer to a value of type SDMMC_BLOCK_CARD_LOCK_STATUS_t). \n\n + * SDMMC_BLOCK_MMC_FORCE_ERASE: Force erase the password. It is useful when user forgets the password. \n ('buffer' is NULL). \n\n + *

+ * + * Example Usage1: + * The example initializes the card. If initialization is successful the control then checks for the lock_status. + * For a card without any password, the program should indicate that the card is not locked. Then a password of length + * 6 is set and the card is locked with the configured password. The lock status is then checked to ensure that it is + * locked. Post this operation, the card is unlocked. If the unlock operation is successful, the card should + * indicate so. The password is then cleared. + * @code + * #include //Declarations from DAVE Code Generation (includes SFR declaration) + * + * SDMMC_BLOCK_PASSWORD_t password = + * { + * .old_pwd_len = 6U, + * .old_pwd = {'p', 'a', 's', 's', 'w', 'd'}, + * }; + * + * int main(void) + * { + * DAVE_STATUS_t status; + * SDMMC_BLOCK_STATUS_t sdmmc_status; + * SDMMC_BLOCK_CARD_LOCK_STATUS_t lock_status; + * + * status = DAVE_Init(); // Initialization of DAVE APPs + * + * sdmmc_status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + * + * if (sdmmc_status == SDMMC_BLOCK_STATUS_SUCCESS) + * { + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_READ_LOCK_STATUS, &lock_status); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_SET_PASSWD, &password); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_LOCK_CARD, &password); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_READ_LOCK_STATUS, &lock_status); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_UNLOCK_CARD, &password); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_READ_LOCK_STATUS, &lock_status); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_CLEAR_PASSWD, &password); + * } + * + * if(status == DAVE_STATUS_FAILURE) + * { + * // Placeholder for error handler code. The while loop below can be replaced with an user error handler. + * XMC_DEBUG("DAVE APPs initialization failed\n"); + * + * while(1U) + * { + * + * } + * } + * + * // Placeholder for user application code. The while loop below can be replaced with user application code. + * while(1U) + * { + * + * } + * } + * @endcode
+ * + * Example Usage2: + * This example demonstrates the procedure to change the existing password of the card and then performs a force erase + * of the card. + * @code + * #include //Declarations from DAVE Code Generation (includes SFR declaration) + * #include + * SDMMC_BLOCK_PASSWORD_t password = + * { + * .old_pwd_len = 6U, + * .old_pwd = {'p', 'a', 's', 's', 'w', 'd'}, + * .new_pwd_len = 6U, + * .new_pwd = {'s', 'e', 'c', 'r', 'e', 't'}, + * }; + * + * int main(void) + * { + * DAVE_STATUS_t status; + * SDMMC_BLOCK_STATUS_t sdmmc_status; + * SDMMC_BLOCK_CARD_LOCK_STATUS_t lock_status; + * uint8_t buffer; + * + * status = DAVE_Init(); /. Initialization of DAVE APPs + * + * sdmmc_status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + * + * if (sdmmc_status == SDMMC_BLOCK_STATUS_SUCCESS) + * { + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_READ_LOCK_STATUS, &lock_status); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_SET_PASSWD, &password); + * + * // Set the old password value with the new one. SO that card can be locked with the password configured. + * memcpy(password.old_pwd, password.new_pwd, password.new_pwd_len); + * password.old_pwd_len = password.new_pwd_len; + * password.new_pwd_len = 0U; + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_LOCK_CARD, &password); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_READ_LOCK_STATUS, &lock_status); + * + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_FORCE_ERASE, &buffer); + * } + * + * if(status == DAVE_STATUS_FAILURE) + * { + * // Placeholder for error handler code. The while loop below can be replaced with an user error handler. + * XMC_DEBUG("DAVE APPs initialization failed\n"); + * + * while(1U) + * { + * + * } + * } + * + * // Placeholder for user application code. The while loop below can be replaced with user application code. + * while(1U) + * { + * + * } + * } + * @endcode
+ */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_Ioctl(SDMMC_BLOCK_t *const obj, + const uint8_t command, + void *buffer); + +#if SDMMC_BLOCK_SD_CARD_DETECTION_SUPPORT + +#ifdef SDMMC_BLOCK_SD + + /** + * @brief Register a callback function + * @param obj A pointer to SDMMC_BLOCK_t, pointing to the SDMMC_BLOCK handle configuration + * @param cb A pointer to a function accepting ::SDMMC_BLOCK_SD_INTERRUPT_t and returning void + * @return SDMMC_BLOCK_STATUS_t: Status of callback function registration.\n + * SDMMC_BLOCK_STATUS_SUCCESS - On successful registration.\n + * SDMMC_BLOCK_STATUS_PARERR - If registration fails (invalid callback parameter).\n + *
+ * \parDescription:
+ * The function can be used to register a callback function to signal a card detection + * event. The microcontroller will generate interrupts for a card insertion and a card + * removal event. The callback can be used to signal these events. + * + * Example Usage: + * The following example registers a callback function for the card-detect events: + * card insertion and removal. + * @code + * #include + * + * volatile bool led_status = false; + * + * void card_detect_callback(SDMMC_BLOCK_SD_INTERRUPT_t card_ins) + * { + * if (card_ins == SDMMC_BLOCK_SD_INTERRUPT_CARD_INSERTION) + * { + * // Turn an LED on perhaps? Be sure to configure the LED first. + * led_status = true; + * } + * else + * { + * // Turn the LED off perhaps? + * led_status = false; + * } + * } + * + * int main(void) + * { + * DAVE_STATUS_t status; + * SDMMC_BLOCK_STATUS_t sdmmc_status; + * SDMMC_BLOCK_CARD_LOCK_STATUS_t lock_status; + * + * // Register the callback now + * sdmmc_status = SDMMC_BLOCK_RegisterCallback(&SDMMC_BLOCK_0, card_detect_callback); + * + * status = DAVE_Init(); // SDMMC_BLOCK_Init() is called from DAVE_Init() + * + * sdmmc_status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + * if (sdmmc_status == SDMMC_BLOCK_STATUS_SUCCESS) + * { + * sdmmc_status = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, SDMMC_BLOCK_MMC_READ_LOCK_STATUS, &lock_status); + * } + * + * // Placeholder for user application code. + * while(1U) + * { + * } + * } + * @endcode
+ */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_RegisterCallback(SDMMC_BLOCK_t *const obj, + void (*cb)(SDMMC_BLOCK_SD_INTERRUPT_t)); + +#endif /* #ifdef SDMMC_BLOCK_SD */ + +#endif /* #if SDMMC_BLOCK_SD_CARD_DETECTION_SUPPORT */ + +/** + * @} + */ + +/* Support for C++ */ +#ifdef __cplusplus +} +#endif + +#include "sdmmc_block_extern.h" + +#endif /* SDMMC_BLOCK_H */ diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_conf.c b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_conf.c new file mode 100644 index 00000000..4ecfedee --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_conf.c @@ -0,0 +1,326 @@ +/********************************************************************************************************************* +* DAVE APP Name : SDMMC_BLOCK APP Version: 4.0.22 +* +* NOTE: +* This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. +*********************************************************************************************************************/ + +/** + * @cond + *********************************************************************************************************************** + * Copyright (c) 2016, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 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. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes + * with Infineon Technologies AG (dave@infineon.com). + *********************************************************************************************************************** + * + * Change History + * -------------- + * + * 2016-01-20: + * - Initial version
+ * + * 2016-02-05: + * - RTOS support added
+ * + * 2016-04-05: + * - MISRA fixes.
+ * - Bug fixes done for PR.
+ * + * 2016-04-05: + * - Code genration fix for XMC4300 device.
+ * + * @endcond + */ + +/*********************************************************************************************************************** + * HEADER FILES + **********************************************************************************************************************/ + +#include "sdmmc_block.h" + +/********************************************************************************************************************** + * LOCAL ROUTINES + **********************************************************************************************************************/ + +/* SDMMC_BLOCK configuration initialization */ +static void SDMMC_BLOCK_0_Config_Init(void); + + +/********************************************************************************************************************** + * EXTERNAL REFERENCES + **********************************************************************************************************************/ + +extern SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_ErrorInterruptHandler(SDMMC_BLOCK_t *const obj, + uint16_t int_status); + +extern SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_NormalInterruptHandler(SDMMC_BLOCK_t *const obj, + uint16_t int_status); + + +/********************************************************************************************************************** + * GLOBAL VARIABLES + **********************************************************************************************************************/ + +volatile uint16_t normal_int_status; /* Normal interrupt status */ +volatile uint16_t err_int_status; /* Error interrupt status */ + + +/********************************************************************************************************************** + * DATA STRUCTURES + **********************************************************************************************************************/ + + +/* SDMMC_BLOCK Data 0 pin config */ +const SDMMC_BLOCK_GPIO_CONFIG_t SDMMC_BLOCK_0_DATA_0_PIN_CONFIG = +{ + .config = + { + .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE, + .output_level = XMC_GPIO_OUTPUT_LEVEL_LOW, + }, + .hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1, +}; + +/* SDMMC_BLOCK Data 0 pin */ +const SDMMC_BLOCK_PIN_CONFIG_t SDMMC_BLOCK_0_DATA_0 = +{ + .port = (XMC_GPIO_PORT_t *)PORT4_BASE, + .pin = (uint8_t)0, + .config = &SDMMC_BLOCK_0_DATA_0_PIN_CONFIG +}; + + +/* SDMMC_BLOCK Data 1 pin config */ +const SDMMC_BLOCK_GPIO_CONFIG_t SDMMC_BLOCK_0_DATA_1_PIN_CONFIG = +{ + .config = + { + .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE, + .output_level = XMC_GPIO_OUTPUT_LEVEL_LOW, + }, + .hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1, +}; + +/* SDMMC_BLOCK Data 1 pin */ +const SDMMC_BLOCK_PIN_CONFIG_t SDMMC_BLOCK_0_DATA_1 = +{ + .port = (XMC_GPIO_PORT_t *)PORT1_BASE, + .pin = (uint8_t)6, + .config = &SDMMC_BLOCK_0_DATA_1_PIN_CONFIG +}; + + +/* SDMMC_BLOCK Data 2 pin config */ +const SDMMC_BLOCK_GPIO_CONFIG_t SDMMC_BLOCK_0_DATA_2_PIN_CONFIG = +{ + .config = + { + .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE, + .output_level = XMC_GPIO_OUTPUT_LEVEL_LOW, + }, + .hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1, +}; + +/* SDMMC_BLOCK Data 2 pin */ +const SDMMC_BLOCK_PIN_CONFIG_t SDMMC_BLOCK_0_DATA_2 = +{ + .port = (XMC_GPIO_PORT_t *)PORT1_BASE, + .pin = (uint8_t)7, + .config = &SDMMC_BLOCK_0_DATA_2_PIN_CONFIG +}; + + +/* SDMMC_BLOCK Data 3 pin config */ +const SDMMC_BLOCK_GPIO_CONFIG_t SDMMC_BLOCK_0_DATA_3_PIN_CONFIG = +{ + .config = + { + .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE, + .output_level = XMC_GPIO_OUTPUT_LEVEL_LOW, + }, + .hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1, +}; + +/* SDMMC_BLOCK Data 3 pin */ +const SDMMC_BLOCK_PIN_CONFIG_t SDMMC_BLOCK_0_DATA_3 = +{ + .port = (XMC_GPIO_PORT_t *)PORT4_BASE, + .pin = (uint8_t)1, + .config = &SDMMC_BLOCK_0_DATA_3_PIN_CONFIG +}; + + +/* SDMMC_BLOCK Command pin config */ +const SDMMC_BLOCK_GPIO_CONFIG_t SDMMC_BLOCK_0_COMMAND_PIN_CONFIG = +{ + .config = + { + .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE, + .output_level = XMC_GPIO_OUTPUT_LEVEL_LOW, + }, + .hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1, +}; + +/* SDMMC_BLOCK Command pin */ +const SDMMC_BLOCK_PIN_CONFIG_t SDMMC_BLOCK_0_COMMAND = +{ + .port = (XMC_GPIO_PORT_t *)PORT3_BASE, + .pin = (uint8_t)5, + .config = &SDMMC_BLOCK_0_COMMAND_PIN_CONFIG +}; + + +/* SDMMC_BLOCK Clock pin config */ +const SDMMC_BLOCK_GPIO_CONFIG_t SDMMC_BLOCK_0_CLK_PIN_CONFIG = +{ + .config = + { + .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL, + .output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE, + .output_level = XMC_GPIO_OUTPUT_LEVEL_LOW, + }, + .hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1, +}; + +/* SDMMC_BLOCK Clock pin */ +const SDMMC_BLOCK_PIN_CONFIG_t SDMMC_BLOCK_0_CLK = +{ + .port = (XMC_GPIO_PORT_t *)PORT3_BASE, + .pin = (uint8_t)6, + .config = &SDMMC_BLOCK_0_CLK_PIN_CONFIG +}; + + +/* SDMMC SD mode instance */ +SDMMC_BLOCK_SD_t SDMMC_BLOCK_0_SD = +{ + .sdmmc = XMC_SDMMC, /* SDMMC instance */ + .int_priority = 63U, /* Node interrupt priority */ + .int_sub_priority = 0U, /* Node interrupt sub-priority */ + .mode_init_flag = false, /* Mode initialization false by default */ +}; + +/* SDMMC_BLOCK APP instance */ +SDMMC_BLOCK_t SDMMC_BLOCK_0 = +{ + .interface_mode = SDMMC_BLOCK_CARD_INTERFACE_SD, /* SD interface */ + .sdmmc_sd = &SDMMC_BLOCK_0_SD, /* SDMMC_SD instance */ + .rtos_mode = SDMMC_BLOCK_RTOS_MODE_DISABLED, /* RTOS mose is not used */ + + #if SDMMC_BLOCK_RTOS_MODE_SELECT + .cmsis_rtos = NULL, /* RTOS mose is not used */ + #endif /* SDMMC_BLOCK_RTOS_MODE_SELECT */ + + .init_pins = SDMMC_BLOCK_0_Config_Init, /* true: Initialized; false: Uninitialized */ + .init_flag = false, /* true: Initialized; false: Uninitialized */ + .card_state = ((uint8_t)SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED | + (uint8_t)SDMMC_BLOCK_CARD_STATE_NO_CARD) /* Card state */ +}; + +/********************************************************************************************************************** + * FUNCTION DEFINITIONS + **********************************************************************************************************************/ + +/* SDMMC SD interrupt handler */ +void SDMMC0_0_IRQHandler(void) +{ + normal_int_status = SDMMC_BLOCK_0.sdmmc_sd->sdmmc->INT_STATUS_NORM; + err_int_status = SDMMC_BLOCK_0.sdmmc_sd->sdmmc->INT_STATUS_ERR; + + if (normal_int_status & SDMMC_INT_STATUS_NORM_ERR_INT_Msk) + { + SDMMC_BLOCK_SD_ErrorInterruptHandler(&SDMMC_BLOCK_0, err_int_status); + } + + if (normal_int_status & SDMMC_BLOCK_NORMAL_INT_STATUS_BITS) + { + SDMMC_BLOCK_SD_NormalInterruptHandler(&SDMMC_BLOCK_0, normal_int_status); + } +} + +/* + * Configuration initialization: + * For pins and other mode specific settings + */ +static void SDMMC_BLOCK_0_Config_Init(void) +{ + /* Enable delay on command and data lines */ + XMC_SDMMC_EnableDelayCmdDatLines(); + + /* Set the delay value chosen in the APP user interface */ + XMC_SDMMC_SetDelay(SDMMC_BLOCK_SD_NUM_DELAY_ELEMENTS); + + XMC_GPIO_Init(SDMMC_BLOCK_0_COMMAND.port, + SDMMC_BLOCK_0_COMMAND.pin, + &SDMMC_BLOCK_0_COMMAND.config->config); + XMC_GPIO_SetHardwareControl(SDMMC_BLOCK_0_COMMAND.port, + SDMMC_BLOCK_0_COMMAND.pin, + SDMMC_BLOCK_0_COMMAND.config->hw_control); + + XMC_GPIO_Init(SDMMC_BLOCK_0_CLK.port, + SDMMC_BLOCK_0_CLK.pin, + &SDMMC_BLOCK_0_CLK.config->config); + XMC_GPIO_SetHardwareControl(SDMMC_BLOCK_0_CLK.port, + SDMMC_BLOCK_0_CLK.pin, + SDMMC_BLOCK_0_CLK.config->hw_control); + + XMC_GPIO_Init(SDMMC_BLOCK_0_DATA_0.port, + SDMMC_BLOCK_0_DATA_0.pin, + &SDMMC_BLOCK_0_DATA_0.config->config); + XMC_GPIO_SetHardwareControl(SDMMC_BLOCK_0_DATA_0.port, + SDMMC_BLOCK_0_DATA_0.pin, + SDMMC_BLOCK_0_DATA_0.config->hw_control); + + XMC_GPIO_Init(SDMMC_BLOCK_0_DATA_1.port, + SDMMC_BLOCK_0_DATA_1.pin, + &SDMMC_BLOCK_0_DATA_1.config->config); + XMC_GPIO_SetHardwareControl(SDMMC_BLOCK_0_DATA_1.port, + SDMMC_BLOCK_0_DATA_1.pin, + SDMMC_BLOCK_0_DATA_1.config->hw_control); + + XMC_GPIO_Init(SDMMC_BLOCK_0_DATA_2.port, + SDMMC_BLOCK_0_DATA_2.pin, + &SDMMC_BLOCK_0_DATA_2.config->config); + XMC_GPIO_SetHardwareControl(SDMMC_BLOCK_0_DATA_2.port, + SDMMC_BLOCK_0_DATA_2.pin, + SDMMC_BLOCK_0_DATA_2.config->hw_control); + + XMC_GPIO_Init(SDMMC_BLOCK_0_DATA_3.port, + SDMMC_BLOCK_0_DATA_3.pin, + &SDMMC_BLOCK_0_DATA_3.config->config); + XMC_GPIO_SetHardwareControl(SDMMC_BLOCK_0_DATA_3.port, + SDMMC_BLOCK_0_DATA_3.pin, + SDMMC_BLOCK_0_DATA_3.config->hw_control); + + XMC_SDMMC_SetCardDetectionSource(XMC_SDMMC, XMC_SDMMC_CD_SOURCE_SW); + XMC_SDMMC_SetCardDetectionStatus(XMC_SDMMC, XMC_SDMMC_CD_STATUS_INSERTED); +} diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_conf.h b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_conf.h new file mode 100644 index 00000000..9380ae74 --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_conf.h @@ -0,0 +1,82 @@ +/********************************************************************************************************************* +* DAVE APP Name : SDMMC_BLOCK APP Version: 4.0.22 +* +* NOTE: +* This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. +*********************************************************************************************************************/ + +/** + * @cond + *********************************************************************************************************************** + * Copyright (c) 2016, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 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. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes + * with Infineon Technologies AG (dave@infineon.com). + *********************************************************************************************************************** + * + * Change History + * -------------- + * + * 2016-01-20: + * - Initial version
+ * + * 2016-02-05: + * - RTOS support added
+ * + * 2016-04-05: + * - Bug fixes done for PR.
+ * + * @endcond + */ + +#ifndef SDMMC_BLOCK_CONF_H +#define SDMMC_BLOCK_CONF_H + + + +/*********************************************************************************************************************** + * HEADER FILES + **********************************************************************************************************************/ + +#include "xmc_scu.h" +#include "xmc_sdmmc.h" + + +/********************************************************************************************************************** + * MACROS + **********************************************************************************************************************/ + +#define SDMMC_BLOCK_MAJOR_VERSION (4U) /**< Major version */ +#define SDMMC_BLOCK_MINOR_VERSION (0U) /**< Minor version */ +#define SDMMC_BLOCK_PATCH_VERSION (22U) /**< Patch version */ + +#define SDMMC_BLOCK_SD +#define SDMMC_BLOCK_SD_NUM_DELAY_ELEMENTS (8U) +#define SDMMC_BLOCK_SD_SUPPORT_4_BUS_WIDTH (1U) +#define SDMMC_BLOCK_RTOS_MODE_SELECT (0U) + +/* Added configurable to support polling mode operation instead of interrupt driven. */ +#define SDMMC_BLOCK_POLLING_MODE (1U) + +#endif /* ifndef SDMMC_BLOCK_CONF_H */ diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_extern.h b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_extern.h new file mode 100644 index 00000000..5fb8d1c6 --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_extern.h @@ -0,0 +1,79 @@ +/********************************************************************************************************************* +* DAVE APP Name : SDMMC_BLOCK APP Version: 4.0.22 +* +* NOTE: +* This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. +*********************************************************************************************************************/ + +/** + * @cond + *********************************************************************************************************************** + * Copyright (c) 2016, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 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. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes + * with Infineon Technologies AG (dave@infineon.com). + *********************************************************************************************************************** + * + * Change History + * -------------- + * + * 2016-01-20: + * - Initial version
+ * + * 2016-02-05: + * - RTOS support added
+ * + * 2016-04-05: + * - Test hooks is added to emulates the hardware failures.
+ * - Bug fixes done for PR.
+ * + * 2016-06-07: + * - Fixed code generation error for project folder paths with spaces in between. + * @endcond + */ + +#ifndef SDMMC_BLOCK_EXTERN_H +#define SDMMC_BLOCK_EXTERN_H + +/*********************************************************************************************************************** + * HEADER FILES + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * MACROS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * EXTERN DECLARATIONS + ***********************************************************************************************************************/ + +extern SDMMC_BLOCK_t SDMMC_BLOCK_0; + +#ifdef SDMMC_BLOCK_TEST_HOOK_ENABLE +extern uint32_t sdmmc_block_test_hook_expected_command; +#endif + + + +#endif /* ifndef SDMMC_BLOCK_EXTERN_H */ diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_private_sd.c b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_private_sd.c new file mode 100644 index 00000000..af860567 --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_private_sd.c @@ -0,0 +1,2911 @@ +/** + * @file sdmmc_block_private_sd.c + * @date 2017-06-08 + * + * NOTE: + * This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. + * + * @cond + *********************************************************************************************************************** + * SDMMC_BLOCK v4.0.22 - Configures the SD host to interface with the SDMMC card. + * + * Copyright (c) 2016-2017, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 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. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes + * with Infineon Technologies AG (dave@infineon.com). + *********************************************************************************************************************** + * + * Change History + * -------------- + * + * 2016-01-20: + * - Initial version.
+ * + * 2016-02-08: + * - Help Doc updated.
+ * - Bug fixes done.
+ * + * 2016-04-05 + * - Bug fixes for public release, April, 2016
+ * - MISRA fixes
+ * - Add timeout for erase()
+ * - Check write protection in write/erase conditions
+ * - Remove mode_init_flag check for functions invoked in IOCTL
+ * + * 2016-07-20: + * - lReadResponse(): Fixes in handling XMC_SDMMC_RESPONSE_TYPE_R2
+ * + * 2016-08-24: + * - Introduce timeout mechanism in SDMMC_BLOCK_SD_lCheckDataCommandLines()
+ * + * 2017-06-08 + * - Fix SDMMC_BLOCK_SD_GetSectorCount() for Standard Capacity cards + * + * @endcond + * + */ + +#include "sdmmc_block_private_sd.h" +#include "boot.h" + + +#ifdef SDMMC_BLOCK_SD + + +/*********************************************************************************************************************** + * EXTERNAL ROUTINES + **********************************************************************************************************************/ +extern void SDMMC0_0_IRQHandler(void); + + +/*********************************************************************************************************************** + * LOCAL ROUTINES + **********************************************************************************************************************/ + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lReset(SDMMC_BLOCK_t *const obj, uint32_t reset); + +static void +SDMMC_BLOCK_SD_lCardCleanUp(SDMMC_BLOCK_t *const obj); + +static uint32_t +SDMMC_BLOCK_SD_lCheckDataCommandLines(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd); + +static void +SDMMC_BLOCK_SD_lCheckArgumentError(const uint32_t *card_status, uint8_t *err); + +static void +SDMMC_BLOCK_SD_lCheckEraseError(const uint32_t *card_status, uint8_t *err); + +static void +SDMMC_BLOCK_SD_lCheckCardError(const uint32_t *card_status, uint8_t *err); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCheckErrorInResponse(const uint32_t *card_status); + +static void +SDMMC_BLOCK_SD_lGetCardLockState(SDMMC_BLOCK_t *const obj, uint32_t card_status, uint16_t cmd_index); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lTransferDelay(SDMMC_BLOCK_t *const obj, uint32_t delay); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lReadResponse(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + XMC_SDMMC_RESPONSE_TYPE_t resp_type, + void *resp); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lSendCommand(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t arg, + XMC_SDMMC_RESPONSE_TYPE_t resp_type, + void *resp); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lSetVoltageWindow(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lQueryOperatingCondition(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lQueryVoltage(SDMMC_BLOCK_t *const obj, uint32_t arg); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lAfterCardInitialize(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lInitializeCard(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lGetWriteProtect(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lConfigureSingleBlockTransfer(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t arg, + uint16_t block_size); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lMultiBlockTransfer(SDMMC_BLOCK_t *const obj, + uint32_t *addr, + uint32_t num_blocks, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t *buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_t transfer_mode); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCheckLockStatus(SDMMC_BLOCK_t *const obj, SDMMC_BLOCK_CARD_LOCK_STATUS_t mode); + +#if SDMMC_BLOCK_SD_SUPPORT_4_BUS_WIDTH +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lSwitchBusWidth(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lSwitchSpeed(SDMMC_BLOCK_t *const obj); +#endif + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCommandDelay(SDMMC_BLOCK_t *const obj, uint32_t delay); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lSwitchToTransferState(SDMMC_BLOCK_t *const obj); + +static void +SDMMC_BLOCK_SD_lAcmdErrorRecovery(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCheckSectorBound(SDMMC_BLOCK_t *const obj, + uint32_t sector_num, + uint32_t sector_count); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lLocalErase(SDMMC_BLOCK_t *const obj, + uint32_t start_addr, + uint32_t end_addr, + uint32_t timeout); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lHostControllerInit(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lHostControllerDeInit(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCardReadMultipleBlocks(SDMMC_BLOCK_t *const obj, + uint32_t *read_buf, + uint32_t read_addr, + uint32_t num_blocks); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCardReadSingleBlock(SDMMC_BLOCK_t *const obj, + uint32_t *read_buf, + uint32_t read_addr); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCardWriteMultipleBlocks(SDMMC_BLOCK_t *const obj, + const uint32_t *write_buf, + uint32_t write_addr, + uint32_t num_blocks); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lCardWriteSingleBlock(SDMMC_BLOCK_t *const obj, + const uint32_t *write_buf, + uint32_t write_addr); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lDelay(SDMMC_BLOCK_t *const obj, uint32_t delay); + +static void +SDMMC_BLOCK_SD_lWriteCardType(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lReadRca(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lReadCardRegisters(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lDataTransfer(SDMMC_BLOCK_t *const obj, + uint32_t *buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_t transfer_mode, + uint32_t quad_bytes); + + + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lErrorInterruptRecovery(SDMMC_BLOCK_t *const obj); + +static SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_lSingleBlockTransfer(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t arg, + uint16_t block_size, + uint32_t *buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_t transfer_mode); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_Start(SDMMC_BLOCK_t *const obj); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_NormalInterruptHandler(SDMMC_BLOCK_t *const obj, uint16_t int_status); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_ErrorInterruptHandler(SDMMC_BLOCK_t *const obj, uint16_t int_status); + +/*********************************************************************************************************************** + * MACROS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * DATA STRUCTURES + **********************************************************************************************************************/ + +/* Command Structure defining SD, MMC and Application specific commands */ +const XMC_SDMMC_COMMAND_t sdmmc_block_command[40] = +{ + /* Start: SD card commands */ + {{0U, 0U, 0U, 0U, 0U, SDMMC_BLOCK_GO_IDLE_STATE}}, /* 0 */ + {{1U, 1U, 0U, 0U, 0U, SDMMC_BLOCK_ALL_SEND_CID}}, /* 1 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SEND_RELATIVE_ADDR}}, /* 2 */ + {{0U, 0U, 0U, 0U, 0U, SDMMC_BLOCK_SET_DSR}}, /* 3 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_SWITCH_FUNC}}, /* 4 */ + {{3U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SELECT_DESELECT_CARD}}, /* 5 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SD_SEND_IF_COND}}, /* 6 */ + {{1U, 1U, 0U, 0U, 0U, SDMMC_BLOCK_SEND_CSD}}, /* 7 */ + {{1U, 1U, 0U, 0U, 0U, SDMMC_BLOCK_SEND_CID}}, /* 8 */ + {{3U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_STOP_TRANSMISSION}}, /* 9 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SEND_STATUS}}, /* 10 */ + {{0U, 0U, 0U, 0U, 0U, SDMMC_BLOCK_GO_INACTIVE_STATE}}, /* 11 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SET_BLOCKLEN}}, /* 12 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_READ_SINGLE_BLOCK}}, /* 13 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_READ_MULTIPLE_BLOCK}}, /* 14 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_WRITE_BLOCK}}, /* 15 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_WRITE_MULTIPLE_BLOCK}}, /* 16 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_PROGRAM_CSD}}, /* 17 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SET_WRITE_PROT}}, /* 18 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_CLR_WRITE_PROT}}, /* 19 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_SEND_WRITE_PROT}}, /* 20 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_ERASE_WR_BLK_START}}, /* 21 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_ERASE_WR_BLK_END}}, /* 22 */ + {{3U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_ERASE}}, /* 23 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_LOCK_UNLOCK}}, /* 24 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_APP_CMD}}, /* 25 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_GEN_CMD}}, /* 26 */ + /* Start: application specific commands */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SET_BUS_WIDTH}}, /* 27 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_SD_STATUS}}, /* 28 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_SEND_NUM_WR_BLOCKS}}, /* 29 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SET_WR_BLK_ERASE_COUNT}}, /* 30 */ + {{2U, 0U, 0U, 0U, 0U, SDMMC_BLOCK_SD_SEND_OP_COND}}, /* 31 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SET_CLR_CARD_DETECT}}, /* 32 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_SEND_SCR}}, /* 33 */ + /* Start of SDMMC_MMC Card specific commands */ + {{2U, 0U, 1U, 0U, 0U, SDMMC_BLOCK_MMC_SEND_OP_COND}}, /* 34 */ + {{3U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_MMC_SLEEP_AWAKE}}, /* 35 */ + {{3U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_SWITCH_FUNC}}, /* 36 */ + {{2U, 1U, 1U, 1U, 0U, SDMMC_BLOCK_MMC_SEND_EXT_CSD}}, /* 37 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_ERASE_GROUP_START}}, /* 38 */ + {{2U, 1U, 1U, 0U, 0U, SDMMC_BLOCK_ERASE_GROUP_END}} /* 39 */ +}; + +/* + * SD card command index hash table + * It contains the index of the command structure + * + * Array index 0-57 is for general SD commands and array + * index 58-64 is for application specific commands. + */ +const uint8_t sdmmc_block_sd_hash_table[65] = +{ + (uint8_t)0x00, (uint8_t)0xFF, (uint8_t)0x01, (uint8_t)0x02, + (uint8_t)0x03, (uint8_t)0xFF, (uint8_t)0x04, (uint8_t)0x05, + (uint8_t)0x06, (uint8_t)0x07, (uint8_t)0x08, (uint8_t)0xFF, + (uint8_t)0x09, (uint8_t)0x0A, (uint8_t)0xFF, (uint8_t)0x0B, + (uint8_t)0x0C, (uint8_t)0x0D, (uint8_t)0x0E, (uint8_t)0xFF, + (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0xFF, + (uint8_t)0x0F, (uint8_t)0x10, (uint8_t)0xFF, (uint8_t)0x11, + (uint8_t)0x12, (uint8_t)0x13, (uint8_t)0x14, (uint8_t)0xFF, + (uint8_t)0x15, (uint8_t)0x16, (uint8_t)0xFF, (uint8_t)0xFF, + (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0x17, (uint8_t)0xFF, + (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0x18, (uint8_t)0xFF, + (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0xFF, + (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0xFF, + (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0xFF, (uint8_t)0x19, + (uint8_t)0x1A, (uint8_t)0xFF, (uint8_t)0x1B, (uint8_t)0x1C, + (uint8_t)0x1D, (uint8_t)0x1E, (uint8_t)0x1F, (uint8_t)0x20, + (uint8_t)0x21 +}; + +/*********************************************************************************************************************** + * EXTERNAL REFERENCES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * API DEFINITIONS + **********************************************************************************************************************/ + +/* Resets the Host Controller's register */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lReset(SDMMC_BLOCK_t *const obj, uint32_t reset) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + uint32_t timeoutTime; + + XMC_SDMMC_SetSWReset(obj->sdmmc_sd->sdmmc, reset); + + /* Set timeout time. */ + timeoutTime = TimerGet() + (SDMMC_BLOCK_RESET_DELAY / 1000u) + 1u; + + do + { + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } + while (((uint32_t)XMC_SDMMC_GetSWResetStatus(obj->sdmmc_sd->sdmmc)) & (reset)); + + return status; +} + +/* Clears card specific structures and stops the SD clock */ +static void SDMMC_BLOCK_SD_lCardCleanUp(SDMMC_BLOCK_t *const obj) +{ + memset((void *)&obj->sdmmc_sd->card_info, 0, sizeof(SDMMC_BLOCK_SD_CARD_INFORMATION_t)); + obj->card_type = (uint8_t)0; + obj->sdmmc_sd->f8 = (uint8_t)0; + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->err_recovery_stat = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->transfer_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->card_state = (uint8_t)0U; + + /* SD clock disable */ + XMC_SDMMC_SDClockDisable(obj->sdmmc_sd->sdmmc); +} + +/* Check if CMD and DAT lines are free before issuing a command */ +static uint32_t SDMMC_BLOCK_SD_lCheckDataCommandLines(SDMMC_BLOCK_t *const obj, const XMC_SDMMC_COMMAND_t *cmd) +{ + uint32_t status = (uint32_t)SDMMC_BLOCK_MODE_STATUS_CMD_LINE_BUSY; + uint32_t timeoutTime; + + timeoutTime = TimerGet() + (SDMMC_BLOCK_DELAY_IN_COMMAND / 1000u) + 1u; + + do + { + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } while ((XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc) || + (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc)))); + + /* Check if command line is not busy; then proceed */ + if (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc) == false) + { + status = (uint32_t)SDMMC_BLOCK_MODE_STATUS_SUCCESS; + if (((uint32_t)cmd->dat_present_sel == (uint32_t)1U) || + ((uint32_t)cmd->cmd_index == (uint32_t)SDMMC_BLOCK_SEND_STATUS) || + ((uint32_t)cmd->response_type_sel == (uint32_t)3U)) + { + if (XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc) != false) + { + status = (uint32_t)SDMMC_BLOCK_MODE_STATUS_DATA_LINE_BUSY; + } + else + { + if (((uint32_t)cmd->dat_present_sel == (uint32_t)1U) || ((uint32_t)cmd->response_type_sel == (uint32_t)3U)) + { + /* Update data line state to active */ + obj->card_state |= (uint8_t)SDMMC_BLOCK_CARD_STATE_DATA_ACTIVE; + } + } + } + + if (status == (uint32_t)SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Update command line state to active */ + obj->card_state |= (uint8_t)SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE; + } + } + + return status; +} + +/* Check response error types in command's arguments category */ +static void SDMMC_BLOCK_SD_lCheckArgumentError(const uint32_t *card_status, uint8_t *err) +{ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_OUT_OF_RANGE_BITMASK) != (uint32_t)0U) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckArgumentError: Out of range error"); + } + + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_ADDRESS_ERROR_BITMASK) != (uint32_t)0U) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckArgumentError: Address error"); + } + + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_BLOCK_LEN_ERROR_BITMASK) != (uint32_t)0U) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckArgumentError: Block length error"); + } + + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_WP_VIOLATION_BITMASK) != (uint32_t)0U) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckArgumentError: Write protection violation error"); + } +} + +/* Checks response error types in erase category */ +static void SDMMC_BLOCK_SD_lCheckEraseError(const uint32_t *card_status, uint8_t *err) +{ + /* An error in the sequence of erase commands occurred.*/ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_ERASE_SEQ_ERROR_BITMASK) != (uint32_t)0) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckEraseError: Sequential erase error"); + } + + /* An invalid selection of write-blocks for erase occurred */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_ERASE_PARAM_BITMASK) != (uint32_t)0) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckEraseError: Parameter erase error"); + } + + /* + * Set when only partial address space was erased due to existing + * write protected blocks OR the temporary/permanent write protected card + * was erased + */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_WP_ERASE_SKIP_BITMASK) != (uint32_t)0) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckEraseError: Write protection erase skip error"); + } +} + +/* Check response error types in card's internal error category */ +static void SDMMC_BLOCK_SD_lCheckCardError(const uint32_t *card_status, uint8_t *err) +{ + /* Card internal ECC was applied but failed to correct the data */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_CARD_ECC_FAILED_BITMASK) != (uint32_t)0U) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckCardError: Card ECC error"); + } + + /* Internal card controller error */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_CC_ERROR_BITMASK) != (uint32_t)0) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckCardError: Internal card controller error"); + } + + /* A general or an unknown error occurred during the operation */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_ERROR_BITMASK) != (uint32_t)0) + { + *err = (uint8_t)1U; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckCardError: Unknown error"); + } +} + +/* Check for any error in the command's (received) response */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCheckErrorInResponse(const uint32_t *card_status) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + uint8_t err = (uint8_t)0; /* No error */ + + /* Check errors in arguments */ + SDMMC_BLOCK_SD_lCheckArgumentError(card_status, &err); + + /* Check errors specific to erase operation */ + SDMMC_BLOCK_SD_lCheckEraseError(card_status, &err); + + /* Check errors specific to the card */ + SDMMC_BLOCK_SD_lCheckCardError(card_status, &err); + + /* + * Set when a sequence or password error has been detected in + * lock/unlock card command + */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_LOCK_UNLOCK_FAILED_BITMASK) != (uint32_t)0) + { + err = (uint8_t)1; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckErrorInResponse: Lock/unlock error"); + } + + /* + * Can be one of the following errors: + * 1) The read only section of the CSD does not match the card content + * 2) An attempt to reverse the copy or permanent WP bits was made + */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_CSD_OVERWRITE_BITMASK) != (uint32_t)0) + { + err = (uint8_t)1; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckErrorInResponse: CSD overwrite error"); + } + + /* Error in the sequence of the authentication process */ + if ((*card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_ASK_SEQ_ERROR_BITMASK) != (uint32_t)0) + { + err = (uint8_t)1; + XMC_DEBUG("SDMMC_BLOCK_SD_CheckErrorInResponse: Authentication sequence error"); + } + + /* Some SD cards treat CMD55 as an illegal command */ + if (err == 1U) + { + status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + } + + return status; +} + +/* Check for lock status of SD card */ +static void SDMMC_BLOCK_SD_lGetCardLockState(SDMMC_BLOCK_t *const obj, uint32_t card_status, uint16_t cmd_index) +{ + if (((card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_CARD_IS_LOCKED_BITMASK) != (uint32_t)0) && + (cmd_index != (uint32_t)SDMMC_BLOCK_SEND_RELATIVE_ADDR)) + { + obj->card_state |= (uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED; + } + else + { + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED; + } +} + +/* Provide transfer delay */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lTransferDelay(SDMMC_BLOCK_t *const obj, uint32_t delay) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + uint32_t timeoutTime; + obj->sdmmc_sd->tmr_expire = (bool)1; + + timeoutTime = TimerGet() + (delay / 1000u) + 1u; + + do + { +#if (SDMMC_BLOCK_POLLING_MODE > 0U) + /* Poll for interrupt events. */ + SDMMC0_0_IRQHandler(); +#endif + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } while (obj->sdmmc_sd->isr_context.transfer_flag == (uint8_t)0U); + + obj->sdmmc_sd->isr_context.transfer_flag = (uint8_t)0U; + + if (obj->sdmmc_sd->transfer_int_err != SDMMC_BLOCK_MODE_STATUS_TRANSFER_COMPLETE) + { + status = (SDMMC_BLOCK_MODE_STATUS_t)obj->sdmmc_sd->data_int_err; + } + + return status; +} + +/* Read response received for the command issued */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lReadResponse(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + XMC_SDMMC_RESPONSE_TYPE_t resp_type, + void *resp) +{ + uint32_t *ptr; + uint32_t card_status = 0U; + uint32_t err_status = 0U; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + /* To mask high byte from response register */ + uint32_t resp_high_mask = 0; + + /* Check for no-response type commands */ + if (((uint16_t)cmd->cmd_index == (uint16_t)SDMMC_BLOCK_GO_IDLE_STATE) || + ((uint16_t)cmd->cmd_index == (uint16_t)SDMMC_BLOCK_GO_INACTIVE_STATE)) + { + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } + else + { + ptr = (uint32_t *)resp; + card_status = (uint32_t)obj->sdmmc_sd->sdmmc->RESPONSE[0]; + + /* Check Lock Status */ + SDMMC_BLOCK_SD_lGetCardLockState(obj, card_status, (uint16_t)cmd->cmd_index); + + /* Check response type */ + switch (resp_type) + { + /* Response R1 */ + case XMC_SDMMC_RESPONSE_TYPE_R1: + /* check the error bits in the response */ + *ptr = card_status; + status = SDMMC_BLOCK_SD_lCheckErrorInResponse(&card_status); + break; + + /* Response R1b */ + case XMC_SDMMC_RESPONSE_TYPE_R1b: + *ptr = card_status; + + status = SDMMC_BLOCK_SD_lCheckErrorInResponse(&card_status); + if (status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Wait for transfer complete interrupt */ + status = SDMMC_BLOCK_SD_lTransferDelay(obj, (uint32_t)SDMMC_BLOCK_DELAY_IN_TRANSFER); + if (status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + XMC_DEBUG("SDMMC_BLOCK_ReadResponse: For R1b, SDMMC_BLOCK_TransferDelay failed"); + } + } + + break; + + /* Response R2: response register R0-R7 */ + case XMC_SDMMC_RESPONSE_TYPE_R2: + *ptr = (uint32_t)((uint32_t)XMC_SDMMC->RESPONSE[0] << 8U); ptr++; + resp_high_mask = (uint32_t)(((uint32_t)XMC_SDMMC->RESPONSE[0] & 0xFF000000) >> 24U); + + *ptr = (uint32_t)(((uint32_t)XMC_SDMMC->RESPONSE[1] << 8U) | resp_high_mask); ptr++; + resp_high_mask = (uint32_t)(((uint32_t)XMC_SDMMC->RESPONSE[1] & 0xFF000000) >> 24U); + + *ptr = (uint32_t)(((uint32_t)XMC_SDMMC->RESPONSE[2] << 8U) | resp_high_mask); + resp_high_mask = (uint32_t)(((uint32_t)XMC_SDMMC->RESPONSE[2] & 0xFF000000) >> 24U); + + *ptr = (uint32_t)(((uint32_t)XMC_SDMMC->RESPONSE[3] << 8U) | resp_high_mask); + break; + + /* Responses R3 and R7 */ + case XMC_SDMMC_RESPONSE_TYPE_R3: + *ptr = card_status; + break; + + case XMC_SDMMC_RESPONSE_TYPE_R7: + *ptr = card_status; + break; + + /* Response R6 */ + case XMC_SDMMC_RESPONSE_TYPE_R6: + err_status = card_status & (uint32_t)SDMMC_RESPONSE0_RESPONSE0_Msk; + status = SDMMC_BLOCK_SD_lCheckErrorInResponse(&err_status); + + /* Read 16-bit RCA received in response R1 register */ + *ptr = ((uint32_t)(card_status & (uint32_t)SDMMC_RESPONSE0_RESPONSE1_Msk) >> SDMMC_BLOCK_HC_RESPONSE1_BITPOS); + break; + + /* No response */ + case XMC_SDMMC_RESPONSE_TYPE_NO_RESPONSE: + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + break; + + default: + status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + break; + } + } + + return status; +} + +/* Send command */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lSendCommand(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t arg, + XMC_SDMMC_RESPONSE_TYPE_t resp_type, + void *resp) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t timeoutTime; + + obj->sdmmc_sd->issue_abort = (uint8_t)0U; + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* Data or command line free? */ + status = (SDMMC_BLOCK_MODE_STATUS_t)SDMMC_BLOCK_SD_lCheckDataCommandLines(obj, cmd); + if (!((status == SDMMC_BLOCK_MODE_STATUS_DATA_LINE_BUSY) || + (status == SDMMC_BLOCK_MODE_STATUS_CMD_LINE_BUSY))) + { + /* Send command */ + (void)XMC_SDMMC_SendCommand(obj->sdmmc_sd->sdmmc, cmd, arg); + + /* Block until any of the bit in the interrupt status register gets set */ + timeoutTime = TimerGet() + (SDMMC_BLOCK_DELAY_IN_COMMAND / 1000u) + 1u; + + do + { +#if (SDMMC_BLOCK_POLLING_MODE > 0U) + /* Poll for interrupt events. */ + SDMMC0_0_IRQHandler(); +#endif + + if (TimerGet() > timeoutTime) + { + XMC_DEBUG("SDMMC_BLOCK_SendCommand: Timeout occured"); + break; + } + /* Service the watchdog. */ + CopService(); + } while ((uint8_t)obj->sdmmc_sd->isr_context.cmd_flag == (uint8_t)0U); + + obj->sdmmc_sd->isr_context.cmd_flag = (uint8_t)0; + + /* Check for possible errors */ + if ((SDMMC_BLOCK_MODE_STATUS_t)obj->sdmmc_sd->cmd_int_err == SDMMC_BLOCK_MODE_STATUS_COMMAND_COMPLETE) + { + /* Read response received */ + status = SDMMC_BLOCK_SD_lReadResponse(obj, cmd, resp_type, resp); + } + /* For cmd8, check for cmd timeout interrupt */ + else if (((SDMMC_BLOCK_MODE_STATUS_t)obj->sdmmc_sd->cmd_int_err == SDMMC_BLOCK_MODE_STATUS_COMMAND_TIMEOUT_ERROR) && + ((uint16_t)cmd->cmd_index == (uint16_t)SDMMC_BLOCK_SD_SEND_IF_COND)) + { + status = SDMMC_BLOCK_MODE_STATUS_COMMAND_TIMEOUT_ERROR; + } + else + { + if ((uint16_t)cmd->dat_present_sel == (uint16_t)1) + { + obj->sdmmc_sd->issue_abort = (uint8_t)1; + } + + /* Error Recovery for the failed command */ + status = SDMMC_BLOCK_SD_lErrorInterruptRecovery(obj); + } + } + + return status; +} + +/* Set voltage window in the OCR register */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lSetVoltageWindow(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t card_status = 0U; + uint32_t loop_count = 0U; + uint32_t arg = 0U; + + if (obj->sdmmc_sd->f8 == (uint8_t)0U) + { + arg = SDMMC_BLOCK_SD_ACMD41_F80_ARG; /* Set HCS=0 for standard cards */ + } + else + { + arg = SDMMC_BLOCK_SD_ACMD41_F81_ARG; /* Set HCS=1 for high capacity cards */ + } + + do + { + /* Send CMD55 for application specific commands (default RCA: 0) */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(55)), + SDMMC_BLOCK_ARGUMENT0, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Send ACMD41 to set card's voltage window */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(62)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R3, + &(obj->sdmmc_sd->card_info.ocr)); + + if ((status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) && + (status != SDMMC_BLOCK_MODE_STATUS_ILLEGAL_COMMAND_ERROR)) + { + break; + } + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + + /* Card takes some time to set power status bit. Card must respond in a second */ + (void)SDMMC_BLOCK_SD_lDelay(obj, (uint32_t)SDMMC_BLOCK_CARD_POWER_DELAY); + } + else + { + loop_count = 100U; + } + } while (((loop_count++) < (uint32_t)50U) && + (!(((uint32_t)obj->sdmmc_sd->card_info.ocr & + (uint32_t)SDMMC_BLOCK_OCR_POWER_STATUS_BITMASK)!= (uint32_t)0UL))); + + return status; +} + +/* Query voltage operating condition of the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lQueryOperatingCondition(SDMMC_BLOCK_t *const obj) +{ + uint32_t resp_data = 0U; + SDMMC_BLOCK_MODE_STATUS_t status; + + /* Query voltage operating condition (cmd8) */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(8)), + SDMMC_BLOCK_SD_CMD8_ARG, + XMC_SDMMC_RESPONSE_TYPE_R7, + &resp_data); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Check if pattern matches in both the argument and response */ + if (((resp_data >> SDMMC_BLOCK_SD_CMD8_CHECK_PATTERN_BITPOS) & SDMMC_BLOCK_SD_CMD8_CHECK_PATTERN_BITMASK) != + (SDMMC_BLOCK_SD_CMD8_CHECK_PATTERN_VALUE)) + { + status = SDMMC_BLOCK_MODE_STATUS_BAD_RESPONSE; + } + /* Check if input voltage accepted by the card in the response */ + else if (((uint8_t)(resp_data >> SDMMC_BLOCK_SD_CMD8_VHS_BITPOS) & SDMMC_BLOCK_SD_CMD8_VHS_BITMASK) != + (SDMMC_BLOCK_SD_VHS_PATTERN_2_7_3_6_VALUE)) + { + status = SDMMC_BLOCK_MODE_STATUS_BAD_RESPONSE; + } + else + { + /* Set Flag f8 */ + obj->sdmmc_sd->f8 = (uint8_t)1U; + } + } + /* Response received; High capacity cards */ + else + { + /* No response is received for Standard Capacity SD cards or MMC card. */ + if (obj->sdmmc_sd->cmd_int_err == SDMMC_BLOCK_MODE_STATUS_COMMAND_TIMEOUT_ERROR) + { + obj->sdmmc_sd->f8 = (uint8_t)0U; + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } + } + + return status; +} + +/* Query voltage supported from the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lQueryVoltage(SDMMC_BLOCK_t *const obj, uint32_t arg) +{ + uint32_t card_status = 0U; + SDMMC_BLOCK_MODE_STATUS_t status; + + /* Send CMD55 for application specific commands with 0 as the default RCA */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(55)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (((obj->sdmmc_sd->f8 == (uint8_t)0U) && (status == SDMMC_BLOCK_MODE_STATUS_ILLEGAL_COMMAND_ERROR)) || + (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS)) + { + /* Send ACMD41 to query the card's voltage window */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(62)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R3, + &(obj->sdmmc_sd->card_info.ocr)); + + if ((status == SDMMC_BLOCK_MODE_STATUS_ILLEGAL_COMMAND_ERROR) || + (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS)) + { + /* Send ACMD41 with voltage window argument set */ + status = SDMMC_BLOCK_SD_lSetVoltageWindow(obj); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* SD Card Type */ + SDMMC_BLOCK_SD_lWriteCardType(obj); + } + } + } + + return status; +} + +/* Read card registers after the card initialization */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lAfterCardInitialize(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint8_t card_lock = (obj->card_state & (uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED); + uint32_t card_status; + + /* Read CSD & SCR register & card write protection flags */ + status = SDMMC_BLOCK_SD_lReadCardRegisters(obj); + + /* Explicitly set block size as 512 */ + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(16)), + 512U, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + } + + if ((status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) && (card_lock == (uint8_t)0U)) + { +#if SDMMC_BLOCK_SD_SUPPORT_4_BUS_WIDTH + /* Switch to 4-bit bus width if supported */ + status = SDMMC_BLOCK_SD_lSwitchBusWidth(obj); + + if (status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Switch to default (1-bit) bus width */ + XMC_SDMMC_SetDataTransferWidth(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_LINES_1); + } + + /* Switch to high speed mode */ + status = SDMMC_BLOCK_SD_lSwitchSpeed(obj); + if (status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Switch host controller to normal (default) speed mode */ + XMC_SDMMC_DisableHighSpeed(obj->sdmmc_sd->sdmmc); + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } +#endif + } + + return status; +} + +/* Initialize the SD card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lInitializeCard(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + SDMMC_BLOCK_CARD_LOCK_STATUS_t lock_status; + uint8_t count = (uint8_t)0U; + + /* Repeat the below steps 2 times if bad response is received */ + do + { + /* Reset the card (CMD0) */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(0)), + SDMMC_BLOCK_ARGUMENT0, + XMC_SDMMC_RESPONSE_TYPE_NO_RESPONSE, + NULL); + + if (status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + break; + } + + /* Query card's operation condition */ + status = SDMMC_BLOCK_SD_lQueryOperatingCondition(obj); + + count++; + } while ((count < (uint8_t)SDMMC_BLOCK_NUM_CARD_RESET_RETRIES) && + (status == SDMMC_BLOCK_MODE_STATUS_BAD_RESPONSE)); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Query and set voltage window */ + status = SDMMC_BLOCK_SD_lQueryVoltage(obj, (uint32_t)obj->sdmmc_sd->card_info.rca); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Read CID */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(2)), + SDMMC_BLOCK_ARGUMENT0, + XMC_SDMMC_RESPONSE_TYPE_R2, + (void *)obj->sdmmc_sd->card_info.cid); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Read RCA */ + status = SDMMC_BLOCK_SD_lReadRca(obj); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Check card lock/unlock status */ + status = SDMMC_BLOCK_SD_GetLockStatus(obj, &lock_status); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + if (lock_status == SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED) + { + status = SDMMC_BLOCK_MODE_STATUS_INITIALIZED_BUT_LOCKED; + } + + /* Update card initialization status */ + obj->card_state &= (uint8_t)~((uint8_t)SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED | + (uint8_t)SDMMC_BLOCK_CARD_STATE_NO_CARD); + } + } + } + } + } + + return status; +} + + +/* Get card type */ +static void SDMMC_BLOCK_SD_lWriteCardType(SDMMC_BLOCK_t *const obj) +{ + /* If F8=0; standard capacity v1 card */ + if (obj->sdmmc_sd->f8 == (uint8_t)0U) + { + obj->card_type |= (uint8_t)SDMMC_BLOCK_CARD_TYPE_STANDARD_CAPACITY_V1X; + } + /* If F8=1; standard capacity v2 or high capacity card */ + else + { + /* Check CCS bit in the OCR register; CCS=1 implies a high capacity card */ + if (((uint32_t)obj->sdmmc_sd->card_info.ocr & (uint32_t)SDMMC_BLOCK_OCR_CCS_BITMASK) != (uint32_t)0U) + { + obj->card_type |= (uint8_t)((uint8_t)SDMMC_BLOCK_CARD_TYPE_HIGH_CAPACITY | + (uint8_t)SDMMC_BLOCK_CARD_TYPE_BLOCK_ADDRESSING); + } + else + { + /* CCS=0 implies standard capacity v2 */ + obj->card_type |= (uint8_t)SDMMC_BLOCK_CARD_TYPE_STANDARD_CAPACITY_V2; + } + } +} + +/* Check write protection status of card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lGetWriteProtect(SDMMC_BLOCK_t *const obj) +{ + uint32_t sd_status[16] = {0U}; + uint32_t write_protect; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + status = SDMMC_BLOCK_SD_GetSdStatus(obj, (void *)&(sd_status[0])); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Bits 480:495 in the SD status provides write protection information */ + write_protect = ((sd_status[0] & 0xFF000000U) >> 24U) | (((sd_status[0] & 0x00FF0000U) >> 16U) << 8U); + if ((write_protect & SDMMC_BLOCK_SD_CARD_TYPE_BITMASK) != 0U) + { + obj->card_state |= (uint8_t)SDMMC_BLOCK_CARD_STATE_WRITE_PROTECTED; + } + } + + return status; +} + +/* Reads RCA (relative card address) of the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lReadRca(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(3)), + SDMMC_BLOCK_ARGUMENT0, + XMC_SDMMC_RESPONSE_TYPE_R6, + &(obj->sdmmc_sd->card_info.rca)); + return status; +} + +/* Read the CSD, SCR and Write protection status of the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lReadCardRegisters(SDMMC_BLOCK_t *const obj) +{ + uint32_t arg = 0U; + uint32_t card_status = 0U; + SDMMC_BLOCK_MODE_STATUS_t status; + SDMMC_BLOCK_SCR_t scr_content = {0U}; + uint8_t card_lock = (obj->card_state & (uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED); + + /* Read CSD Register */ + arg |= (uint32_t)((uint32_t)obj->sdmmc_sd->card_info.rca << (uint16_t)SDMMC_BLOCK_ARG_RCA_BITPOS); + + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(9)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R2, + (void *)obj->sdmmc_sd->card_info.csd); + + if ((status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) && (card_lock == (uint8_t)0U)) + { + /* Set write protection flags */ + status = SDMMC_BLOCK_SD_lGetWriteProtect(obj); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Read SCR register for SD card */ + if (((uint8_t)obj->card_type & (uint8_t)SDMMC_BLOCK_CARD_TYPE_MMC) == 0U) + { + /* Switch to Transferring State. */ + status = SDMMC_BLOCK_SD_lSwitchToTransferState(obj); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Send application specific command CMD55 */ + arg |= (uint32_t)((uint32_t)obj->sdmmc_sd->card_info.rca << (uint32_t)SDMMC_BLOCK_ARG_RCA_BITPOS); + + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(55)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Set direction select bit */ + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_CARD_TO_HOST); + + /* Read the transferred SCR data */ + status = SDMMC_BLOCK_SD_lSingleBlockTransfer(obj, + &(SDMMC_BLOCK_SD_COMMAND(64)), + (uint32_t)SDMMC_BLOCK_ARGUMENT0, + (uint16_t)8U, + (uint32_t *)&scr_content, + SDMMC_BLOCK_SD_DATA_TRANSFER_READ_BUFFER); + + obj->sdmmc_sd->card_info.scr = scr_content; + } + } + } + } + } + else + { + status = SDMMC_BLOCK_SD_lSwitchToTransferState(obj); + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_CARD_TO_HOST); + } + + return status; +} + +/* Configure the registers for a single block transfer */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lConfigureSingleBlockTransfer(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t arg, + uint16_t block_size) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t card_status = 0U; + XMC_SDMMC_TRANSFER_MODE_t response; + + response.block_size = block_size; + response.type = XMC_SDMMC_TRANSFER_MODE_TYPE_SINGLE; + response.auto_cmd = XMC_SDMMC_TRANSFER_MODE_AUTO_CMD_DISABLED; + + XMC_SDMMC_SetDataTransferMode(obj->sdmmc_sd->sdmmc, &response); + + status = SDMMC_BLOCK_SD_lSendCommand(obj, cmd, arg, XMC_SDMMC_RESPONSE_TYPE_R1, &card_status); + + return status; +} + +/* Configure the registers for a multi-block transfer */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lConfigureMultiBlockTransfer(SDMMC_BLOCK_t *const obj, + uint32_t *arg, + uint32_t num_blocks, + const XMC_SDMMC_COMMAND_t *cmd) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + uint32_t card_status = 0U; + XMC_SDMMC_TRANSFER_MODE_t response; + + /* Block addressing */ + if (((uint8_t)obj->card_type & (uint8_t)SDMMC_BLOCK_CARD_TYPE_BLOCK_ADDRESSING) == (uint8_t)0U) + { + *arg *= (uint32_t)512U; + } + + response.block_size = SDMMC_BLOCK_TX_BLOCK_SIZE_VALUE; + response.num_blocks = num_blocks; + response.type = XMC_SDMMC_TRANSFER_MODE_TYPE_MULTIPLE; + response.auto_cmd = XMC_SDMMC_TRANSFER_MODE_AUTO_CMD_12; + + XMC_SDMMC_SetDataTransferMode(obj->sdmmc_sd->sdmmc, &response); + + /* Enable ACMD 12 interrupt signal */ + XMC_SDMMC_EnableEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_ACMD_ERR); + + /* Send multiple block transfer command */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, cmd, *arg, XMC_SDMMC_RESPONSE_TYPE_R1, &card_status); + + return status; +} + +/* Transfer multiple blocks of data */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lMultiBlockTransfer(SDMMC_BLOCK_t *const obj, + uint32_t *addr, + uint32_t num_blocks, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t *buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_t transfer_mode) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + obj->sdmmc_sd->transfer_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* Configure registers for Multi block transfer*/ + status = SDMMC_BLOCK_SD_lConfigureMultiBlockTransfer(obj, addr, (uint32_t)num_blocks, cmd); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Read/write block data */ + while ((uint32_t)num_blocks > 0U) + { + /* Perform Transfer */ + status = SDMMC_BLOCK_SD_lDataTransfer(obj, buf, transfer_mode, SDMMC_BLOCK_NUM_QUADLETS_IN_BLOCK); + if (status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + break; + } + /* Decrement number of blocks */ + num_blocks--; + /* Pointer pointing to the next block pointer */ + buf += (uint32_t)SDMMC_BLOCK_NUM_QUADLETS_IN_BLOCK; + } + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Block on transfer complete interrupt */ + /* Timeout: 5ms */ + status = SDMMC_BLOCK_SD_lTransferDelay(obj, SDMMC_BLOCK_DELAY_IN_TRANSFER); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Check if transfer happened successfully; Check ACMD status */ + if ((SDMMC_BLOCK_MODE_STATUS_t)obj->sdmmc_sd->acmd_int_err == SDMMC_BLOCK_MODE_STATUS_ACMD12_ERROR) + { + /* Call ACMD12 error recovery */ + SDMMC_BLOCK_SD_lAcmdErrorRecovery(obj); + } + } + } + } + return status; +} + +/* Performs single block transfer */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lSingleBlockTransfer(SDMMC_BLOCK_t *const obj, + const XMC_SDMMC_COMMAND_t *cmd, + uint32_t arg, + uint16_t block_size, + uint32_t *buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_t transfer_mode) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + uint32_t timeoutTime; + uint32_t qbytes = (uint32_t)(((((uint32_t)block_size + 3UL) >> 2U) << 2U) >> 2U); + + status = SDMMC_BLOCK_SD_lConfigureSingleBlockTransfer(obj, cmd, arg, block_size); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Perform data transfer */ + status = SDMMC_BLOCK_SD_lDataTransfer(obj, buf, transfer_mode, qbytes); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Block on transfer complete interrupt */ + timeoutTime = TimerGet() + (SDMMC_BLOCK_DELAY_IN_TRANSFER / 1000u) + 1u; + + do + { +#if (SDMMC_BLOCK_POLLING_MODE > 0U) + /* Poll for interrupt events. */ + SDMMC0_0_IRQHandler(); +#endif + + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } while ((uint8_t)obj->sdmmc_sd->isr_context.transfer_flag == (uint8_t)0U); + + obj->sdmmc_sd->isr_context.transfer_flag = (uint8_t)0U; + + /* Check transfer complete status */ + if ((SDMMC_BLOCK_MODE_STATUS_t)obj->sdmmc_sd->transfer_int_err == SDMMC_BLOCK_MODE_STATUS_TRANSFER_COMPLETE) + { + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } + else + { + obj->sdmmc_sd->issue_abort = (uint8_t)1U; + status = SDMMC_BLOCK_SD_lErrorInterruptRecovery(obj); + } + } + } + + return status; +} + +/* Check lock status */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCheckLockStatus(SDMMC_BLOCK_t *const obj, + SDMMC_BLOCK_CARD_LOCK_STATUS_t mode) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + SDMMC_BLOCK_CARD_LOCK_STATUS_t lock_status; + + status = SDMMC_BLOCK_SD_GetLockStatus(obj, &lock_status); + /* For lock, card state must be "locked" */ + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + if ((lock_status == SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED) && (mode == SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED)) + { + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } + /* For unlock, card state must be "unlocked" */ + else if ((lock_status == SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED) && (mode == SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED)) + { + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } + else + { + status = SDMMC_BLOCK_MODE_STATUS_LOCK_UNLOCK_ERROR; + } + } + + return status; +} + +#if SDMMC_BLOCK_SD_SUPPORT_4_BUS_WIDTH + +/* Switch bus width to 4-bit if supported */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lSwitchBusWidth(SDMMC_BLOCK_t *const obj) +{ + uint32_t arg = 0U; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t card_status = 0U; + + /* Switch to transfer state (CMD7) */ + status = SDMMC_BLOCK_SD_lSwitchToTransferState(obj); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Disable card insertion interrupt */ + XMC_SDMMC_DisableEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CARD_INS); + + /* Check data transfer width supported in SCR register */ + if ((obj->sdmmc_sd->card_info.scr.sd_bus_width & SDMMC_BLOCK_SCR_BUS_WIDTH4_BITMASK)) + { + /* Set the argument */ + arg |= ((uint32_t)obj->sdmmc_sd->card_info.rca << (uint32_t)SDMMC_BLOCK_ARG_RCA_BITPOS); + + /* Send application specific command */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(55)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Send ACMD6 to switch the bus width */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(58)), + SDMMC_BLOCK_SD_4BUS_WIDTH_ARG, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + } + } + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Set data transfer width */ + XMC_SDMMC_SetDataTransferWidth(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_LINES_4); + } + } + + return status; +} + +/* Switch the card speed mode to high speed if supported */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lSwitchSpeed(SDMMC_BLOCK_t *const obj) +{ + uint32_t switch_status[16] = {0U}; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* Check CMD6 support in SCR register */ + if (obj->sdmmc_sd->card_info.scr.sd_spec != 0UL) + { + /* Switch to transfer state (CMD7) */ + status = SDMMC_BLOCK_SD_lSwitchToTransferState(obj); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* + * Send the Switch function command and read the transferred block of + * data from the card + */ + status = SDMMC_BLOCK_SD_lSingleBlockTransfer(obj, + &(SDMMC_BLOCK_SD_COMMAND(6)), + SDMMC_BLOCK_SD_HIGH_SPEED_ARG, + 64U, + (uint32_t *)switch_status, + SDMMC_BLOCK_SD_DATA_TRANSFER_READ_BUFFER); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + if (((switch_status[4] & (uint32_t)SDMMC_BLOCK_SWITCH_FUNC_GRP1_STATUS_BITMASK) >> + (uint32_t)SDMMC_BLOCK_SWITCH_FUNC_GRP1_STATUS_BITPOS) != (uint32_t)1U) + { + status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + } + } + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Change speed mode (high speed) in the host controller */ + XMC_SDMMC_EnableHighSpeed(obj->sdmmc_sd->sdmmc); + } + } + } + + return status; +} + +#endif + +/* Provides delay in command execution */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCommandDelay(SDMMC_BLOCK_t *const obj, uint32_t delay) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + uint32_t timeoutTime; + obj->sdmmc_sd->tmr_expire = (bool)1U; + + timeoutTime = TimerGet() + (delay / 1000u) + 1u; + + do + { +#if (SDMMC_BLOCK_POLLING_MODE > 0U) + /* Poll for interrupt events. */ + SDMMC0_0_IRQHandler(); +#endif + + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } while ((!((obj->sdmmc_sd->isr_context.cmd_flag == 1U) || + (obj->sdmmc_sd->isr_context.data_flag == 1U))) && + ((XMC_SDMMC_GetEvent(obj->sdmmc_sd->sdmmc, XMC_SDMMC_CARD_ERR) != 0U))); + + obj->sdmmc_sd->isr_context.cmd_flag = (uint8_t)0U; + obj->sdmmc_sd->isr_context.data_flag = (uint8_t)0U; + + return status; +} + +/* Recovery task for error interrupts */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lErrorInterruptRecovery(SDMMC_BLOCK_t *const obj) +{ + XMC_SDMMC_COMMAND_t *cmd = (XMC_SDMMC_COMMAND_t *)&(SDMMC_BLOCK_COMMON_COMMAND(12)); + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_NONRECOVERABLE_ERROR; + uint32_t normal_events = 0U; + uint32_t error_events = 0U; + + error_events = ((uint32_t)XMC_SDMMC_CMD_TIMEOUT_ERR) | + ((uint32_t)XMC_SDMMC_CMD_CRC_ERR) | + ((uint32_t)XMC_SDMMC_CMD_END_BIT_ERR) | + ((uint32_t)XMC_SDMMC_CMD_IND_ERR) | + ((uint32_t)XMC_SDMMC_DATA_TIMEOUT_ERR) | + ((uint32_t)XMC_SDMMC_DATA_CRC_ERR) | + ((uint32_t)XMC_SDMMC_DATA_END_BIT_ERR) | + ((uint32_t)XMC_SDMMC_CURRENT_LIMIT_ERR) | + ((uint32_t)XMC_SDMMC_TARGET_RESP_ERR); + + /* Disable all error events */ + XMC_SDMMC_DisableEvent(obj->sdmmc_sd->sdmmc, error_events); + + /* Check error interrupt status bits D0-D3 for CMD line errors */ + if ((((uint32_t)obj->sdmmc_sd->isr_context.int_status_shadow & + (uint32_t)SDMMC_BLOCK_ERROR_CMD_STATUS_BITMASK) != (uint32_t)0U) || + (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc) == true)) + { + /* Set software reset for CMD line */ + status = SDMMC_BLOCK_SD_lReset(obj, (uint32_t)XMC_SDMMC_SW_RST_CMD_LINE); + } + + /* Check error interrupt status bits D4-D6 for data line errors */ + if ((((uint32_t)obj->sdmmc_sd->isr_context.int_status_shadow & + (uint32_t)SDMMC_BLOCK_ERROR_DATA_STATUS_BITMASK) != (uint32_t)0U) || + (XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc) == true)) + { + /* Set software reset for data line */ + status = SDMMC_BLOCK_SD_lReset(obj, (uint32_t)XMC_SDMMC_SW_RST_DAT_LINE); + } + + error_events = ((uint32_t)XMC_SDMMC_CMD_TIMEOUT_ERR) | + ((uint32_t)XMC_SDMMC_CMD_CRC_ERR) | + ((uint32_t)XMC_SDMMC_CMD_END_BIT_ERR) | + ((uint32_t)XMC_SDMMC_CMD_IND_ERR) | + ((uint32_t)XMC_SDMMC_DATA_TIMEOUT_ERR) | + ((uint32_t)XMC_SDMMC_DATA_CRC_ERR) | + ((uint32_t)XMC_SDMMC_DATA_END_BIT_ERR) | + ((uint32_t)XMC_SDMMC_CURRENT_LIMIT_ERR) | + ((uint32_t)XMC_SDMMC_CARD_ERR); + + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, error_events); + + if (obj->sdmmc_sd->issue_abort == (uint8_t)1U) + { + /* Issue abort command. Set argument register */ + (void)XMC_SDMMC_SendCommand(obj->sdmmc_sd->sdmmc, cmd, SDMMC_BLOCK_ARGUMENT0); + + /* Wait for any interrupt status bit to be set */ + + /* Timeout of 5ms */ + status = SDMMC_BLOCK_SD_lCommandDelay(obj, (uint32_t)SDMMC_BLOCK_DELAY_IN_COMMAND); + if ((SDMMC_BLOCK_MODE_STATUS_t)status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* If error status bit is set in the status register */ + if (XMC_SDMMC_IsAnyErrorEvent(obj->sdmmc_sd->sdmmc) == true) + { + status = SDMMC_BLOCK_MODE_STATUS_NONRECOVERABLE_ERROR; + + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, normal_events); + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, error_events); + + /* Set software reset for CMD line and data line */ + (void)SDMMC_BLOCK_SD_lReset(obj, (uint32_t)((uint32_t)XMC_SDMMC_SW_RST_CMD_LINE | + (uint32_t)XMC_SDMMC_SW_RST_DAT_LINE)); + } + } + + /* Check Data lines status in present status register */ + if (XMC_SDMMC_IsAnyErrorEvent(obj->sdmmc_sd->sdmmc) == false) + { + if (XMC_SDMMC_IsAllDataLinesHigh(obj->sdmmc_sd->sdmmc) == true) + { + status = SDMMC_BLOCK_MODE_STATUS_RECOVERABLE_ERROR; + } + else + { + status = SDMMC_BLOCK_MODE_STATUS_NONRECOVERABLE_ERROR; + } + } + } + else + { + if (XMC_SDMMC_IsAnyErrorEvent(obj->sdmmc_sd->sdmmc) == false) + { + if (XMC_SDMMC_IsAllDataLinesHigh(obj->sdmmc_sd->sdmmc) == true) + { + status = SDMMC_BLOCK_MODE_STATUS_RECOVERABLE_ERROR; + } + else + { + status = SDMMC_BLOCK_MODE_STATUS_NONRECOVERABLE_ERROR; + } + } + } + + /* Enable the error interrupt signal */ + error_events |= (uint32_t)XMC_SDMMC_TARGET_RESP_ERR; + XMC_SDMMC_EnableEvent(obj->sdmmc_sd->sdmmc, error_events); + + /* Global error recovery variable */ + obj->sdmmc_sd->err_recovery_stat = status; + + return status; +} + +/* Handles interrupts in normal interrupt status register */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_NormalInterruptHandler(SDMMC_BLOCK_t *const obj, uint16_t int_status) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + +#if SDMMC_BLOCK_SD_CARD_DETECTION_SUPPORT + bool pstate; + + /* Card removal interrupt */ + if ((int_status & (uint32_t)XMC_SDMMC_CARD_REMOVAL) != 0U) + { + obj->sdmmc_sd->card_detect_state |= ((uint32_t)1U << SDMMC_BLOCK_SD_INTERRUPT_CARD_REMOVAL); + /* Clear the interrupt status bit */ + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CARD_REMOVAL); + } + + /* Card insertion interrupt */ + if ((int_status & (uint32_t)XMC_SDMMC_CARD_INS) != 0U) + { + obj->sdmmc_sd->card_detect_state |= ((uint32_t)1U << SDMMC_BLOCK_SD_INTERRUPT_CARD_INSERTION); + /* Clear the interrupt status bit */ + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CARD_INS); + } + + /* Invoke a callback function if a user has registered one */ + if ((obj->sdmmc_sd->callback != NULL) && (obj->sdmmc_sd->card_detect_state != 0U)) + { + obj->sdmmc_sd->card_detect_state = 0U; + pstate = (bool)(SDMMC_BLOCK_0.sdmmc_sd->sdmmc->PRESENT_STATE & SDMMC_PRESENT_STATE_CARD_INSERTED_Msk); + obj->sdmmc_sd->callback((SDMMC_BLOCK_SD_INTERRUPT_t)pstate); + } + else + { + status = SDMMC_BLOCK_MODE_STATUS_NULL_POINTER; + } +#endif + + /* Buffer read ready interrupt */ + if (((uint32_t)int_status & (uint32_t)XMC_SDMMC_BUFFER_READ_READY) != (uint32_t)0) + { + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_BUFFER_READY; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_BUFFER_READ_READY); + obj->sdmmc_sd->isr_context.data_flag = (uint8_t)1U; + } + + /* Buffer write ready interrupt */ + if (((uint32_t)int_status & (uint32_t)XMC_SDMMC_BUFFER_WRITE_READY) != (uint32_t)0) + { + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_BUFFER_READY; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_BUFFER_WRITE_READY); + obj->sdmmc_sd->isr_context.data_flag = (uint8_t)1U; + } + + /* Transfer complete interrupt */ + if (((uint32_t)int_status & (uint32_t)XMC_SDMMC_TX_COMPLETE) != (uint32_t)0) + { + obj->sdmmc_sd->transfer_int_err = SDMMC_BLOCK_MODE_STATUS_TRANSFER_COMPLETE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_TX_COMPLETE); + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_DATA_ACTIVE; + obj->sdmmc_sd->isr_context.transfer_flag = (uint8_t)1U; + } + + /* Command complete interrupt */ + if (((uint32_t)int_status & (uint32_t)XMC_SDMMC_CMD_COMPLETE) != (uint32_t)0) + { + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_COMMAND_COMPLETE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CMD_COMPLETE); + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE; + obj->sdmmc_sd->isr_context.cmd_flag = (uint8_t)1; + } + + return status; +} + +/* Handles interrupt in error interrupt status register */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_ErrorInterruptHandler(SDMMC_BLOCK_t *const obj, + uint16_t int_status) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->isr_context.int_status_shadow = int_status; + + /* Command timeout error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_CMD_TIMEOUT_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_COMMAND_TIMEOUT_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CMD_TIMEOUT_ERR); + obj->sdmmc_sd->isr_context.cmd_flag = 1U; + } + + /* Command CRC error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_CMD_CRC_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_COMMAND_CRC_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CMD_CRC_ERR); + obj->sdmmc_sd->isr_context.cmd_flag = 1U; + } + + /* Command end bit error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_CMD_END_BIT_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_COMMAND_ENDBIT_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CMD_END_BIT_ERR); + obj->sdmmc_sd->isr_context.cmd_flag = 1U; + } + + /* Command index error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_CMD_IND_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_COMMAND_INDEX_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_CMD_IND_ERR); + obj->sdmmc_sd->isr_context.cmd_flag = 1U; + } + + /* Data timeout error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_DATA_TIMEOUT_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_DATA_TIMEOUT_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_DATA_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_DATA_TIMEOUT_ERR); + obj->sdmmc_sd->isr_context.data_flag = 1U; + } + + /* Data CRC error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_DATA_CRC_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_DATA_CRC_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_DATA_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_DATA_CRC_ERR); + obj->sdmmc_sd->isr_context.data_flag = 1U; + } + + /* Data end bit error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_DATA_END_BIT_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_DATA_ENDBIT_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_DATA_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_DATA_END_BIT_ERR); + obj->sdmmc_sd->isr_context.data_flag = 1U; + } + + /* ACMD12 error interrupt */ + if (((uint32_t)int_status & ((uint32_t)XMC_SDMMC_ACMD_ERR >> 16U)) != (uint32_t)0) + { + obj->sdmmc_sd->acmd_int_err = SDMMC_BLOCK_MODE_STATUS_ACMD12_ERROR; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_CMD_ACTIVE; + obj->card_state &= (uint8_t)~(uint8_t)SDMMC_BLOCK_CARD_STATE_DATA_ACTIVE; + XMC_SDMMC_ClearEvent(obj->sdmmc_sd->sdmmc, (uint32_t)XMC_SDMMC_ACMD_ERR); + obj->sdmmc_sd->isr_context.cmd_flag = 1U; + } + + return status; +} + +/* Switch the card state to transferring state if it isn't */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lSwitchToTransferState(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t arg = 0UL; + uint32_t card_status = 0U; + + /* Check the current state of the card */ + arg |= (uint32_t)((uint32_t)obj->sdmmc_sd->card_info.rca << (uint32_t)SDMMC_BLOCK_ARG_RCA_BITPOS); + + /* Send CMD13 to read card status */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(13)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Check if it is in transferring state */ + if (((card_status & SDMMC_BLOCK_SD_CSR_CURRENT_STATE_BITMASK) >> SDMMC_BLOCK_SD_CSR_CURRENT_STATE_BITPOS) == + SDMMC_BLOCK_SD_CSR_CURRENT_STATE_TRANS_VALUE) + { + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } + else + { + /* Switch to transfer state (CMD7) */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(7)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R1b, + &card_status); + } + } + + return status; +} + +/* Do data transfer to OR from card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lDataTransfer(SDMMC_BLOCK_t *const obj, + uint32_t *buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_t transfer_mode, + uint32_t quad_bytes) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t timeoutTime; + uint32_t count = 0U; + + /* Block on buffer read/write ready interrupt */ + timeoutTime = TimerGet() + (SDMMC_BLOCK_RESET_IN_DATA_TRANSFER / 1000u) + 1u; + + do + { +#if (SDMMC_BLOCK_POLLING_MODE > 0U) + /* Poll for interrupt events. */ + SDMMC0_0_IRQHandler(); +#endif + + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } while (obj->sdmmc_sd->isr_context.data_flag == 0U); + + obj->sdmmc_sd->isr_context.data_flag = (uint8_t)0U; + + /* Check if buffer is ready */ + if (obj->sdmmc_sd->data_int_err == SDMMC_BLOCK_MODE_STATUS_BUFFER_READY) + { + /* 4 bytes data transmission in each iteration */ + for (count = 0U; count < quad_bytes; count++) + { + if (transfer_mode == SDMMC_BLOCK_SD_DATA_TRANSFER_READ_BUFFER) + { + *buf = (uint32_t)XMC_SDMMC_ReadFIFO(obj->sdmmc_sd->sdmmc); + } + + if (transfer_mode == SDMMC_BLOCK_SD_DATA_TRANSFER_WRITE_BUFFER) + { + XMC_SDMMC_WriteFIFO(obj->sdmmc_sd->sdmmc, buf); + } + + buf++; + } + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + } + else + { + obj->sdmmc_sd->issue_abort = (uint8_t)1U; + status = SDMMC_BLOCK_SD_lErrorInterruptRecovery(obj); + } + + return status; +} + +/* Performs the ACMD error recovery */ +static void SDMMC_BLOCK_SD_lAcmdErrorRecovery(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + uint32_t pcmd_flag = 0U; + uint32_t card_status = 0U; + + /* Check ACMD12 "Not executed err" in Auto CMD12 error status register */ + if (XMC_SDMMC_GetACMDErrStatus(obj->sdmmc_sd->sdmmc, XMC_SDMMC_ACMD12_NOT_EXEC_ERR) == true) + { + pcmd_flag = 1U; + /* Check Return Status of Recovery function of CMD_wo_DAT command */ + if (obj->sdmmc_sd->err_recovery_stat == SDMMC_BLOCK_MODE_STATUS_RECOVERABLE_ERROR) + { + /* For recoverable error, issue CMD12 */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(12)), + SDMMC_BLOCK_ARGUMENT0, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + } + if ((status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) && (status != SDMMC_BLOCK_MODE_STATUS_NONRECOVERABLE_ERROR)) + { + /* Set software reset for data line */ + status = SDMMC_BLOCK_SD_lReset(obj, (uint32_t)XMC_SDMMC_SW_RST_DAT_LINE); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Check for XMC_SDMMC_CMD_NOT_ISSUED_BY_ACMD12_ERR */ + if (XMC_SDMMC_GetACMDErrStatus(obj->sdmmc_sd->sdmmc, XMC_SDMMC_CMD_NOT_ISSUED_BY_ACMD12_ERR) == true) + { + XMC_DEBUG("SDMMC_BLOCK_ACMDErrorRecovery: SDMMC_BLOCK_ACMD_CMD_wo_DAT_NOT_ISSUED"); + } + else + { + /* + * Check pcmd_flag. If 1, an error occurred in CMD_wo_DAT, + * and also in the SD memory transfer + */ + if (pcmd_flag == 1U) + { + XMC_DEBUG("SDMMC_BLOCK_CheckPCMDFlag: ACMD both error"); + } + else + { + XMC_DEBUG("SDMMC_BLOCK_CheckPCMDFlag: ACMD SD transfer error"); + } + } + } + } + } + else + { + /* Set software reset for CMD line */ + status = SDMMC_BLOCK_SD_lReset(obj, (uint32_t)XMC_SDMMC_SW_RST_CMD_LINE); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Issue CMD12 */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(12)), + SDMMC_BLOCK_ARGUMENT0, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + if (status != SDMMC_BLOCK_MODE_STATUS_NONRECOVERABLE_ERROR) + { + /*Set Software Reset for Data line*/ + status = SDMMC_BLOCK_SD_lReset(obj, (uint32_t)XMC_SDMMC_SW_RST_DAT_LINE); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Check XMC_SDMMC_CMD_NOT_ISSUED_BY_ACMD12_ERR */ + if (XMC_SDMMC_GetACMDErrStatus(obj->sdmmc_sd->sdmmc, XMC_SDMMC_CMD_NOT_ISSUED_BY_ACMD12_ERR) == true) + { + XMC_DEBUG("SDMMC_BLOCK_ACMDErrorRecovery: SDMMC_BLOCK_ACMD_CMD_wo_DAT_NOT_ISSUED"); + } + else + { + /* + * Check PCMD flag. If 1, an error occurred in CMD_wo_DAT, + * and also in the SD memory transfer + */ + if (pcmd_flag == 1U) + { + XMC_DEBUG("SDMMC_BLOCK_CheckPCMDFlag: ACMD both error"); + } + else + { + XMC_DEBUG("SDMMC_BLOCK_CheckPCMDFlag: ACMD SD transfer error"); + } + } + } + } + } + } +} + +/* Delay function */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lDelay(SDMMC_BLOCK_t *const obj, uint32_t delay) +{ + uint32_t timeoutTime; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_CREATE_TIMER_FAILED; + + /* Set timeout time. */ + timeoutTime = TimerGet() + (delay / 1000u) + 1u; + + /* Wait for the timer to expire. */ + while (TimerGet() < timeoutTime) + { + /* Service the watchdog. */ + CopService(); + } + + /* Update the status. */ + status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + + /* Return the status. */ + return status; +} + +/* + * Perform host controller initialization and card initialization. + * Also, reading card registers + */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_CardIdentificationProcess(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t timeoutTime; + + /* Wait until the internal clock is stable */ + timeoutTime = TimerGet() + (SDMMC_BLOCK_CLOCK_STABLE_DELAY / 1000u) + 1u; + + do + { + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } while ((XMC_SDMMC_GetClockStability(obj->sdmmc_sd->sdmmc) == false)); + + if (status != SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED) + { + /* Enable the SD clock */ + XMC_SDMMC_SDClockEnable(obj->sdmmc_sd->sdmmc); + + /* Turn the bus power on */ + XMC_SDMMC_BusPowerOn(obj->sdmmc_sd->sdmmc); + + if (obj->sdmmc_sd->mode_init_flag == false) + { + status = SDMMC_BLOCK_SD_lInitializeCard(obj); + if ((status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) || + (status == SDMMC_BLOCK_MODE_STATUS_INITIALIZED_BUT_LOCKED)) + { + status = SDMMC_BLOCK_SD_lAfterCardInitialize(obj); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + obj->sdmmc_sd->mode_init_flag = 1U; + } + } + } + } + + return status; +} + +/* Check if the sector address is out of bound */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCheckSectorBound(SDMMC_BLOCK_t *const obj, + uint32_t sector_num, + uint32_t sector_count) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + uint32_t local_sector_count = 0U; + + /* Get sector count function */ + status = SDMMC_BLOCK_SD_GetSectorCount(obj, (void *)&local_sector_count); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Check the sector count limit */ + if ((sector_num + sector_count) > local_sector_count) + { + status = SDMMC_BLOCK_MODE_STATUS_SECTOR_OUT_OF_BOUND; + } + } + + return status; +} + +/* Perform erase operation */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lLocalErase(SDMMC_BLOCK_t *const obj, + uint32_t start_addr, + uint32_t end_addr, + uint32_t timeout) +{ + /* Stores the response received */ + uint32_t card_status = 0U; + uint32_t timeoutTime; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + if (((uint32_t)obj->card_type & (uint32_t)SDMMC_BLOCK_CARD_TYPE_BLOCK_ADDRESSING) == (uint32_t)0U) + { + start_addr *= (uint32_t)512U; + end_addr *= (uint32_t)512U; + } + + /* SD erase start command */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(32)), + start_addr, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* SD Erase End Command */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(33)), + end_addr, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + } + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(38)), + SDMMC_BLOCK_ARGUMENT0, + XMC_SDMMC_RESPONSE_TYPE_R1b, + &card_status); + + timeoutTime = TimerGet() + ((timeout * (uint32_t)1000U)) + 1u; + + do + { + if (TimerGet() > timeoutTime) + { + status = SDMMC_BLOCK_MODE_STATUS_TIMEOUT_OCCURED; + break; + } + /* Service the watchdog. */ + CopService(); + } while ((XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc) || + (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc)))); + + } + + return status; +} + +/* + * PUBLIC FUNCTIONS + */ + +/* Initialize host controller */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lHostControllerInit(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_HOST_CONTROLLER_INITIALIZED; + + /* Check if host controller is initialized */ + if (((uint32_t)obj->card_state & (uint32_t)SDMMC_BLOCK_CARD_STATE_HC_INITIALIZED) == (uint32_t)0U) + { + /* Reset the registers to default values */ + status = SDMMC_BLOCK_SD_lReset(obj, (uint32_t)XMC_SDMMC_SW_RESET_ALL); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* + * The internal clock should be disabled before + * updating frequency clock select (Please see + * section 2.2.14 -> Clock Control Register) + */ + XMC_SDMMC_Stop(obj->sdmmc_sd->sdmmc); + + /* Select SD clock frequency */ + XMC_SDMMC_SDClockFreqSelect(obj->sdmmc_sd->sdmmc, XMC_SDMMC_CLK_DIV_2); + + /* Internal clock enable */ + XMC_SDMMC_Start(obj->sdmmc_sd->sdmmc); + + /* + * Enable all normal interrupt status bits except block-gap + * event, card interrupt event, DMA int., ADMA and auto cmd + * errors. Enable the status and the events themselves. + */ + obj->sdmmc_sd->sdmmc->EN_INT_STATUS_NORM = SDMMC_BLOCK_NORMAL_INT_STATUS_ENABLE; + obj->sdmmc_sd->sdmmc->EN_INT_STATUS_ERR = SDMMC_BLOCK_ERROR_INT_STATUS_ENABLE; + obj->sdmmc_sd->sdmmc->EN_INT_SIGNAL_NORM = SDMMC_BLOCK_NORMAL_INT_SIGNAL_ENABLE; + obj->sdmmc_sd->sdmmc->EN_INT_SIGNAL_ERR = SDMMC_BLOCK_ERROR_INT_SIGNAL_ENABLE; + +#if SDMMC_BLOCK_SD_CARD_DETECTION_SUPPORT + XMC_SDMMC_EnableEvent(obj->sdmmc_sd->sdmmc, ((uint32_t)XMC_SDMMC_CARD_REMOVAL) | + ((uint32_t)XMC_SDMMC_CARD_INS) | + ((uint32_t)XMC_SDMMC_CARD_INT)); +#endif + + /* Set data-line timeout */ + XMC_SDMMC_SetDataLineTimeout(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DAT_TIMEOUT_COUNTER_2_POW_27); + + /* Set bus voltage in the power control register: flattop 3.3 volts */ + XMC_SDMMC_SetBusVoltage(obj->sdmmc_sd->sdmmc, XMC_SDMMC_BUS_VOLTAGE_3_3_VOLTS); + + /* Update the state status to card initialized */ + obj->card_state |= (uint8_t)((uint8_t)SDMMC_BLOCK_CARD_STATE_HC_INITIALIZED | + (uint8_t)SDMMC_BLOCK_CARD_STATE_NO_CARD | + (uint8_t)SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED); + + /* A stub of delay for initialization */ + for (volatile uint32_t i = 0; (uint32_t)i < (uint32_t)100000U; i++) + { + } + } + } + + return status; +} + +/* De-initialize the host controller */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lHostControllerDeInit(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* Check if the host controller is initialized */ + if (((uint32_t)obj->card_state & (uint32_t)SDMMC_BLOCK_CARD_STATE_HC_INITIALIZED) != (uint32_t)0U) + { + /* Cleanup the card */ + SDMMC_BLOCK_SD_lCardCleanUp(obj); + + /* Reset host controller's registers */ + status = SDMMC_BLOCK_SD_lReset(obj, (uint32_t)XMC_SDMMC_SW_RESET_ALL); + } + + return status; +} + +/* Read multiple blocks of data from the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCardReadMultipleBlocks(SDMMC_BLOCK_t *const obj, + uint32_t *read_buf, + uint32_t read_addr, + uint32_t num_blocks) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_INIT_FAIL; + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->transfer_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* Check if initialization is successful */ + if (obj->sdmmc_sd->mode_init_flag == true) + { + /* Ensure that sector number is not out of bound */ + status = SDMMC_BLOCK_SD_lCheckSectorBound(obj, read_addr, num_blocks); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Set transfer direction select in the Transfer Mode Register */ + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_CARD_TO_HOST); + + /* Send Multiple Block Read Command i.e CMD18 */ + status = SDMMC_BLOCK_SD_lMultiBlockTransfer(obj, + &read_addr, + num_blocks, + &(SDMMC_BLOCK_COMMON_COMMAND(18)), + read_buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_READ_BUFFER); + } + } + + return status; +} + +/* Read single block of data from the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCardReadSingleBlock(SDMMC_BLOCK_t *const obj, + uint32_t *read_buf, + uint32_t read_addr) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_INIT_FAIL; + uint32_t sector_count = 1U; + + /* Check if initialization successful */ + if (obj->sdmmc_sd->mode_init_flag == true) + { + /* Ensure that the sector number is not out of bound */ + status = SDMMC_BLOCK_SD_lCheckSectorBound(obj, read_addr, sector_count); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Block addressing or byte addressing */ + if (((uint32_t)obj->card_type & (uint32_t)SDMMC_BLOCK_CARD_TYPE_BLOCK_ADDRESSING) == (uint32_t)0UL) + { + read_addr = (uint32_t)(read_addr * 512UL); + } + + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_CARD_TO_HOST); + /* SDMMC->TRANSFER_MODE |= (uint16_t)((uint32_t)1U << (uint32_t)SDMMC_TRANSFER_MODE_TX_DIR_SELECT_Pos); */ + + /* Perform the Single block transfer operation */ + status = SDMMC_BLOCK_SD_lSingleBlockTransfer(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(17)), + read_addr, + (uint16_t)SDMMC_BLOCK_BLOCK_SIZE, + read_buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_READ_BUFFER); + } + } + + return status; +} + +/* Write multiple blocks of data on the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCardWriteMultipleBlocks(SDMMC_BLOCK_t *const obj, + const uint32_t *write_buf, + uint32_t write_addr, + uint32_t num_blocks) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_INIT_FAIL; + + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->transfer_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* Check if initialization is successful */ + if (obj->sdmmc_sd->mode_init_flag == true) + { + /* Ensure sector number is not out of bound */ + status = SDMMC_BLOCK_SD_lCheckSectorBound(obj, write_addr, num_blocks); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Clear transfer direction select in transfer mode register */ + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_HOST_TO_CARD); + + /* Send Multiple Block Write Command i.e CMD25 */ + status = SDMMC_BLOCK_SD_lMultiBlockTransfer(obj, + &write_addr, + num_blocks, + &(SDMMC_BLOCK_COMMON_COMMAND(25)), + (uint32_t *)write_buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_WRITE_BUFFER); + } + } + + return status; +} + +/* Write single block of data on the card */ +static SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_lCardWriteSingleBlock(SDMMC_BLOCK_t *const obj, + const uint32_t *write_buf, + uint32_t write_addr) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_INIT_FAIL; + uint32_t sector_count = 1U; + + /* Check if initialization is successful */ + if (obj->sdmmc_sd->mode_init_flag == true) + { + /* Check if sector number is not out of bound */ + status = SDMMC_BLOCK_SD_lCheckSectorBound(obj, write_addr, sector_count); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* If not block addressing, then multiply by 512 bytes */ + if (((uint32_t)obj->card_type & (uint32_t)SDMMC_BLOCK_CARD_TYPE_BLOCK_ADDRESSING) == (uint32_t)0U) + { + write_addr = (uint32_t)(write_addr * 512U); + } + + /* Clear transfer direction select bit */ + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_HOST_TO_CARD); + + /* Single block transfer function */ + status = SDMMC_BLOCK_SD_lSingleBlockTransfer(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(24)), + write_addr, + (uint16_t)SDMMC_BLOCK_BLOCK_SIZE, + (uint32_t *)write_buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_WRITE_BUFFER); + } + } + + return status; +} + +/* Erase data from the card */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_EraseBlock(SDMMC_BLOCK_t *const obj, uint32_t start_addr, uint32_t end_addr) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_INIT_FAIL; + uint32_t tmp_start_addr; + uint32_t num_sectors = 0U; + /* Allocation unit to no. of sectors in 1 AU table mapping */ + uint32_t au_to_sectors[10] = {0U, 32U, 64U, 128U, 256U, 512U, 1024U, 2048U, 4096U, 8192U}; + uint16_t erase_size = (uint16_t)0U; + uint8_t erase_offset = (uint8_t)0U; + uint8_t erase_timeout = (uint8_t)0U; + uint8_t au_size = (uint8_t)0U; + uint32_t sectors_in_au = 0U; + uint32_t sectors_in_erase_cluster = 0U; + /* Read SD status */ + uint32_t sd_status[16] = {0U}; + uint32_t erase_timeout_per_cluster = 0UL; + + obj->sdmmc_sd->cmd_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->data_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + obj->sdmmc_sd->transfer_int_err = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* If the card is read only or write protected */ + if ((obj->card_state & (uint8_t)SDMMC_BLOCK_CARD_STATE_WRITE_PROTECTED) != (uint8_t)0U) + { + status = SDMMC_BLOCK_MODE_STATUS_WP_VIOLATION_ERROR; + } +#ifdef SDMMC_BLOCK_CARD_WRITE_PROTECT_SIGNAL + else if ((obj->sdwc != NULL) && (XMC_GPIO_GetInput(obj->sdwc->port, obj->sdwc->pin))) + { + status = SDMMC_BLOCK_MODE_STATUS_WP_VIOLATION_ERROR; + } +#endif /* SDMMC_BLOCK_CARD_WRITE_PROTECT_SIGNAL */ + /* Assume initialization is successful: This is invoked from IOCTL */ + else + { + tmp_start_addr = start_addr; + num_sectors = (end_addr - tmp_start_addr) + 1U; + /* Check sector number is not out of bound */ + status = SDMMC_BLOCK_SD_lCheckSectorBound(obj, tmp_start_addr, num_sectors); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Erase timeout calculation */ + /* Get SD status */ + status = SDMMC_BLOCK_SD_GetSdStatus(obj, (void*)&(sd_status[0])); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Bits 400-401 in SD status: Erase offset */ + erase_offset = (uint8_t)(((sd_status[3] & 0x00000300UL)) >> 8U); + + /* Bits 402-407: Erase timeout */ + erase_timeout = (uint8_t)(((sd_status[3] & 0x0000FC00UL)) >> 10UL); + + /* Bits 408-423: Erase size */ + erase_size = (uint16_t)((((sd_status[2] & 0xFF000000U) >> 24U) << 8U) | (sd_status[3] & 0x000000FFU)); + + /* Bits 428-431: Allocation unit size */ + au_size = (uint8_t)((sd_status[2] & 0x00F00000U) >> 20); + + /* Erase timeout calculations */ + erase_timeout_per_cluster = ((uint32_t)erase_timeout / (uint32_t)erase_size) + (uint32_t)erase_offset; + + /* Number of sectors in 1 AU */ + sectors_in_au = au_to_sectors[au_size]; + sectors_in_erase_cluster = sectors_in_au * erase_size; + + while (num_sectors >= sectors_in_erase_cluster) + { + status = SDMMC_BLOCK_SD_lLocalErase(obj, + tmp_start_addr, + (tmp_start_addr + sectors_in_erase_cluster), + erase_timeout_per_cluster); + if (status != SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + break; + } + tmp_start_addr = tmp_start_addr + sectors_in_erase_cluster; + num_sectors = num_sectors - sectors_in_erase_cluster; + } + + if (num_sectors != 0U) + { + status = SDMMC_BLOCK_SD_lLocalErase(obj, tmp_start_addr, end_addr, erase_timeout_per_cluster); + } + } + } + } + + /* Wait for until the command OR data lines aren't busy */ + while ((XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc)) || (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc))) + { + } + + return status; +} + +/* Set, clear password, lock/unlock card */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_LockUnlockCard(SDMMC_BLOCK_t *const obj, + SDMMC_BLOCK_LOCK_STRUCTURE_t *lock, + SDMMC_BLOCK_CARD_LOCK_STATUS_t operation_mode) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t data_length = 0U; + uint32_t card_status; + + /* Select the card before proceeding */ + status = SDMMC_BLOCK_SD_lSwitchToTransferState(obj); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Send CMD42 and write the lock data structure */ + /* Clear transfer direction select in transfer mode register */ + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_HOST_TO_CARD); + + /* Compute password length */ + data_length = (uint32_t)((((uint32_t)lock->pwd_len + (uint32_t)1U) >> 1U) << 1U) + 2U; + + /* Set block length */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(16)), + data_length, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + status = SDMMC_BLOCK_SD_lSingleBlockTransfer(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(42)), + (uint32_t)SDMMC_BLOCK_ARGUMENT0, + (uint16_t)data_length, + (uint32_t *)lock, + SDMMC_BLOCK_SD_DATA_TRANSFER_WRITE_BUFFER); + + while (XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc)) + { + } + + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(16)), + 512U, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + /* Wait for until the command OR data lines aren't busy */ + while ((XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc)) || + (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc))) + { + } + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + status = SDMMC_BLOCK_SD_lCheckLockStatus(obj, operation_mode); + } + } + } + return status; +} + +/* Get the lock status from card */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetLockStatus(SDMMC_BLOCK_t *const obj, + SDMMC_BLOCK_CARD_LOCK_STATUS_t *lock_status) +{ + uint32_t card_status = 0UL; + uint32_t arg = 0UL; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + arg |= ((uint32_t)obj->sdmmc_sd->card_info.rca << SDMMC_BLOCK_ARG_RCA_BITPOS); + + /* Send CMD13 to read card status */ + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(13)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Lock/unlock status bit in the CSR register */ + if (((uint32_t)card_status & (uint32_t)SDMMC_BLOCK_SD_CSR_CARD_IS_LOCKED_BITMASK) != (uint32_t)0) + { + *lock_status = SDMMC_BLOCK_CARD_LOCK_STATUS_LOCKED; + obj->card_state |= (uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED; + } + else + { + *lock_status = SDMMC_BLOCK_CARD_LOCK_STATUS_UNLOCKED; + obj->card_state &= (uint8_t)~(uint8_t)(SDMMC_BLOCK_CARD_STATE_LOCKED); + } + } + + return status; +} + +/* Get card's current state */ +uint8_t SDMMC_BLOCK_SD_GetState(SDMMC_BLOCK_t *obj) +{ + return (obj->card_state & 0xFU); +} + +/* Get card type */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetCardType(SDMMC_BLOCK_t *const obj, uint32_t *card_type) +{ + *card_type = obj->card_type; + + return SDMMC_BLOCK_MODE_STATUS_SUCCESS; +} + +/* Get CID register information of card */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetCid(SDMMC_BLOCK_t *const obj, void *buf) +{ + SDMMC_BLOCK_CID_t *temp = (SDMMC_BLOCK_CID_t *)buf; + + temp->manufacturing_date = (uint16_t)((obj->sdmmc_sd->card_info.cid[0]) & 0xFFFU); + temp->product_serial_num = (obj->sdmmc_sd->card_info.cid[1] << 16U) | (obj->sdmmc_sd->card_info.cid[0] >> 16U); + temp->product_rev = (uint8_t)((obj->sdmmc_sd->card_info.cid[1] >> 16U) & 0xFFU); + temp->product_name[0] = (uint8_t)((obj->sdmmc_sd->card_info.cid[2] >> 24U) & 0xFFU); + temp->product_name[1] = (uint8_t)((obj->sdmmc_sd->card_info.cid[2] >> 16U) & 0xFFU); + temp->product_name[2] = (uint8_t)((obj->sdmmc_sd->card_info.cid[2] >> 8U) & 0xFFU); + temp->product_name[3] = (uint8_t)((obj->sdmmc_sd->card_info.cid[2] >> 0U) & 0xFFU); + temp->product_name[4] = (uint8_t)((obj->sdmmc_sd->card_info.cid[1] >> 24U) & 0xFFU); + temp->app_oem_id[0] = (uint8_t)((obj->sdmmc_sd->card_info.cid[3] >> 8U) & 0xFFU); + temp->app_oem_id[1] = (uint8_t)((obj->sdmmc_sd->card_info.cid[3]) & 0xFFU); + temp->manufacturer_id = (uint8_t)((obj->sdmmc_sd->card_info.cid[3] >> 16U) & 0xFFU); + + return SDMMC_BLOCK_MODE_STATUS_SUCCESS; +} + +/* Get OCR information */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetOcr(SDMMC_BLOCK_t *const obj, void *buf) +{ + *(uint32_t *)buf = obj->sdmmc_sd->card_info.ocr; + + return SDMMC_BLOCK_MODE_STATUS_SUCCESS; +} + +/* Get CSD information */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetCsd(SDMMC_BLOCK_t *const obj, void *buf) +{ + /* + * CSD Structure includes 7-bit CRC and 1-bit fixed bit + * which is not sent by the card. So, skip 1 byte before + * copying into the structure. + */ + memcpy(((uint8_t *)buf + 1U), (void *)obj->sdmmc_sd->card_info.csd, 15U); + + return SDMMC_BLOCK_MODE_STATUS_SUCCESS; +} + +/* Get number of sectors present on the card */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetSectorCount(SDMMC_BLOCK_t *const obj, void *buf) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + uint32_t mult = 0U; + + if (((uint32_t)obj->card_type & (uint32_t)SDMMC_BLOCK_CARD_TYPE_HIGH_CAPACITY) != (uint32_t)0U) + { + SDMMC_BLOCK_SDV2_CSD_t temp_csd_v2 = {0U}; + + /* Get CSD function */ + status = SDMMC_BLOCK_SD_GetCsd(obj, (void *)&temp_csd_v2); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* + * For High Capacity SD card, (C_SIZE field value + 1) * 1024 + * gives the sector count + */ + *(uint32_t *)buf = (uint32_t)(((((uint32_t)temp_csd_v2.dev_size_high << (uint32_t)16UL) | + ((uint32_t)temp_csd_v2.dev_size_low)) + (uint32_t)1UL) << (uint32_t)10UL); + } + } + /* + * For Standard SD (and MMC) cards: + * Sector Count = (Device Size + 1) * Mult, where Mult = 2 ^ C_SIZE_MULT + */ + else + { + SDMMC_BLOCK_SDV1_CSD_t temp_csd_v1 = {0U}; + /* Get CSD function */ + status = SDMMC_BLOCK_SD_GetCsd(obj, (void *)&temp_csd_v1); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Left shift evaluates 1 * 2 ^ (TmpMmcCsd.DeviceSizeMult + 2) */ + mult = (uint32_t)((uint32_t)temp_csd_v1.dev_size_mult + 2U); + + /* Sector Count = device_size * mult */ + *(uint32_t *)buf = (uint32_t)((((uint32_t)temp_csd_v1.dev_size_high << (uint32_t)2UL) | + ((uint32_t)temp_csd_v1.dev_size_low)) + (uint32_t)1UL) << mult; + } + } + + return status; +} + +/* Get sector size info from the card */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetSectorSize(SDMMC_BLOCK_t *const obj, void *buf) +{ + /* Sector Size is fixed to 512 bytes */ + *(uint16_t *)buf = (uint16_t)512U; + + return SDMMC_BLOCK_MODE_STATUS_SUCCESS; +} + +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetBlockSize(SDMMC_BLOCK_t *const obj, void *buf) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_SUCCESS; + + /* SD high capacity card (CSD V2) */ + if (((uint32_t)obj->card_type & (uint32_t)SDMMC_BLOCK_CARD_TYPE_HIGH_CAPACITY) != (uint32_t)0) + { + SDMMC_BLOCK_SDV2_CSD_t temp_csd_v2 = {0U}; + /* Get CSD function */ + status = SDMMC_BLOCK_SD_GetCsd(obj, (void *)&temp_csd_v2); + *(uint32_t *)buf = (uint32_t)((uint32_t)temp_csd_v2.erase_sector_size + (uint32_t)1U); + } + /* SD standard capacity card (CSD V1) */ + else + { + SDMMC_BLOCK_SDV2_CSD_t temp_csd_v1 = {0U}; + /* Get CSD function */ + status = SDMMC_BLOCK_SD_GetCsd(obj, (void *)&temp_csd_v1); + *(uint32_t *)buf = (uint32_t)((uint32_t)temp_csd_v1.erase_sector_size + (uint32_t)1U); + } + + return status; +} + +/* Get SD status information */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_GetSdStatus(SDMMC_BLOCK_t *const obj, void *buf) +{ + uint32_t arg = 0U; + uint32_t card_status = 0U; + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + + /* Select the card (CMD7) */ + status = SDMMC_BLOCK_SD_lSwitchToTransferState(obj); + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Send CMD55 (application specific command) */ + arg |= (uint32_t)((uint32_t)obj->sdmmc_sd->card_info.rca << (uint32_t)SDMMC_BLOCK_ARG_RCA_BITPOS); + + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_COMMON_COMMAND(55)), + arg, + XMC_SDMMC_RESPONSE_TYPE_R1, + &card_status); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Set transfer mode */ + XMC_SDMMC_SetDataTransferDirection(obj->sdmmc_sd->sdmmc, XMC_SDMMC_DATA_TRANSFER_CARD_TO_HOST); + + /* Read the SD status from the data line */ + status = SDMMC_BLOCK_SD_lSingleBlockTransfer(obj, + &(SDMMC_BLOCK_SD_COMMAND(59)), + (uint32_t)SDMMC_BLOCK_ARGUMENT0, + (uint16_t)64U, + (uint32_t *)buf, + SDMMC_BLOCK_SD_DATA_TRANSFER_READ_BUFFER); + } + } + + return status; +} + +/* Eject SD card */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_EjectCard(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_FAILURE; + uint32_t arg = 0U; + + if ((obj->card_state & (uint16_t)SDMMC_BLOCK_CARD_STATE_NO_CARD) == 0U) + { + /* Send CMD15 to deactivate the card */ + arg |= (uint32_t)((uint32_t)obj->sdmmc_sd->card_info.rca << (uint32_t)SDMMC_BLOCK_ARG_RCA_BITPOS); + + status = SDMMC_BLOCK_SD_lSendCommand(obj, + &(SDMMC_BLOCK_SD_COMMAND(15)), + (uint32_t)arg, + (XMC_SDMMC_RESPONSE_TYPE_t)XMC_SDMMC_RESPONSE_TYPE_NO_RESPONSE, + NULL); + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + /* Card Cleanup */ + SDMMC_BLOCK_SD_lCardCleanUp(obj); + obj->sdmmc_sd->mode_init_flag = false; + } + } + + return status; +} + +/* + * Initialize low level drivers, host controller, the card + * and read card registers. + */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_Start(SDMMC_BLOCK_t *const obj) +{ + SDMMC_BLOCK_MODE_STATUS_t status = SDMMC_BLOCK_MODE_STATUS_HOST_CONTROLLER_INITIALIZED; + + /* Check If host controller is already initialized */ + if (((uint32_t)obj->card_state & (uint32_t)SDMMC_BLOCK_CARD_STATE_HC_INITIALIZED) == (uint32_t)0U) + { +#if (SDMMC_BLOCK_POLLING_MODE == 0U) + /* Enable Interrupt */ + NVIC_SetPriority(SDMMC0_0_IRQn, + NVIC_EncodePriority(NVIC_GetPriorityGrouping(), + obj->sdmmc_sd->int_priority, + obj->sdmmc_sd->int_sub_priority)); + + NVIC_ClearPendingIRQ(SDMMC0_0_IRQn); + NVIC_EnableIRQ(SDMMC0_0_IRQn); +#endif + + /* Host controller initialize */ + status = SDMMC_BLOCK_SD_lHostControllerInit(obj); + } + + return status; +} + +/* De-assert the SDMMC peripheral */ +SDMMC_BLOCK_MODE_STATUS_t SDMMC_BLOCK_SD_Init(SDMMC_BLOCK_t *const obj) +{ + /* Enable SDMMC peripheral */ + XMC_SDMMC_Enable(obj->sdmmc_sd->sdmmc); + + /* Enable SCU clock for SDMMC */ + XMC_SCU_CLOCK_EnableClock(XMC_SCU_CLOCK_MMC); + + /* De-initialize host controller */ + (void)SDMMC_BLOCK_SD_lHostControllerDeInit(obj); + + /* Initialize LLD and host controller */ + return SDMMC_BLOCK_SD_Start(obj); +} + +/* Reads the data from the card */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_SD_ReadBlock(SDMMC_BLOCK_t *const obj, + uint8_t *read_buf, + uint32_t sector_num, + uint8_t sector_count) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + uint8_t disk_status; + SDMMC_BLOCK_STATUS_t res; + + /* Check the status before reading data */ + disk_status = obj->card_state; + + if ((disk_status & (uint8_t)SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED) != (uint8_t)0U) + { + res = SDMMC_BLOCK_STATUS_NOTRDY; + } + else if ((disk_status & (uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED) != (uint8_t)0U) + { + res = SDMMC_BLOCK_STATUS_LOCKED; + } + else + { + /* Check for single block read or multiple block read based on sector count */ + if (sector_count == (uint8_t)1U) + { + status = SDMMC_BLOCK_SD_lCardReadSingleBlock(obj, (uint32_t *)read_buf, sector_num); + } + else + { + status = SDMMC_BLOCK_SD_lCardReadMultipleBlocks(obj, (uint32_t *)read_buf, sector_num, (uint32_t)sector_count); + } + + if (status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) + { + res = SDMMC_BLOCK_STATUS_SUCCESS; + } + else if (status == SDMMC_BLOCK_MODE_STATUS_SECTOR_OUT_OF_BOUND) + { + res = SDMMC_BLOCK_STATUS_PARERR; + } + else + { + res = SDMMC_BLOCK_STATUS_FAILURE; + } + } + + /* Wait for until the command OR data lines aren't busy */ + while ((XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc)) || (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc))) + { + } + + return res; +} + +/* Writes the data on the card */ +SDMMC_BLOCK_STATUS_t SDMMC_BLOCK_SD_WriteBlock(SDMMC_BLOCK_t *const obj, + const uint8_t *write_buf, + uint32_t sector_num, + uint8_t sector_count) +{ + SDMMC_BLOCK_MODE_STATUS_t status; + uint8_t disk_status; + SDMMC_BLOCK_STATUS_t res; + + /* Get card state */ + disk_status = obj->card_state; + + /* If the card is not initialized */ + if ((disk_status & (uint8_t)SDMMC_BLOCK_CARD_STATE_NOT_INITIALIZED) != (uint8_t)0U) + { + res = SDMMC_BLOCK_STATUS_NOTRDY; + } + else if ((disk_status & (uint8_t)SDMMC_BLOCK_CARD_STATE_LOCKED) != (uint8_t)0U) + { + res = SDMMC_BLOCK_STATUS_LOCKED; + } + /* If the card is read only or write protected */ + else if ((disk_status & (uint8_t)SDMMC_BLOCK_CARD_STATE_WRITE_PROTECTED) != (uint8_t)0U) + { + res = SDMMC_BLOCK_STATUS_WRPRT; + } +#ifdef SDMMC_BLOCK_CARD_WRITE_PROTECT_SIGNAL + else if ((obj->sdwc != NULL) && (XMC_GPIO_GetInput(obj->sdwc->port, obj->sdwc->pin))) + { + res = SDMMC_BLOCK_STATUS_WRPRT; + } +#endif /* SDMMC_BLOCK_CARD_WRITE_PROTECT_SIGNAL */ + else + { + /* Check for single block write or multiple block write */ + if (sector_count == (uint8_t)1U) + { + status = SDMMC_BLOCK_SD_lCardWriteSingleBlock(obj, (const uint32_t *)write_buf, sector_num); + } + else + { + status = SDMMC_BLOCK_SD_lCardWriteMultipleBlocks(obj, + (const uint32_t *)write_buf, + sector_num, + (uint32_t)sector_count); + } + + if ((status == SDMMC_BLOCK_MODE_STATUS_SUCCESS) || (status == SDMMC_BLOCK_MODE_STATUS_BUFFER_READY)) + { + res = SDMMC_BLOCK_STATUS_SUCCESS; + } + else if (status == SDMMC_BLOCK_MODE_STATUS_SECTOR_OUT_OF_BOUND) + { + res = SDMMC_BLOCK_STATUS_PARERR; + } + else + { + res = SDMMC_BLOCK_STATUS_FAILURE; + } + } + + /* Wait for until the command OR data lines aren't busy */ + while ((XMC_SDMMC_IsDataLineBusy(obj->sdmmc_sd->sdmmc)) || (XMC_SDMMC_IsCommandLineBusy(obj->sdmmc_sd->sdmmc))) + { + } + + return res; +} + +#endif /* SDMMC_BLOCK_SD */ + diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_private_sd.h b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_private_sd.h new file mode 100644 index 00000000..6bec7078 --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/SDMMC_BLOCK/sdmmc_block_private_sd.h @@ -0,0 +1,263 @@ +/** + * @file sdmmc_block_private_sd.h + * @date 2016-08-24 + * + * NOTE: + * This file is generated by DAVE. Any manual modification done to this file will be lost when the code is regenerated. + * + * @cond + *********************************************************************************************************************** + * SDMMC_BLOCK v4.0.22 - Configures the SD host to interface with the SDMMC card. + * + * Copyright (c) 2016-2017, Infineon Technologies AG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the + * following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * + * 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. + * + * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. + * + * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes + * with Infineon Technologies AG (dave@infineon.com). + *********************************************************************************************************************** + * + * Change History + * -------------- + * + * 2016-01-20: + * - Initial version.
+ * + * 2016-02-08: + * - Help Doc updated.
+ * - Bug fixes done.
+ * + * 2016-04-05: + * - MISRA fixes
+ * + * @endcond + * + */ + + +#ifndef SDMMC_BLOCK_SD_H +#define SDMMC_BLOCK_SD_H + +/*********************************************************************************************************************** + * HEADER FILES + **********************************************************************************************************************/ + +#include +#include "sdmmc_block.h" + +#ifdef SDMMC_BLOCK_SD + +/*********************************************************************************************************************** + * LOCAL DATA + **********************************************************************************************************************/ + +extern const XMC_SDMMC_COMMAND_t sdmmc_block_command[40]; +extern const uint8_t sdmmc_block_sd_hash_table[65]; + +/*********************************************************************************************************************** + * MACROS + **********************************************************************************************************************/ + +/** + * @brief This structure stores the command register fields. + */ +#define SDMMC_BLOCK_COMMON_COMMAND(c) sdmmc_block_command[sdmmc_block_sd_hash_table[c]] +#define SDMMC_BLOCK_SD_COMMAND(c) SDMMC_BLOCK_COMMON_COMMAND(c) + +#define SDMMC_BLOCK_ERROR_CMD_STATUS_BITMASK (0x000FU) /* Command line Int errors status bit-mask */ +#define SDMMC_BLOCK_ERROR_DATA_STATUS_BITMASK (0x0070U) /* Data line Error status bitmask */ +#define SDMMC_BLOCK_TX_BLOCK_SIZE_VALUE (0x0200U) /* Transfer block register */ +#define SDMMC_BLOCK_HC_RESPONSE1_BITPOS (0x10U) /* Response register */ +#define SDMMC_BLOCK_SWITCH_FUNC_GRP1_STATUS_BITMASK (0x0000000FU) /* Switch speed function bit-mask */ +#define SDMMC_BLOCK_SWITCH_FUNC_GRP1_STATUS_BITPOS (0x0U) /* Switch speed function bit-position */ + +/* + * Append by 3 zeros since the SYSTIMER APP takes + * time in microseconds + */ +#define SDMMC_BLOCK_CARD_POWER_DELAY (20000U) /* Card power delay */ +#define SDMMC_BLOCK_DELAY_IN_TRANSFER (1000000U) /* Transfer delay */ +#define SDMMC_BLOCK_RESET_IN_DATA_TRANSFER (1000000U) /* Reset in data transfer */ +#define SDMMC_BLOCK_DELAY_IN_COMMAND (1000000U) /* Command delay */ +#define SDMMC_BLOCK_RESET_DELAY (500000U) /* Reset delay */ +#define SDMMC_BLOCK_CLOCK_STABLE_DELAY (1000000U) /* Clock stable delay */ + +#define SDMMC_BLOCK_NUM_CARD_RESET_RETRIES (2U) /* Number of reset retries at card init */ +#define SDMMC_BLOCK_BLOCK_SIZE (512U) /* Block Size in bytes */ +#define SDMMC_BLOCK_NUM_QUADLETS_IN_BLOCK (SDMMC_BLOCK_BLOCK_SIZE >> 2U) /* Block size in quad bytes */ + +/* Command index */ +#define SDMMC_BLOCK_GO_IDLE_STATE (0x00U) /* CMD0 */ +#define SDMMC_BLOCK_MMC_SEND_OP_COND (0x01U) /* MMC CMD1 */ +#define SDMMC_BLOCK_ALL_SEND_CID (0x02U) /* CMD2 */ +#define SDMMC_BLOCK_SEND_RELATIVE_ADDR (0x03U) /* CMD3 */ +#define SDMMC_BLOCK_SET_DSR (0x04U) /* CMD4 */ +#define SDMMC_BLOCK_MMC_SLEEP_AWAKE (0x05U) /* MMC CMD5 */ +#define SDMMC_BLOCK_SWITCH_FUNC (0x06U) /* CMD6 */ +#define SDMMC_BLOCK_SELECT_DESELECT_CARD (0x07U) /* CMD7 */ +#define SDMMC_BLOCK_SD_SEND_IF_COND (0x08U) /* SD CMD8 */ +#define SDMMC_BLOCK_MMC_SEND_EXT_CSD (0x08U) /* MMC CMD8 */ +#define SDMMC_BLOCK_SEND_CSD (0x09U) /* CMD9 */ +#define SDMMC_BLOCK_SEND_CID (0x0AU) /* CMD10 */ +#define SDMMC_BLOCK_STOP_TRANSMISSION (0x0CU) /* CMD12 */ +#define SDMMC_BLOCK_SEND_STATUS (0x0DU) /* CMD13 */ +#define SDMMC_BLOCK_GO_INACTIVE_STATE (0x0FU) /* CMD15 */ +#define SDMMC_BLOCK_SET_BLOCKLEN (0x10U) /* CMD16 */ +#define SDMMC_BLOCK_READ_SINGLE_BLOCK (0x11U) /* CMD17 */ +#define SDMMC_BLOCK_READ_MULTIPLE_BLOCK (0x12U) /* CMD18 */ +#define SDMMC_BLOCK_WRITE_BLOCK (0x18U) /* CMD24 */ +#define SDMMC_BLOCK_WRITE_MULTIPLE_BLOCK (0x19U) /* CMD25 */ +#define SDMMC_BLOCK_PROGRAM_CSD (0x1BU) /* CMD27 */ +#define SDMMC_BLOCK_SET_WRITE_PROT (0x1CU) /* CMD28 */ +#define SDMMC_BLOCK_CLR_WRITE_PROT (0x1DU) /* CMD29 */ +#define SDMMC_BLOCK_SEND_WRITE_PROT (0x1EU) /* CMD30 */ +#define SDMMC_BLOCK_ERASE_WR_BLK_START (0x20U) /* CMD32 */ +#define SDMMC_BLOCK_ERASE_WR_BLK_END (0x21U) /* CMD33 */ +#define SDMMC_BLOCK_ERASE_GROUP_START (0x23U) /* CMD35 */ +#define SDMMC_BLOCK_ERASE_GROUP_END (0x24U) /* CMD36 */ +#define SDMMC_BLOCK_ERASE (0x26U) /* CMD38 */ +#define SDMMC_BLOCK_LOCK_UNLOCK (0x2AU) /* CMD42 */ +#define SDMMC_BLOCK_APP_CMD (0x37U) /* CMD55 */ +#define SDMMC_BLOCK_GEN_CMD (0x38U) /* CMD56 */ +#define SDMMC_BLOCK_SET_BUS_WIDTH (0x06U) /* ACMD6 */ +#define SDMMC_BLOCK_SD_STATUS (0x0DU) /* ACMD13 */ +#define SDMMC_BLOCK_SEND_NUM_WR_BLOCKS (0x16U) /* ACMD22 */ +#define SDMMC_BLOCK_SET_WR_BLK_ERASE_COUNT (0x17U) /* ACMD23 */ +#define SDMMC_BLOCK_SD_SEND_OP_COND (0x29U) /* ACMD41 */ +#define SDMMC_BLOCK_SET_CLR_CARD_DETECT (0x2AU) /* ACMD42 */ +#define SDMMC_BLOCK_SEND_SCR (0x33U) /* ACMD51 */ + +/* Start of Card Status Register i.e CSR Error Bits bitmask */ +#define SDMMC_BLOCK_SD_CSR_OUT_OF_RANGE_BITMASK (0x80000000U) +#define SDMMC_BLOCK_SD_CSR_ADDRESS_ERROR_BITMASK (0x40000000U) +#define SDMMC_BLOCK_SD_CSR_BLOCK_LEN_ERROR_BITMASK (0x20000000U) +#define SDMMC_BLOCK_SD_CSR_ERASE_SEQ_ERROR_BITMASK (0x10000000U) +#define SDMMC_BLOCK_SD_CSR_ERASE_PARAM_BITMASK (0x08000000U) +#define SDMMC_BLOCK_SD_CSR_WP_VIOLATION_BITMASK (0x04000000U) +#define SDMMC_BLOCK_SD_CSR_LOCK_UNLOCK_FAILED_BITMASK (0x01000000U) +#define SDMMC_BLOCK_SD_CSR_COM_CRC_ERROR_BITMASK (0x00800000U) +#define SDMMC_BLOCK_SD_CSR_ILLEGAL_COMMAND_BITMASK (0x00400000U) +#define SDMMC_BLOCK_SD_CSR_CARD_ECC_FAILED_BITMASK (0x00200000U) +#define SDMMC_BLOCK_SD_CSR_CC_ERROR_BITMASK (0x00100000U) +#define SDMMC_BLOCK_SD_CSR_ERROR_BITMASK (0x00080000U) +#define SDMMC_BLOCK_SD_CSR_CSD_OVERWRITE_BITMASK (0x00010000U) +#define SDMMC_BLOCK_SD_CSR_WP_ERASE_SKIP_BITMASK (0x00008000U) +#define SDMMC_BLOCK_SD_SWITCH_ERROR_BITMASK (0x00000080U) +#define SDMMC_BLOCK_SD_CSR_ASK_SEQ_ERROR_BITMASK (0x00000008U) +#define SDMMC_BLOCK_SD_CSR_CARD_IS_LOCKED_BITMASK (0x02000000U) +#define SDMMC_BLOCK_SD_CSR_CURRENT_STATE_BITMASK (0x00001D00U) +#define SDMMC_BLOCK_SD_CSR_CURRENT_STATE_BITPOS (0x00000009U) +#define SDMMC_BLOCK_SD_CSR_CURRENT_STATE_TRANS_VALUE (0x00000004U) +#define SDMMC_BLOCK_SD_CSR_CARD_IS_LOCKED_BITMASK (0x02000000U) + +/* Normal and error interrupt status defines */ +#define SDMMC_BLOCK_NORMAL_INT_STATUS_ENABLE (0x00F3U) +#define SDMMC_BLOCK_ERROR_INT_STATUS_ENABLE (0xE0FFU) +#define SDMMC_BLOCK_NORMAL_INT_SIGNAL_ENABLE (0x0033U) +#define SDMMC_BLOCK_ERROR_INT_SIGNAL_ENABLE (0xE0FFU) + +/*********************************************************************************************************************** + * ENUMS + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * DATA STRUCTURES + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * API PROTOTYPES + **********************************************************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetLockStatus(SDMMC_BLOCK_t *const obj, SDMMC_BLOCK_CARD_LOCK_STATUS_t *lock_stat); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_CardIdentificationProcess(SDMMC_BLOCK_t *const obj); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetSdStatus(SDMMC_BLOCK_t *const obj, void *buf); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetSectorCount(SDMMC_BLOCK_t *const obj, void *buf); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetCid(SDMMC_BLOCK_t *const obj, void *buf); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetOcr(SDMMC_BLOCK_t *const obj, void *buf); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetCsd(SDMMC_BLOCK_t *const obj, void *buf); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetCardType(SDMMC_BLOCK_t *const obj, uint32_t *card_type); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_EraseBlock(SDMMC_BLOCK_t *const obj, uint32_t start_addr, uint32_t end_addr); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetSectorSize(SDMMC_BLOCK_t *const obj, void *buf); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_GetBlockSize(SDMMC_BLOCK_t *const obj, void *buf); + +uint8_t +SDMMC_BLOCK_SD_GetState(SDMMC_BLOCK_t *const obj); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_Init(SDMMC_BLOCK_t *const obj); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_CheckLockStatus(SDMMC_BLOCK_t *const obj, + SDMMC_BLOCK_CARD_LOCK_STATUS_t mode); + +SDMMC_BLOCK_STATUS_t +SDMMC_BLOCK_SD_ReadBlock(SDMMC_BLOCK_t *const obj, + uint8_t *read_buf, + uint32_t sector_num, + uint8_t sector_count); + +SDMMC_BLOCK_STATUS_t +SDMMC_BLOCK_SD_WriteBlock(SDMMC_BLOCK_t *const obj, + const uint8_t *write_buf, + uint32_t sector_num, + uint8_t sector_count); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_LockUnlockCard(SDMMC_BLOCK_t *const obj, + SDMMC_BLOCK_LOCK_STRUCTURE_t *lock, + SDMMC_BLOCK_CARD_LOCK_STATUS_t mode); + +SDMMC_BLOCK_MODE_STATUS_t +SDMMC_BLOCK_SD_EjectCard(SDMMC_BLOCK_t *const obj); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifdef SDMMC_BLOCK_SD */ + +#endif /* SDMMC_BLOCK_SD_H */ diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/ffconf.h b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/ffconf.h new file mode 100644 index 00000000..c51b9383 --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/ffconf.h @@ -0,0 +1,266 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.12 (C)ChaN, 2016 +/---------------------------------------------------------------------------*/ + +#define _FFCONF 88100 /* Revision ID */ + +/*---------------------------------------------------------------------------/ +/ Function Configurations +/---------------------------------------------------------------------------*/ + +#define _FS_READONLY 0 +/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ + + +#define _FS_MINIMIZE 0 +/* This option defines minimization level to remove some basic API functions. +/ +/ 0: All basic functions are enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() +/ are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */ +/* This option switches string functions, f_gets(), f_putc(), f_puts() and +/ f_printf(). +/ +/ 0: Disable string functions. +/ 1: Enable without LF-CRLF conversion. +/ 2: Enable with LF-CRLF conversion. */ + + +#define _USE_FIND 0 +/* This option switches filtered directory read functions, f_findfirst() and +/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ + + +#define _USE_MKFS 0 +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ + + +#define _USE_FASTSEEK 0 +/* This option switches fast seek function. (0:Disable or 1:Enable) */ + + +#define _USE_EXPAND 0 +/* This option switches f_expand function. (0:Disable or 1:Enable) */ + + +#define _USE_CHMOD 0 +/* This option switches attribute manipulation functions, f_chmod() and f_utime(). +/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */ + + +#define _USE_LABEL 0 +/* This option switches volume label functions, f_getlabel() and f_setlabel(). +/ (0:Disable or 1:Enable) */ + + +#define _USE_FORWARD 0 +/* This option switches f_forward() function. (0:Disable or 1:Enable) +/ To enable it, also _FS_TINY need to be 1. */ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define _CODE_PAGE 437 +/* This option specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 1 - ASCII (No extended character. Non-LFN cfg. only) +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 771 - KBL +/ 775 - Baltic +/ 850 - Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 860 - Portuguese +/ 861 - Icelandic +/ 862 - Hebrew +/ 863 - Canadian French +/ 864 - Arabic +/ 865 - Nordic +/ 866 - Russian +/ 869 - Greek 2 +/ 932 - Japanese (DBCS) +/ 936 - Simplified Chinese (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese (DBCS) +*/ + + +#define _USE_LFN 1 /* 0 to 3 */ +#define _MAX_LFN 255 +/* The _USE_LFN switches the support of long file name (LFN). +/ +/ 0: Disable support of LFN. _MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added +/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and +/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255. +/ It should be set 255 to support full featured LFN operations. +/ When use stack for the working buffer, take care on stack overflow. When use heap +/ memory for the working buffer, memory management functions, ff_memalloc() and +/ ff_memfree(), must be added to the project. */ + + +#define _LFN_UNICODE 0 +/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode) +/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1. +/ This option also affects behavior of string I/O functions. */ + + +#define _STRF_ENCODE 3 +/* When _LFN_UNICODE == 1, this option selects the character encoding on the file to +/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf(). +/ +/ 0: ANSI/OEM +/ 1: UTF-16LE +/ 2: UTF-16BE +/ 3: UTF-8 +/ +/ This option has no effect when _LFN_UNICODE == 0. */ + + +#define _FS_RPATH 0 +/* This option configures support of relative path. +/ +/ 0: Disable relative path and remove related functions. +/ 1: Enable relative path. f_chdir() and f_chdrive() are available. +/ 2: f_getcwd() function is available in addition to 1. +*/ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define _VOLUMES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _STR_VOLUME_ID 0 +#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3" +/* _STR_VOLUME_ID switches string support of volume ID. +/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive +/ number in the path name. _VOLUME_STRS defines the drive ID strings for each +/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for +/ the drive ID strings are: A-Z and 0-9. */ + + +#define _MULTI_PARTITION 0 +/* This option switches support of multi-partition on a physical drive. +/ By default (0), each logical drive number is bound to the same physical drive +/ number and only an FAT volume found on the physical drive will be mounted. +/ When multi-partition is enabled (1), each logical drive number can be bound to +/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() +/ funciton will be available. */ + + +#define _MIN_SS 512 +#define _MAX_SS 512 +/* These options configure the range of sector size to be supported. (512, 1024, +/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and +/ harddisk. But a larger value may be required for on-board flash memory and some +/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured +/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the +/ disk_ioctl() function. */ + + +#define _USE_TRIM 0 +/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable) +/ To enable Trim function, also CTRL_TRIM command should be implemented to the +/ disk_ioctl() function. */ + + +#define _FS_NOFSINFO 0 +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this +/ option, and f_getfree() function at first time after volume mount will force +/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define _FS_TINY 0 +/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) +/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS bytes. +/ Instead of private sector buffer eliminated from the file object, common sector +/ buffer in the file system object (FATFS) is used for the file data transfer. */ + + +#define _FS_EXFAT 0 +/* This option switches support of exFAT file system in addition to the traditional +/ FAT file system. (0:Disable or 1:Enable) To enable exFAT, also LFN must be enabled. +/ Note that enabling exFAT discards C89 compatibility. */ + + +#define _FS_NORTC 1 +#define _NORTC_MON 3 +#define _NORTC_MDAY 1 +#define _NORTC_YEAR 2016 +/* The option _FS_NORTC switches timestamp functiton. If the system does not have +/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable +/ the timestamp function. All objects modified by FatFs will have a fixed timestamp +/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time. +/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to get current time form real-time clock. _NORTC_MON, +/ _NORTC_MDAY and _NORTC_YEAR have no effect. +/ These options have no effect at read-only configuration (_FS_READONLY = 1). */ + + +#define _FS_LOCK 0 +/* The option _FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when _FS_READONLY +/ is 1. +/ +/ 0: Disable file lock function. To avoid volume corruption, application program +/ should avoid illegal open, remove and rename to the open objects. +/ >0: Enable file lock function. The value defines how many files/sub-directories +/ can be opened simultaneously under file lock control. Note that the file +/ lock control is independent of re-entrancy. */ + + +#define _FS_REENTRANT 0 +#define _FS_TIMEOUT 1000 +#define _SYNC_t HANDLE +/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/ module itself. Note that regardless of this option, file access to different +/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() +/ and f_fdisk() function, are always not re-entrant. Only file/directory access +/ to the same volume is under control of this function. +/ +/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function, must be added to the project. Samples are available in +/ option/syscall.c. +/ +/ The _FS_TIMEOUT defines timeout period in unit of time tick. +/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, +/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be +/ included somewhere in the scope of ff.c. */ + + +/*--- End of configuration options ---*/ diff --git a/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/mmc.c b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/mmc.c new file mode 100644 index 00000000..9a22012e --- /dev/null +++ b/Target/Demo/ARMCM4_XMC4_XMC4700_Relax_Kit_Keil/Boot/lib/FatFS/mmc.c @@ -0,0 +1,217 @@ +/*------------------------------------------------------------------------/ +/ MMCv3/SDv1/SDv2 (in SDIO mode) control module +/-------------------------------------------------------------------------/ +/ +/ Copyright (C) 2013, ChaN, all right reserved. +/ +/ * This software is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-------------------------------------------------------------------------*/ + + +/* + * This file was modified from a sample available from the FatFs + * web site. It was modified to work with a Infineon XMC4700 Relax Kit + * evaluation board. It is based on the DAVE 4 SDMMC_BLOCK app, which was modified + * to work with an existing timer and for operation in polling mode. + * + */ +#include "diskio.h" +#include "boot.h" +#include "sdmmc_block.h" + + +static volatile +DSTATUS Stat = STA_NOINIT; /* Disk status */ + +const +DRESULT FATFS_errorcodes[5] = { + RES_OK , + RES_ERROR, + RES_WRPRT, + RES_NOTRDY, + RES_PARERR + }; +const +DSTATUS FATFS_statuscodes[4] = { + (DSTATUS)0, + (DSTATUS)STA_NOINIT, + (DSTATUS)STA_NODISK, + (DSTATUS)STA_PROTECT + }; + +/*-------------------------------------------------------------------------- + + Public Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* Initialize Disk Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize ( + BYTE pdrv /* Physical drive number (0) */ +) +{ + DSTATUS diskstatus; + uint32_t status; + + /* Make sure the SDMMC block is initialized. Note that it has a protection + * against mutiple initialization. + */ + SDMMC_BLOCK_Init(&SDMMC_BLOCK_0); + + /* If drive number is greater than the maximum drives allowed */ + if (pdrv > 0) + { + diskstatus = (DSTATUS)((uint8_t)STA_NODISK | (uint8_t)STA_NOINIT); + } + else + { + /* Call the Initialize function. */ + status = SDMMC_BLOCK_Initialize(&SDMMC_BLOCK_0); + /* Fatfs to Device Abstraction Layer Error Code Mapping */ + diskstatus = FATFS_statuscodes[status]; + } + + return (diskstatus); +} + + + +/*-----------------------------------------------------------------------*/ +/* Get Disk Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status ( + BYTE pdrv /* Physical drive nmuber (0) */ +) +{ + DSTATUS diskstatus; + uint32_t status; + + /* If drive number is greater than the maximum drives allowed */ + if (pdrv > 0) + { + diskstatus = (DSTATUS)((uint8_t)STA_NODISK | (uint8_t)STA_NOINIT); + } + else + { + /* Call the Initialize function.*/ + status = SDMMC_BLOCK_GetStatus(&SDMMC_BLOCK_0); + /* Fatfs to Block Layer Error Code Mapping */ + diskstatus = FATFS_statuscodes[status]; + } + return (diskstatus); +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read ( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Sector address in LBA */ + UINT count /* Number of sectors to read */ +) +{ + DRESULT diskresult; + uint32_t result; + + /* If drive number is greater than the maximum drives allowed */ + if (pdrv > 0) + { + diskresult = RES_PARERR; + } + /* If sector count is less than 1. Minimum 1 sector is needed*/ + else if (count < (uint8_t)1) + { + diskresult = RES_PARERR; + } + /*Call the ReadBlk function.*/ + else + { + result = (uint32_t)SDMMC_BLOCK_ReadBlock(&SDMMC_BLOCK_0, (uint8_t *)buff, + (uint32_t)sector, count); + + /* FatFs to Device Abstraction Layer Error Code Mapping */ + diskresult = FATFS_errorcodes[result]; + } + return (diskresult); +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_write ( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector address in LBA */ + UINT count /* Number of sectors to write */ +) +{ + DRESULT diskresult; + uint32_t result; + + /* If drive number is greater than the maximum drives allowed */ + if (pdrv > 0) + { + diskresult = RES_PARERR; + } + /* If sector count is less than 1. Minimum 1 sector is needed*/ + else if (count < (uint8_t)1) + { + diskresult = RES_PARERR; + } + /*Call the WriteBlk function.*/ + else + { + result = (uint32_t)SDMMC_BLOCK_WriteBlock(&SDMMC_BLOCK_0,(uint8_t *)buff, + (uint32_t)sector, count); + /* FatFs to Device Abstraction Layer Error Code Mapping */ + diskresult = FATFS_errorcodes[result]; + } + return (diskresult); +} + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_ioctl ( + BYTE pdrv, /* Physical drive nmuber (0) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive data block */ +) +{ + DRESULT diskresult; + uint32_t result; + if (pdrv > 0) + { + diskresult = RES_PARERR; + } + /*Call the Ioctl function.*/ + else + { + result = SDMMC_BLOCK_Ioctl(&SDMMC_BLOCK_0, cmd, buff); + /* FatFs to Block Layer Error Code Mapping */ + diskresult = FATFS_errorcodes[result]; + } + return (diskresult); +} + + +