From d5c3f8b3f2c7a65234433c551755e573c1849396 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sun, 8 Jul 2012 14:11:37 +0000 Subject: [PATCH] Complete first release candidate for the SAM4S-EK demo. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1757 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../RTOSDemo.atsln | 3 - .../RTOSDemo.atsuo | Bin 26112 -> 39424 bytes .../RTOSDemo.cproj | 548 ++++-- .../src/Common-Demo-Source/comtest.c | 304 +++ .../src/Common-Demo-Source/flash_timer.c | 137 ++ .../src/Common-Demo-Source/include/comtest2.h | 74 + .../Common-Demo-Source/include/demo_serial.h | 137 ++ .../Common-Demo-Source/include/flash_timer.h | 80 + .../src/Common-Demo-Source/include/partest.h | 77 + .../src/FreeRTOSConfig.h | 6 +- .../src/ParTest.c | 6 +- Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf.h | 11 +- .../src/asf/common/services/clock/genclk.h | 172 ++ .../src/asf/common/services/clock/osc.h | 158 ++ .../src/asf/common/services/clock/pll.h | 314 +++ .../asf/common/services/clock/sam4s/genclk.h | 264 +++ .../src/asf/common/services/clock/sam4s/osc.h | 217 +++ .../src/asf/common/services/clock/sam4s/pll.h | 241 +++ .../asf/common/services/clock/sam4s/sysclk.c | 265 +++ .../asf/common/services/clock/sam4s/sysclk.h | 442 +++++ .../src/asf/common/services/clock/sysclk.h | 165 ++ .../src/asf/sam/drivers/pmc/pmc.c | 1058 ++++++++++ .../src/asf/sam/drivers/pmc/pmc.h | 437 +++++ .../src/asf/sam/drivers/pmc/sleep.h | 217 +++ .../src/asf/sam/drivers/usart/usart.c | 1707 +++++++++++++++++ .../src/asf/sam/drivers/usart/usart.h | 633 ++++++ .../thirdparty/CMSIS/Include/core_cmFunc.h | 1 + .../src/config/conf_board.h | 8 +- .../src/config/conf_clock.h | 99 + Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main.c | 55 +- .../src/main_blinky.c | 7 +- .../src/main_full.c | 58 +- .../CORTEX_M4_ATSAM4S_AVR_Studio/src/serial.c | 291 +++ 33 files changed, 7908 insertions(+), 284 deletions(-) create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/comtest.c create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/flash_timer.c create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/comtest2.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/demo_serial.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/flash_timer.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/partest.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/genclk.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/osc.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/pll.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/genclk.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/osc.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/pll.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.c create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sysclk.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.c create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/sleep.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.c create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_clock.h create mode 100644 Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/serial.c diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/RTOSDemo.atsln b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/RTOSDemo.atsln index d6af61e52..cbafd976a 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/RTOSDemo.atsln +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/RTOSDemo.atsln @@ -6,13 +6,10 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM - Release|ARM = Release|ARM EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {3D8959CD-73CA-4147-9C1B-CFCF2EE40326}.Debug|ARM.ActiveCfg = Debug|ARM {3D8959CD-73CA-4147-9C1B-CFCF2EE40326}.Debug|ARM.Build.0 = Debug|ARM - {3D8959CD-73CA-4147-9C1B-CFCF2EE40326}.Release|ARM.ActiveCfg = Release|ARM - {3D8959CD-73CA-4147-9C1B-CFCF2EE40326}.Release|ARM.Build.0 = Release|ARM EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/RTOSDemo.atsuo b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/RTOSDemo.atsuo index d6467076a56b0759997a9024c6e4f2da5f26f086..f638ada0159e6841c92eb0a92f13ec86a06880f6 100644 GIT binary patch literal 39424 zcmeHQ34ByVnt$OEP*6Zl6~iHdl1wg6WyYkFC}<>*2#PIjr_)KAbh<+y91=WWbw|f> zP#HXMJy~Z~cO1`Imt`Dendsnw*LvbPUc;iIqs}gaF#rFnSM=+b*Zp3S4nF)*{rh*l zqq@GTdf)feS6@}VeqsB7_wIUV#QTaN{8;I(?AzZ*>7~1#g=0bu$0$lS9CQcv?ccv& zTvQYs9u9|43w(#N_Q1m%0rUip0Qk&%1ATzLz)`@FKtG^AfJd(!4GaVZ0E2*2fMbEd zzz|?4Fbo(D90!aAjt5QvCIH#MXkZjD2`BVm3WS|^43z!N_19;CEeuC>~0L4HF-~vj4GT?0BOkgI!-_Alj1}FrK`5fx! zbCobYF+7hlC4@MlEJrQvhaun^*#>+@>B1RJ{U!{$=(#NFj58`k%1TfSD~r(9A*BvS zWy-R2S+uz~1X@VaXWS-1iVNgnhHAyDM3qM693_A_rksawKguMpM@6!f-(xlUtdm{( zSx8IyVmM!EQi4h)O5sB(yh=T&&sLgIk^ovGgwmuBpr1v$lsmihskeJmkP*n=1j|pk zqz<6`QxE8M0Og;0K&Gesvkm1rb%2zAUZec~OuJ9rLLDIGpYluD&IU#S)B`e~n{~(X z8g&bKi+X_ifVzQtK*~RL0cDdqgt}xpKwY4h|I=`OIxqwHF_2FFsXr+H)FIRXl>f7V za{#jKxxj3o5|{(b1*(AafSZ7MzH=sVu<6w65w%Q89-_NPvAg$WvThRa{Y2nkJvs6Q0*#sc9`rPtT!t@lsNp68E5 zaXuqIFIW9c%yz|tv3SHkBjk_ABHrM{?8=CaB_#)wGxGt7EFA$A;gQ7~gY7y%FkplB#=O;m z=4ftZAQbY}1pVqs*|L~F6b;k_f`Qob+)9=-iYq?Td!)q2;{~K-RA@E`z>`J zf1eHd%#XAgc+D#GLjvk51|$6vNRuCBXhf@o(H`s*)9K*xpno#*84uW{Pt|)Jz+j}$ z{*P^Mw+9#p`eTs~b+ujk1GMyrz8CiINzM;tj_Gx5E?Hg^2v;~5^!q5iB-w)^qB33| zc6Z0{i{VHSb?93Pafg14AMy9A02g{KH>@AG$`MNtm#duUNAFUN-lhsy=7S?6;7oF5 zJ$?}emn_$Q(S$QMuFY1{m!a?Rpsy;zcQJlng>Rl!sps>M#)IP+Ys9zyK2#{VQ@!8)kRvirV;fI^$x87yZUD!(mt={mYV)@JhvM4`I{2fE`t66 z-EWsZZ6BGZk$weQn*7gk(0r{e!phQ=eZWN2pSCD>K3~8H1MvXtbny%3hR6t zto3P-_)=K)Q*g}%DbGQQd|(QWcrPEL^BlzGDhi+>%T)d^ga=?Utl3;>u%!mNV*I41 zdNim~-?c599~@2zo`Dt_m*KLVrf}4e+1e)fr3I}u7j2&l?N*{{I$BL7coMa0ePoMs z#FM%Vv^Qel`3U+HFMdn;58^xun@~JG(L(HPXbaIc)LTT;J1u`=zR0F2LEZta09Icc_a4^f!2#(E$2Y}_ySFMqJHLq0G+xgpBLIpW= z%z87HsT<0{{wsvGV~g@QC#g4gquqn*vul7A$UwU)g0j*^;<#uXTG*~N+P(pLr8iRT zkH$=f=N|LndHb?=g`1kfp&U93a;n1dh|ljX35I=*b4&=o7^>FZ=^QL z!=k9i-{=m60%nzL&LquvED(&keN7nQ3&No43&v~x;w*o%FP9FaWG_g_Sc2KGu@<2h zsRsubb^JWlgT_2khtbe~$Kf{pe|GiH7^KzI4`>Qrj6!At;KQYDN|Bm2?@0eA{f&0% z>-Def<=784qb#)iC=J3|V1JiBNdGTsGo()~?p7n(M1v9GJV+|3deLk90a+f=>!$NO zh~K0A+pYig_3wzAja(mV2t;a|y^+{*x2vLRW|e!U#(X}wmOQ?u@_5LM{~C<^*Aej_4nH z#J6$~h+wo{?CL%7Yx*R*WpNCtDnFb0?VNtZ z*q_*Ke;Rml{F|=**(V6=O)IQPMEb|$I_qSY{$!-xqUDv$f3(;*;;9EWQ2wj~{ofqQ z&~CF!pZ;o&+Zo)TM=y^X-?Zp!RckO8Ezfab(Y8l!THCKr-`;D>&b#~<6F9ka;7OAj zgWhK-^I|$h*gXBzloVuVl+Te)=nlL{@ z!#UZ`@@9gnv6As9dN;TFZ9+1b36drim0hd8!fm_PnVF!D3Y+xY@eF0Hw^`cu+!g+& z3U8?1-Qf2&dkRe2w=Pq~FdHz)k%LL~FU}NQpE^2ni*Z9B6!S+S@#cAu|7vJl_WAU- zE<^uA&9ekr$j%%f?SHNVpgy5Cpd?rY>V7$IV5NTxEHb11CEbxoXP5p8r2R_E*NT3j zHT@)wXpvmK&3TS)>@*Rq=og7(DZknOpMblpJ44EZx*HtzZ`RJuOyw)GGR1Oa_0;23 zFl2K$g!y&%fg_L5Zf*5TRcDJt&9AN^kP8J&L_8xZlv-O8wWvR`B;fO7luj>%HcF2! zkNSd*CW5}QvsGlxWS`Nt)uX~867x4T2fY|1xls_DcvRJ6QXF5VilZAU9#Fe6Z?rLL z@&vk+=;F9P?l%yfldUMX+ptqo`R^!388I>V;7nVJ7KT|<&CkU1@r6TmfqL+3sLrE0 zu}m1@oJvF0yk-Ow8ms%Z@I;8AGcVvCPcS~?C=;yKpgkg!XG6( z+nnQf!ADnxQ7P8}aIK^d{WWLrZ*@%hxrUMJCOLwMsovzH?|f#(oEP_%jec}R)!7^0 zdV^yw(Mu)1*E**B9OrWsPCxkc@6P(lQ~L7uF*|o<4SX&81X?(WGK(Xza^lyHDZg>O zh<+w17d-Xm&|7}?Y5kUc-#t06tYFvV(Y;LSRE^oy_N^TG+%fe}FF(fCaYMRE6l=C{K2TiE8n3EK%Z+y5SRtHjF@qQ6v9*2=mtP-K-;(Qam==7LT4=}}Y zK-}@*NdA@_`NhsXzlu*@S9E@lH!s-n=x5iO=?64#+OX4c?PspP?eL#ids2Zm;`%N( zT8JK*W^iJG$}1)BT=L+m)vt}aX7?ZW?tSsx(HwJac3k~^;0ZYgnaoAhuH=LWK3pHd zUgGXfmjBsK{$9+Gc5LodtelfRFR6c|{BShQ9Cn z(Zd_wc&ht^Rm1wzvuV^W$>PwS<$G^@C?ATw<2B-+y?v$a651Za3^pVa5r!dumSiJa4+yH zfWQ4W#P#lJgS{DmybO@e{~&%9cuhNh1M!={TiW^Ch~EL; z1>OVR2R;D)415TD1bhq}1^>XOi2nlY1eo_O#Ge75Yv;QWe+hi0oqvt^8{k{*{QnUD zKd=Y*yLRn6#=w5yN@(lwn5}K2#yggWEA8K4~LZUGfBn)FR zvx&~k=?`gtdQ^Lay0Q^{CvAiob2oL{zk1R58|T)(zT)Y-?mh}l2zE#cm)G38pigkf zu4g`N*){d7<4sb?F;eoril!oy(NdRtuN%k(N!v5j{Tpa+lhUO1|K>3#Ep$Vi4ajx0 z>DIkw;&*Jxp841WlFtIz+My!dGY1xo^i^6gebZfeAggqG9zH7yOQ%koG|g3-Go{c~ zoKuuvG$m)6E59ViRqiS;C@U+JXFuRb|mX;M$OA4nJ;FB}C zAg>@NKfg3TXX?}`c{zCq?fy-G? zdNL@d!gJ$RTaM!br}>WCQ-_2vM%L$6$JIxUrA32pbZq&o#`>cC4|hTNw`6sW2d(uF zHB0Is^}m#{)F~5peuKmJv{P&PQxiWlIU;@9@&$lh{r3>k(mr6Yraw(2Oz{o+NqQzl zvZTw8;f%fp1}pjn7|o;$tUrez?4|71|4F2!4}l?qIS=l};95_5>!e*FbwXG0Z2NYm zrt+_)vadwFp6CKu>)LX+)yK~tggS6!!L=ye0s5G@H@g?WR}}EP58}SSk=l7b#QlMz z0oo7)fPugu;82)X>=An^3TtCQJyP1N(* zL%N>H^LnC2@BM&kWHwVNYPr>MwKVsKq*@O`FMi+HL<(N6Q?I^tm6FehqunJGTErPhaeR5W88q1I7>9+@Z=D*r+UIni%Wv z+g<;kBfq{{o>ul>zG~T~E&%Pn5n6uK`l(YU?!16Q>HpC01!cYEUeE?*;qs^6Im&B-<^n39G0t+?(or-xzjDy5y7*09n)>Ajy~|Lut= z#3;b7{;5G)&e1bi(NFLFROu&4smL|`w;#8k*OFM#Pw)K@_0L9LV*tDL4GaH-_Jbm$o_t51eB%jcgqqcn4CzqS zUE`Q>9qX(pPVrB6ctD@uB$!vC;pFa?Ad)@>kTJ< zb1WWa?>}$Q_G3rTU zd!*X;Cf6Ok z;hy{MINGFLq%OF<)Abk6if>==fOZq!zrwem_|%m>vu55GTe0Jk6Q0cZ= z&-jFJsS}~Ixiu(nKY#Tf9=NG=z{ZU`R=s`kM;rR1H1>1Noc|}Wezp!R7}UHV-bm}{ zk%I=eem*7V)xy_5EH*1$G2T7Z_Kmpqdau_z{ro$=b}xDVfj$41aaP7`uVLFBxowY@ zYOj=F#T^dp={j0dWC6(*+#hb);Iga;JzIGXNc_|KC8HYpfWo>8GCoAbtAiX8?BV&$_RZXwwY_ zHaUiG+V49NZ#;Y2F*T6AuU(!>-aRG$+wDQe)F##QNQ@ik&lCTM!v8_b)W6`^8}ql7 z(B!=+;@?1Sb4+WteKU`E|K3{1lu&T5c&7BW9gLOF9a|-u;6TxHCcnc$`lI=F6!D%1 zQ75e2=+s-rq_;IQqj9r0y^2|~cO1qM?R^`T+(T*ZO%?xE{Q3{Bjzy}kSp0|Y?n9(@ zZFQ)9AEQhuyhEHt{$Z^uPpqQP$LL4Q1c-l7b&jX8{q}}jTPpTzi+}yx3jY~(n(TMm z@4rl5!`c4-FX@VR>L=BoWoUzpMNSpSLSV8qXuT%%lTtr zwe$jSyy+Nzl^Ta*1G&zdl4e{Vpx>vR(4->5N>;Og0_8t;7 z>zX%NivJTibiF}`{TEz8+TM5HChWY!{)>b0AJuY{aM*ug_um=2c61{xGIO7Ex*e+Q z{S!W#!~ToI{)>b4Klf6Hq~~4Z*ob~ebN@x>c29i&s}C|)0(Nbv^665uR=kvpcPnKPH_L?<=zsh_3rrqHQW-EA8Fo%uH4>+d%C>hfK zqF=wCm~o<4=F;Yy@A&4~1y#Qv_vv>v(LWF4%#s;j*r>Xi#CrWn`W>JhS^vTfSv$1? zTG21G-v60(I`X2gO3H+mb;_s*=4 z63zPZHty2bbBd4_=e)l|*5ADUw6@6RU%2hd)ylA|`nZE4-g}Rv9x%3TV(qa0eT8DiVi;=D!?7Ao@5{Gq5eaR; T8SnPI5gPB{Lrb*U;JbeS6rTS` delta 2252 zcmZ`)dr(wW7{6z|yWZuo?&2cLf(i(@;4a+7RS|i(?6P1KiwdMWq>P3}nS!h#y5>^$ zaLAJVIhw{FmM?ltldjW48^ttpN(IV4nyEi*@{g>htU)K8%D!{CFzM9U{oVVW@B7ZV z-}zoAd|VU0$ack|RlrIzQ#CMvcqfIsz5g%k$q>EDx#ufWc^aL)kaU>SVJST6ldjg0X(R;ty#|D?yC@5xa97GDRcPkV7VpJ>BtT$BZ7P7j&d-P#0(? z5m6WIG*yoiV>s{BPP?v-hzSDjm}~en8ch6`$au9f?@a zNj$Jgd@VO~*ydzDD?i17WjJWGmkdrGwwPgJbRMsTVh9-mXk6G$WB&eR1wn#_d_ zX*CKp3pdmJl8MAzMKLv)UMq16%qoKw;bwZb>C)2eC7-ufx_eUw2J)_r%hsUHlh0EC zJvAvfPe-}7CjsR7sH+$!v!CgMbL0)EVqaa~G+F*y%w zEmmAl-HzO>$_X*5HWPTpke!pAOh8-B6Zo=f7Z!DVOs8Dme9Y0vOpgsYet+{y{E@$c z`9hU*=1mE1=R}0_cAIXM9rFHd9J=!CjMu`q!a>3b zm1+8bCZiR@-zRxZzuv^ql`$L33X_;0t*KtDE79U~u?}BLCiK~w(Peiaod38ft5M!w z)K~NTEqMtmqmovv!%(0AZ8I!5Z!bdYG#Ni-B}Qy!9LRiuJ)-(F4xeRM@uFopn)b@r zwd_?4?vT*5ITNJ?24vR!Z0Zv{LXprYR1myEv+xw|=DHDH?V~KnU=d2>9wjf_tvhga zm4wS4gW5UX0qc4jI`3iDM_PL!cNlQRZ%1uSkmxj3>n%kVSYw2>YCrh9VUK|wChnoA zwdxs$eak2m@HM-Fq0X;V={2IiNA0Sg@mpXXP8H{~ z5H<&9u#5PmxC;|9Q!tRKM_YXUt{5mzk|76)vO5Jl#mVG$Vh$E9Pu)cz-k zo=ET>RaURH=xJr?)(6H^g#LP>d8_occ#CBEZI;#H;P3k$qp~fb;>GLMYzVfjTU#1h zROespZGLiHD70C2l^43p3kw|XS#t^;E?2@O%#m<9!^Dl8)S*<%y?WmBV`?2)MzLjWOAreKC8%xReV@&DC_%+#t{kb04=bG_wss*<#v1pR_QTVe(+VLaa^l`Sn1ZnlvI9(_q zRAQsJPnxuXc2-A!I}!ZS@V-mueGZ1=T(05|jw(=#;?*0+Ro-W6;M@hiiaD+dr=xt1 zYo^2L^vVu*h0{$TbjzN(vd`!9%%s3Q)Y87v*RrO$y%g#76;y&oN-~@6f3j)8zdjit zI!!ryt)US2AU+G3b*b3Dr$KF$32Hq4E8`_RxatNPwH6%fOu*HRai+M_=XSqzsd}5H nd+3{K-|ju$h%-H9XwoJ`9t|VSRt}0b8j_PxX>i~7;k3.1.3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ATSAM4S16C sam4s @@ -136,103 +151,147 @@ false 1 + JTAG + com.atmel.avrdbg.tool.samice + + com.atmel.avrdbg.tool.samice + SAM-ICE + 000158000789 + true + false + + + + 127.0.0.1 + 3166 + False + + + JTAG + + 4000000 + 1000000 + 150000 + false + false + 0 + 0 + 0 + 0 + + + - - - ARM_MATH_CM4=true - BOARD=SAM4S_EK - __SAM4S16C__ - - - - - ../src - ../src/asf/common/applications/user_application/sam4s16c_sam4s_ek - ../src/asf/common/boards - ../src/asf/common/services/gpio - ../src/asf/common/utils - ../src/asf/sam/boards - ../src/asf/sam/boards/sam4s_ek - ../src/asf/sam/drivers/pio - ../src/asf/sam/utils - ../src/asf/sam/utils/cmsis/sam4s/include - ../src/asf/sam/utils/cmsis/sam4s/source/templates - ../src/asf/sam/utils/header_files - ../src/asf/sam/utils/preprocessor - ../src/asf/thirdparty/CMSIS/Include - ../src/asf/thirdparty/CMSIS/Lib/GCC - ../src/config - - - - - ../src - ../src/asf/common/applications/user_application/sam4s16c_sam4s_ek - ../src/asf/common/boards - ../src/asf/common/services/gpio - ../src/asf/common/utils - ../src/asf/sam/boards - ../src/asf/sam/boards/sam4s_ek - ../src/asf/sam/drivers/pio - ../src/asf/sam/utils - ../src/asf/sam/utils/cmsis/sam4s/include - ../src/asf/sam/utils/cmsis/sam4s/source/templates - ../src/asf/sam/utils/header_files - ../src/asf/sam/utils/preprocessor - ../src/asf/thirdparty/CMSIS/Include - ../src/asf/thirdparty/CMSIS/Lib/GCC - ../src/config - - - - - ../src - ../src/asf/common/applications/user_application/sam4s16c_sam4s_ek - ../src/asf/common/boards - ../src/asf/common/services/gpio - ../src/asf/common/utils - ../src/asf/sam/boards - ../src/asf/sam/boards/sam4s_ek - ../src/asf/sam/drivers/pio - ../src/asf/sam/utils - ../src/asf/sam/utils/cmsis/sam4s/include - ../src/asf/sam/utils/cmsis/sam4s/source/templates - ../src/asf/sam/utils/header_files - ../src/asf/sam/utils/preprocessor - ../src/asf/thirdparty/CMSIS/Include - ../src/asf/thirdparty/CMSIS/Lib/GCC - ../src/config - - - - Optimize for size (-Os) - -T../src/asf/sam/utils/linker_scripts/sam4s/sam4s16/gcc/flash.ld -Wl,--cref -Wl,--entry=Reset_Handler -mthumb - - - arm_cortexM4l_math - - - - - ../src/asf/thirdparty/CMSIS/Lib/GCC - - - - - - - True - None - True - True - -fdata-sections - -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -std=gnu99 -ffunction-sections -fdata-sections -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wbad-function-cast -Wwrite-strings -Wsign-compare -Waggregate-return -Wmissing-declarations -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wunreachable-code -Wcast-align --param max-inline-insns-single=500 -Dprintf=iprintf - - -DARM_MATH_CM4=true -DBOARD=SAM4S_EK -D__SAM4S16C__ - + __SAM4S16C__ + True + True + True + True + + + ARM_MATH_CM4=true + BOARD=SAM4S_EK + __SAM4S16C__ + + + + + ../src + ../src/asf/common/applications/user_application/sam4s16c_sam4s_ek + ../src/asf/common/boards + ../src/asf/common/services/gpio + ../src/asf/common/utils + ../src/asf/sam/boards + ../src/asf/sam/boards/sam4s_ek + ../src/asf/sam/drivers/pio + ../src/asf/sam/utils + ../src/asf/sam/utils/cmsis/sam4s/include + ../src/asf/sam/utils/cmsis/sam4s/source/templates + ../src/asf/sam/utils/header_files + ../src/asf/sam/utils/preprocessor + ../src/asf/thirdparty/CMSIS/Include + ../src/asf/thirdparty/CMSIS/Lib/GCC + ../src/config + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles\CMSIS\Include + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles\Device\ATMEL + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles\Device\ATMEL\sam4s\include + ../src/asf/sam/drivers/pmc + ../src/asf/common/services/clock + ../src/asf/sam/drivers/usart + + + Optimize for size (-Os) + -fdata-sections + True + True + -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -std=gnu99 -ffunction-sections -fdata-sections -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wbad-function-cast -Wwrite-strings -Wsign-compare -Waggregate-return -Wmissing-declarations -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wunreachable-code -Wcast-align --param max-inline-insns-single=500 -Dprintf=iprintf + + + + + + arm_cortexM4l_math + + + + + ../src/asf/thirdparty/CMSIS/Lib/GCC + + + True + -T../src/asf/sam/utils/linker_scripts/sam4s/sam4s16/gcc/flash.ld -Wl,--cref -Wl,--entry=Reset_Handler -mthumb + + + ../src + ../src/asf/common/applications/user_application/sam4s16c_sam4s_ek + ../src/asf/common/boards + ../src/asf/common/services/gpio + ../src/asf/common/utils + ../src/asf/sam/boards + ../src/asf/sam/boards/sam4s_ek + ../src/asf/sam/drivers/pio + ../src/asf/sam/utils + ../src/asf/sam/utils/cmsis/sam4s/include + ../src/asf/sam/utils/cmsis/sam4s/source/templates + ../src/asf/sam/utils/header_files + ../src/asf/sam/utils/preprocessor + ../src/asf/thirdparty/CMSIS/Include + ../src/asf/thirdparty/CMSIS/Lib/GCC + ../src/config + ../src/asf/sam/drivers/pmc + ../src/asf/common/services/clock + ../src/asf/sam/drivers/usart + + + -DARM_MATH_CM4=true -DBOARD=SAM4S_EK -D__SAM4S16C__ + + + ../src + ../src/asf/common/applications/user_application/sam4s16c_sam4s_ek + ../src/asf/common/boards + ../src/asf/common/services/gpio + ../src/asf/common/utils + ../src/asf/sam/boards + ../src/asf/sam/boards/sam4s_ek + ../src/asf/sam/drivers/pio + ../src/asf/sam/utils + ../src/asf/sam/utils/cmsis/sam4s/include + ../src/asf/sam/utils/cmsis/sam4s/source/templates + ../src/asf/sam/utils/header_files + ../src/asf/sam/utils/preprocessor + ../src/asf/thirdparty/CMSIS/Include + ../src/asf/thirdparty/CMSIS/Lib/GCC + ../src/config + ../src/asf/sam/drivers/pmc + ../src/asf/common/services/clock + ../src/asf/sam/drivers/usart + + + True True @@ -242,6 +301,7 @@ + __SAM4S16C__ True True True @@ -277,6 +337,13 @@ ../src/asf/thirdparty/FreeRTOS/include ../src/asf/thirdparty/FreeRTOS/portable/GCC/ARM_CM3 ../src/Common-Demo-Source/include + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles\CMSIS\Include + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles\Device\ATMEL + C:\devtools\Atmel\Atmel Studio 6.0\extensions\Atmel\ARMGCC\3.3.1.83\ARMSupportFiles\Device\ATMEL\sam4s\include + ../src/asf/sam/drivers/pmc + ../src/asf/common/services/clock + ../src/asf/sam/drivers/usart -fdata-sections @@ -314,6 +381,9 @@ ../src/asf/thirdparty/CMSIS/Include ../src/asf/thirdparty/CMSIS/Lib/GCC ../src/config + ../src/asf/sam/drivers/pmc + ../src/asf/common/services/clock + ../src/asf/sam/drivers/usart -DARM_MATH_CM4=true -DBOARD=SAM4S_EK -D__SAM4S16C__ @@ -335,6 +405,9 @@ ../src/asf/thirdparty/CMSIS/Include ../src/asf/thirdparty/CMSIS/Lib/GCC ../src/config + ../src/asf/sam/drivers/pmc + ../src/asf/common/services/clock + ../src/asf/sam/drivers/usart @@ -345,6 +418,45 @@ True + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + compile @@ -357,6 +469,15 @@ compile + + compile + + + compile + + + compile + compile @@ -426,6 +547,9 @@ compile + + compile + compile @@ -435,6 +559,9 @@ compile + + compile + compile @@ -444,6 +571,9 @@ compile + + compile + compile @@ -453,6 +583,9 @@ compile + + compile + compile @@ -483,6 +616,9 @@ compile + + compile + compile @@ -778,6 +914,8 @@ + + @@ -787,6 +925,8 @@ + + diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/comtest.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/comtest.c new file mode 100644 index 000000000..18b7d4a5a --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/comtest.c @@ -0,0 +1,304 @@ +/* + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong? * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + + +/* + * This version of comtest. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * Creates two tasks that operate on an interrupt driven serial port. A + * loopback connector should be used so that everything that is transmitted is + * also received. The serial port does not use any flow control. On a + * standard 9way 'D' connector pins two and three should be connected together. + * + * The first task posts a sequence of characters to the Tx queue, toggling an + * LED on each successful post. At the end of the sequence it sleeps for a + * pseudo-random period before resending the same sequence. + * + * The UART Tx end interrupt is enabled whenever data is available in the Tx + * queue. The Tx end ISR removes a single character from the Tx queue and + * passes it to the UART for transmission. + * + * The second task blocks on the Rx queue waiting for a character to become + * available. When the UART Rx end interrupt receives a character it places + * it in the Rx queue, waking the second task. The second task checks that the + * characters removed from the Rx queue form the same sequence as those posted + * to the Tx queue, and toggles an LED for each correct character. + * + * The receiving task is spawned with a higher priority than the transmitting + * task. The receiver will therefore wake every time a character is + * transmitted so neither the Tx or Rx queue should ever hold more than a few + * characters. + * + */ + +/* Scheduler include files. */ +#include +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "demo_serial.h" +#include "comtest2.h" +#include "partest.h" + +#define comSTACK_SIZE configMINIMAL_STACK_SIZE +#define comTX_LED_OFFSET ( 0 ) +#define comRX_LED_OFFSET ( 1 ) +#define comTOTAL_PERMISSIBLE_ERRORS ( 2 ) + +/* The Tx task will transmit the sequence of characters at a pseudo random +interval. This is the maximum and minimum block time between sends. */ +#define comTX_MAX_BLOCK_TIME ( ( portTickType ) 0x96 ) +#define comTX_MIN_BLOCK_TIME ( ( portTickType ) 0x32 ) +#define comOFFSET_TIME ( ( portTickType ) 3 ) + +/* We should find that each character can be queued for Tx immediately and we +don't have to block to send. */ +#define comNO_BLOCK ( ( portTickType ) 0 ) + +/* The Rx task will block on the Rx queue for a long period. */ +#define comRX_BLOCK_TIME ( ( portTickType ) 0xffff ) + +/* The sequence transmitted is from comFIRST_BYTE to and including comLAST_BYTE. */ +#define comFIRST_BYTE ( 'A' ) +#define comLAST_BYTE ( 'X' ) + +#define comBUFFER_LEN ( ( unsigned portBASE_TYPE ) ( comLAST_BYTE - comFIRST_BYTE ) + ( unsigned portBASE_TYPE ) 1 ) +#define comINITIAL_RX_COUNT_VALUE ( 0 ) + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort = NULL; + +/* The transmit task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComTxTask, pvParameters ); + +/* The receive task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComRxTask, pvParameters ); + +/* The LED that should be toggled by the Rx and Tx tasks. The Rx task will +toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task will toggle LED +( uxBaseLED + comTX_LED_OFFSET ). */ +static unsigned portBASE_TYPE uxBaseLED = 0; + +/* Check variable used to ensure no error have occurred. The Rx task will +increment this variable after every successfully received sequence. If at any +time the sequence is incorrect the the variable will stop being incremented. */ +static volatile unsigned portBASE_TYPE uxRxLoops = comINITIAL_RX_COUNT_VALUE; + +/*-----------------------------------------------------------*/ + +void vAltStartComTestTasks( unsigned portBASE_TYPE uxPriority, unsigned long ulBaudRate, unsigned portBASE_TYPE uxLED ) +{ + /* Initialise the com port then spawn the Rx and Tx tasks. */ + uxBaseLED = uxLED; + xSerialPortInitMinimal( ulBaudRate, comBUFFER_LEN ); + + /* The Tx task is spawned with a lower priority than the Rx task. */ + xTaskCreate( vComTxTask, ( signed char * ) "COMTx", comSTACK_SIZE, NULL, uxPriority - 1, ( xTaskHandle * ) NULL ); + xTaskCreate( vComRxTask, ( signed char * ) "COMRx", comSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComTxTask, pvParameters ) +{ +signed char cByteToSend; +portTickType xTimeToWait; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Simply transmit a sequence of characters from comFIRST_BYTE to + comLAST_BYTE. */ + for( cByteToSend = comFIRST_BYTE; cByteToSend <= comLAST_BYTE; cByteToSend++ ) + { + if( xSerialPutChar( xPort, cByteToSend, comNO_BLOCK ) == pdPASS ) + { + vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET ); + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comTX_LED_OFFSET, pdFALSE ); + + /* We have posted all the characters in the string - wait before + re-sending. Wait a pseudo-random time as this will provide a better + test. */ + xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME; + + /* Make sure we don't wait too long... */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* ...but we do want to wait. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + vTaskDelay( xTimeToWait ); + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComRxTask, pvParameters ) +{ +signed char cExpectedByte, cByteRxed; +portBASE_TYPE xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* We expect to receive the characters from comFIRST_BYTE to + comLAST_BYTE in an incrementing order. Loop to receive each byte. */ + for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ ) + { + /* Block on the queue that contains received bytes until a byte is + available. */ + if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) ) + { + /* Was this the byte we were expecting? If so, toggle the LED, + otherwise we are out on sync and should break out of the loop + until the expected character sequence is about to restart. */ + if( cByteRxed == cExpectedByte ) + { + vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); + } + else + { + xResyncRequired = pdTRUE; + break; /*lint !e960 Non-switch break allowed. */ + } + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE ); + + /* Did we break out of the loop because the characters were received in + an unexpected order? If so wait here until the character sequence is + about to restart. */ + if( xResyncRequired == pdTRUE ) + { + while( cByteRxed != comLAST_BYTE ) + { + /* Block until the next char is available. */ + xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ); + } + + /* Note that an error occurred which caused us to have to resync. + We use this to stop incrementing the loop counter so + sAreComTestTasksStillRunning() will return false - indicating an + error. */ + xErrorOccurred++; + + /* We have now resynced with the Tx task and can continue. */ + xResyncRequired = pdFALSE; + } + else + { + if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS ) + { + /* Increment the count of successful loops. As error + occurring (i.e. an unexpected character being received) will + prevent this counter being incremented for the rest of the + execution. Don't worry about mutual exclusion on this + variable - it doesn't really matter as we just want it + to change. */ + uxRxLoops++; + } + } + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreComTestTasksStillRunning( void ) +{ +portBASE_TYPE xReturn; + + /* If the count of successful reception loops has not changed than at + some time an error occurred (i.e. a character was received out of sequence) + and we will return false. */ + if( uxRxLoops == comINITIAL_RX_COUNT_VALUE ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Reset the count of successful Rx loops. When this function is called + again we expect this to have been incremented. */ + uxRxLoops = comINITIAL_RX_COUNT_VALUE; + + return xReturn; +} + diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/flash_timer.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/flash_timer.c new file mode 100644 index 000000000..39c0fc8a4 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/flash_timer.c @@ -0,0 +1,137 @@ +/* + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong? * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +/** + * Repeatedly toggles one or more LEDs using software timers - one timer per + * LED. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "timers.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash_timer.h" + +/* The toggle rates are all a multple of ledFLASH_RATE_BASE. */ +#define ledFLASH_RATE_BASE ( ( ( portTickType ) 333 ) / portTICK_RATE_MS ) + +/* A block time of zero simple means "don't block". */ +#define ledDONT_BLOCK ( ( portTickType ) 0 ) + +/*-----------------------------------------------------------*/ + +/* + * The callback function used by each LED flashing timer. All the timers use + * this function, and the timer ID is used within the function to determine + * which timer has actually expired. + */ +static void prvLEDTimerCallback( xTimerHandle xTimer ); + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTimers( unsigned portBASE_TYPE uxNumberOfLEDs ) +{ +unsigned portBASE_TYPE uxLEDTimer; +xTimerHandle xTimer; + + /* Create and start the requested number of timers. */ + for( uxLEDTimer = 0; uxLEDTimer < uxNumberOfLEDs; ++uxLEDTimer ) + { + /* Create the timer. */ + xTimer = xTimerCreate( ( const signed char * const ) "Flasher",/* A text name, purely to help debugging. */ + ledFLASH_RATE_BASE * ( uxLEDTimer + 1 ), /* The timer period, which is a multiple of ledFLASH_RATE_BASE. */ + pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ + ( void * ) uxLEDTimer, /* The ID is used to identify the timer within the timer callback function, as each timer uses the same callback. */ + prvLEDTimerCallback /* Each timer uses the same callback. */ + ); + + /* If the timer was created successfully, attempt to start it. If the + scheduler has not yet been started then the timer command queue must + be long enough to hold each command sent to it until such time that the + scheduler is started. The timer command queue length is set by + configTIMER_QUEUE_LENGTH in FreeRTOSConfig.h. */ + if( xTimer != NULL ) + { + xTimerStart( xTimer, ledDONT_BLOCK ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLEDTimerCallback( xTimerHandle xTimer ) +{ +portBASE_TYPE xTimerID; + + /* The timer ID is used to identify the timer that has actually expired as + each timer uses the same callback. The ID is then also used as the number + of the LED that is to be toggled. */ + xTimerID = ( portBASE_TYPE ) pvTimerGetTimerID( xTimer ); + vParTestToggleLED( xTimerID ); +} + + diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/comtest2.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/comtest2.h new file mode 100644 index 000000000..7014670e5 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/comtest2.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong? * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( unsigned portBASE_TYPE uxPriority, unsigned long ulBaudRate, unsigned portBASE_TYPE uxLED ); +portBASE_TYPE xAreComTestTasksStillRunning( void ); + +#endif + diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/demo_serial.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/demo_serial.h new file mode 100644 index 000000000..afafdd5f4 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/demo_serial.h @@ -0,0 +1,137 @@ +/* + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong? * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +#ifndef SERIAL_COMMS_H +#define SERIAL_COMMS_H + +typedef void * xComPortHandle; + +typedef enum +{ + serCOM1, + serCOM2, + serCOM3, + serCOM4, + serCOM5, + serCOM6, + serCOM7, + serCOM8 +} eCOMPort; + +typedef enum +{ + serNO_PARITY, + serODD_PARITY, + serEVEN_PARITY, + serMARK_PARITY, + serSPACE_PARITY +} eParity; + +typedef enum +{ + serSTOP_1, + serSTOP_2 +} eStopBits; + +typedef enum +{ + serBITS_5, + serBITS_6, + serBITS_7, + serBITS_8 +} eDataBits; + +typedef enum +{ + ser50, + ser75, + ser110, + ser134, + ser150, + ser200, + ser300, + ser600, + ser1200, + ser1800, + ser2400, + ser4800, + ser9600, + ser19200, + ser38400, + ser57600, + ser115200 +} eBaud; + +xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ); +xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength ); +void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ); +signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ); +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ); +portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort ); +void vSerialClose( xComPortHandle xPort ); + +#endif + diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/flash_timer.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/flash_timer.h new file mode 100644 index 000000000..fd0b071eb --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/flash_timer.h @@ -0,0 +1,80 @@ +/* + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong? * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +#ifndef FLASH_TIMER_H +#define FLASH_TIMER_H + +/* + * Creates the LED flashing timers. xNumberOfLEDs specifies how many timers to + * create, with each timer toggling a different LED. The first LED to be + * toggled is LED 0, with subsequent LEDs following on in numerical order. Each + * timer uses the exact same callback function, with the timer ID being used + * within the callback function to determine which timer has actually expired + * (and therefore which LED to toggle). + */ +void vStartLEDFlashTimers( unsigned portBASE_TYPE uxNumberOfLEDs ); + +#endif /* FLASH_TIMER_H */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/partest.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/partest.h new file mode 100644 index 000000000..398239ff8 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/Common-Demo-Source/include/partest.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong? * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +#ifndef PARTEST_H +#define PARTEST_H + +#define partstDEFAULT_PORT_ADDRESS ( ( unsigned short ) 0x378 ) + +void vParTestInitialise( void ); +void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue ); +void vParTestToggleLED( unsigned portBASE_TYPE uxLED ); + +#endif + diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/FreeRTOSConfig.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/FreeRTOSConfig.h index 217b7bb8c..94c791cfa 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/FreeRTOSConfig.h +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/FreeRTOSConfig.h @@ -99,11 +99,11 @@ extern uint32_t SystemCoreClock; #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 40960 ) ) #define configMAX_TASK_NAME_LEN ( 10 ) -#define configUSE_TRACE_FACILITY 1 +#define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_MUTEXES 1 -#define configQUEUE_REGISTRY_SIZE 8 +#define configQUEUE_REGISTRY_SIZE 0 #define configCHECK_FOR_STACK_OVERFLOW 2 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_MALLOC_FAILED_HOOK 1 @@ -112,7 +112,7 @@ extern uint32_t SystemCoreClock; #define configGENERATE_RUN_TIME_STATS 0 /* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 +#define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* Software timer definitions. */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/ParTest.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/ParTest.c index b9e602a23..54fe4976e 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/ParTest.c +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/ParTest.c @@ -100,11 +100,11 @@ void vParTestInitialise( void ) { unsigned long ul; - for( l = 0; l < partestNUM_LEDS; l++ ) + for( ul = 0; ul < partestNUM_LEDS; ul++ ) { /* Configure the LED, before ensuring it starts in the off state. */ - gpio_configure_pin( ulLED[ l ], ( PIO_OUTPUT_1 | PIO_DEFAULT ) ); - vParTestSetLED( l, pdFALSE ); + gpio_configure_pin( ulLED[ ul ], ( PIO_OUTPUT_1 | PIO_DEFAULT ) ); + vParTestSetLED( ul, pdFALSE ); } } /*-----------------------------------------------------------*/ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf.h index 5d7a6cd48..3021332fa 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf.h +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf.h @@ -67,7 +67,14 @@ #include #include -// From module: SAM4S startup code -#include +// From module: PMC - Power Management Controller +#include +#include + +// From module: System Clock Control - SAM4S implementation +#include + +// From module: USART - Univ. Syn Async Rec/Trans +#include #endif // ASF_H diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/genclk.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/genclk.h new file mode 100644 index 000000000..d8f1f623e --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/genclk.h @@ -0,0 +1,172 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2011 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/osc.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/osc.h new file mode 100644 index 000000000..7dc331b24 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/osc.h @@ -0,0 +1,158 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/pll.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/pll.h new file mode 100644 index 000000000..1e700c3a3 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/pll.h @@ -0,0 +1,314 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2011 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/genclk.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/genclk.h new file mode 100644 index 000000000..fc820c22a --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/genclk.h @@ -0,0 +1,264 @@ +/** + * \file + * + * \brief Chip-specific generic clock management. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef CHIP_GENCLK_H_INCLUDED +#define CHIP_GENCLK_H_INCLUDED + +#include +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup genclk_group + * @{ + */ + +//! \name Programmable Clock Identifiers (PCK) +//@{ +#define GENCLK_PCK_0 0 //!< PCK0 ID +#define GENCLK_PCK_1 1 //!< PCK1 ID +#define GENCLK_PCK_2 2 //!< PCK2 ID +//@} + +//! \name Programmable Clock Sources (PCK) +//@{ + +enum genclk_source { + GENCLK_PCK_SRC_SLCK_RC = 0, //!< Internal 32kHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_SLCK_XTAL = 1, //!< External 32kHz crystal oscillator as PCK source clock + GENCLK_PCK_SRC_SLCK_BYPASS = 2, //!< External 32kHz bypass oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_4M_RC = 3, //!< Internal 4MHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_8M_RC = 4, //!< Internal 8MHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_12M_RC = 5, //!< Internal 12MHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_XTAL = 6, //!< External crystal oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_BYPASS = 7, //!< External bypass oscillator as PCK source clock + GENCLK_PCK_SRC_PLLACK = 8, //!< Use PLLACK as PCK source clock + GENCLK_PCK_SRC_PLLBCK = 9, //!< Use PLLBCK as PCK source clock +}; + +//@} + +//! \name Programmable Clock Prescalers (PCK) +//@{ + +enum genclk_divider { + GENCLK_PCK_PRES_1 = PMC_PCK_PRES_CLK_1, //!< Set PCK clock prescaler to 1 + GENCLK_PCK_PRES_2 = PMC_PCK_PRES_CLK_2, //!< Set PCK clock prescaler to 2 + GENCLK_PCK_PRES_4 = PMC_PCK_PRES_CLK_4, //!< Set PCK clock prescaler to 4 + GENCLK_PCK_PRES_8 = PMC_PCK_PRES_CLK_8, //!< Set PCK clock prescaler to 8 + GENCLK_PCK_PRES_16 = PMC_PCK_PRES_CLK_16, //!< Set PCK clock prescaler to 16 + GENCLK_PCK_PRES_32 = PMC_PCK_PRES_CLK_32, //!< Set PCK clock prescaler to 32 + GENCLK_PCK_PRES_64 = PMC_PCK_PRES_CLK_64, //!< Set PCK clock prescaler to 64 +}; + +//@} + +struct genclk_config { + uint32_t ctrl; +}; + +static inline void genclk_config_defaults(struct genclk_config *p_cfg, + uint32_t ul_id) +{ + ul_id = ul_id; + p_cfg->ctrl = 0; +} + +static inline void genclk_config_read(struct genclk_config *p_cfg, + uint32_t ul_id) +{ + p_cfg->ctrl = PMC->PMC_PCK[ul_id]; +} + +static inline void genclk_config_write(const struct genclk_config *p_cfg, + uint32_t ul_id) +{ + PMC->PMC_PCK[ul_id] = p_cfg->ctrl; +} + +//! \name Programmable Clock Source and Prescaler configuration +//@{ + +static inline void genclk_config_set_source(struct genclk_config *p_cfg, + enum genclk_source e_src) +{ + p_cfg->ctrl &= (~PMC_PCK_CSS_Msk); + + switch (e_src) { + case GENCLK_PCK_SRC_SLCK_RC: + case GENCLK_PCK_SRC_SLCK_XTAL: + case GENCLK_PCK_SRC_SLCK_BYPASS: + p_cfg->ctrl |= (PMC_MCKR_CSS_SLOW_CLK); + break; + + case GENCLK_PCK_SRC_MAINCK_4M_RC: + case GENCLK_PCK_SRC_MAINCK_8M_RC: + case GENCLK_PCK_SRC_MAINCK_12M_RC: + case GENCLK_PCK_SRC_MAINCK_XTAL: + case GENCLK_PCK_SRC_MAINCK_BYPASS: + p_cfg->ctrl |= (PMC_MCKR_CSS_MAIN_CLK); + break; + + case GENCLK_PCK_SRC_PLLACK: + p_cfg->ctrl |= (PMC_MCKR_CSS_PLLA_CLK); + break; + + case GENCLK_PCK_SRC_PLLBCK: + p_cfg->ctrl |= (PMC_MCKR_CSS_PLLB_CLK); + break; + } +} + +static inline void genclk_config_set_divider(struct genclk_config *p_cfg, + enum genclk_divider e_divider) +{ + p_cfg->ctrl &= ~PMC_PCK_PRES_Msk; + p_cfg->ctrl |= e_divider; +} + +//@} + +static inline void genclk_enable(const struct genclk_config *p_cfg, uint32_t ul_id) +{ + PMC->PMC_PCK[ul_id] = p_cfg->ctrl; + pmc_enable_pck(ul_id); +} + +static inline void genclk_disable(uint32_t ul_id) +{ + pmc_disable_pck(ul_id); +} + +static inline void genclk_enable_source(enum genclk_source e_src) +{ + switch (e_src) { + case GENCLK_PCK_SRC_SLCK_RC: + if (!osc_is_ready(OSC_SLCK_32K_RC)) { + osc_enable(OSC_SLCK_32K_RC); + osc_wait_ready(OSC_SLCK_32K_RC); + } + break; + + case GENCLK_PCK_SRC_SLCK_XTAL: + if (!osc_is_ready(OSC_SLCK_32K_XTAL)) { + osc_enable(OSC_SLCK_32K_XTAL); + osc_wait_ready(OSC_SLCK_32K_XTAL); + } + break; + + case GENCLK_PCK_SRC_SLCK_BYPASS: + if (!osc_is_ready(OSC_SLCK_32K_BYPASS)) { + osc_enable(OSC_SLCK_32K_BYPASS); + osc_wait_ready(OSC_SLCK_32K_BYPASS); + } + break; + + case GENCLK_PCK_SRC_MAINCK_4M_RC: + if (!osc_is_ready(OSC_MAINCK_4M_RC)) { + osc_enable(OSC_MAINCK_4M_RC); + osc_wait_ready(OSC_MAINCK_4M_RC); + } + break; + + case GENCLK_PCK_SRC_MAINCK_8M_RC: + if (!osc_is_ready(OSC_MAINCK_8M_RC)) { + osc_enable(OSC_MAINCK_8M_RC); + osc_wait_ready(OSC_MAINCK_8M_RC); + } + break; + + case GENCLK_PCK_SRC_MAINCK_12M_RC: + if (!osc_is_ready(OSC_MAINCK_12M_RC)) { + osc_enable(OSC_MAINCK_12M_RC); + osc_wait_ready(OSC_MAINCK_12M_RC); + } + break; + + case GENCLK_PCK_SRC_MAINCK_XTAL: + if (!osc_is_ready(OSC_MAINCK_XTAL)) { + osc_enable(OSC_MAINCK_XTAL); + osc_wait_ready(OSC_MAINCK_XTAL); + } + break; + + case GENCLK_PCK_SRC_MAINCK_BYPASS: + if (!osc_is_ready(OSC_MAINCK_BYPASS)) { + osc_enable(OSC_MAINCK_BYPASS); + osc_wait_ready(OSC_MAINCK_BYPASS); + } + break; + +#ifdef CONFIG_PLL0_SOURCE + case GENCLK_PCK_SRC_PLLACK: + pll_enable_config_defaults(0); + break; +#endif + +#ifdef CONFIG_PLL1_SOURCE + case GENCLK_PCK_SRC_PLLBCK: + pll_enable_config_defaults(1); + break; +#endif + + default: + Assert(false); + break; + } +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_GENCLK_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/osc.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/osc.h new file mode 100644 index 000000000..353969a92 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/osc.h @@ -0,0 +1,217 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions. + * + * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef CHIP_OSC_H_INCLUDED +#define CHIP_OSC_H_INCLUDED + +#include "board.h" +#include "pmc.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup osc_group + * @{ + */ + +//! \name Oscillator identifiers +//@{ +#define OSC_SLCK_32K_RC 0 //!< Internal 32kHz RC oscillator. +#define OSC_SLCK_32K_XTAL 1 //!< External 32kHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS 2 //!< External 32kHz bypass oscillator. +#define OSC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator. +#define OSC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator. +#define OSC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator. +#define OSC_MAINCK_XTAL 6 //!< External crystal oscillator. +#define OSC_MAINCK_BYPASS 7 //!< External bypass oscillator. +//@} + +//! \name Oscillator clock speed in hertz +//@{ +#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32kHz RC oscillator. +#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32kHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32kHz bypass oscillator. +#define OSC_MAINCK_4M_RC_HZ CHIP_FREQ_MAINCK_RC_4MHZ //!< Internal 4MHz RC oscillator. +#define OSC_MAINCK_8M_RC_HZ CHIP_FREQ_MAINCK_RC_8MHZ //!< Internal 8MHz RC oscillator. +#define OSC_MAINCK_12M_RC_HZ CHIP_FREQ_MAINCK_RC_12MHZ //!< Internal 12MHz RC oscillator. +#define OSC_MAINCK_XTAL_HZ BOARD_FREQ_MAINCK_XTAL //!< External crystal oscillator. +#define OSC_MAINCK_BYPASS_HZ BOARD_FREQ_MAINCK_BYPASS //!< External bypass oscillator. +//@} + +static inline void osc_enable(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + break; + + case OSC_SLCK_32K_XTAL: + pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + break; + + case OSC_SLCK_32K_BYPASS: + pmc_switch_sclk_to_32kxtal(PMC_OSC_BYPASS); + break; + + + case OSC_MAINCK_4M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + break; + + case OSC_MAINCK_8M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + break; + + case OSC_MAINCK_12M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + break; + + + case OSC_MAINCK_XTAL: + pmc_switch_mainck_to_xtal(PMC_OSC_XTAL); + break; + + case OSC_MAINCK_BYPASS: + pmc_switch_mainck_to_xtal(PMC_OSC_BYPASS); + break; + } +} + +static inline void osc_disable(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + case OSC_SLCK_32K_XTAL: + case OSC_SLCK_32K_BYPASS: + break; + + case OSC_MAINCK_4M_RC: + case OSC_MAINCK_8M_RC: + case OSC_MAINCK_12M_RC: + pmc_osc_disable_fastrc(); + break; + + case OSC_MAINCK_XTAL: + pmc_osc_disable_xtal(PMC_OSC_XTAL); + break; + + case OSC_MAINCK_BYPASS: + pmc_osc_disable_xtal(PMC_OSC_BYPASS); + break; + } +} + +static inline bool osc_is_ready(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + return 1; + + case OSC_SLCK_32K_XTAL: + case OSC_SLCK_32K_BYPASS: + return pmc_osc_is_ready_32kxtal(); + + case OSC_MAINCK_4M_RC: + case OSC_MAINCK_8M_RC: + case OSC_MAINCK_12M_RC: + case OSC_MAINCK_XTAL: + case OSC_MAINCK_BYPASS: + return pmc_osc_is_ready_mainck(); + } + + return 0; +} + +static inline uint32_t osc_get_rate(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + return OSC_SLCK_32K_RC_HZ; + +#ifdef BOARD_FREQ_SLCK_XTAL + case OSC_SLCK_32K_XTAL: + return BOARD_FREQ_SLCK_XTAL; +#endif + +#ifdef BOARD_FREQ_SLCK_BYPASS + case OSC_SLCK_32K_BYPASS: + return BOARD_FREQ_SLCK_BYPASS; +#endif + + case OSC_MAINCK_4M_RC: + return OSC_MAINCK_4M_RC_HZ; + + case OSC_MAINCK_8M_RC: + return OSC_MAINCK_8M_RC_HZ; + + case OSC_MAINCK_12M_RC: + return OSC_MAINCK_12M_RC_HZ; + +#ifdef BOARD_FREQ_MAINCK_XTAL + case OSC_MAINCK_XTAL: + return BOARD_FREQ_MAINCK_XTAL; +#endif + +#ifdef BOARD_FREQ_MAINCK_BYPASS + case OSC_MAINCK_BYPASS: + return BOARD_FREQ_MAINCK_BYPASS; +#endif + } + + return 0; +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_OSC_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/pll.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/pll.h new file mode 100644 index 000000000..ef0d28663 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/pll.h @@ -0,0 +1,241 @@ +/** + * \file + * + * \brief Chip-specific PLL definitions. + * + * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef CHIP_PLL_H_INCLUDED +#define CHIP_PLL_H_INCLUDED + +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup pll_group + * @{ + */ + +#define PLL_OUTPUT_MIN_HZ 80000000 +#define PLL_OUTPUT_MAX_HZ 240000000 + +#define PLL_INPUT_MIN_HZ 3000000 +#define PLL_INPUT_MAX_HZ 32000000 + +#define NR_PLLS 2 +#define PLLA_ID 0 +#define PLLB_ID 1 + +#define PLL_COUNT 0x3fU + +enum pll_source { + PLL_SRC_MAINCK_4M_RC = OSC_MAINCK_4M_RC, //!< Internal 4MHz RC oscillator. + PLL_SRC_MAINCK_8M_RC = OSC_MAINCK_8M_RC, //!< Internal 8MHz RC oscillator. + PLL_SRC_MAINCK_12M_RC = OSC_MAINCK_12M_RC, //!< Internal 12MHz RC oscillator. + PLL_SRC_MAINCK_XTAL = OSC_MAINCK_XTAL, //!< External crystal oscillator. + PLL_SRC_MAINCK_BYPASS = OSC_MAINCK_BYPASS, //!< External bypass oscillator. + PLL_NR_SOURCES, //!< Number of PLL sources. +}; + +struct pll_config { + uint32_t ctrl; +}; + +#define pll_get_default_rate(pll_id) \ + ((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE) \ + * CONFIG_PLL##pll_id##_MUL) \ + / CONFIG_PLL##pll_id##_DIV) + +/** + * \note The SAM3S PLL hardware interprets mul as mul+1. For readability the hardware mul+1 + * is hidden in this implementation. Use mul as mul effective value. + */ +static inline void pll_config_init(struct pll_config *p_cfg, + enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul) +{ + uint32_t vco_hz; + + Assert(e_src < PLL_NR_SOURCES); + + /* Calculate internal VCO frequency */ + vco_hz = osc_get_rate(e_src) / ul_div; + Assert(vco_hz >= PLL_INPUT_MIN_HZ); + Assert(vco_hz <= PLL_INPUT_MAX_HZ); + + vco_hz *= ul_mul; + Assert(vco_hz >= PLL_OUTPUT_MIN_HZ); + Assert(vco_hz <= PLL_OUTPUT_MAX_HZ); + + /* PMC hardware will automatically make it mul+1 */ + p_cfg->ctrl = CKGR_PLLAR_MULA(ul_mul - 1) | CKGR_PLLAR_DIVA(ul_div) | CKGR_PLLAR_PLLACOUNT(PLL_COUNT); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) + p_cfg->ctrl = PMC->CKGR_PLLAR; + else + p_cfg->ctrl = PMC->CKGR_PLLBR; +} + +static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + pmc_disable_pllack(); // Always stop PLL first! + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; + } else { + pmc_disable_pllbck(); + PMC->CKGR_PLLBR = p_cfg->ctrl; + } +} + +static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + pmc_disable_pllack(); // Always stop PLL first! + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; + } else { + pmc_disable_pllbck(); + PMC->CKGR_PLLBR = p_cfg->ctrl; + } +} + +/** + * \note This will only disable the selected PLL, not the underlying oscillator (mainck). + */ +static inline void pll_disable(uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) + pmc_disable_pllack(); + else + pmc_disable_pllbck(); +} + +static inline uint32_t pll_is_locked(uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) + return pmc_is_locked_pllack(); + else + return pmc_is_locked_pllbck(); +} + +static inline void pll_enable_source(enum pll_source e_src) +{ + switch (e_src) { + case PLL_SRC_MAINCK_4M_RC: + case PLL_SRC_MAINCK_8M_RC: + case PLL_SRC_MAINCK_12M_RC: + case PLL_SRC_MAINCK_XTAL: + case PLL_SRC_MAINCK_BYPASS: + osc_enable(e_src); + osc_wait_ready(e_src); + break; + + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int ul_pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(ul_pll_id)) { + return; // Pll already running + } + switch (ul_pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif +#ifdef CONFIG_PLL1_SOURCE + case 1: + pll_enable_source(CONFIG_PLL1_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL1_SOURCE, + CONFIG_PLL1_DIV, + CONFIG_PLL1_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, ul_pll_id); + while (!pll_is_locked(ul_pll_id)); +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_PLL_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.c new file mode 100644 index 000000000..9ea91379f --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.c @@ -0,0 +1,265 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup sysclk_group + * @{ + */ + +#if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +/** + * \brief boolean signaling that the sysclk_init is done. + */ +uint32_t sysclk_initialized = 0; +#endif + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param cpu_shift The CPU clock will be divided by \f$2^{mck\_pres}\f$ + */ +void sysclk_set_prescalers(uint32_t ul_pres) +{ + pmc_mck_set_prescaler(ul_pres); + SystemCoreClockUpdate(); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +void sysclk_set_source(uint32_t ul_src) +{ + switch (ul_src) { + case SYSCLK_SRC_SLCK_RC: + case SYSCLK_SRC_SLCK_XTAL: + case SYSCLK_SRC_SLCK_BYPASS: + pmc_mck_set_source(PMC_MCKR_CSS_SLOW_CLK); + break; + + case SYSCLK_SRC_MAINCK_4M_RC: + case SYSCLK_SRC_MAINCK_8M_RC: + case SYSCLK_SRC_MAINCK_12M_RC: + case SYSCLK_SRC_MAINCK_XTAL: + case SYSCLK_SRC_MAINCK_BYPASS: + pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK); + break; + + case SYSCLK_SRC_PLLACK: + pmc_mck_set_source(PMC_MCKR_CSS_PLLA_CLK); + break; + + case SYSCLK_SRC_PLLBCK: + pmc_mck_set_source(PMC_MCKR_CSS_PLLB_CLK); + break; + } + + SystemCoreClockUpdate(); +} + +#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +/** + * \brief Enable USB clock. + * + * \note The SAM3S UDP hardware interprets div as div+1. For readability the hardware div+1 + * is hidden in this implementation. Use div as div effective value. + * + * \param pll_id Source of the USB clock. + * \param div Actual clock diviser. Must be superior to 0. + */ +void sysclk_enable_usb(void) +{ + Assert(CONFIG_USBCLK_DIV > 0); + + switch (CONFIG_USBCLK_SOURCE) { +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL0: { + struct pll_config pllcfg; + + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1); + pmc_enable_udpck(); + break; + } +#endif + +#ifdef CONFIG_PLL1_SOURCE + case USBCLK_SRC_PLL1: { + struct pll_config pllcfg; + + pll_enable_source(CONFIG_PLL1_SOURCE); + pll_config_defaults(&pllcfg, 1); + pll_enable(&pllcfg, 1); + pll_wait_for_lock(1); + pmc_switch_udpck_to_pllbck(CONFIG_USBCLK_DIV - 1); + pmc_enable_udpck(); + break; + } +#endif + } +} + +/** + * \brief Disable the USB clock. + * + * \note This implementation does not switch off the PLL, it just turns off the USB clock. + */ +void sysclk_disable_usb(void) +{ + pmc_disable_udpck(); +} +#endif // CONFIG_USBCLK_SOURCE + +void sysclk_init(void) +{ + struct pll_config pllcfg; + + /* Set a flash wait state depending on the new cpu frequency */ + system_init_flash(sysclk_get_cpu_hz()); + + /* Config system clock setting */ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_SLCK_RC: + osc_enable(OSC_SLCK_32K_RC); + osc_wait_ready(OSC_SLCK_32K_RC); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_SLCK_XTAL: + osc_enable(OSC_SLCK_32K_XTAL); + osc_wait_ready(OSC_SLCK_32K_XTAL); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_SLCK_BYPASS: + osc_enable(OSC_SLCK_32K_BYPASS); + osc_wait_ready(OSC_SLCK_32K_BYPASS); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_MAINCK_4M_RC: + /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ + break; + + case SYSCLK_SRC_MAINCK_8M_RC: + osc_enable(OSC_MAINCK_8M_RC); + osc_wait_ready(OSC_MAINCK_8M_RC); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_MAINCK_12M_RC: + osc_enable(OSC_MAINCK_12M_RC); + osc_wait_ready(OSC_MAINCK_12M_RC); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + + + case SYSCLK_SRC_MAINCK_XTAL: + osc_enable(OSC_MAINCK_XTAL); + osc_wait_ready(OSC_MAINCK_XTAL); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + + case SYSCLK_SRC_MAINCK_BYPASS: + osc_enable(OSC_MAINCK_BYPASS); + osc_wait_ready(OSC_MAINCK_BYPASS); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLLACK: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); + break; +#endif + +#ifdef CONFIG_PLL1_SOURCE + case SYSCLK_SRC_PLLBCK: + pll_enable_source(CONFIG_PLL1_SOURCE); + pll_config_defaults(&pllcfg, 1); + pll_enable(&pllcfg, 1); + pll_wait_for_lock(1); + pmc_switch_mck_to_pllbck(CONFIG_SYSCLK_PRES); + break; +#endif + } + + /* Update the SystemFrequency variable */ + SystemCoreClockUpdate(); + +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + /* Signal that the internal frequencies are setup */ + sysclk_initialized = 1; +#endif +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.h new file mode 100644 index 000000000..e72951a03 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sam4s/sysclk.h @@ -0,0 +1,442 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef CHIP_SYSCLK_H_INCLUDED +#define CHIP_SYSCLK_H_INCLUDED + +#include +#include + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (SAM4S) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 120MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / BUS_div + * #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 + * \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode + * -# Configure the PLL module to use the fast external fast crystal oscillator as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode + * -# Configure the PLL module to multiply the external fast crystal oscillator frequency up to 120MHz: + * \code + * #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the board \c conf_board.h configuration + * file as the frequency of the fast crystal attached to the microcontroller. + * -# Configure the main clock to run at the full 120MHz, disable scaling of the main system clock speed: + * \code + * #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (SAM4S) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 120MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The USB clock + * will be configured via a seperate PLL module. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + * sysclk_init(); + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + * #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK + * + * // Fpll0 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL0_DIV 1 + * + * // Fbus = Fsys / BUS_div + * #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 + * + * // Fusb = Fsys / USB_div + * #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + * #define CONFIG_USBCLK_DIV 1 + * + * // Fpll1 = (Fclk * PLL_mul) / PLL_div + * #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + * #define CONFIG_PLL1_MUL (48000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL1_DIV 1 + * \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL0 module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode + * -# Configure the PLL0 module to use the fast external fast crystal oscillator as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode + * -# Configure the PLL0 module to multiply the external fast crystal oscillator frequency up to 120MHz: + * \code + * #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL0_DIV 1 + * \endcode + * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the board \c conf_board.h configuration + * file as the frequency of the fast crystal attached to the microcontroller. + * -# Configure the main clock to run at the full 120MHz, disable scaling of the main system clock speed: + * \code + * #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 + * \endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the output of the PLL1 module as its source: + * \code #define CONFIG_SYSCLK_SOURCE USBCLK_SRC_PLL1 \endcode + * -# Configure the PLL1 module to use the fast external fast crystal oscillator as its source: + * \code #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL \endcode + * -# Configure the PLL1 module to multiply the external fast crystal oscillator frequency up to 48MHz: + * \code + * #define CONFIG_PLL1_MUL (48000000UL / BOARD_FREQ_MAINCK_XTAL) + * #define CONFIG_PLL1_DIV 1 + * \endcode + */ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup sysclk_group + * @{ + */ + +//! \name Configuration Symbols +//@{ +/** + * \def CONFIG_SYSCLK_SOURCE + * \brief Initial/static main system clock source + * + * The main system clock will be configured to use this clock during + * initialization. + */ +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC +#endif +/** + * \def CONFIG_SYSCLK_PRES + * \brief Initial CPU clock divider (mck) + * + * The MCK will run at + * \f[ + * f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz} + * \f] + * after initialization. + */ +#ifndef CONFIG_SYSCLK_PRES +# define CONFIG_SYSCLK_PRES 0 +#endif + +//@} + +//! \name Master Clock Sources (MCK) +//@{ +#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock +#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock +#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock +#define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_XTAL 6 //!< External crystal oscillator as master source clock +#define SYSCLK_SRC_MAINCK_BYPASS 7 //!< External bypass oscillator as master source clock +#define SYSCLK_SRC_PLLACK 8 //!< Use PLLACK as master source clock +#define SYSCLK_SRC_PLLBCK 9 //!< Use PLLBCK as master source clock +//@} + +//! \name Master Clock Prescalers (MCK) +//@{ +#define SYSCLK_PRES_1 PMC_MCKR_PRES_CLK_1 //!< Set master clock prescaler to 1 +#define SYSCLK_PRES_2 PMC_MCKR_PRES_CLK_2 //!< Set master clock prescaler to 2 +#define SYSCLK_PRES_4 PMC_MCKR_PRES_CLK_4 //!< Set master clock prescaler to 4 +#define SYSCLK_PRES_8 PMC_MCKR_PRES_CLK_8 //!< Set master clock prescaler to 8 +#define SYSCLK_PRES_16 PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16 +#define SYSCLK_PRES_32 PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32 +#define SYSCLK_PRES_64 PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64 +#define SYSCLK_PRES_3 PMC_MCKR_PRES_CLK_3 //!< Set master clock prescaler to 3 +//@} + +//! \name USB Clock Sources +//@{ +#define USBCLK_SRC_PLL0 0 //!< Use PLLA +#define USBCLK_SRC_PLL1 1 //!< Use PLLB +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB generic clock source + * + * Sets the clock source to use for the USB. The source must also be properly + * configured. + * + * Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if + * USB is not required. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +/** + * \def CONFIG_USBCLK_DIV + * \brief Configuration symbol for the USB generic clock divider setting + * + * Sets the clock division for the USB generic clock. If a USB clock source is + * selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be + * defined. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_DIV +#endif + +/** + * \name Querying the system clock + * + * The following functions may be used to query the current frequency of + * the system clock and the CPU and bus clocks derived from it. + * sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be + * available on all platforms, although some platforms may define + * additional accessors for various chip-internal bus clocks. These are + * usually not intended to be queried directly by generic code. + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + */ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +extern uint32_t sysclk_initialized; +#endif +static inline uint32_t sysclk_get_main_hz(void) +{ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + if (!sysclk_initialized ) { + return OSC_MAINCK_4M_RC_HZ; + } +#endif + + /* Config system clock setting */ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_SLCK_RC: + return OSC_SLCK_32K_RC_HZ; + + case SYSCLK_SRC_SLCK_XTAL: + return OSC_SLCK_32K_XTAL_HZ; + + case SYSCLK_SRC_SLCK_BYPASS: + return OSC_SLCK_32K_BYPASS_HZ; + + + case SYSCLK_SRC_MAINCK_4M_RC: + return OSC_MAINCK_4M_RC_HZ; + + case SYSCLK_SRC_MAINCK_8M_RC: + return OSC_MAINCK_8M_RC_HZ; + + case SYSCLK_SRC_MAINCK_12M_RC: + return OSC_MAINCK_12M_RC_HZ; + + case SYSCLK_SRC_MAINCK_XTAL: + return OSC_MAINCK_XTAL_HZ; + + case SYSCLK_SRC_MAINCK_BYPASS: + return OSC_MAINCK_BYPASS_HZ; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLLACK: + return pll_get_default_rate(0); +#endif + +#ifdef CONFIG_PLL1_SOURCE + case SYSCLK_SRC_PLLBCK: + return pll_get_default_rate(1); +#endif + + default: + /* unhandled_case(CONFIG_SYSCLK_SOURCE); */ + return 0; + } +} + +/** + * \brief Return the current rate in Hz of the CPU clock + * + * \todo This function assumes that the CPU always runs at the system + * clock frequency. We want to support at least two more scenarios: + * Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus + * clock dividers (which may change at run time). Ditto for all the bus + * clocks. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + /* CONFIG_SYSCLK_PRES is the register value for setting the expected */ + /* prescaler, not an immediat value. */ + return sysclk_get_main_hz() / ((CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos) + 1); +} + +/** + * \brief Retrieves the current rate in Hz of the peripheral clocks. + * + * \return Frequency of the peripheral clocks, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_hz(void) +{ + /* CONFIG_SYSCLK_PRES is the register value for setting the expected */ + /* prescaler, not an immediat value. */ + return sysclk_get_main_hz() / ((CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos) + 1); +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable a peripheral's clock. + * + * \param ul_id Id (number) of the peripheral clock. + */ +static inline void sysclk_enable_peripheral_clock(uint32_t ul_id) +{ + pmc_enable_periph_clk(ul_id); +} + +/** + * \brief Disable a peripheral's clock. + * + * \param ul_id Id (number) of the peripheral clock. + */ +static inline void sysclk_disable_peripheral_clock(uint32_t ul_id) +{ + pmc_disable_periph_clk(ul_id); +} + +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +extern void sysclk_set_prescalers(uint32_t ul_pres); +extern void sysclk_set_source(uint32_t ul_src); + +//@} + +extern void sysclk_enable_usb(void); +extern void sysclk_disable_usb(void); + +extern void sysclk_init(void); + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_SYSCLK_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sysclk.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sysclk.h new file mode 100644 index 000000000..a154460f1 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/common/services/clock/sysclk.h @@ -0,0 +1,165 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.c new file mode 100644 index 000000000..1a992e2e2 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.c @@ -0,0 +1,1058 @@ +/** + * \file + * + * \brief Power Management Controller (PMC) driver for SAM. + * + * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "pmc.h" + +#if (SAM3N) +# define MAX_PERIPH_ID 31 +#elif (SAM3XA) +# define MAX_PERIPH_ID 44 +#elif (SAM3U) +# define MAX_PERIPH_ID 29 +#elif (SAM3S || SAM4S) +# define MAX_PERIPH_ID 34 +#endif + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \defgroup sam_drivers_pmc_group Power Management Controller (PMC) + * + * \par Purpose + * + * The Power Management Controller (PMC) optimizes power consumption by controlling + * all system and user peripheral clocks. The PMC enables/disables the clock inputs + * to many of the peripherals and the Cortex-M Processor. + * + * @{ + */ + +/** + * \brief Set the prescaler of the MCK. + * + * \param ul_pres Prescaler value. + */ +void pmc_mck_set_prescaler(uint32_t ul_pres) +{ + PMC->PMC_MCKR = + (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); +} + +/** + * \brief Set the source of the MCK. + * + * \param ul_source Source selection value. + */ +void pmc_mck_set_source(uint32_t ul_source) +{ + PMC->PMC_MCKR = + (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | ul_source; + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); +} + +/** + * \brief Switch master clock source selection to slow clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | PMC_MCKR_CSS_SLOW_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch master clock source selection to main clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_MAIN_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch master clock source selection to PLLA clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_PLLA_CLK; + + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +#if (SAM3S || SAM4S) +/** + * \brief Switch master clock source selection to PLLB clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_PLLB_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +#if (SAM3XA || SAM3U) +/** + * \brief Switch master clock source selection to UPLL clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_UPLL_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +/** + * \brief Switch slow clock source selection to external 32k (Xtal or Bypass). + * + * \note This function disables the PLLs. + * + * \note Switching SCLK back to 32krc is only possible by shutting down the VDDIO + * power supply. + * + * \param ul_bypass 0 for Xtal, 1 for bypass. + */ +void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass) +{ + /* Set Bypass mode if required */ + if (ul_bypass == 1) { + SUPC->SUPC_MR |= SUPC_MR_KEY(SUPC_KEY_VALUE) | + SUPC_MR_OSCBYPASS; + } + + SUPC->SUPC_CR |= SUPC_CR_KEY(SUPC_KEY_VALUE) | SUPC_CR_XTALSEL; +} + +/** + * \brief Check if the external 32k Xtal is ready. + * + * \retval 1 External 32k Xtal is ready. + * \retval 0 External 32k Xtal is not ready. + */ +uint32_t pmc_osc_is_ready_32kxtal(void) +{ + return ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) + && (PMC->PMC_SR & PMC_SR_OSCSELS)); +} + +/** + * \brief Switch main clock source selection to internal fast RC. + * + * \param ul_moscrcf Fast RC oscillator(4/8/12Mhz). + * + * \retval 0 Success. + * \retval 1 Timeout error. + * \retval 2 Invalid frequency. + */ +void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf) +{ + uint32_t ul_needXTEN = 0; + + /* Enable Fast RC oscillator but DO NOT switch to RC now */ + if (PMC->CKGR_MOR & CKGR_MOR_MOSCXTEN) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) | + PMC_CKGR_MOR_KEY_VALUE | CKGR_MOR_MOSCRCEN | + ul_moscrcf; + } else { + ul_needXTEN = 1; + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) | + PMC_CKGR_MOR_KEY_VALUE | CKGR_MOR_MOSCRCEN | + CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCXTST(PMC_XTAL_STARTUP_TIME) | + ul_moscrcf; + } + + /* Wait the Fast RC to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); + + /* Switch to Fast RC */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | PMC_CKGR_MOR_KEY_VALUE; + + // BUG FIX : clock_example3_sam3s does not switch sclk->mainck with XT disabled. + if (ul_needXTEN) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | + PMC_CKGR_MOR_KEY_VALUE; + } +} + +/** + * \brief Enable fast RC oscillator. + * + * \param ul_rc Fast RC oscillator(4/8/12Mhz). + */ +void pmc_osc_enable_fastrc(uint32_t ul_rc) +{ + /* Enable Fast RC oscillator but DO NOT switch to RC now. Keep MOSCSEL to 1 */ + PMC->CKGR_MOR = PMC_CKGR_MOR_KEY_VALUE | CKGR_MOR_MOSCSEL | + CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCRCEN | ul_rc; + /* Wait the Fast RC to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); +} + +/** + * \brief Disable the internal fast RC. + */ +void pmc_osc_disable_fastrc(void) +{ + /* Disable Fast RC oscillator */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN) | PMC_CKGR_MOR_KEY_VALUE; +} + +/** + * \brief Switch main clock source selection to external Xtal/Bypass. + * The function may switch MCK to SCLK if MCK source is MAINCK to avoid any + * system crash. + * + * \note If used in Xtal mode, the Xtal is automatically enabled. + * + * \param ul_bypass 0 for Xtal, 1 for bypass. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +void pmc_switch_mainck_to_xtal(uint32_t ul_bypass) +{ + /* Enable Main Xtal oscillator */ + if (ul_bypass) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | + PMC_CKGR_MOR_KEY_VALUE | CKGR_MOR_MOSCXTBY | + CKGR_MOR_MOSCSEL; + } else { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | + PMC_CKGR_MOR_KEY_VALUE | CKGR_MOR_MOSCXTEN | + CKGR_MOR_MOSCXTST(PMC_XTAL_STARTUP_TIME); + /* Wait the Xtal to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)); + + PMC->CKGR_MOR |= PMC_CKGR_MOR_KEY_VALUE | CKGR_MOR_MOSCSEL; + } +} + +/** + * \brief Disable the external Xtal. + * + * \param ul_bypass 0 for Xtal, 1 for bypass. + */ +void pmc_osc_disable_xtal(uint32_t ul_bypass) +{ + /* Disable xtal oscillator */ + if (ul_bypass) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | + PMC_CKGR_MOR_KEY_VALUE; + } else { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | + PMC_CKGR_MOR_KEY_VALUE; + } +} + +/** + * \brief Check if the MAINCK is ready. Depending on MOSCEL, MAINCK can be one + * of Xtal, bypass or internal RC. + * + * \retval 1 Xtal is ready. + * \retval 0 Xtal is not ready. + */ +uint32_t pmc_osc_is_ready_mainck(void) +{ + return PMC->PMC_SR & PMC_SR_MOSCSELS; +} + +/** + * \brief Enable PLLA clock. + * + * \param mula PLLA multiplier. + * \param pllacount PLLA counter. + * \param diva Divider. + */ +void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva) +{ + pmc_disable_pllack(); // Hardware BUG FIX : first disable the PLL to unlock the lock! + // It occurs when re-enabling the PLL with the same parameters. + + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_DIVA(diva) | + CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula); + while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0); +} + +/** + * \brief Disable PLLA clock. + */ +void pmc_disable_pllack(void) +{ + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0); +} + +/** + * \brief Is PLLA locked? + * + * \retval 0 Not locked. + * \retval 1 Locked. + */ +uint32_t pmc_is_locked_pllack(void) +{ + return (PMC->PMC_SR & PMC_SR_LOCKA); +} + +#if (SAM3S || SAM4S) +/** + * \brief Enable PLLB clock. + * + * \param mulb PLLB multiplier. + * \param pllbcount PLLB counter. + * \param divb Divider. + */ +void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb) +{ + pmc_disable_pllbck(); // Hardware BUG FIX : first disable the PLL to unlock the lock! + // It occurs when re-enabling the PLL with the same parameters. + PMC->CKGR_PLLBR = + CKGR_PLLBR_DIVB(divb) | CKGR_PLLBR_PLLBCOUNT(pllbcount) + | CKGR_PLLBR_MULB(mulb); + while ((PMC->PMC_SR & PMC_SR_LOCKB) == 0); +} + +/** + * \brief Disable PLLB clock. + */ +void pmc_disable_pllbck(void) +{ + PMC->CKGR_PLLBR = CKGR_PLLBR_MULB(0); +} + +/** + * \brief Is PLLB locked? + * + * \retval 0 Not locked. + * \retval 1 Locked. + */ +uint32_t pmc_is_locked_pllbck(void) +{ + return (PMC->PMC_SR & PMC_SR_LOCKB); +} +#endif + +#if (SAM3XA || SAM3U) +/** + * \brief Enable UPLL clock. + */ +void pmc_enable_upll_clock(void) +{ + PMC->CKGR_UCKR = CKGR_UCKR_UPLLCOUNT(3) | CKGR_UCKR_UPLLEN; + + /* Wait UTMI PLL Lock Status */ + while (!(PMC->PMC_SR & PMC_SR_LOCKU)); +} + +/** + * \brief Disable UPLL clock. + */ +void pmc_disable_upll_clock(void) +{ + PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN; +} + +/** + * \brief Is UPLL locked? + * + * \retval 0 Not locked. + * \retval 1 Locked. + */ +uint32_t pmc_is_locked_upll(void) +{ + return (PMC->PMC_SR & PMC_SR_LOCKU); +} +#endif + +/** + * \brief Enable the specified peripheral clock. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Success. + * \retval 1 Invalid parameter. + */ +uint32_t pmc_enable_periph_clk(uint32_t ul_id) +{ + if (ul_id > MAX_PERIPH_ID) { + return 1; + } + + if (ul_id < 32) { + if ((PMC->PMC_PCSR0 & (1u << ul_id)) != (1u << ul_id)) { + PMC->PMC_PCER0 = 1 << ul_id; + } +#if (SAM3S || SAM3XA || SAM4S) + } else { + ul_id -= 32; + if ((PMC->PMC_PCSR1 & (1u << ul_id)) != (1u << ul_id)) { + PMC->PMC_PCER1 = 1 << ul_id; + } +#endif + } + + return 0; +} + +/** + * \brief Disable the specified peripheral clock. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Success. + * \retval 1 Invalid parameter. + */ +uint32_t pmc_disable_periph_clk(uint32_t ul_id) +{ + if (ul_id > MAX_PERIPH_ID) { + return 1; + } + + if (ul_id < 32) { + if ((PMC->PMC_PCSR0 & (1u << ul_id)) == (1u << ul_id)) { + PMC->PMC_PCDR0 = 1 << ul_id; + } +#if (SAM3S || SAM3XA || SAM4S) + } else { + ul_id -= 32; + if ((PMC->PMC_PCSR1 & (1u << ul_id)) == (1u << ul_id)) { + PMC->PMC_PCDR1 = 1 << ul_id; + } +#endif + } + return 0; +} + +/** + * \brief Enable all peripheral clocks. + */ +void pmc_enable_all_periph_clk(void) +{ + PMC->PMC_PCER0 = PMC_MASK_STATUS0; + while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != PMC_MASK_STATUS0); + +#if (SAM3S || SAM3XA || SAM4S) + PMC->PMC_PCER1 = PMC_MASK_STATUS1; + while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != PMC_MASK_STATUS1); +#endif +} + +/** + * \brief Disable all peripheral clocks. + */ +void pmc_disable_all_periph_clk(void) +{ + PMC->PMC_PCDR0 = PMC_MASK_STATUS0; + while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != 0); + +#if (SAM3S || SAM3XA || SAM4S) + PMC->PMC_PCDR1 = PMC_MASK_STATUS1; + while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != 0); +#endif +} + +/** + * \brief Check if the specified peripheral clock is enabled. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Peripheral clock is disabled or unknown. + * \retval 1 Peripheral clock is enabled. + */ +uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id) +{ + if (ul_id > MAX_PERIPH_ID) { + return 0; + } + +#if (SAM3S || SAM3XA || SAM4S) + if (ul_id < 32) { +#endif + if ((PMC->PMC_PCSR0 & (1u << ul_id))) { + return 1; + } else { + return 0; + } +#if (SAM3S || SAM3XA || SAM4S) + } else { + ul_id -= 32; + if ((PMC->PMC_PCSR1 & (1u << ul_id))) { + return 1; + } else { + return 0; + } + } +#endif +} + +/** + * \brief Set the prescaler for the specified programmable clock. + * + * \param ul_id Peripheral ID. + * \param ul_pres Prescaler value. + */ +void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres) +{ + PMC->PMC_PCK[ul_id] = + (PMC->PMC_PCK[ul_id] & ~PMC_PCK_PRES_Msk) | ul_pres; + while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id)) + && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id))); +} + +/** + * \brief Set the source oscillator for the specified programmable clock. + * + * \param ul_id Peripheral ID. + * \param ul_source Source selection value. + */ +void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source) +{ + PMC->PMC_PCK[ul_id] = + (PMC->PMC_PCK[ul_id] & ~PMC_PCK_CSS_Msk) | ul_source; + while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id)) + && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id))); +} + +/** + * \brief Switch programmable clock source selection to slow clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_SLOW_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch programmable clock source selection to main clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_MAIN_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch programmable clock source selection to PLLA clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLA_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +#if (SAM3S || SAM4S) +/** + * \brief Switch programmable clock source selection to PLLB clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLB_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +#if (SAM3XA || SAM3U) +/** + * \brief Switch programmable clock source selection to UPLL clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_UPLL_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +/** + * \brief Enable the specified programmable clock. + * + * \param ul_id Id of the programmable clock. + */ +void pmc_enable_pck(uint32_t ul_id) +{ + PMC->PMC_SCER = PMC_SCER_PCK0 << ul_id; +} + +/** + * \brief Disable the specified programmable clock. + * + * \param ul_id Id of the programmable clock. + */ +void pmc_disable_pck(uint32_t ul_id) +{ + PMC->PMC_SCDR = PMC_SCER_PCK0 << ul_id; +} + +/** + * \brief Enable all programmable clocks. + */ +void pmc_enable_all_pck(void) +{ + PMC->PMC_SCER = PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2; +} + +/** + * \brief Disable all programmable clocks. + */ +void pmc_disable_all_pck(void) +{ + PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2; +} + +/** + * \brief Check if the specified programmable clock is enabled. + * + * \param ul_id Id of the programmable clock. + * + * \retval 0 Programmable clock is disabled or unknown. + * \retval 1 Programmable clock is enabled. + */ +uint32_t pmc_is_pck_enabled(uint32_t ul_id) +{ + if (ul_id > 2) { + return 0; + } + + return (PMC->PMC_SCSR & (PMC_SCSR_PCK0 << ul_id)); +} + +#if (SAM3S || SAM3XA || SAM4S) +/** + * \brief Switch UDP (USB) clock source selection to PLLA clock. + * + * \param ul_usbdiv Clock divisor. + */ +void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv); +} +#endif + +#if (SAM3S || SAM4S) +/** + * \brief Switch UDP (USB) clock source selection to PLLB clock. + * + * \param ul_usbdiv Clock divisor. + */ +void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv) | PMC_USB_USBS; +} +#endif + +#if (SAM3XA) +/** + * \brief Switch UDP (USB) clock source selection to UPLL clock. + * + * \param dw_usbdiv Clock divisor. + */ +void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBS | PMC_USB_USBDIV(ul_usbdiv); +} +#endif + +#if (SAM3S || SAM3XA || SAM4S) +/** + * \brief Enable UDP (USB) clock. + */ +void pmc_enable_udpck(void) +{ +# if (SAM3S || SAM4S) + PMC->PMC_SCER = PMC_SCER_UDP; +# else + PMC->PMC_SCER = PMC_SCER_UOTGCLK; +# endif +} + +/** + * \brief Disable UDP (USB) clock. + */ +void pmc_disable_udpck(void) +{ +# if (SAM3S || SAM4S) + PMC->PMC_SCDR = PMC_SCDR_UDP; +# else + PMC->PMC_SCDR = PMC_SCDR_UOTGCLK; +# endif +} +#endif + +/** + * \brief Enable PMC interrupts. + * + * \param ul_sources Interrupt sources bit map. + */ +void pmc_enable_interrupt(uint32_t ul_sources) +{ + PMC->PMC_IER = ul_sources; +} + +/** + * \brief Disable PMC interrupts. + * + * \param ul_sources Interrupt sources bit map. + */ +void pmc_disable_interrupt(uint32_t ul_sources) +{ + PMC->PMC_IDR = ul_sources; +} + +/** + * \brief Get PMC interrupt mask. + * + * \return The interrupt mask value. + */ +uint32_t pmc_get_interrupt_mask(void) +{ + return PMC->PMC_IMR; +} + +/** + * \brief Get current status. + * + * \return The current PMC status. + */ +uint32_t pmc_get_status(void) +{ + return PMC->PMC_SR; +} + +/** + * \brief Set the wake-up inputs for fast startup mode registers (event generation). + * + * \param ul_inputs Wake up inputs to enable. + */ +void pmc_set_fast_startup_input(uint32_t ul_inputs) +{ + ul_inputs &= (~ PMC_FAST_STARTUP_Msk); + PMC->PMC_FSMR |= ul_inputs; +} + +/** + * \brief Clear the wake-up inputs for fast startup mode registers (remove event generation). + * + * \param ul_inputs Wake up inputs to disable. + */ +void pmc_clr_fast_startup_input(uint32_t ul_inputs) +{ + ul_inputs &= (~ PMC_FAST_STARTUP_Msk); + PMC->PMC_FSMR &= ~ul_inputs; +} + +/** + * \brief Enable Sleep Mode. + * Enter condition: (WFE or WFI) + (SLEEPDEEP bit = 0) + (LPM bit = 0) + * + * \param uc_type 0 for wait for interrupt, 1 for wait for event. + */ +void pmc_enable_sleepmode(uint8_t uc_type) +{ + PMC->PMC_FSMR &= (uint32_t) ~ PMC_FSMR_LPM; // Enter Sleep mode + SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; // Deep sleep + + if (uc_type == 0) { + __WFI(); + } else { + __WFE(); + } +} + +/** + * \brief Enable Wait Mode. + * Enter condition: WFE + (SLEEPDEEP bit = 0) + (LPM bit = 1) + */ +void pmc_enable_waitmode(void) +{ + uint32_t i; + + PMC->PMC_FSMR |= PMC_FSMR_LPM; // Enter Wait mode + SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; // Deep sleep + __WFE(); + + /* Waiting for MOSCRCEN bit cleared is strongly recommended + * to ensure that the core will not execute undesired instructions + */ + for (i = 0; i < 500; i++) { + __NOP(); + } + while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN)); +} + +/** + * \brief Enable Backup Mode. + * Enter condition: WFE + (SLEEPDEEP bit = 1) + */ +void pmc_enable_backupmode(void) +{ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + __WFE(); +} + +/** + * \brief Enable or disable write protect of PMC registers. + * + * \param ul_enable 1 to enable, 0 to disable. + */ +void pmc_set_writeprotect(uint32_t ul_enable) +{ + if (ul_enable) { + PMC->PMC_WPMR = PMC_WPMR_WPKEY_VALUE | PMC_WPMR_WPEN; + } else { + PMC->PMC_WPMR = PMC_WPMR_WPKEY_VALUE; + } +} + +/** + * \brief Return write protect status. + * + * \retval 0 Protection disabled. + * \retval 1 Protection enabled. + */ +uint32_t pmc_get_writeprotect_status(void) +{ + return PMC->PMC_WPMR & PMC_WPMR_WPEN; +} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.h new file mode 100644 index 000000000..960db24b3 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/pmc.h @@ -0,0 +1,437 @@ +/** + * \file + * + * \brief Power Management Controller (PMC) driver for SAM. + * + * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef PMC_H_INCLUDED +#define PMC_H_INCLUDED + +#include "compiler.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** Bit mask for peripheral clocks (PCER0) */ +#define PMC_MASK_STATUS0 (0xFFFFFFFC) + +/** Bit mask for peripheral clocks (PCER1) */ +#define PMC_MASK_STATUS1 (0xFFFFFFFF) + +/** Loop counter timeout value */ +#define PMC_TIMEOUT (2048) + +/** Key to unlock CKGR_MOR register */ +#define PMC_CKGR_MOR_KEY_VALUE CKGR_MOR_KEY(0x37) + +/** Key used to write SUPC registers */ +#define SUPC_KEY_VALUE ((uint32_t) 0xA5) + +/** PMC xtal statup time */ +#define PMC_XTAL_STARTUP_TIME (0x3F) + +/** Mask to access fast startup input */ +#define PMC_FAST_STARTUP_Msk (0xFFFFu) + +/** PMC_WPMR Write Protect KEY, unlock it */ +#define PMC_WPMR_WPKEY_VALUE PMC_WPMR_WPKEY((uint32_t) 0x504D43) + +/** Using external oscillator */ +#define PMC_OSC_XTAL 0 + +/** Oscillator in bypass mode */ +#define PMC_OSC_BYPASS 1 + +#define PMC_PCK_0 0 /* PCK0 ID */ +#define PMC_PCK_1 1 /* PCK1 ID */ +#define PMC_PCK_2 2 /* PCK2 ID */ + +/** + * \name Master clock (MCK) Source and Prescaler configuration + * + * The following functions may be used to select the clock source and + * prescaler for the master clock. + */ +//@{ + +void pmc_mck_set_prescaler(uint32_t ul_pres); +void pmc_mck_set_source(uint32_t ul_source); +uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres); +uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres); +uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres); +#if (SAM3S || SAM4S) +uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres); +#endif +#if (SAM3XA || SAM3U) +uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres); +#endif + +//@} + +/** + * \name Slow clock (SLCK) oscillator and configuration + * + */ +//@{ + +void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass); +uint32_t pmc_osc_is_ready_32kxtal(void); + +//@} + +/** + * \name Main Clock (MAINCK) oscillator and configuration + * + */ +//@{ + +void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf); +void pmc_osc_enable_fastrc(uint32_t ul_rc); +void pmc_osc_disable_fastrc(void); +void pmc_switch_mainck_to_xtal(uint32_t ul_bypass); +void pmc_osc_disable_xtal(uint32_t ul_bypass); +uint32_t pmc_osc_is_ready_mainck(void); + +//@} + +/** + * \name PLL oscillator and configuration + * + */ +//@{ + +void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva); +void pmc_disable_pllack(void); +uint32_t pmc_is_locked_pllack(void); + +#if (SAM3S || SAM4S) +void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb); +void pmc_disable_pllbck(void); +uint32_t pmc_is_locked_pllbck(void); +#endif + +#if (SAM3XA || SAM3U) +void pmc_enable_upll_clock(void); +void pmc_disable_upll_clock(void); +uint32_t pmc_is_locked_upll(void); +#endif + +//@} + +/** + * \name Peripherals clock configuration + * + */ +//@{ + +uint32_t pmc_enable_periph_clk(uint32_t ul_id); +uint32_t pmc_disable_periph_clk(uint32_t ul_id); +void pmc_enable_all_periph_clk(void); +void pmc_disable_all_periph_clk(void); +uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id); + +//@} + +/** + * \name Programmable clock Source and Prescaler configuration + * + * The following functions may be used to select the clock source and + * prescaler for the specified programmable clock. + */ +//@{ + +void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres); +void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source); +uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres); +uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres); +uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres); +#if (SAM3S || SAM4S) +uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres); +#endif +#if (SAM3XA || SAM3U) +uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres); +#endif +void pmc_enable_pck(uint32_t ul_id); +void pmc_disable_pck(uint32_t ul_id); +void pmc_enable_all_pck(void); +void pmc_disable_all_pck(void); +uint32_t pmc_is_pck_enabled(uint32_t ul_id); + +//@} + +/** + * \name USB clock configuration + * + */ +//@{ + +#if (SAM3S || SAM3XA || SAM4S) +void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv); +#endif +#if (SAM3S || SAM4S) +void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv); +#endif +#if (SAM3XA) +void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv); +#endif +#if (SAM3S || SAM3XA || SAM4S) +void pmc_enable_udpck(void); +void pmc_disable_udpck(void); +#endif + +//@} + +/** + * \name Interrupt and status management + * + */ +//@{ + +void pmc_enable_interrupt(uint32_t ul_sources); +void pmc_disable_interrupt(uint32_t ul_sources); +uint32_t pmc_get_interrupt_mask(void); +uint32_t pmc_get_status(void); + +//@} + +/** + * \name Power management + * + * The following functions are used to configure sleep mode and additionnal + * wake up inputs. + */ +//@{ + +void pmc_set_fast_startup_input(uint32_t ul_inputs); +void pmc_clr_fast_startup_input(uint32_t ul_inputs); +void pmc_enable_sleepmode(uint8_t uc_type); +void pmc_enable_waitmode(void); +void pmc_enable_backupmode(void); + +//@} + +/** + * \name Write protection + * + */ +//@{ + +void pmc_set_writeprotect(uint32_t ul_enable); +uint32_t pmc_get_writeprotect_status(void); + +//@} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +//! @} + +/** + * \page sam_pmc_quickstart Quick start guide for the SAM PMC module + * + * This is the quick start guide for the \ref pmc_group "PMC module", with + * step-by-step instructions on how to configure and use the driver in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section pmc_use_cases PMC use cases + * - \ref pmc_basic_use_case Basic use case - Switch Main Clock sources + * - \ref pmc_use_case_2 Advanced use case - Configure Programmable Clocks + * + * \section pmc_basic_use_case Basic use case - Switch Main Clock sources + * In this use case, the PMC module is configured for a variety of system clock + * sources and speeds. A LED is used to visually indicate the current clock + * speed as the source is switched. + * + * \section pmc_basic_use_case_setup Setup + * + * \subsection pmc_basic_use_case_setup_prereq Prerequisites + * -# \ref gpio_group "General Purpose I/O Management (gpio)" + * + * \subsection pmc_basic_use_case_setup_code Code + * The following function needs to be added to the user application, to flash a + * board LED a variable number of times at a rate given in CPU ticks. + * + * \code + * #define FLASH_TICK_COUNT 0x00012345 + * + * void flash_led(uint32_t tick_count, uint8_t flash_count) + * { + * SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; + * SysTick->LOAD = tick_count; + * + * while (flash_count--) + * { + * gpio_toggle_pin(LED0_GPIO); + * while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); + * gpio_toggle_pin(LED0_GPIO); + * while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); + * } + * } + * \endcode + * + * \section pmc_basic_use_case_usage Use case + * + * \subsection pmc_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + * for (;;) + * { + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * pmc_switch_mainck_to_xtal(0); + * flash_led(FLASH_TICK_COUNT, 5); + * } + * \endcode + * + * \subsection pmc_basic_use_case_usage_flow Workflow + * -# Wrap the code in an infinite loop: + * \code + * for (;;) + * \endcode + * -# Switch the Master CPU frequency to the internal 12MHz RC oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + * -# Switch the Master CPU frequency to the internal 8MHz RC oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + * -# Switch the Master CPU frequency to the internal 4MHz RC oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + * -# Switch the Master CPU frequency to the external crystal oscillator, flash + * a LED on the board several times: + * \code + * pmc_switch_mainck_to_xtal(0); + * flash_led(FLASH_TICK_COUNT, 5); + * \endcode + */ + +/** + * \page pmc_use_case_2 Use case #2 - Configure Programmable Clocks + * In this use case, the PMC module is configured to start the Slow Clock from + * an attached 32KHz crystal, and start one of the Programmable Clock modules + * sourced from the Slow Clock divided down with a prescale factor of 64. + * + * \section pmc_use_case_2_setup Setup + * + * \subsection pmc_use_case_2_setup_prereq Prerequisites + * -# \ref pio_group "Parallel Input/Output Controller (pio)" + * + * \subsection pmc_use_case_2_setup_code Code + * The following code must be added to the user application: + * \code + * pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17); + * \endcode + * + * \subsection pmc_use_case_2_setup_code_workflow Workflow + * -# Configure the PCK1 pin to output on a specific port pin (in this case, + * PIOA pin 17) of the microcontroller. + * \code + * pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17); + * \endcode + * \note The peripheral selection and pin will vary according to your selected + * SAM device model. Refer to the "Peripheral Signal Multiplexing on I/O + * Lines" of your device's datasheet. + * + * \section pmc_use_case_2_usage Use case + * The generated PCK1 clock output can be viewed on an oscilloscope attached to + * the correct pin of the microcontroller. + * + * \subsection pmc_use_case_2_usage_code Example code + * Add to application C-file: + * \code + * pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + * pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64); + * pmc_enable_pck(PMC_PCK_1); + * + * for (;;) + * { + * // Do Nothing + * } + * \endcode + * + * \subsection pmc_use_case_2_usage_flow Workflow + * -# Switch the Slow Clock source input to an external 32KHz crystal: + * \code + * pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + * \endcode + * -# Switch the Programmable Clock module PCK1 source clock to the Slow Clock, + * with a prescaler of 64: + * \code + * pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64); + * \endcode + * -# Enable Programmable Clock module PCK1: + * \code + * pmc_enable_pck(PMC_PCK_1); + * \endcode + * -# Enter an infinite loop: + * \code + * for (;;) + * { + * // Do Nothing + * } + * \endcode + */ + +#endif /* PMC_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/sleep.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/sleep.h new file mode 100644 index 000000000..79ac91fcb --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/pmc/sleep.h @@ -0,0 +1,217 @@ +/** + * \file + * + * \brief Sleep mode access + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef SLEEP_H +#define SLEEP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \defgroup sleep_group Power Manager (PM) + * + * This is a stub on the SAM Power Manager Control (PMC) for the sleepmgr service. + * + * \note To minimize the code overhead, these functions do not feature + * interrupt-protected access since they are likely to be called inside + * interrupt handlers or in applications where such protection is not + * necessary. If such protection is needed, it must be ensured by the calling + * code. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \brief Sets the MCU in the specified sleep mode + * \param sleep_mode Sleep mode to set. + */ +#endif + +#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S) // SAM3 and SAM4 series +# include "pmc.h" + +# define SAM_PM_SMODE_ACTIVE 0 +# define SAM_PM_SMODE_SLEEP_WFE 1 +# define SAM_PM_SMODE_SLEEP_WFI 2 +# define SAM_PM_SMODE_WAIT 3 +# define SAM_PM_SMODE_BACKUP 4 + +/* (SCR) Sleep deep bit */ +#define SCR_SLEEPDEEP (0x1 << 2) + +/** + * Save clock settings and shutdown PLLs + */ +static inline void pmc_save_clock_settings( + uint32_t *p_osc_setting, + uint32_t *p_pll0_setting, + uint32_t *p_pll1_setting, + uint32_t *p_mck_setting) +{ + if (p_osc_setting) { + *p_osc_setting = PMC->CKGR_MOR; + } + if (p_pll0_setting) { + *p_pll0_setting = PMC->CKGR_PLLAR; + } + if (p_pll1_setting) { +#if SAM3S||SAM4S + *p_pll1_setting = PMC->CKGR_PLLBR; +#elif SAM3U||SAM3XA + *p_pll1_setting = PMC->CKGR_UCKR; +#else + *p_pll1_setting = 0; +#endif + } + if (p_mck_setting) { + *p_mck_setting = PMC->PMC_MCKR; + } + + // Switch MCK to Main clock (internal or external 12MHz) for fast wakeup + // If MAIN_CLK is already the source, just skip + if ((PMC->PMC_MCKR & PMC_MCKR_CSS_Msk) == PMC_MCKR_CSS_MAIN_CLK) { + return; + } + // If we have to enable the MAIN_CLK + if ((PMC->PMC_SR & PMC_SR_MOSCXTS) == 0) { + // Intend to use internal RC as source of MAIN_CLK + pmc_osc_enable_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + } + pmc_switch_mck_to_mainck(PMC_MCKR_PRES_CLK_1); +} + +/** + * Restore clock settings + */ +static inline void pmc_restore_clock_setting( + uint32_t osc_setting, + uint32_t pll0_setting, + uint32_t pll1_setting, + uint32_t mck_setting) +{ + uint32_t mckr; + if ((pll0_setting & CKGR_PLLAR_MULA_Msk) && + pll0_setting != PMC->CKGR_PLLAR) { + PMC->CKGR_PLLAR = 0; + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | pll0_setting; + while (!(PMC->PMC_SR & PMC_SR_LOCKA)); + } +#if SAM3S||SAM4S + if ((pll1_setting & CKGR_PLLBR_MULB_Msk) && + pll1_setting != PMC->CKGR_PLLBR) { + PMC->CKGR_PLLBR = 0; + PMC->CKGR_PLLBR = pll1_setting ; + while (!(PMC->PMC_SR & PMC_SR_LOCKB)); + } +#elif SAM3U||SAM3XA + if ((pll1_setting & CKGR_UCKR_UPLLEN) && + pll1_setting != PMC->CKGR_UCKR) { + PMC->CKGR_UCKR = 0; + PMC->CKGR_UCKR = pll1_setting; + while (!(PMC->PMC_SR & PMC_SR_LOCKU)); + } +#endif + /* Switch to faster clock */ + mckr = PMC->PMC_MCKR; + // Set PRES + PMC->PMC_MCKR = (mckr & ~PMC_MCKR_PRES_Msk) + | (mck_setting & PMC_MCKR_PRES_Msk); + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); + // Set CSS and others + PMC->PMC_MCKR = mck_setting; + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); + /* Shutdown fastrc */ + if (0 == (osc_setting & CKGR_MOR_MOSCRCEN)) { + pmc_osc_disable_fastrc(); + } +} + +static inline void pmc_sleep(int sleep_mode) +{ + switch (sleep_mode) { + case SAM_PM_SMODE_SLEEP_WFI: + case SAM_PM_SMODE_SLEEP_WFE: + PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM; + SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP; + cpu_irq_enable(); + if (sleep_mode == SAM_PM_SMODE_SLEEP_WFI) + __WFI(); + else + __WFE(); + break; + + case SAM_PM_SMODE_WAIT: { + uint32_t mor, pllr0, pllr1, mckr; + pmc_save_clock_settings(&mor, &pllr0, &pllr1, &mckr); + + PMC->PMC_FSMR |= PMC_FSMR_LPM; + SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP ; + cpu_irq_enable(); + __WFE(); + + cpu_irq_disable(); + pmc_restore_clock_setting(mor, pllr0, pllr1, mckr); + cpu_irq_enable(); + break; + } + + case SAM_PM_SMODE_BACKUP: + SCB->SCR |= SCR_SLEEPDEEP ; + cpu_irq_enable(); + __WFE() ; + break; + } +} + +#endif + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* SLEEP_H */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.c new file mode 100644 index 000000000..b4e9924ae --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.c @@ -0,0 +1,1707 @@ +/** + * \file + * + * \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver for SAM. + * + * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "usart.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \defgroup sam_drivers_usart_group Universal Synchronous Asynchronous Receiver Transmitter (USART) + * + * The Universal Synchronous Asynchronous Receiver Transceiver (USART) provides one full duplex + * universal synchronous asynchronous serial link. Data frame format is widely programmable + * (data length, parity, number of stop bits) to support a maximum of standards. The receiver + * implements parity error, framing error and overrun error detection. The receiver time-out enables + * handling variable-length frames and the transmitter timeguard facilitates communications with + * slow remote devices. Multidrop communications are also supported through address bit handling + * in reception and transmission. + * The driver supports the following modes: RS232, RS485, SPI, IrDA, ISO7816, MODEM, + * Hardware handshaking and LIN. + * + * @{ + */ + +/* The write protect key value. */ +#define US_WPKEY_VALUE 0x555341 + +/* The CD value scope programmed in MR register. */ +#define MIN_CD_VALUE 0x01 +#define MIN_CD_VALUE_SPI 0x04 +#define MAX_CD_VALUE US_BRGR_CD_Msk + +/* Define the default time-out value for USART. */ +#define USART_DEFAULT_TIMEOUT 1000 + +/* The receiver sampling divide of baudrate clock. */ +#define HIGH_FRQ_SAMPLE_DIV 16 +#define LOW_FRQ_SAMPLE_DIV 8 + +/* Max transmitter timeguard. */ +#define MAX_TRAN_GUARD_TIME US_TTGR_TG_Msk + +/* The non-existent parity error number. */ +#define USART_PARITY_ERROR 5 + +/* ISO7816 protocol type. */ +#define ISO7816_T_0 0 +#define ISO7816_T_1 1 + +/** + * \brief Calculate a clock divider(CD) and a fractional part (FP) for the + * USART asynchronous modes to generate a baudrate as close as possible to + * the baudrate set point. + * + * \note Baud rate calculation: Baudrate = ul_mck/(Over * (CD + FP/8)) + * (Over being 16 or 8). The maximal oversampling is selected if it allows to + * generate a baudrate close to the set point. + * + * \param p_usart Pointer to a USART instance. + * \param baudrate Baud rate set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 Baud rate is successfully initialized. + * \retval 1 Baud rate set point is out of range for the given input clock + * frequency. + */ +static uint32_t usart_set_async_baudrate(Usart *p_usart, + uint32_t baudrate, uint32_t ul_mck) +{ + uint32_t over; + uint32_t cd_fp; + uint32_t cd; + uint32_t fp; + + /* Calculate the receiver sampling divide of baudrate clock. */ + if (ul_mck >= HIGH_FRQ_SAMPLE_DIV * baudrate) { + over = HIGH_FRQ_SAMPLE_DIV; + } else { + over = LOW_FRQ_SAMPLE_DIV; + } + + /* Calculate the clock divider according to the fraction calculated formula. */ + cd_fp = (8 * ul_mck + (over * baudrate) / 2) / (over * baudrate); + cd = cd_fp >> 3; + fp = cd_fp & 0x07; + if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) { + return 1; + } + + /* Configure the OVER bit in MR register. */ + if (over == 8) { + p_usart->US_MR |= US_MR_OVER; + } + + /* Configure the baudrate generate register. */ + p_usart->US_BRGR = (cd << US_BRGR_CD_Pos) | (fp << US_BRGR_FP_Pos); + + return 0; +} + +/** + * \brief Calculate a clock divider for the USART synchronous master modes + * to generate a baudrate as close as possible to the baudrate set point. + * + * \note Synchronous baudrate calculation: baudrate = ul_mck / cd + * + * \param p_usart Pointer to a USART instance. + * \param baudrate Baud rate set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 Baud rate is successfully initialized. + * \retval 1 Baud rate set point is out of range for the given input clock + * frequency. + */ +static uint32_t usart_set_sync_master_baudrate(Usart *p_usart, + uint32_t baudrate, uint32_t ul_mck) +{ + uint32_t cd; + + /* Calculate the clock divider according to the formula in synchronous mode. */ + cd = (ul_mck + baudrate / 2) / baudrate; + + if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) { + return 1; + } + + /* Configure the baudrate generate register. */ + p_usart->US_BRGR = cd << US_BRGR_CD_Pos; + + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) | + US_MR_USCLKS_MCK | US_MR_SYNC; + return 0; +} + +/** + * \brief Select the SCK pin as the source of baud rate for the USART + * synchronous slave modes. + * + * \param p_usart Pointer to a USART instance. + */ +static void usart_set_sync_slave_baudrate(Usart *p_usart) +{ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) | + US_MR_USCLKS_SCK | US_MR_SYNC; +} + + +/** + * \brief Calculate a clock divider (\e CD) for the USART ISO7816 mode to + * generate an ISO7816 clock as close as possible to the clock set point. + * + * \note ISO7816 clock calculation: Clock = ul_mck / cd + * + * \param p_usart Pointer to a USART instance. + * \param clock ISO7816 clock set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 ISO7816 clock is successfully initialized. + * \retval 1 ISO7816 clock set point is out of range for the given input clock + * frequency. + */ +static uint32_t usart_set_iso7816_clock(Usart *p_usart, + uint32_t clock, uint32_t ul_mck) +{ + uint32_t cd; + + /* Calculate the clock divider according to the formula in ISO7816 mode. */ + cd = (ul_mck + clock / 2) / clock; + + if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) { + return 1; + } + + p_usart->US_MR = (p_usart->US_MR & ~(US_MR_USCLKS_Msk | US_MR_SYNC | + US_MR_OVER)) | US_MR_USCLKS_MCK | US_MR_CLKO; + + /* Configure the baudrate generate register. */ + p_usart->US_BRGR = cd << US_BRGR_CD_Pos; + + return 0; +} + +/** + * \brief Calculate a clock divider (\e CD) for the USART SPI master mode to + * generate a baud rate as close as possible to the baud rate set point. + * + * \note Baud rate calculation: + * \f$ Baudrate = \frac{SelectedClock}{CD} \f$. + * + * \param p_usart Pointer to a USART instance. + * \param baudrate Baud rate set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 Baud rate is successfully initialized. + * \retval 1 Baud rate set point is out of range for the given input clock + * frequency. + */ +static uint32_t usart_set_spi_master_baudrate(Usart *p_usart, + uint32_t baudrate, uint32_t ul_mck) +{ + uint32_t cd; + + /* Calculate the clock divider according to the formula in SPI mode. */ + cd = (ul_mck + baudrate / 2) / baudrate; + + if (cd < MIN_CD_VALUE_SPI || cd > MAX_CD_VALUE) { + return 1; + } + + p_usart->US_BRGR = cd << US_BRGR_CD_Pos; + + return 0; +} + +/** + * \brief Select the SCK pin as the source of baudrate for the USART SPI slave + * mode. + * + * \param p_usart Pointer to a USART instance. + */ +static void usart_set_spi_slave_baudrate(Usart *p_usart) +{ + p_usart->US_MR &= ~US_MR_USCLKS_Msk; + p_usart->US_MR |= US_MR_USCLKS_SCK; +} + +/** + * \brief Reset the USART and disable TX and RX. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset(Usart *p_usart) +{ + /* Disable the Write Protect. Some register can't be written if the write protect is enabled. */ + usart_disable_writeprotect(p_usart); + + /* Reset mode and other registers that could cause unpredictable behavior after reset. */ + p_usart->US_MR = 0; + p_usart->US_RTOR = 0; + p_usart->US_TTGR = 0; + + /* Disable TX and RX, reset status bits and turn off RTS and DTR if exist. */ + usart_reset_tx(p_usart); + usart_reset_rx(p_usart); + usart_reset_status(p_usart); + usart_drive_RTS_pin_high(p_usart); +#if (SAM3S || SAM4S || SAM3U) + usart_drive_DTR_pin_high(p_usart); +#endif +} + +/** + * \brief Configure USART to work in RS232 mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_rs232(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + /* Check whether the input values are legal. */ + if (!p_usart_opt || + usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) { + return 1; + } + + /* Configure the character length, parity type, channel mode and stop bit length. */ + ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type | + p_usart_opt->channel_mode | p_usart_opt->stop_bits; + + /* Configure the USART mode as normal mode. */ + ul_reg_val |= US_MR_USART_MODE_NORMAL; + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in hardware handshaking mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_hw_handshaking(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set hardware handshaking mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_HW_HANDSHAKING; + + return 0; +} + +#if (SAM3S || SAM4S || SAM3U) +/** + * \brief Configure USART to work in modem mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_modem(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* SAM3S || SAM4S series support MODEM mode only on USART1, and + SAM3U series support MODEM mode only on USART0. */ +#if (SAM3S || SAM4S) + if (p_usart != USART1) { + return 1; + } +#elif (SAM3U) + if (p_usart != USART0) { + return 1; + } +#endif + + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set MODEM mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_MODEM; + + return 0; +} +#endif + +/** + * \brief Configure USART to work in SYNC mode and act as a master. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_sync_master(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + /* Check whether the input values are legal. */ + if (!p_usart_opt || + usart_set_sync_master_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) { + return 1; + } + + /* Configure the character length, parity type, channel mode and stop bit length. */ + ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type | + p_usart_opt->channel_mode | p_usart_opt->stop_bits; + + /* Set normal mode and output clock on the SCK pin as synchronous master. */ + ul_reg_val |= US_MR_USART_MODE_NORMAL | US_MR_CLKO; + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in SYNC mode and act as a slave. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_sync_slave(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + usart_set_sync_slave_baudrate(p_usart); + + /* Check whether the input values are legal. */ + if (!p_usart_opt) { + return 1; + } + + /* Configure the character length, parity type, channel mode and stop bit length. */ + ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type | + p_usart_opt->channel_mode | p_usart_opt->stop_bits; + + /* Set normal mode. */ + ul_reg_val |= US_MR_USART_MODE_NORMAL; + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in RS485 mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_rs485(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set RS485 mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_RS485; + + return 0; +} + +/** + * \brief Configure USART to work in IrDA mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_irda(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set IrDA filter. */ + p_usart->US_IF = p_usart_opt->irda_filter; + + /* Set IrDA mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_IRDA; + + return 0; +} + +/** + * \brief Configure USART to work in ISO7816 mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_iso7816(Usart *p_usart, + const usart_iso7816_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + + /* Check whether the input values are legal. */ + if (!p_usart_opt || ((p_usart_opt->parity_type != US_MR_PAR_EVEN) && + (p_usart_opt->parity_type != US_MR_PAR_ODD))) { + return 1; + } + + if (p_usart_opt->protocol_type == ISO7816_T_0) { + ul_reg_val |= US_MR_USART_MODE_IS07816_T_0 | US_MR_NBSTOP_2_BIT | + (p_usart_opt->max_iterations << US_MR_MAX_ITERATION_Pos); + + if (p_usart_opt->bit_order) { + ul_reg_val |= US_MR_MSBF; + } + } else if (p_usart_opt->protocol_type == ISO7816_T_1) { + /* Only LSBF is used in the T=1 protocol, and max_iterations field is only used in T=0 mode.*/ + if (p_usart_opt->bit_order || p_usart_opt->max_iterations) { + return 1; + } + + /* Set USART mode to ISO7816, T=1, and always uses 1 stop bit. */ + ul_reg_val |= US_MR_USART_MODE_IS07816_T_1 | US_MR_NBSTOP_1_BIT; + } else { + return 1; + } + + /* Set up the baudrate. */ + if (usart_set_iso7816_clock(p_usart, p_usart_opt->iso7816_hz, ul_mck)) { + return 1; + } + + /* Set FIDI register: bit rate = iso7816_hz / fidi_ratio. */ + p_usart->US_FIDI = p_usart_opt->fidi_ratio; + + /* Set ISO7816 parity type in the MODE register. */ + ul_reg_val |= p_usart_opt->parity_type; + + if (p_usart_opt->inhibit_nack) { + ul_reg_val |= US_MR_INACK; + } + if (p_usart_opt->dis_suc_nack) { + ul_reg_val |= US_MR_DSNACK; + } + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in SPI mode and act as a master. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_spi_master(Usart *p_usart, + const usart_spi_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + /* Check whether the input values are legal. */ + if (!p_usart_opt || + (p_usart_opt->spi_mode > SPI_MODE_3) || + usart_set_spi_master_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) { + return 1; + } + + /* Configure the character length bit in MR register. */ + ul_reg_val |= p_usart_opt->char_length; + + /* Set SPI master mode and channel mode. */ + ul_reg_val |= US_MR_USART_MODE_SPI_MASTER | US_MR_CLKO | + p_usart_opt->channel_mode; + + switch (p_usart_opt->spi_mode) { + case SPI_MODE_0: + ul_reg_val |= US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + case SPI_MODE_1: + ul_reg_val &= ~US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + case SPI_MODE_2: + ul_reg_val |= US_MR_CPHA; + ul_reg_val |= US_MR_CPOL; + break; + case SPI_MODE_3: + ul_reg_val |= US_MR_CPOL; + ul_reg_val &= ~US_MR_CPHA; + break; + default: + break; + } + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in SPI mode and act as a slave. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_spi_slave(Usart *p_usart, + const usart_spi_opt_t *p_usart_opt) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + usart_set_spi_slave_baudrate(p_usart); + + /* Check whether the input values are legal. */ + if (!p_usart_opt || + p_usart_opt->spi_mode > SPI_MODE_3) { + return 1; + } + + /* Configure the character length bit in MR register. */ + ul_reg_val |= p_usart_opt->char_length; + + /* Set SPI slave mode and channel mode. */ + ul_reg_val |= US_MR_USART_MODE_SPI_SLAVE | p_usart_opt->channel_mode; + + switch (p_usart_opt->spi_mode) { + case SPI_MODE_0: + ul_reg_val |= US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + case SPI_MODE_1: + ul_reg_val &= ~US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + case SPI_MODE_2: + ul_reg_val |= US_MR_CPHA; + ul_reg_val |= US_MR_CPOL; + break; + case SPI_MODE_3: + ul_reg_val |= US_MR_CPOL; + ul_reg_val &= ~US_MR_CPHA; + break; + default: + break; + } + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +#if SAM3XA +/** + * \brief Configure USART to work in LIN mode and act as a LIN master. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_lin_master(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + /* Set up the baudrate. */ + if (usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) { + return 1; + } + + /* Set LIN master mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_LIN_MASTER; + + return 0; +} + +/** + * \brief Configure USART to work in LIN mode and act as a LIN slave. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_lin_slave(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + /* Set up the baudrate. */ + if (usart_set_async_baudrate(p_usart, p_usart_opt->baudrate, ul_mck)) { + return 1; + } + + /* Set LIN slave mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_LIN_SLAVE; + + return 0; +} + +/** + * \brief Abort the current LIN transmission. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_abort_tx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_LINABT; +} + +/** + * \brief Send a wakeup signal on the LIN bus. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_send_wakeup_signal(Usart *p_usart) +{ + p_usart->US_CR = US_CR_LINWKUP; +} + +/** + * \brief Configure the LIN node action, which should be one of PUBLISH, + * SUBSCRIBE or IGNORE. + * + * \param p_usart Pointer to a USART instance. + * \param uc_action 0 for PUBLISH, 1 for SUBSCRIBE, 2 for IGNORE. + */ +void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_NACT_Msk) | + (uc_action << US_LINMR_NACT_Pos); +} + +/** + * \brief Disable the parity check during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_parity(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_PARDIS; +} + +/** + * \brief Enable the parity check during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_parity(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_PARDIS; +} + +/** + * \brief Disable the checksum during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_checksum(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_CHKDIS; +} + +/** + * \brief Enable the checksum during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_checksum(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_CHKDIS; +} + +/** + * \brief Configure the checksum type during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_type 0 for LIN 2.0 Enhanced checksum or 1 for LIN 1.3 Classic checksum. + */ +void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_CHKTYP) | + (uc_type << 4); +} + +/** + * \brief Configure the data length mode during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_mode Indicate the checksum type: 0 if the data length is defined by the + * DLC of LIN mode register or 1 if the data length is defined by the bit 5 and 6 of + * the identifier. + */ +void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLM) | + (uc_mode << 5); +} + +/** + * \brief Disable the frame slot mode during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_frame_slot(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_FSDIS; +} + +/** + * \brief Enable the frame slot mode during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_frame_slot(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_FSDIS; +} + +/** + * \brief Configure the wakeup signal type during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_type Indicate the checksum type: 0 if the wakeup signal is a LIN 2.0 + * wakeup signal; 1 if the wakeup signal is a LIN 1.3 wakeup signal. + */ +void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_WKUPTYP) | + (uc_type << 7); +} + +/** + * \brief Configure the response data length if the data length is defined by + * the DLC field during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_len Indicate the response data length. + */ +void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLC_Msk) | + (uc_len << US_LINMR_DLC_Pos); +} + +/** + * \brief The LIN mode register is not written by the PDC. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_pdc_mode(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_PDCM; +} + +/** + * \brief The LIN mode register (except this flag) is written by the PDC. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_pdc_mode(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_PDCM; +} + +/** + * \brief Configure the LIN identifier when USART works in LIN master mode. + * + * \param p_usart Pointer to a USART instance. + * \param uc_id The identifier to be transmitted. + */ +void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id) +{ + p_usart->US_LINIR = (p_usart->US_LINIR & ~US_LINIR_IDCHR_Msk) | + US_LINIR_IDCHR(uc_id); +} + +/** + * \brief Read the identifier when USART works in LIN mode. + * + * \param p_usart Pointer to a USART instance. + * + * \return The last identifier received in LIN slave mode or the last identifier + * transmitted in LIN master mode. + */ +uint8_t usart_lin_read_identifier(Usart *p_usart) +{ + return (p_usart->US_LINMR & US_LINIR_IDCHR_Msk); +} +#endif + +/** + * \brief Enable USART transmitter. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_enable_tx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_TXEN; +} + +/** + * \brief Disable USART transmitter. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_disable_tx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_TXDIS; +} + +/** + * \brief Immediately stop and disable USART transmitter. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_tx(Usart *p_usart) +{ + /* Reset transmitter */ + p_usart->US_CR = US_CR_RSTTX | US_CR_TXDIS; +} + +/** + * \brief Configure the transmit timeguard register. + * + * \param p_usart Pointer to a USART instance. + * \param timeguard The value of transmit timeguard. + */ +void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard) +{ + p_usart->US_TTGR = timeguard; +} + +/** + * \brief Enable USART receiver. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_enable_rx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RXEN; +} + +/** + * \brief Disable USART receiver. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_disable_rx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RXDIS; +} + +/** + * \brief Immediately stop and disable USART receiver. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_rx(Usart *p_usart) +{ + /* Reset Receiver */ + p_usart->US_CR = US_CR_RSTRX | US_CR_RXDIS; +} + +/** + * \brief Configure the receive timeout register. + * + * \param p_usart Pointer to a USART instance. + * \param timeout The value of receive timeout. + */ +void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout) +{ + p_usart->US_RTOR = timeout; +} + +/** + * \brief Enable USART interrupts. + * + * \param p_usart Pointer to a USART peripheral. + * \param ul_sources Interrupt sources bit map. + */ +void usart_enable_interrupt(Usart *p_usart, uint32_t ul_sources) +{ + p_usart->US_IER = ul_sources; +} + +/** + * \brief Disable USART interrupts. + * + * \param p_usart Pointer to a USART peripheral. + * \param ul_sources Interrupt sources bit map. + */ +void usart_disable_interrupt(Usart *p_usart, uint32_t ul_sources) +{ + p_usart->US_IDR = ul_sources; +} + +/** + * \brief Read USART interrupt mask. + * + * \param p_usart Pointer to a USART peripheral. + * + * \return The interrupt mask value. + */ +uint32_t usart_get_interrupt_mask(Usart *p_usart) +{ + return p_usart->US_IMR; +} + +/** + * \brief Get current status. + * + * \param p_usart Pointer to a USART instance. + * + * \return The current USART status. + */ +uint32_t usart_get_status(Usart *p_usart) +{ + return p_usart->US_CSR; +} + +/** + * \brief Reset status bits (PARE, OVER, MANERR, UNRE and PXBRK in US_CSR). + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_status(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RSTSTA; +} + +/** + * \brief Start transmission of a break. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_start_tx_break(Usart *p_usart) +{ + p_usart->US_CR = US_CR_STTBRK; +} + +/** + * \brief Stop transmission of a break. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_stop_tx_break(Usart *p_usart) +{ + p_usart->US_CR = US_CR_STPBRK; +} + +/** + * \brief Start waiting for a character before clocking the timeout count. + * Reset the status bit TIMEOUT in US_CSR. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_start_rx_timeout(Usart *p_usart) +{ + p_usart->US_CR = US_CR_STTTO; +} + +/** + * \brief In Multidrop mode only, the next character written to the US_THR + * is sent with the address bit set. + * + * \param p_usart Pointer to a USART instance. + * \param ul_addr The address to be sent out. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr) +{ + if ((p_usart->US_MR & US_MR_PAR_MULTIDROP) != US_MR_PAR_MULTIDROP) { + return 1; + } + + p_usart->US_CR = US_CR_SENDA; + + if (usart_write(p_usart, ul_addr)) { + return 1; + } else { + return 0; + } +} + +/** + * \brief Reset the ITERATION in US_CSR when the ISO7816 mode is enabled. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_iterations(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RSTIT; +} + +/** + * \brief Reset NACK in US_CSR. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_nack(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RSTNACK; +} + +/** + * \brief Restart the receive timeout. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_restart_rx_timeout(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RETTO; +} + +#if (SAM3S || SAM4S || SAM3U) +/** + * \brief Drive the pin DTR to 0. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_DTR_pin_low(Usart *p_usart) +{ + p_usart->US_CR = US_CR_DTREN; +} + +/** + * \brief Drive the pin DTR to 1. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_DTR_pin_high(Usart *p_usart) +{ + p_usart->US_CR = US_CR_DTRDIS; +} +#endif + +/** + * \brief Drive the pin RTS to 0. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_RTS_pin_low(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RTSEN; +} + +/** + * \brief Drive the pin RTS to 1. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_RTS_pin_high(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RTSDIS; +} + +/** + * \brief Drive the slave select line NSS (RTS pin) to 0 in SPI master mode. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_spi_force_chip_select(Usart *p_usart) +{ + p_usart->US_CR = US_CR_FCS; +} + +/** + * \brief Drive the slave select line NSS (RTS pin) to 1 in SPI master mode. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_spi_release_chip_select(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RCS; +} + +/** + * \brief Check if Transmit is Ready. + * Check if data have been loaded in USART_THR and are waiting to be loaded + * into the Transmit Shift Register (TSR). + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 No data is in the Transmit Holding Register. + * \retval 0 There is data in the Transmit Holding Register. + */ +uint32_t usart_is_tx_ready(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_TXRDY) > 0; +} + +/** + * \brief Check if Transmit Holding Register is empty. + * Check if the last data written in USART_THR have been loaded in TSR and the last + * data loaded in TSR have been transmitted. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Transmitter is empty. + * \retval 0 Transmitter is not empty. + */ +uint32_t usart_is_tx_empty(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_TXEMPTY) > 0; +} + +/** + * \brief Check if the received data are ready. + * Check if Data have been received and loaded into USART_RHR. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Some data has been received. + * \retval 0 No data has been received. + */ +uint32_t usart_is_rx_ready(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_RXRDY) > 0; +} + +/** + * \brief Check if one receive buffer is filled. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Receive is complete. + * \retval 0 Receive is still pending. + */ +uint32_t usart_is_rx_buf_end(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_ENDRX) > 0; +} + +/** + * \brief Check if one transmit buffer is empty. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Transmit is complete. + * \retval 0 Transmit is still pending. + */ +uint32_t usart_is_tx_buf_end(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_ENDTX) > 0; +} + +/** + * \brief Check if both receive buffers are full. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Receive buffers are full. + * \retval 0 Receive buffers are not full. + */ +uint32_t usart_is_rx_buf_full(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_RXBUFF) > 0; +} + +/** + * \brief Check if both transmit buffers are empty. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Transmit buffers are empty. + * \retval 0 Transmit buffers are not empty. + */ +uint32_t usart_is_tx_buf_empty(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_TXBUFE) > 0; +} + +/** + * \brief Write to USART Transmit Holding Register. + * + * \note Before writing user should check if tx is ready (or empty). + * + * \param p_usart Pointer to a USART instance. + * \param c Data to be sent. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_write(Usart *p_usart, uint32_t c) +{ + if (!(p_usart->US_CSR & US_CSR_TXRDY)) { + return 1; + } + + p_usart->US_THR = US_THR_TXCHR(c); + return 0; +} + +/** + * \brief Write to USART Transmit Holding Register. + * + * \note Before writing user should check if tx is ready (or empty). + * + * \param p_usart Pointer to a USART instance. + * \param c Data to be sent. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_putchar(Usart *p_usart, uint32_t c) +{ + uint32_t timeout = USART_DEFAULT_TIMEOUT; + + while (!(p_usart->US_CSR & US_CSR_TXRDY)) { + if (!timeout--) { + return 1; + } + } + + p_usart->US_THR = US_THR_TXCHR(c); + + return 0; +} + +/** + * \brief Write one-line string through USART. + * + * \param p_usart Pointer to a USART instance. + * \param string Pointer to one-line string to be sent. + */ +void usart_write_line(Usart *p_usart, const char *string) +{ + while (*string != '\0') { + usart_putchar(p_usart, *string++); + } +} + +/** + * \brief Read from USART Receive Holding Register. + * + * \note Before reading user should check if rx is ready. + * + * \param p_usart Pointer to a USART instance. + * \param c Pointer where the one-byte received data will be stored. + * + * \retval 0 on success. + * \retval 1 if no data is available or errors. + */ +uint32_t usart_read(Usart *p_usart, uint32_t *c) +{ + if (!(p_usart->US_CSR & US_CSR_RXRDY)) { + return 1; + } + + /* Read character */ + *c = p_usart->US_RHR & US_RHR_RXCHR_Msk; + + return 0; +} + +/** + * \brief Read from USART Receive Holding Register. + * Before reading user should check if rx is ready. + * + * \param p_usart Pointer to a USART instance. + * \param c Pointer where the one-byte received data will be stored. + * + * \retval 0 Data has been received. + * \retval 1 on failure. + */ +uint32_t usart_getchar(Usart *p_usart, uint32_t *c) +{ + uint32_t timeout = USART_DEFAULT_TIMEOUT; + + /* If the receiver is empty, wait until it's not empty or timeout has reached. */ + while (!(p_usart->US_CSR & US_CSR_RXRDY)) { + if (!timeout--) { + return 1; + } + } + + /* Read character */ + *c = p_usart->US_RHR & US_RHR_RXCHR_Msk; + + return 0; +} + +#if (SAM3XA || SAM3U) +/** + * \brief Get Transmit address for DMA operation. + * + * \param p_usart Pointer to a USART instance. + * + * \return Transmit address for DMA access. + */ +uint32_t *usart_get_tx_access(Usart *p_usart) +{ + return (uint32_t *)&(p_usart->US_THR); +} + +/** + * \brief Get Receive address for DMA operation. + * + * \param p_usart Pointer to a USART instance. + * + * \return Receive address for DMA access. + */ +uint32_t *usart_get_rx_access(Usart *p_usart) +{ + return (uint32_t *)&(p_usart->US_RHR); +} +#endif + +/** + * \brief Get USART PDC base address. + * + * \param p_usart Pointer to a UART instance. + * + * \return USART PDC registers base for PDC driver to access. + */ +Pdc *usart_get_pdc_base(Usart *p_usart) +{ + Pdc *p_pdc_base; + + p_pdc_base = (Pdc *) NULL; + + if (p_usart == USART0) { + p_pdc_base = PDC_USART0; + return p_pdc_base; + } +#if (SAM3S || SAM4S || SAM3XA || SAM3U) + else if (p_usart == USART1) { + p_pdc_base = PDC_USART1; + return p_pdc_base; + } +#endif +#if (SAM3SD8 || SAM3XA || SAM3U) + else if (p_usart == USART2) { + p_pdc_base = PDC_USART2; + return p_pdc_base; + } +#endif +#if (SAM3XA || SAM3U) + else if (p_usart == USART3) { + p_pdc_base = PDC_USART3; + return p_pdc_base; + } +#endif + + return p_pdc_base; +} + +/** + * \brief Enable write protect of USART registers. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_enable_writeprotect(Usart *p_usart) +{ + p_usart->US_WPMR = US_WPMR_WPEN | US_WPMR_WPKEY(US_WPKEY_VALUE); +} + +/** + * \brief Disable write protect of USART registers. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_disable_writeprotect(Usart *p_usart) +{ + p_usart->US_WPMR = US_WPMR_WPKEY(US_WPKEY_VALUE); +} + +/** + * \brief Get write protect status. + * + * \param p_usart Pointer to a USART instance. + * + * \return 0 if the peripheral is not protected. + * \return 16-bit Write Protect Violation Status otherwise. + */ +uint32_t usart_get_writeprotect_status(Usart *p_usart) +{ + uint32_t reg_value; + + reg_value = p_usart->US_WPSR; + if (reg_value & US_WPSR_WPVS) { + return (reg_value & US_WPSR_WPVSRC_Msk) >> US_WPSR_WPVSRC_Pos; + } else { + return 0; + } +} + +/** + * \brief Get the total number of errors that occur during an ISO7816 transfer. + * + * \param p_usart Pointer to a USART instance. + * + * \return The number of errors that occured. + */ +uint8_t usart_get_error_number(Usart *p_usart) +{ + return (p_usart->US_NER & US_NER_NB_ERRORS_Msk); +} + +#if (SAM3S || SAM4S || SAM3U || SAM3XA) +/** + * \brief Configure the transmitter preamble length when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_len The transmitter preamble length, which should be 0 ~ 15. + */ +void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PL_Msk) | + US_MAN_TX_PL(uc_len); +} + +/** + * \brief Configure the transmitter preamble pattern when the Manchester + * encode/decode is enabled, which should be 0 ~ 3. + * + * \param p_usart Pointer to a USART instance. + * \param uc_pattern 0 if the preamble is composed of '1's; + * 1 if the preamble is composed of '0's; + * 2 if the preamble is composed of '01's; + * 3 if the preamble is composed of '10's. + */ +void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PP_Msk) | + (uc_pattern << US_MAN_TX_PP_Pos); +} + +/** + * \brief Configure the transmitter Manchester polarity when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_polarity Indicate the transmitter Manchester polarity, which + * should be 0 or 1. + */ +void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_MPOL) | + (uc_polarity << 12); +} + +/** + * \brief Configure the detected receiver preamble length when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_len The detected receiver preamble length, which should be 0 ~ 15. + */ +void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PL_Msk) | + US_MAN_RX_PL(uc_len); +} + +/** + * \brief Configure the detected receiver preamble pattern when the Manchester + * encode/decode is enabled, which should be 0 ~ 3. + * + * \param p_usart Pointer to a USART instance. + * \param uc_pattern 0 if the preamble is composed of '1's; + * 1 if the preamble is composed of '0's; + * 2 if the preamble is composed of '01's; + * 3 if the preamble is composed of '10's. + */ +void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PP_Msk) | + (uc_pattern << US_MAN_RX_PP_Pos); +} + +/** + * \brief Configure the receiver Manchester polarity when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_polarity Indicate the receiver Manchester polarity, which should + * be 0 or 1. + */ +void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_MPOL) | + (uc_polarity << 28); +} + +/** + * \brief Enable drift compensation. + * + * \note The 16X clock mode must be enabled. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_man_enable_drift_compensation(Usart *p_usart) +{ + p_usart->US_MAN |= US_MAN_DRIFT; +} + +/** + * \brief Disable drift compensation. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_man_disable_drift_compensation(Usart *p_usart) +{ + p_usart->US_MAN &= ~US_MAN_DRIFT; +} +#endif + +//@} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.h new file mode 100644 index 000000000..2771c2273 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/sam/drivers/usart/usart.h @@ -0,0 +1,633 @@ +/** + * \file + * + * \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver for SAM. + * + * Copyright (c) 2011-2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef USART_H_INCLUDED +#define USART_H_INCLUDED + +#include "compiler.h" + +/** + * \defgroup usart_group Universal Synchronous Asynchronous Receiver Transmitter (USART) + * + * See \ref sam_usart_quickstart. + * + * This is a low-level driver implementation for the SAM Universal + * Synchronous/Asynchronous Receiver/Transmitter. + * + * @{ + */ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** Clock phase. */ +#define SPI_CPHA (1 << 0) + +/** Clock polarity. */ +#define SPI_CPOL (1 << 1) + +/** SPI mode definition. */ +#define SPI_MODE_0 (SPI_CPHA) +#define SPI_MODE_1 0 +#define SPI_MODE_2 (SPI_CPOL | SPI_CPHA) +#define SPI_MODE_3 (SPI_CPOL) + +//! Input parameters when initializing RS232 and similar modes. +typedef struct { + //! Set baud rate of the USART (unused in slave modes). + uint32_t baudrate; + + //! Number of bits, which should be one of the following: US_MR_CHRL_5_BIT, + //! US_MR_CHRL_6_BIT, US_MR_CHRL_7_BIT, US_MR_CHRL_8_BIT or US_MR_MODE9. + uint32_t char_length; + + //! Parity type, which should be one of the following: US_MR_PAR_EVEN, US_MR_PAR_ODD, + //! US_MR_PAR_SPACE, US_MR_PAR_MARK, US_MR_PAR_NO or US_MR_PAR_MULTIDROP. + uint32_t parity_type; + + //! Number of stop bits between two characters: US_MR_NBSTOP_1_BIT, + //! US_MR_NBSTOP_1_5_BIT, US_MR_NBSTOP_2_BIT. + //! \note US_MR_NBSTOP_1_5_BIT is supported in asynchronous modes only. + uint32_t stop_bits; + + //! Run the channel in test mode, which should be one of following: US_MR_CHMODE_NORMAL, + //! US_MR_CHMODE_AUTOMATIC, US_MR_CHMODE_LOCAL_LOOPBACK, US_MR_CHMODE_REMOTE_LOOPBACK + uint32_t channel_mode; + + //! Filter of IrDA mode, useless in other modes. + uint32_t irda_filter; +} sam_usart_opt_t; + +//! Input parameters when initializing ISO7816 mode. +typedef struct { + //! Set the frequency of the ISO7816 clock. + uint32_t iso7816_hz; + + //! The number of ISO7816 clock ticks in every bit period (1 to 2047, 0 = disable clock). + //! Baudrate rate = iso7816_hz / fidi_ratio + uint32_t fidi_ratio; + + //! How to calculate the parity bit: US_MR_PAR_EVEN for normal mode or + //! US_MR_PAR_ODD for inverse mode. + uint32_t parity_type; + + //! Inhibit Non Acknowledge: + //! - 0: the NACK is generated; + //! - 1: the NACK is not generated. + //! + //! \note This bit will be used only in ISO7816 mode, protocol T = 0 receiver. + uint32_t inhibit_nack; + + //! Disable successive NACKs. + //! - 0: NACK is sent on the ISO line as soon as a parity error occurs in the received character. + //! Successive parity errors are counted up to the value in the max_iterations field. + //! These parity errors generate a NACK on the ISO line. As soon as this value is reached, + //! No additional NACK is sent on the ISO line. The ITERATION flag is asserted. + uint32_t dis_suc_nack; + + //! Max number of repetitions (0 to 7). + uint32_t max_iterations; + + //! Bit order in transmitted characters: + //! - 0: LSB first; + //! - 1: MSB first. + uint32_t bit_order; + + //! Which protocol is used: + //! - 0: T = 0; + //! - 1: T = 1. + uint32_t protocol_type; +} usart_iso7816_opt_t; + +//! Input parameters when initializing SPI mode. +typedef struct { + //! Set the frequency of the SPI clock (unused in slave mode). + uint32_t baudrate; + + //! Number of bits, which should be one of the following: US_MR_CHRL_5_BIT, + //! US_MR_CHRL_6_BIT, US_MR_CHRL_7_BIT, US_MR_CHRL_8_BIT or US_MR_MODE9. + uint32_t char_length; + + //! Which SPI mode to use, which should be one of the following: + //! SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3. + uint32_t spi_mode; + + //! Run the channel in test mode, which should be one of following: US_MR_CHMODE_NORMAL, + //! US_MR_CHMODE_AUTOMATIC, US_MR_CHMODE_LOCAL_LOOPBACK, US_MR_CHMODE_REMOTE_LOOPBACK + uint32_t channel_mode; +} usart_spi_opt_t; + +void usart_reset(Usart *p_usart); +uint32_t usart_init_rs232(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_hw_handshaking(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +#if (SAM3S || SAM4S || SAM3U) +uint32_t usart_init_modem(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +#endif +uint32_t usart_init_sync_master(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_sync_slave(Usart *p_usart, const sam_usart_opt_t *p_usart_opt); +uint32_t usart_init_rs485(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_irda(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_iso7816(Usart *p_usart, const usart_iso7816_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_spi_master(Usart *p_usart, const usart_spi_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_spi_slave(Usart *p_usart, const usart_spi_opt_t *p_usart_opt); +#if SAM3XA +uint32_t usart_init_lin_master(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_lin_slave(Usart *p_usart, const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +void usart_lin_abort_tx(Usart *p_usart); +void usart_lin_send_wakeup_signal(Usart *p_usart); +void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action); +void usart_lin_disable_parity(Usart *p_usart); +void usart_lin_enable_parity(Usart *p_usart); +void usart_lin_disable_checksum(Usart *p_usart); +void usart_lin_enable_checksum(Usart *p_usart); +void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type); +void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode); +void usart_lin_disable_frame_slot(Usart *p_usart); +void usart_lin_enable_frame_slot(Usart *p_usart); +void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type); +void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len); +void usart_lin_disable_pdc_mode(Usart *p_usart); +void usart_lin_enable_pdc_mode(Usart *p_usart); +void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id); +uint8_t usart_lin_read_identifier(Usart *p_usart); +#endif +void usart_enable_tx(Usart *p_usart); +void usart_disable_tx(Usart *p_usart); +void usart_reset_tx(Usart *p_usart); +void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard); +void usart_enable_rx(Usart *p_usart); +void usart_disable_rx(Usart *p_usart); +void usart_reset_rx(Usart *p_usart); +void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout); +void usart_enable_interrupt(Usart *p_usart,uint32_t ul_sources); +void usart_disable_interrupt(Usart *p_usart,uint32_t ul_sources); +uint32_t usart_get_interrupt_mask(Usart *p_usart); +uint32_t usart_get_status(Usart *p_usart); +void usart_reset_status(Usart *p_usart); +void usart_start_tx_break(Usart *p_usart); +void usart_stop_tx_break(Usart *p_usart); +void usart_start_rx_timeout(Usart *p_usart); +uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr); +void usart_reset_iterations(Usart *p_usart); +void usart_reset_nack(Usart *p_usart); +void usart_restart_rx_timeout(Usart *p_usart); +#if (SAM3S || SAM4S || SAM3U) +void usart_drive_DTR_pin_low(Usart *p_usart); +void usart_drive_DTR_pin_high(Usart *p_usart); +#endif +void usart_drive_RTS_pin_low(Usart *p_usart); +void usart_drive_RTS_pin_high(Usart *p_usart); +void usart_spi_force_chip_select(Usart *p_usart); +void usart_spi_release_chip_select(Usart *p_usart); +uint32_t usart_is_tx_ready(Usart *p_usart); +uint32_t usart_is_tx_empty(Usart *p_usart); +uint32_t usart_is_rx_ready(Usart *p_usart); +uint32_t usart_is_rx_buf_end(Usart *p_usart); +uint32_t usart_is_tx_buf_end(Usart *p_usart); +uint32_t usart_is_rx_buf_full(Usart *p_usart); +uint32_t usart_is_tx_buf_empty(Usart *p_usart); +uint32_t usart_write(Usart *p_usart, uint32_t c); +uint32_t usart_putchar(Usart *p_usart, uint32_t c); +void usart_write_line(Usart *p_usart, const char *string); +uint32_t usart_read(Usart *p_usart, uint32_t *c); +uint32_t usart_getchar(Usart *p_usart, uint32_t *c); +#if (SAM3XA || SAM3U) +uint32_t * usart_get_tx_access(Usart *p_usart); +uint32_t * usart_get_rx_access(Usart *p_usart); +#endif +Pdc *usart_get_pdc_base(Usart *p_usart); +void usart_enable_writeprotect(Usart *p_usart); +void usart_disable_writeprotect(Usart *p_usart); +uint32_t usart_get_writeprotect_status(Usart *p_usart); +uint8_t usart_get_error_number(Usart *p_usart); +#if (SAM3S || SAM4S || SAM3U || SAM3XA) +void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len); +void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern); +void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity); +void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len); +void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern); +void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity); +void usart_man_enable_drift_compensation(Usart *p_usart); +void usart_man_disable_drift_compensation(Usart *p_usart); +#endif + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +//! @} + +/** + * \page sam_usart_quickstart Quick start guide for the SAM USART module + * + * This is the quick start guide for the \ref usart_group "USART module", with + * step-by-step instructions on how to configure and use the driver in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \note Some SAM devices contain both USART and UART modules, with the latter + * being a subset in functionality of the former but physically seperate + * peripherals. UART modules are compatible with the USART driver, but + * only for the functions and modes suported by the base UART driver. + * + * \section usart_basic_use_case Basic use case + * \section usart_use_cases USART use cases + * - \ref usart_basic_use_case + * - \subpage usart_use_case_1 + * - \subpage usart_use_case_2 + * + * \section usart_basic_use_case Basic use case - transmit a character + * In this use case, the USART module is configured for: + * - Using USART0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * \section usart_basic_use_case_setup Setup steps + * + * \subsection usart_basic_use_case_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclock)" + * -# \ref pio_group "Parallel Input/Output Controller (pio)" + * -# \ref pmc_group "Power Management Controller (pmc)" + * + * \subsection usart_basic_use_case_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.) + * \code + * #define USART_SERIAL USART0 + * #define USART_SERIAL_ID ID_USART0 + * #define USART_SERIAL_PIO PINS_USART_PIO + * #define USART_SERIAL_TYPE PINS_USART_TYPE + * #define USART_SERIAL_PINS PINS_USART_PINS + * #define USART_SERIAL_MASK PINS_USART_MASK + * #define USART_SERIAL_BAUDRATE 9600 + * #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT + * #define USART_SERIAL_PARITY US_MR_PAR_NO + * #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT + * \endcode + * + * Add to application initialization: + * \code + * sysclk_init(); + * + * pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE, + * USART_SERIAL_MASK, USART_SERIAL_ATTR); + * + * const sam_usart_opt_t usart_console_settings = { + * USART_SERIAL_BAUDRATE, + * USART_SERIAL_CHAR_LENGTH, + * USART_SERIAL_PARITY, + * USART_SERIAL_STOP_BIT, + * US_MR_CHMODE_NORMAL + * }; + * + * pmc_enable_periph_clk(USART_SERIAL_ID); + * + * usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); + * usart_enable_tx(USART_SERIAL); + * usart_enable_rx(USART_SERIAL); + * \endcode + * + * \subsection usart_basic_use_case_setup_flow Workflow + * -# Initialize system clock: + * \code + * sysclk_init(); + * \endcode + * -# Configure the USART Tx and Rx pins as Outputs and Inputs respectively: + * \code + * pio_configure(PINS_UART_PIO, PINS_UART_TYPE, PINS_UART_MASK, + * PINS_UART_ATTR); + * \endcode + * -# Create USART options struct: + * \code + * const sam_usart_opt_t usart_console_settings = { + * USART_SERIAL_BAUDRATE, + * USART_SERIAL_CHAR_LENGTH, + * USART_SERIAL_PARITY, + * USART_SERIAL_STOP_BIT, + * US_MR_CHMODE_NORMAL + * }; + * \endcode + * -# Enable the clock to the USART module: + * \code + * pmc_enable_periph_clk(USART_SERIAL_ID); + * \endcode + * -# Initialize the USART module in RS232 mode: + * \code + * usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); + * \endcode + * -# Enable the Rx and Tx modes of the USART module: + * \code + * usart_enable_tx(USART_SERIAL); + * usart_enable_rx(USART_SERIAL); + * \endcode + * + * \section usart_basic_use_case_usage Usage steps + * + * \subsection usart_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + * usart_putchar(USART_SERIAL, 'a'); + * \endcode + * + * \subsection usart_basic_use_case_usage_flow Workflow + * -# Send an 'a' character via USART + * \code usart_putchar(USART_SERIAL, 'a'); \endcode + */ + +/** + * \page usart_use_case_1 USART receive character and echo back + * + * In this use case, the USART module is configured for: + * - Using USART0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. + * + * \section usart_use_case_1_setup Setup steps + * + * \subsection usart_use_case_1_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclock)" + * -# \ref pio_group "Parallel Input/Output Controller (pio)" + * -# \ref pmc_group "Power Management Controller (pmc)" + * + * \subsection usart_use_case_1_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.): + * \code + * #define USART_SERIAL USART0 + * #define USART_SERIAL_ID ID_USART0 + * #define USART_SERIAL_PIO PINS_USART_PIO + * #define USART_SERIAL_TYPE PINS_USART_TYPE + * #define USART_SERIAL_PINS PINS_USART_PINS + * #define USART_SERIAL_MASK PINS_USART_MASK + * #define USART_SERIAL_BAUDRATE 9600 + * #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT + * #define USART_SERIAL_PARITY US_MR_PAR_NO + * #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT + * \endcode + * + * A variable for the received byte must be added: + * \code + * uint32_t received_byte; + * \endcode + * + * Add to application initialization: + * \code + * sysclk_init(); + * + * pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE, + * USART_SERIAL_MASK, USART_SERIAL_ATTR); + * + * const sam_usart_opt_t usart_console_settings = { + * USART_SERIAL_BAUDRATE, + * USART_SERIAL_CHAR_LENGTH, + * USART_SERIAL_PARITY, + * USART_SERIAL_STOP_BIT, + * US_MR_CHMODE_NORMAL + * }; + * + * pmc_enable_periph_clk(USART_SERIAL_ID); + * + * usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); + * usart_enable_tx(USART_SERIAL); + * usart_enable_rx(USART_SERIAL); + * \endcode + * + * \subsection usart_use_case_1_setup_flow Workflow + * -# Initialize system clock: + * \code + * sysclk_init(); + * \endcode + * -# Configure the USART Tx and Rx pins as Outputs and Inputs respectively: + * \code + * pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE, + * USART_SERIAL_MASK, USART_SERIAL_ATTR); + * \endcode + * -# Create USART options struct: + * \code + * const sam_usart_opt_t usart_console_settings = { + * USART_SERIAL_BAUDRATE, + * USART_SERIAL_CHAR_LENGTH, + * USART_SERIAL_PARITY, + * USART_SERIAL_STOP_BIT, + * US_MR_CHMODE_NORMAL + * }; + * \endcode + * -# Enable the clock to the USART module: + * \code pmc_enable_periph_clk(USART_SERIAL_ID); \endcode + * -# Initialize the USART module in RS232 mode: + * \code usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); \endcode + * -# Enable the Rx and Tx modes of the USART module: + * \code + * usart_enable_tx(USART_SERIAL); + * usart_enable_rx(USART_SERIAL); + * \endcode + * + * \section usart_use_case_1_usage Usage steps + * + * \subsection usart_use_case_1_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + * received_byte = usart_getchar(USART_SERIAL); + * usart_putchar(USART_SERIAL, received_byte); + * \endcode + * + * \subsection usart_use_case_1_usage_flow Workflow + * -# Wait for reception of a character: + * \code usart_getchar(USART_SERIAL, &received_byte); \endcode + * -# Echo the character back: + * \code usart_putchar(USART_SERIAL, received_byte); \endcode + */ + +/** + * \page usart_use_case_2 USART receive character and echo back via interrupts + * + * In this use case, the USART module is configured for: + * - Using USART0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. The character reception is + * performed via an interrupt handler, rather than the polling method used + * in \ref usart_use_case_1. + * + * \section usart_use_case_2_setup Setup steps + * + * \subsection usart_use_case_2_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclock)" + * -# \ref pio_group "Parallel Input/Output Controller (pio)" + * -# \ref pmc_group "Power Management Controller (pmc)" + * + * \subsection usart_use_case_2_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.): + * \code + * #define USART_SERIAL USART0 + * #define USART_SERIAL_ID ID_USART0 + * #define USART_SERIAL_ISR_HANDLER USART0_Handler + * #define USART_SERIAL_PIO PINS_USART_PIO + * #define USART_SERIAL_TYPE PINS_USART_TYPE + * #define USART_SERIAL_PINS PINS_USART_PINS + * #define USART_SERIAL_MASK PINS_USART_MASK + * #define USART_SERIAL_BAUDRATE 9600 + * #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT + * #define USART_SERIAL_PARITY US_MR_PAR_NO + * #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT + * \endcode + * + * A variable for the received byte must be added: + * \code + * uint32_t received_byte; + * \endcode + * + * Add to application initialization: + * \code + * sysclk_init(); + * + * pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE, + * USART_SERIAL_MASK, USART_SERIAL_ATTR); + * + * const sam_usart_opt_t usart_console_settings = { + * USART_SERIAL_BAUDRATE, + * USART_SERIAL_CHAR_LENGTH, + * USART_SERIAL_PARITY, + * USART_SERIAL_STOP_BIT, + * US_MR_CHMODE_NORMAL + * }; + * + * pmc_enable_periph_clk(USART_SERIAL_ID); + * + * usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); + * usart_enable_tx(USART_SERIAL); + * usart_enable_rx(USART_SERIAL); + * + * usart_enable_interrupt(USART_SERIAL, US_IER_RXRDY); + * NVIC_EnableIRQ(USART_SERIAL_IRQ); + * \endcode + * + * \subsection usart_use_case_2_setup_flow Workflow + * -# Initialize system clock: + * \code + * sysclk_init(); + * \endcode + * -# Configure the USART Tx and Rx pins as Outputs and Inputs respectively: + * \code + * pio_configure(USART_SERIAL_PIO, USART_SERIAL_TYPE, + * USART_SERIAL_MASK, USART_SERIAL_ATTR); + * \endcode + * -# Create USART options struct: + * \code + * const sam_usart_opt_t usart_console_settings = { + * USART_SERIAL_BAUDRATE, + * USART_SERIAL_CHAR_LENGTH, + * USART_SERIAL_PARITY, + * USART_SERIAL_STOP_BIT, + * US_MR_CHMODE_NORMAL + * }; + * \endcode + * -# Enable the clock to the USART module: + * \code pmc_enable_periph_clk(USART_SERIAL_ID); \endcode + * -# Initialize the USART module in RS232 mode: + * \code usart_init_rs232(USART_SERIAL, &usart_console_settings, sysclk_get_main_hz()); \endcode + * -# Enable the Rx and Tx modes of the USART module: + * \code + * usart_enable_tx(USART_SERIAL); + * usart_enable_rx(USART_SERIAL); + * \endcode + * -# Enable the USART character reception interrupt, and general interrupts for the USART module. + * \code + * usart_enable_interrupt(USART_SERIAL, US_IER_RXRDY); + * NVIC_EnableIRQ(USART_SERIAL_IRQ); + * \endcode + * \section usart_use_case_2_usage Usage steps + * + * \subsection usart_use_case_2_usage_code Example code + * Add to your main application C-file the USART interrupt handler: + * \code + * void USART_SERIAL_ISR_HANDLER(void) + * { + * uint32_t dw_status = usart_get_status(USART_SERIAL); + * + * if (dw_status & US_CSR_RXRDY) { + * uint32_t received_byte; + * + * usart_read(USART_SERIAL, &received_byte); + * usart_write(USART_SERIAL, received_byte); + * } + * } + * \endcode + * + * \subsection usart_use_case_2_usage_flow Workflow + * -# When the USART ISR fires, retrieve the USART module interrupt flags: + * \code uint32_t dw_status = usart_get_status(USART_SERIAL); \endcode + * -# Check if the USART Receive Character interrupt has fired: + * \code if (dw_status & US_CSR_RXRDY) \endcode + * -# If a character has been received, fetch it into a temporary variable: + * \code usart_read(USART_SERIAL, &received_byte); \endcode + * -# Echo the character back: + * \code usart_write(USART_SERIAL, received_byte); \endcode + */ + +#endif /* USART_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/thirdparty/CMSIS/Include/core_cmFunc.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/thirdparty/CMSIS/Include/core_cmFunc.h index c999b1c83..bd08fc867 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/thirdparty/CMSIS/Include/core_cmFunc.h +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/asf/thirdparty/CMSIS/Include/core_cmFunc.h @@ -587,6 +587,7 @@ __attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fps #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); #endif + ( void ) fpscr; } #endif /* (__CORTEX_M == 0x04) */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_board.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_board.h index 93313faba..6ba5abe74 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_board.h +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_board.h @@ -43,7 +43,7 @@ #define CONF_BOARD_H /* Configure UART pins */ -#define CONF_BOARD_UART_CONSOLE +//#define CONF_BOARD_UART_CONSOLE /* Configure ADC example pins */ //#define CONF_BOARD_ADC @@ -65,10 +65,10 @@ //#define CONF_BOARD_SPI_NPCS3 /* Configure USART RXD pin */ -//#define CONF_BOARD_USART_RXD +#define CONF_BOARD_USART_RXD /* Configure USART TXD pin */ -//#define CONF_BOARD_USART_TXD +#define CONF_BOARD_USART_TXD /* Configure USART CTS pin */ //#define CONF_BOARD_USART_CTS @@ -80,7 +80,7 @@ //#define CONF_BOARD_USART_SCK /* Configure ADM33312 enable pin */ -//#define CONF_BOARD_ADM3312_EN +#define CONF_BOARD_ADM3312_EN /* Configure IrDA transceiver shutdown pin */ //#define CONF_BOARD_TFDU4300_SD diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_clock.h b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_clock.h new file mode 100644 index 000000000..ef9e046a9 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/config/conf_clock.h @@ -0,0 +1,99 @@ +/** + * \file + * + * \brief SAM4S clock configuration. + * + * Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef CONF_CLOCK_H_INCLUDED +#define CONF_CLOCK_H_INCLUDED + +// ===== System Clock (MCK) Source Options +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_XTAL +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_BYPASS +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_8M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_12M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_XTAL +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_BYPASS +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLBCK + +// ===== System Clock (MCK) Prescaler Options (Fmck = Fsys / (SYSCLK_PRES)) +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 +#define CONFIG_SYSCLK_PRES SYSCLK_PRES_2 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_4 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_8 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_16 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_32 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_64 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_3 + +// ===== PLL0 (A) Options (Fpll = (Fclk * PLL_mul) / PLL_div) +// Use mul and div effective values here. +#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL +#define CONFIG_PLL0_MUL 20 +#define CONFIG_PLL0_DIV 1 + +// ===== PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) +// Use mul and div effective values here. +//#define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL +//#define CONFIG_PLL1_MUL 16 +//#define CONFIG_PLL1_DIV 2 + +// ===== USB Clock Source Options (Fusb = FpllX / USB_div) +// Use div effective value here. +//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0 +//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 +//#define CONFIG_USBCLK_DIV 2 + +// ===== Target frequency (System clock) +// - XTAL frequency: 12MHz +// - System clock source: PLLA +// - System clock prescaler: 2 (divided by 2) +// - PLLA source: XTAL +// - PLLA output: XTAL * 20 / 1 +// - System clock: 12 * 20 / 1 / 2 = 120MHz +// ===== Target frequency (USB Clock) +// - USB clock source: PLLB +// - USB clock devider: 2 (devided by 2) +// - PLLB output: XTAL * 16 / 2 +// - USB clock: 12 * 16 / 2 / 2 = 48MHz + + +#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main.c index 39b94034e..80b553322 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main.c +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main.c @@ -44,7 +44,7 @@ *************************************************************************** * * * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong? * + * not run, what could be wrong?" * * * * http://www.FreeRTOS.org/FAQHelp.html * * * @@ -75,16 +75,6 @@ * This file implements the code that is not demo specific, including the * hardware setup and FreeRTOS hook functions. * - * - * Additional code: - * - * This demo does not contain a non-kernel interrupt service routine that - * can be used as an example for application writers to use as a reference. - * Therefore, the framework of a dummy (not installed) handler is provided - * in this file. The dummy function is called Dummy_IRQHandler(). Please - * ensure to read the comments in the function itself, but more importantly, - * the notes on the function contained on the documentation page for this demo - * that is found on the FreeRTOS.org web site. */ /* Standard includes. */ @@ -94,12 +84,16 @@ #include "FreeRTOS.h" #include "task.h" +/* Standard demo includes - just needed for the LED (ParTest) initialisation +function. */ +#include "partest.h" + /* Atmel library includes. */ #include /* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, or 0 to run the more comprehensive test and demo application. */ -#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 1 +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 /*-----------------------------------------------------------*/ @@ -117,6 +111,9 @@ extern void main_full( void ); /*-----------------------------------------------------------*/ +/* See the documentation page for this demo on the FreeRTOS.org web site for +full information - including hardware setup requirements. */ + int main( void ) { /* Prepare the hardware to run this demo. */ @@ -142,14 +139,18 @@ static void prvSetupHardware( void ) { extern void SystemCoreClockUpdate( void ); - /* Ensure SystemCoreClock variable is set. */ - SystemCoreClockUpdate(); + /* ASF function to setup clocking. */ + sysclk_init(); /* Ensure all priority bits are assigned as preemption priority bits. */ NVIC_SetPriorityGrouping( 0 ); /* Atmel library function to setup for the evaluation kit being used. */ board_init(); + + /* Perform any configuration necessary to use the ParTest LED output + functions. */ + vParTestInitialise(); } /*-----------------------------------------------------------*/ @@ -207,29 +208,3 @@ void vApplicationTickHook( void ) } /*-----------------------------------------------------------*/ -#ifdef JUST_AN_EXAMPLE_ISR - -void Dummy_IRQHandler(void) -{ -long lHigherPriorityTaskWoken = pdFALSE; - - /* Clear the interrupt if necessary. */ - Dummy_ClearITPendingBit(); - - /* This interrupt does nothing more than demonstrate how to synchronise a - task with an interrupt. A semaphore is used for this purpose. Note - lHigherPriorityTaskWoken is initialised to zero. */ - xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); - - /* If there was a task that was blocked on the semaphore, and giving the - semaphore caused the task to unblock, and the unblocked task has a priority - higher than the current Running state task (the task that this interrupt - interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE - internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the - portEND_SWITCHING_ISR() macro will result in a context switch being pended to - ensure this interrupt returns directly to the unblocked, higher priority, - task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ - portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); -} - -#endif /* JUST_AN_EXAMPLE_ISR */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_blinky.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_blinky.c index d9386d772..ddad97dec 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_blinky.c +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_blinky.c @@ -128,7 +128,7 @@ will remove items as they are added, meaning the send task should always find the queue empty. */ #define mainQUEUE_LENGTH ( 1 ) -/* Values passed to the two tasks just to check the task parameter +/* Values passed to the two tasks just to check the task parameter functionality. */ #define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) #define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) @@ -147,11 +147,6 @@ static void prvQueueSendTask( void *pvParameters ); */ void main_blinky( void ); -/* - * The hardware only has a single LED. Simply toggle it. - */ -extern void vMainToggleLED( void ); - /*-----------------------------------------------------------*/ /* The queue used by both tasks. */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_full.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_full.c index b87bfeb56..c7a174eb8 100644 --- a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_full.c +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/main_full.c @@ -84,24 +84,20 @@ * In addition to the standard demo tasks, the following tasks and tests are * defined and/or created within this file: * - * "Reg test" tasks - These fill both the core and floating point registers with - * known values, then check that each register maintains its expected value for - * the lifetime of the task. Each task uses a different set of values. The reg - * test tasks execute with a very low priority, so get preempted very - * frequently. A register containing an unexpected value is indicative of an - * error in the context switching mechanism. - * * "Check" timer - The check software timer period is initially set to three * seconds. The callback function associated with the check software timer - * checks that all the standard demo tasks, and the register check tasks, are - * not only still executing, but are executing without reporting any errors. If - * the check software timer discovers that a task has either stalled, or - * reported an error, then it changes its own execution period from the initial - * three seconds, to just 200ms. The check software timer callback function - * also toggles the single LED each time it is called. This provides a visual - * indication of the system status: If the LED toggles every three seconds, - * then no issues have been discovered. If the LED toggles every 200ms, then - * an issue has been discovered with at least one task. + * checks that all the standard demo tasks are not only still executing, but + * are executing without reporting any errors. If the check software timer + * discovers that a task has either stalled, or reported an error, then it + * changes its own execution period from the initial three seconds, to just + * 200ms. The check software timer callback function also toggles the green + * LED each time it is called. This provides a visual indication of the system + * status: If the green LED toggles every three seconds, then no issues have + * been discovered. If the green LED toggles every 200ms, then an issue has + * been discovered with at least one task. + * + * See the documentation page for this demo on the FreeRTOS.org web site for + * full information, including hardware setup requirements. */ /* Standard includes. */ @@ -124,7 +120,10 @@ #include "GenQTest.h" #include "recmutex.h" #include "death.h" +#include "flash_timer.h" #include "partest.h" +#include "comtest2.h" + /* Atmel library includes. */ #include "asf.h" @@ -135,6 +134,7 @@ #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) #define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 ) /* A block time of zero simply means "don't block". */ #define mainDONT_BLOCK ( 0UL ) @@ -149,8 +149,21 @@ reported in one of the standard demo tasks. ms are converted to the equivalent in ticks using the portTICK_RATE_MS constant. */ #define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS ) -/* The LED toggles by the check timer. */ -#define mainCHECK_LED ( 3 ) +/* The standard demo flash timers can be used to flash any number of LEDs. In +this case, because only three LEDs are available, and one is in use by the +check timer, only two are used by the flash timers. */ +#define mainNUMBER_OF_FLASH_TIMERS_LEDS ( 2 ) + +/* The LED toggled by the check timer. The first two LEDs are toggle by the +standard demo flash timers. */ +#define mainCHECK_LED ( 2 ) + +/* Baud rate used by the comtest tasks. */ +#define mainCOM_TEST_BAUD_RATE ( 115200 ) + +/* The LED used by the comtest tasks. In this case, there are no LEDs available +for the comtest, so the LED number is deliberately out of range. */ +#define mainCOM_TEST_LED ( 3 ) /*-----------------------------------------------------------*/ @@ -177,6 +190,8 @@ xTimerHandle xCheckTimer = NULL; vStartRecursiveMutexTasks(); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartLEDFlashTimers( mainNUMBER_OF_FLASH_TIMERS_LEDS ); + vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); /* Create the software timer that performs the 'check' functionality, as described at the top of this file. */ @@ -215,7 +230,7 @@ static long lChangedTimerPeriodAlready = pdFALSE; unsigned long ulErrorFound = pdFALSE; /* Check all the demo tasks (other than the flash tasks) to ensure - that they are all still running, and that none have detected an error. */ + they are all still running, and that none have detected an error. */ if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) { @@ -262,6 +277,11 @@ unsigned long ulErrorFound = pdFALSE; ulErrorFound = pdTRUE; } + if( xAreComTestTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + /* Toggle the check LED to give an indication of the system status. If the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then everything is ok. A faster toggle indicates an error. */ diff --git a/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/serial.c b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/serial.c new file mode 100644 index 000000000..ed407a217 --- /dev/null +++ b/Demo/CORTEX_M4_ATSAM4S_AVR_Studio/src/serial.c @@ -0,0 +1,291 @@ +/* + FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong? * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, training, latest information, + license and contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool. + + Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell + the code with commercial support, indemnification, and middleware, under + the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also + provide a safety engineered and independently SIL3 certified version under + the SafeRTOS brand: http://www.SafeRTOS.com. +*/ + +/* + BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR USART1. + + ***Note*** This example uses queues to send each character into an interrupt + service routine and out of an interrupt service routine individually. This + is done to demonstrate queues being used in an interrupt, and to deliberately + load the system to test the FreeRTOS port. It is *NOT* meant to be an + example of an efficient implementation. An efficient implementation should + use FIFO's or DMA if available, and only use FreeRTOS API functions when + enough has been received to warrant a task being unblocked to process the + data. +*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "queue.h" +#include "semphr.h" +#include "comtest2.h" + +/* Library includes. */ +#include "asf.h" + +/* Demo application includes. */ +#include "demo_serial.h" +/*-----------------------------------------------------------*/ + +/* Misc defines. */ +#define serINVALID_QUEUE ( ( xQueueHandle ) 0 ) +#define serNO_BLOCK ( ( portTickType ) 0 ) +#define serPMC_USART_ID ( BOARD_ID_USART ) + +/* The USART supported by this file. */ +#define serUSART_PORT ( USART1 ) +#define serUSART_IRQ ( USART1_IRQn ) + +/* Every bit in the interrupt mask. */ +#define serMASK_ALL_INTERRUPTS ( 0xffffffffUL ) + +/*-----------------------------------------------------------*/ + +/* The queue used to hold received characters. */ +static xQueueHandle xRxedChars; +static xQueueHandle xCharsForTx; + +/*-----------------------------------------------------------*/ + +/* + * See the serial.h header file. + */ +xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) +{ +uint32_t ulChar; +xComPortHandle xReturn; +const sam_usart_opt_t xUSARTSettings = +{ + ulWantedBaud, + US_MR_CHRL_8_BIT, + US_MR_PAR_NO, + US_MR_NBSTOP_1_BIT, + US_MR_CHMODE_NORMAL, + 0 /* Only used in IrDA mode. */ +}; + + /* Create the queues used to hold Rx/Tx characters. */ + xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); + xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); + + /* If the queues were created correctly then setup the serial port + hardware. */ + if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) + { + /* Enable the peripheral clock in the PMC. */ + pmc_enable_periph_clk( serPMC_USART_ID ); + + /* Configure USART in serial mode. */ + usart_init_rs232( serUSART_PORT, &xUSARTSettings, sysclk_get_cpu_hz() ); + + /* Disable all the interrupts. */ + usart_disable_interrupt( serUSART_PORT, serMASK_ALL_INTERRUPTS ); + + /* Enable the receiver and transmitter. */ + usart_enable_tx( serUSART_PORT ); + usart_enable_rx( serUSART_PORT ); + + /* Clear any characters before enabling interrupt. */ + usart_getchar( serUSART_PORT, &ulChar ); + + /* Enable Rx end interrupt. */ + usart_enable_interrupt( serUSART_PORT, US_IER_RXRDY ); + + /* Configure and enable interrupt of USART. */ + NVIC_SetPriority( serUSART_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_EnableIRQ( serUSART_IRQ ); + } + else + { + xReturn = ( xComPortHandle ) 0; + } + + /* This demo file only supports a single port but we have to return + something to comply with the standard demo header file. */ + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, portTickType xBlockTime ) +{ + /* The port handle is not required as this driver only supports one port. */ + ( void ) pxPort; + + /* Get the next character from the buffer. Return false if no characters + are available, or arrive before xBlockTime expires. */ + if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) ) + { + return pdTRUE; + } + else + { + return pdFALSE; + } +} +/*-----------------------------------------------------------*/ + +void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ) +{ +signed char *pxNext; + + /* A couple of parameters that this port does not use. */ + ( void ) usStringLength; + ( void ) pxPort; + + /* NOTE: This implementation does not handle the queue being full as no + block time is used! */ + + /* The port handle is not required as this driver only supports USART1. */ + ( void ) pxPort; + + /* Send each character in the string, one at a time. */ + pxNext = ( signed char * ) pcString; + while( *pxNext ) + { + xSerialPutChar( pxPort, *pxNext, serNO_BLOCK ); + pxNext++; + } +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, portTickType xBlockTime ) +{ +signed portBASE_TYPE xReturn; + + /* This simple example only supports one port. */ + ( void ) pxPort; + + if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS ) + { + xReturn = pdPASS; + usart_enable_interrupt( serUSART_PORT, US_IER_TXRDY ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vSerialClose( xComPortHandle xPort ) +{ + /* Not supported as not required by the demo application. */ + ( void ) xPort; +} +/*-----------------------------------------------------------*/ + +void USART1_Handler( void ) +{ +portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; +uint8_t ucChar; +uint32_t ulChar; +uint32_t ulUSARTStatus, ulUSARTMask; + + ulUSARTStatus = usart_get_status( serUSART_PORT ); + ulUSARTMask = usart_get_interrupt_mask( serUSART_PORT ); + ulUSARTStatus &= ulUSARTMask; + + if( ( ulUSARTStatus & US_CSR_TXRDY ) != 0UL ) + { + /* The interrupt was caused by the TX register becoming empty. Are + there any more characters to transmit? */ + if( xQueueReceiveFromISR( xCharsForTx, &ucChar, &xHigherPriorityTaskWoken ) == pdTRUE ) + { + /* A character was retrieved from the queue so can be sent to the + USART now. */ + usart_putchar( serUSART_PORT, ( uint32_t ) ucChar ); + } + else + { + usart_disable_interrupt( serUSART_PORT, US_IER_TXRDY ); + } + } + + if( ( ulUSARTStatus & US_CSR_RXRDY ) != 0UL ) + { + /* A character has been received on the USART, send it to the Rx + handler task. */ + usart_getchar( serUSART_PORT, &ulChar ); + ucChar = ( uint8_t ) ( ulChar & 0xffUL ); + xQueueSendFromISR( xRxedChars, &ucChar, &xHigherPriorityTaskWoken ); + } + + /* If sending or receiving from a queue has caused a task to unblock, and + the unblocked task has a priority equal to or higher than the currently + running task (the task this ISR interrupted), then xHigherPriorityTaskWoken + will have automatically been set to pdTRUE within the queue send or receive + function. portEND_SWITCHING_ISR() will then ensure that this ISR returns + directly to the higher priority unblocked task. */ + portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); +} + + + + + + -- 2.39.5