ac.h 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436
  1. /**
  2. * \file
  3. *
  4. * \brief SAM Analog Comparator Driver
  5. *
  6. * Copyright (c) 2012-2016 Atmel Corporation. All rights reserved.
  7. *
  8. * \asf_license_start
  9. *
  10. * \page License
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright notice,
  16. * this list of conditions and the following disclaimer.
  17. *
  18. * 2. Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. *
  22. * 3. The name of Atmel may not be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * 4. This software may only be redistributed and used in connection with an
  26. * Atmel microcontroller product.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  29. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  30. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  31. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  32. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  36. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * \asf_license_stop
  41. *
  42. */
  43. /*
  44. * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
  45. */
  46. #ifndef AC_H_INCLUDED
  47. #define AC_H_INCLUDED
  48. /**
  49. * \defgroup asfdoc_sam0_ac_group SAM Analog Comparator (AC) Driver
  50. *
  51. * This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers
  52. * provides an interface for the configuration
  53. * and management of the device's Analog Comparator functionality, for the
  54. * comparison of analog voltages against a known reference voltage to determine
  55. * its relative level. The following driver API modes are covered by this
  56. * manual:
  57. * - Polled APIs
  58. * \if AC_CALLBACK_MODE
  59. * - Callback APIs
  60. * \endif
  61. *
  62. * The following peripherals are used by this module:
  63. * - AC (Analog Comparator)
  64. *
  65. * The following devices can use this module:
  66. * - Atmel | SMART SAM D20/D21
  67. * - Atmel | SMART SAM R21
  68. * - Atmel | SMART SAM D10/D11
  69. * - Atmel | SMART SAM L21/L22
  70. * - Atmel | SMART SAM DA1
  71. * - Atmel | SMART SAM C20/C21
  72. * - Atmel | SMART SAM HA1
  73. *
  74. * The outline of this documentation is as follows:
  75. * - \ref asfdoc_sam0_ac_prerequisites
  76. * - \ref asfdoc_sam0_ac_module_overview
  77. * - \ref asfdoc_sam0_ac_special_considerations
  78. * - \ref asfdoc_sam0_ac_extra_info
  79. * - \ref asfdoc_sam0_ac_examples
  80. * - \ref asfdoc_sam0_ac_api_overview
  81. *
  82. *
  83. * \section asfdoc_sam0_ac_prerequisites Prerequisites
  84. *
  85. * There are no prerequisites for this module.
  86. *
  87. *
  88. * \section asfdoc_sam0_ac_module_overview Module Overview
  89. *
  90. * The Analog Comparator module provides an interface for the comparison of one
  91. * or more analog voltage inputs (sourced from external or internal inputs)
  92. * against a known reference voltage, to determine if the unknown voltage is
  93. * higher or lower than the reference. Additionally, window functions are
  94. * provided so that two comparators can be connected together to determine if
  95. * an input is below, inside, above, or outside the two reference points of the
  96. * window.
  97. *
  98. * Each comparator requires two analog input voltages, a positive and negative
  99. * channel input. The result of the comparison is a binary \c true if the
  100. * comparator's positive channel input is higher than the comparator's negative
  101. * input channel, and \c false if otherwise.
  102. *
  103. *
  104. * \subsection asfdoc_sam0_ac_module_features Driver Feature Macro Definition
  105. * <table>
  106. * <tr>
  107. * <th>Driver Feature Macro</th>
  108. * <th>Supported devices</th>
  109. * </tr>
  110. * <tr>
  111. * <td>FEATURE_AC_HYSTERESIS_LEVEL</td>
  112. * <td>SAM L21/L22/C20/C21</td>
  113. * </tr>
  114. * <tr>
  115. * <td>FEATURE_AC_SYNCBUSY_SCHEME_VERSION_2</td>
  116. * <td>SAM L21/L22/C20/C21</td>
  117. * </tr>
  118. * <tr>
  119. * <td>FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR</td>
  120. * <td>SAM L21/L22/C20/C21</td>
  121. * </tr>
  122. * <tr>
  123. * <td>FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR</td>
  124. * <td>SAM D20/L22/D21/D10/D11/R21/DA1/HA1</td>
  125. * </tr>
  126. * </table>
  127. * \note The specific features are only available in the driver when the
  128. * selected device supports those features.
  129. *
  130. * \subsection asfdoc_sam0_ac_module_overview_pairs Window Comparators and Comparator Pairs
  131. * Each comparator module contains one or more comparator pairs, a set of two
  132. * distinct comparators which can be used independently or linked together for
  133. * Window Comparator mode. In this latter mode, the two comparator units in a
  134. * comparator pair are linked together to allow the module to detect if an input
  135. * voltage is below, inside, above, or outside a window set by the upper and
  136. * lower threshold voltages set by the two comparators. If not required, window
  137. * comparison mode can be turned off and the two comparator units can be
  138. * configured and used separately.
  139. *
  140. * \subsection asfdoc_sam0_ac_module_overview_pos_neg_mux Positive and Negative Input MUXes
  141. * Each comparator unit requires two input voltages, a positive and a negative
  142. * channel (note that these names refer to the logical operation that the unit
  143. * performs, and both voltages should be above GND), which are then compared with
  144. * one another. Both the positive and the negative channel inputs are connected to
  145. * a pair of multiplexers (MUXes), which allows one of several possible inputs to be
  146. * selected for each comparator channel.
  147. *
  148. * The exact channels available for each comparator differ for the positive and
  149. * the negative inputs, but the same MUX choices are available for all comparator
  150. * units (i.e. all positive MUXes are identical, all negative MUXes are
  151. * identical). This allows the user application to select which voltages are
  152. * compared to one another.
  153. *
  154. * When used in window mode, both comparators in the window pair should have
  155. * their positive channel input MUXes configured to the same input channel, with
  156. * the negative channel input MUXes used to set the lower and upper window
  157. * bounds.
  158. *
  159. * \subsection asfdoc_sam0_ac_module_overview_output_filtering Output Filtering
  160. * The output of each comparator unit can either be used directly with no
  161. * filtering (giving a lower latency signal, with potentially more noise around
  162. * the comparison threshold) or be passed through a multiple stage
  163. * digital majority filter. Several filter lengths are available, with the
  164. * longer stages producing a more stable result, at the expense of a higher
  165. * latency.
  166. *
  167. * When output filtering is used in single shot mode, a single trigger of the
  168. * comparator will automatically perform the required number of samples to
  169. * produce a correctly filtered result.
  170. *
  171. * \subsection asfdoc_sam0_ac_module_overview_input_hysteresis Input Hysteresis
  172. * To prevent unwanted noise around the threshold where the comparator unit's
  173. * positive and negative input channels are close in voltage to one another, an
  174. * optional hysteresis can be used to widen the point at which the output result
  175. * flips. This mode will prevent a change in the comparison output unless the
  176. * inputs cross one another beyond the hysteresis gap introduces by this mode.
  177. *
  178. * \subsection asfdoc_sam0_ac_module_overview_sampling Single Shot and Continuous Sampling Modes
  179. * Comparators can be configured to run in either Single Shot or Continuous
  180. * sampling modes; when in Single Shot mode, the comparator will only perform a
  181. * comparison (and any resulting filtering, see
  182. * \ref asfdoc_sam0_ac_module_overview_output_filtering) when triggered via a
  183. * software or event trigger. This mode improves the power efficiency of the
  184. * system by only performing comparisons when actually required by the
  185. * application.
  186. *
  187. * For systems requiring a lower latency or more frequent comparisons,
  188. * continuous mode will place the comparator into continuous sampling mode,
  189. * which increases the module's power consumption, but decreases the latency
  190. * between each comparison result by automatically performing a comparison on
  191. * every cycle of the module's clock.
  192. *
  193. * \subsection asfdoc_sam0_ac_module_overview_events Events
  194. * Each comparator unit is capable of being triggered by both software and
  195. * hardware triggers. Hardware input events allow for other peripherals to
  196. * automatically trigger a comparison on demand - for example, a timer output
  197. * event could be used to trigger comparisons at a desired regular interval.
  198. *
  199. * The module's output events can similarly be used to trigger other hardware
  200. * modules each time a new comparison result is available. This scheme allows
  201. * for reduced levels of CPU usage in an application and lowers the overall
  202. * system response latency by directly triggering hardware peripherals from one
  203. * another without requiring software intervention.
  204. *
  205. * \note The connection of events between modules requires the use of the
  206. * \ref asfdoc_sam0_events_group "SAM Event System Driver (EVENTS)"
  207. * to route output event of one module to the input event of another.
  208. * For more information on event routing, refer to the event driver
  209. * documentation.
  210. *
  211. * \subsection asfdoc_sam0_ac_module_overview_physical Physical Connection
  212. * Physically, the modules are interconnected within the device as shown in
  213. * \ref asfdoc_sam0_ac_module_int_connections "the diagram below".
  214. *
  215. * \anchor asfdoc_sam0_ac_module_int_connections
  216. * \dot
  217. * digraph overview {
  218. * rankdir = LR;
  219. * splines = false;
  220. *
  221. * pos_src1_1 [label="GPIO Pins", shape=none, height=0];
  222. * neg_src1_1 [label="GPIO Pins", shape=none, height=0];
  223. * neg_src1_2 [label="Internal DAC", shape=none, height=0];
  224. * neg_src1_3 [label="Internal Refs", shape=none, height=0];
  225. * pos_src2_1 [label="GPIO Pins", shape=none, height=0];
  226. * neg_src2_1 [label="GPIO Pins", shape=none, height=0];
  227. * neg_src2_2 [label="Internal DAC", shape=none, height=0];
  228. * neg_src2_3 [label="Internal Refs", shape=none, height=0];
  229. * res_out1 [label="", style=invisible];
  230. * res_out2 [label="", style=invisible];
  231. * res_window [label="", style=invisible];
  232. *
  233. * mux_pos1 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2];
  234. * mux_neg1 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2];
  235. * mux_neg2 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2];
  236. * mux_pos2 [label="", shape=polygon, sides=4, distortion=0.6, orientation=90, style=filled, fillcolor=black, height=0.9, width=0.2];
  237. * ac1 [label="AC 1", shape=triangle, orientation=-90, style=filled, fillcolor=darkolivegreen1, height=1, width=1];
  238. * ac2 [label="AC 2", shape=triangle, orientation=-90, style=filled, fillcolor=darkolivegreen1, height=1, width=1];
  239. *
  240. * window_comp [label="Window\nLogic", shape=rectangle style=filled fillcolor=lightgray];
  241. *
  242. * edge [dir="forward"];
  243. *
  244. * pos_src1_1:e -> mux_pos1:w;
  245. * mux_pos1:e -> ac1:nw [label="+"];
  246. * neg_src1_1:e -> mux_neg1:nw;
  247. * neg_src1_2:e -> mux_neg1:w;
  248. * neg_src1_3:e -> mux_neg1:sw;
  249. * mux_neg1:e -> ac1:sw [label="-"];
  250. * ac1:e -> res_out1 [label="Comparator 1 Result"];
  251. *
  252. * pos_src2_1:e -> mux_pos2:w;
  253. * mux_pos2:e -> ac2:sw [label="+"];
  254. * neg_src2_1:e -> mux_neg2:nw;
  255. * neg_src2_2:e -> mux_neg2:w;
  256. * neg_src2_3:e -> mux_neg2:sw;
  257. * mux_neg2:e -> ac2:nw [label="-"];
  258. * ac2:e -> res_out2 [label="Comparator 2 Result"];
  259. *
  260. * ac1:e -> window_comp:nw;
  261. * ac2:e -> window_comp:sw;
  262. * window_comp:e -> res_window:w [label="Window Result"];
  263. *
  264. * {rank=same; pos_src1_1 neg_src1_1 neg_src1_2 neg_src1_3 pos_src2_1 neg_src2_1 neg_src2_2 neg_src2_3 }
  265. * {rank=same; mux_pos1 mux_neg1 mux_pos2 mux_neg2 }
  266. * {rank=same; ac1 ac2 }
  267. * {rank=same; res_out1 res_out2 res_window }
  268. * }
  269. * \enddot
  270. *
  271. *
  272. * \section asfdoc_sam0_ac_special_considerations Special Considerations
  273. *
  274. * The number of comparator pairs (and, thus, window comparators) within a
  275. * single hardware instance of the Analog Comparator module is device-specific.
  276. * Some devices will contain a single comparator pair, while others may have two
  277. * pairs; refer to your device specific datasheet for details.
  278. *
  279. *
  280. * \section asfdoc_sam0_ac_extra_info Extra Information
  281. *
  282. * For extra information, see \ref asfdoc_sam0_ac_extra. This includes:
  283. * - \ref asfdoc_sam0_ac_extra_acronyms
  284. * - \ref asfdoc_sam0_ac_extra_dependencies
  285. * - \ref asfdoc_sam0_ac_extra_errata
  286. * - \ref asfdoc_sam0_ac_extra_history
  287. *
  288. *
  289. * \section asfdoc_sam0_ac_examples Examples
  290. *
  291. * For a list of examples related to this driver, see
  292. * \ref asfdoc_sam0_ac_exqsg.
  293. *
  294. *
  295. * \section asfdoc_sam0_ac_api_overview API Overview
  296. * @{
  297. */
  298. #include <compiler.h>
  299. #include <clock.h>
  300. #ifdef __cplusplus
  301. extern "C" {
  302. #endif
  303. /**
  304. * \name Driver Feature Definition
  305. * Define AC driver feature set according to different device family.
  306. * @{
  307. */
  308. #if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || (SAMR30) || defined(__DOXYGEN__)
  309. /** Setting of hysteresis level */
  310. # define FEATURE_AC_HYSTERESIS_LEVEL
  311. /** SYNCBUSY scheme version 2 */
  312. # define FEATURE_AC_SYNCBUSY_SCHEME_VERSION_2
  313. #endif
  314. #if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || (SAMR30) || defined(__DOXYGEN__)
  315. /** Run in standby feature for each comparator */
  316. # define FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR
  317. #else
  318. /** Run in standby feature for comparator pair */
  319. # define FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR
  320. #endif
  321. /* @} */
  322. #if !defined(__DOXYGEN__)
  323. /* Forward declaration of struct */
  324. struct ac_module;
  325. extern struct ac_module *_ac_instance[AC_INST_NUM];
  326. #endif
  327. /**
  328. * \name AC Window Channel Status Flags
  329. *
  330. * AC window channel status flags, returned by \ref ac_win_get_status().
  331. *
  332. * @{
  333. */
  334. /** Unknown output state; the comparator window channel was not ready. */
  335. #define AC_WIN_STATUS_UNKNOWN (1UL << 0)
  336. /** Window Comparator's input voltage is above the window */
  337. #define AC_WIN_STATUS_ABOVE (1UL << 1)
  338. /** Window Comparator's input voltage is inside the window */
  339. #define AC_WIN_STATUS_INSIDE (1UL << 2)
  340. /** Window Comparator's input voltage is below the window */
  341. #define AC_WIN_STATUS_BELOW (1UL << 3)
  342. /**
  343. * This state reflects the window interrupt flag. When the interrupt flag
  344. * should be set is configured in \ref ac_win_set_config(). This state needs
  345. * to be cleared by the of \ref ac_win_clear_status().
  346. */
  347. #define AC_WIN_STATUS_INTERRUPT_SET (1UL << 4)
  348. /** @} */
  349. /**
  350. * \name AC Channel Status Flags
  351. *
  352. * AC channel status flags, returned by \ref ac_chan_get_status().
  353. *
  354. * @{
  355. */
  356. /** Unknown output state; the comparator channel was not ready. */
  357. #define AC_CHAN_STATUS_UNKNOWN (1UL << 0)
  358. /** Comparator's negative input pin is higher in voltage than the positive
  359. * input pin. */
  360. #define AC_CHAN_STATUS_NEG_ABOVE_POS (1UL << 1)
  361. /** Comparator's positive input pin is higher in voltage than the negative
  362. * input pin. */
  363. #define AC_CHAN_STATUS_POS_ABOVE_NEG (1UL << 2)
  364. /**
  365. * This state reflects the channel interrupt flag. When the interrupt flag
  366. * should be set is configured in ac_chan_set_config(). This state needs
  367. * to be cleared by the of ac_chan_clear_status().
  368. */
  369. #define AC_CHAN_STATUS_INTERRUPT_SET (1UL << 3)
  370. /** @} */
  371. /** Type definition for a AC module callback function. */
  372. typedef void (*ac_callback_t)(struct ac_module *const module_inst);
  373. /** Enum for possible callback types for the AC module. */
  374. enum ac_callback {
  375. /** Callback for comparator 0 */
  376. AC_CALLBACK_COMPARATOR_0 = 0,
  377. /** Callback for comparator 1 */
  378. AC_CALLBACK_COMPARATOR_1 = 1,
  379. /** Callback for window 0 */
  380. AC_CALLBACK_WINDOW_0 = 4,
  381. #if (AC_NUM_CMP > 2)
  382. /** Callback for comparator 2 */
  383. AC_CALLBACK_COMPARATOR_2 = 2,
  384. /** Callback for comparator 3 */
  385. AC_CALLBACK_COMPARATOR_3 = 3,
  386. /** Callback for window 1 */
  387. AC_CALLBACK_WINDOW_1 = 5,
  388. /** Number of available callbacks */
  389. #endif /* (AC_NUM_CMP == 2) */
  390. #if !defined(__DOXYGEN__)
  391. AC_CALLBACK_N,
  392. #endif /* !defined(__DOXYGEN__) */
  393. };
  394. #ifdef FEATURE_AC_HYSTERESIS_LEVEL
  395. /** Enum for possible hysteresis level types for AC module. */
  396. enum ac_hysteresis_level {
  397. /** Hysteresis level of 50mV */
  398. AC_HYSTERESIS_LEVEL_50 = 0,
  399. /** Hysteresis level of 70mV */
  400. AC_HYSTERESIS_LEVEL_70,
  401. /** Hysteresis level of 90mV */
  402. AC_HYSTERESIS_LEVEL_90,
  403. /** Hysteresis level of 110mV */
  404. AC_HYSTERESIS_LEVEL_110
  405. };
  406. #endif
  407. /**
  408. * \brief AC comparator channel selection enum.
  409. *
  410. * Enum for the possible comparator channels.
  411. */
  412. enum ac_chan_channel {
  413. /** Comparator channel 0 (Pair 0, Comparator 0) */
  414. AC_CHAN_CHANNEL_0 = 0,
  415. /** Comparator channel 1 (Pair 0, Comparator 1) */
  416. AC_CHAN_CHANNEL_1 = 1,
  417. #if defined(__DOXYGEN__) || (AC_NUM_CMP > 2)
  418. /** Comparator channel 2 (Pair 1, Comparator 0) */
  419. AC_CHAN_CHANNEL_2 = 2,
  420. /** Comparator channel 3 (Pair 1, Comparator 1) */
  421. AC_CHAN_CHANNEL_3 = 3,
  422. #endif
  423. };
  424. /**
  425. * \brief AC channel input sampling mode configuration enum.
  426. *
  427. * Enum for the possible channel sampling modes of an Analog Comparator channel.
  428. */
  429. enum ac_chan_sample_mode {
  430. /** Continuous sampling mode; when the channel is enabled the comparator
  431. * output is available for reading at any time */
  432. AC_CHAN_MODE_CONTINUOUS = 0,
  433. /** Single shot mode; when used the comparator channel must be triggered to
  434. * perform a comparison before reading the result */
  435. AC_CHAN_MODE_SINGLE_SHOT = AC_COMPCTRL_SINGLE,
  436. };
  437. /**
  438. * \brief AC channel positive comparator pin input configuration enum.
  439. *
  440. * Enum for the possible channel positive pin input of an Analog Comparator
  441. * channel.
  442. */
  443. enum ac_chan_pos_mux {
  444. /** Positive comparator input is connected to physical AC input pin 0 */
  445. AC_CHAN_POS_MUX_PIN0 = AC_COMPCTRL_MUXPOS_PIN0,
  446. /** Positive comparator input is connected to physical AC input pin 1 */
  447. AC_CHAN_POS_MUX_PIN1 = AC_COMPCTRL_MUXPOS_PIN1,
  448. /** Positive comparator input is connected to physical AC input pin 2 */
  449. AC_CHAN_POS_MUX_PIN2 = AC_COMPCTRL_MUXPOS_PIN2,
  450. /** Positive comparator input is connected to physical AC input pin 3 */
  451. AC_CHAN_POS_MUX_PIN3 = AC_COMPCTRL_MUXPOS_PIN3,
  452. };
  453. /**
  454. * \brief AC channel negative comparator pin input configuration enum.
  455. *
  456. * Enum for the possible channel negative pin input of an Analog Comparator
  457. * channel.
  458. */
  459. enum ac_chan_neg_mux {
  460. /** Negative comparator input is connected to physical AC input pin 0 */
  461. AC_CHAN_NEG_MUX_PIN0 = AC_COMPCTRL_MUXNEG_PIN0,
  462. /** Negative comparator input is connected to physical AC input pin 1 */
  463. AC_CHAN_NEG_MUX_PIN1 = AC_COMPCTRL_MUXNEG_PIN1,
  464. /** Negative comparator input is connected to physical AC input pin 2 */
  465. AC_CHAN_NEG_MUX_PIN2 = AC_COMPCTRL_MUXNEG_PIN2,
  466. /** Negative comparator input is connected to physical AC input pin 3 */
  467. AC_CHAN_NEG_MUX_PIN3 = AC_COMPCTRL_MUXNEG_PIN3,
  468. /** Negative comparator input is connected to the internal ground plane */
  469. AC_CHAN_NEG_MUX_GND = AC_COMPCTRL_MUXNEG_GND,
  470. /** Negative comparator input is connected to the channel's internal V<SUB>CC</SUB>
  471. * plane voltage scalar */
  472. AC_CHAN_NEG_MUX_SCALED_VCC = AC_COMPCTRL_MUXNEG_VSCALE,
  473. /** Negative comparator input is connected to the internal band gap voltage
  474. * reference */
  475. AC_CHAN_NEG_MUX_BANDGAP = AC_COMPCTRL_MUXNEG_BANDGAP,
  476. #if !(SAML22)
  477. /**
  478. * For SAM D20/D21/D10/D11/R21/DA1/HA1:
  479. * Negative comparator input is connected to the channel's internal DAC
  480. * channel 0 output.
  481. * For SAM L21/C20/C21:
  482. * Negative comparator input is connected to the channel's internal DAC
  483. * channel 0 output for Comparator 0 or OPAMP output for Comparator 1.
  484. */
  485. AC_CHAN_NEG_MUX_DAC0 = AC_COMPCTRL_MUXNEG_DAC,
  486. #endif
  487. };
  488. /**
  489. * \brief AC channel output filtering configuration enum.
  490. *
  491. * Enum for the possible channel output filtering configurations of an Analog
  492. * Comparator channel.
  493. */
  494. enum ac_chan_filter {
  495. /** No output filtering is performed on the comparator channel */
  496. AC_CHAN_FILTER_NONE = AC_COMPCTRL_FLEN_OFF,
  497. /** Comparator channel output is passed through a Majority-of-Three
  498. * filter */
  499. AC_CHAN_FILTER_MAJORITY_3 = AC_COMPCTRL_FLEN_MAJ3,
  500. /** Comparator channel output is passed through a Majority-of-Five
  501. * filter */
  502. AC_CHAN_FILTER_MAJORITY_5 = AC_COMPCTRL_FLEN_MAJ5,
  503. };
  504. /**
  505. * \brief AC channel GPIO output routing configuration enum.
  506. *
  507. * Enum for the possible channel GPIO output routing configurations of an Analog
  508. * Comparator channel.
  509. */
  510. enum ac_chan_output {
  511. /** Comparator channel output is not routed to a physical GPIO pin, and is
  512. * used internally only */
  513. AC_CHAN_OUTPUT_INTERNAL = AC_COMPCTRL_OUT_OFF,
  514. /** Comparator channel output is routed to its matching physical GPIO pin,
  515. * via an asynchronous path */
  516. AC_CHAN_OUTPUT_ASYNCRONOUS = AC_COMPCTRL_OUT_ASYNC,
  517. /** Comparator channel output is routed to its matching physical GPIO pin,
  518. * via a synchronous path */
  519. AC_CHAN_OUTPUT_SYNCHRONOUS = AC_COMPCTRL_OUT_SYNC,
  520. };
  521. /**
  522. * \brief AC window channel selection enum.
  523. *
  524. * Enum for the possible window comparator channels.
  525. */
  526. enum ac_win_channel {
  527. /** Window channel 0 (Pair 0, Comparators 0 and 1) */
  528. AC_WIN_CHANNEL_0 = 0,
  529. #if defined(__DOXYGEN__) || (AC_PAIRS > 1)
  530. /** Window channel 1 (Pair 1, Comparators 2 and 3) */
  531. AC_WIN_CHANNEL_1 = 1,
  532. #endif
  533. };
  534. /**
  535. * \brief Channel interrupt selection enum.
  536. *
  537. * This enum is used to select when a channel interrupt should occur.
  538. */
  539. enum ac_chan_interrupt_selection {
  540. /** An interrupt will be generated when the comparator level is passed */
  541. AC_CHAN_INTERRUPT_SELECTION_TOGGLE = AC_COMPCTRL_INTSEL_TOGGLE,
  542. /** An interrupt will be generated when the measurement goes above the
  543. * compare level
  544. */
  545. AC_CHAN_INTERRUPT_SELECTION_RISING = AC_COMPCTRL_INTSEL_RISING,
  546. /** An interrupt will be generated when the measurement goes below the
  547. * compare level
  548. */
  549. AC_CHAN_INTERRUPT_SELECTION_FALLING = AC_COMPCTRL_INTSEL_FALLING,
  550. /**
  551. * An interrupt will be generated when a new measurement is complete.
  552. * Interrupts will only be generated in single shot mode. This state needs
  553. * to be cleared by the use of ac_chan_cleare_status()
  554. */
  555. AC_CHAN_INTERRUPT_SELECTION_END_OF_COMPARE = AC_COMPCTRL_INTSEL_EOC,
  556. };
  557. /**
  558. * \brief Window interrupt selection enum.
  559. *
  560. * This enum is used to select when a window interrupt should occur.
  561. */
  562. enum ac_win_interrupt_selection {
  563. /** Interrupt is generated when the compare value goes above the window */
  564. AC_WIN_INTERRUPT_SELECTION_ABOVE = AC_WINCTRL_WINTSEL0_ABOVE,
  565. /** Interrupt is generated when the compare value goes inside the window */
  566. AC_WIN_INTERRUPT_SELECTION_INSIDE = AC_WINCTRL_WINTSEL0_INSIDE,
  567. /** Interrupt is generated when the compare value goes below the window */
  568. AC_WIN_INTERRUPT_SELECTION_BELOW = AC_WINCTRL_WINTSEL0_BELOW,
  569. /** Interrupt is generated when the compare value goes outside the window */
  570. AC_WIN_INTERRUPT_SELECTION_OUTSIDE = AC_WINCTRL_WINTSEL0_OUTSIDE,
  571. };
  572. /**
  573. * \brief AC software device instance structure.
  574. *
  575. * AC software instance structure, used to retain software state information
  576. * of an associated hardware module instance.
  577. *
  578. * \note The fields of this structure should not be altered by the user
  579. * application; they are reserved for module-internal use only.
  580. */
  581. struct ac_module {
  582. #if !defined(__DOXYGEN__)
  583. /** Hardware module pointer of the associated Analog Comparator peripheral. */
  584. Ac *hw;
  585. # if AC_CALLBACK_MODE == true
  586. /** Array of callbacks */
  587. ac_callback_t callback[AC_CALLBACK_N];
  588. /** Bit mask for callbacks registered */
  589. uint8_t register_callback_mask;
  590. /** Bit mask for callbacks enabled */
  591. uint8_t enable_callback_mask;
  592. # endif
  593. #endif
  594. };
  595. /**
  596. * \brief AC event enable/disable structure.
  597. *
  598. * Event flags for the Analog Comparator module. This is used to enable and
  599. * disable events via \ref ac_enable_events() and \ref ac_disable_events().
  600. */
  601. struct ac_events {
  602. /** If \c true, an event will be generated when a comparator window state
  603. * changes */
  604. bool generate_event_on_window[AC_PAIRS];
  605. /** If \c true, an event will be generated when a comparator state
  606. * changes */
  607. bool generate_event_on_state[AC_NUM_CMP];
  608. /** If \c true, a comparator will be sampled each time an event is
  609. * received */
  610. bool on_event_sample[AC_NUM_CMP];
  611. };
  612. /**
  613. * \brief Analog Comparator module configuration structure.
  614. *
  615. * Configuration structure for a comparator channel, to configure the input and
  616. * output settings of the comparator.
  617. */
  618. struct ac_config {
  619. #ifdef FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR
  620. /** If \c true, the comparator pairs will continue to sample during sleep
  621. * mode when triggered */
  622. bool run_in_standby[AC_PAIRS];
  623. #endif
  624. #if (SAMD) || (SAMHA1) || (SAMR21)
  625. /** Digital source generator for AC GCLK */
  626. enum gclk_generator dig_source_generator;
  627. /** Analog source generator for AC GCLK */
  628. enum gclk_generator ana_source_generator;
  629. #else
  630. /** Source generator for AC GCLK */
  631. enum gclk_generator source_generator;
  632. #endif
  633. };
  634. /**
  635. * \brief Analog Comparator Comparator channel configuration structure.
  636. *
  637. * Configuration structure for a comparator channel, to configure the input and
  638. * output settings of the comparator.
  639. */
  640. struct ac_chan_config {
  641. /** Sampling mode of the comparator channel */
  642. enum ac_chan_sample_mode sample_mode;
  643. /** Filtering mode for the comparator output, when the comparator is used
  644. * in a supported mode */
  645. enum ac_chan_filter filter;
  646. /** When \c true, hysteresis mode is enabled on the comparator inputs */
  647. bool enable_hysteresis;
  648. #ifdef FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR
  649. /** If \c true, the comparator will continue to sample during sleep
  650. * mode when triggered */
  651. bool run_in_standby;
  652. #endif
  653. #ifdef FEATURE_AC_HYSTERESIS_LEVEL
  654. /** Hysteresis level of the comparator channel */
  655. enum ac_hysteresis_level hysteresis_level;
  656. #endif
  657. /** Output mode of the comparator, whether it should be available for
  658. * internal use, or asynchronously/synchronously linked to a
  659. * general-purpose input/output (GPIO) pin */
  660. enum ac_chan_output output_mode;
  661. /** Input multiplexer selection for the comparator's positive input pin */
  662. enum ac_chan_pos_mux positive_input;
  663. /** Input multiplexer selection for the comparator's negative input pin.
  664. * Any internal reference source, such as a bandgap reference voltage or
  665. * the DAC, must be configured and enabled prior to its use as a
  666. * comparator input.*/
  667. enum ac_chan_neg_mux negative_input;
  668. /** Scaled VCC voltage division factor for the channel, when a comparator
  669. * pin is connected to the V<SUB>CC</SUB> voltage scalar input. The formular is:
  670. * Vscale = Vdd * vcc_scale_factor / 64.
  671. * If the V<SUB>CC</SUB> voltage scalar is not selected as a comparator
  672. * channel pin's input, this value will be ignored. */
  673. uint8_t vcc_scale_factor;
  674. /** Interrupt criteria for the comparator channel, to select the condition
  675. * that will trigger a callback */
  676. enum ac_chan_interrupt_selection interrupt_selection;
  677. };
  678. /**
  679. * \brief Analog Comparator Window configuration structure.
  680. */
  681. struct ac_win_config {
  682. /** Interrupt criteria for the comparator window channel, to select the
  683. * condition that will trigger a callback */
  684. enum ac_win_interrupt_selection interrupt_selection;
  685. };
  686. /**
  687. * \name Configuration and Initialization
  688. * @{
  689. */
  690. enum status_code ac_reset(
  691. struct ac_module *const module_inst);
  692. enum status_code ac_init(
  693. struct ac_module *const module_inst,
  694. Ac *const hw,
  695. struct ac_config *const config);
  696. #if (AC_INST_NUM > 1) && !defined(__DOXYGEN__)
  697. /**
  698. * \internal Find the index of given AC module instance.
  699. *
  700. * \param[in] AC module instance pointer.
  701. *
  702. * \return Index of the given AC module instance.
  703. */
  704. static uint8_t _ac_get_inst_index(
  705. Ac *const hw)
  706. {
  707. /* List of available AC modules. */
  708. static Ac *const ac_modules[AC_INST_NUM] = AC_INSTS;
  709. /* Find index for AC instance. */
  710. for (uint32_t i = 0; i < AC_INST_NUM; i++) {
  711. if (hw == ac_modules[i]) {
  712. return i;
  713. }
  714. }
  715. /* Invalid data given. */
  716. Assert(false);
  717. return 0;
  718. }
  719. #endif /* (AC_INST_NUM > 1) && !defined(__DOXYGEN__) */
  720. /**
  721. * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
  722. *
  723. * Checks to see if the underlying hardware peripheral module(s) are currently
  724. * synchronizing across multiple clock domains to the hardware bus. This
  725. * function can be used to delay further operations on a module until such time
  726. * that it is ready, to prevent blocking delays for synchronization in the
  727. * user application.
  728. *
  729. * \param[in] module_inst Pointer to the AC software instance struct
  730. *
  731. * \return Synchronization status of the underlying hardware module(s).
  732. *
  733. * \retval false If the module has completed synchronization
  734. * \retval ture If the module synchronization is ongoing
  735. */
  736. static inline bool ac_is_syncing(
  737. struct ac_module *const module_inst)
  738. {
  739. /* Sanity check arguments */
  740. Assert(module_inst);
  741. Ac *const ac_module = module_inst->hw;
  742. #ifdef FEATURE_AC_SYNCBUSY_SCHEME_VERSION_2
  743. if (ac_module->SYNCBUSY.reg & AC_SYNCBUSY_MASK) {
  744. return true;
  745. }
  746. return false;
  747. #else
  748. if (ac_module->STATUSB.reg & AC_STATUSB_SYNCBUSY) {
  749. return true;
  750. }
  751. return false;
  752. #endif
  753. }
  754. /**
  755. * \brief Initializes all members of an Analog Comparator configuration
  756. * structure to safe defaults.
  757. *
  758. * Initializes all members of a given Analog Comparator configuration
  759. * structure to safe known default values. This function should be called on
  760. * all new instances of these configuration structures before being modified
  761. * by the user application.
  762. *
  763. * The default configuration is as follows:
  764. * \li All comparator pairs disabled during sleep mode (if has this feature)
  765. * \li Generator 0 is the default GCLK generator
  766. *
  767. * \param[out] config Configuration structure to initialize to default values
  768. */
  769. static inline void ac_get_config_defaults(
  770. struct ac_config *const config)
  771. {
  772. /* Sanity check arguments */
  773. Assert(config);
  774. #ifdef FEATURE_AC_RUN_IN_STANDY_PAIR_COMPARATOR
  775. /* Default configuration values */
  776. for (uint32_t i = 0; i < AC_PAIRS; i++) {
  777. config->run_in_standby[i] = false;
  778. }
  779. #endif
  780. #if (SAMD) || (SAMHA1) || (SAMR21)
  781. config->dig_source_generator = GCLK_GENERATOR_0;
  782. config->ana_source_generator = GCLK_GENERATOR_3;
  783. #else
  784. config->source_generator = GCLK_GENERATOR_0;
  785. #endif
  786. }
  787. /**
  788. * \brief Enables an Analog Comparator that was previously configured.
  789. *
  790. * Enables an Analog Comparator that was previously configured via a
  791. * call to \ref ac_init().
  792. *
  793. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  794. */
  795. static inline void ac_enable(
  796. struct ac_module *const module_inst)
  797. {
  798. /* Sanity check arguments */
  799. Assert(module_inst);
  800. Assert(module_inst->hw);
  801. Ac *const ac_module = module_inst->hw;
  802. while (ac_is_syncing(module_inst)) {
  803. /* Wait until synchronization is complete */
  804. }
  805. /* Write the new comparator module control configuration */
  806. ac_module->CTRLA.reg |= AC_CTRLA_ENABLE;
  807. }
  808. /**
  809. * \brief Disables an Analog Comparator that was previously enabled.
  810. *
  811. * Disables an Analog Comparator that was previously started via a call to
  812. * \ref ac_enable().
  813. *
  814. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  815. */
  816. static inline void ac_disable(
  817. struct ac_module *const module_inst)
  818. {
  819. /* Sanity check arguments */
  820. Assert(module_inst);
  821. Assert(module_inst->hw);
  822. Ac *const ac_module = module_inst->hw;
  823. while (ac_is_syncing(module_inst)) {
  824. /* Wait until synchronization is complete */
  825. }
  826. /* Disbale interrupt */
  827. ac_module->INTENCLR.reg = AC_INTENCLR_MASK;
  828. /* Clear interrupt flag */
  829. ac_module->INTFLAG.reg = AC_INTFLAG_MASK;
  830. /* Write the new comparator module control configuration */
  831. ac_module->CTRLA.reg &= ~AC_CTRLA_ENABLE;
  832. }
  833. /**
  834. * \brief Enables an Analog Comparator event input or output.
  835. *
  836. * Enables one or more input or output events to or from the Analog Comparator
  837. * module. See \ref ac_events for a list of events this module
  838. * supports.
  839. *
  840. * \note Events cannot be altered while the module is enabled.
  841. *
  842. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  843. * \param[in] events Struct containing flags of events to enable
  844. */
  845. static inline void ac_enable_events(
  846. struct ac_module *const module_inst,
  847. struct ac_events *const events)
  848. {
  849. /* Sanity check arguments */
  850. Assert(module_inst);
  851. Assert(module_inst->hw);
  852. Assert(events);
  853. Ac *const ac_module = module_inst->hw;
  854. uint32_t event_mask = 0;
  855. /* Configure window output events for each comparator pair */
  856. for (uint8_t i = 0; i < AC_PAIRS; i++) {
  857. if (events->generate_event_on_window[i] == true) {
  858. event_mask |= (AC_EVCTRL_WINEO0 << i);
  859. }
  860. }
  861. /* Configure sample input/output events for each comparator */
  862. for (uint8_t i = 0; i < AC_NUM_CMP; i++) {
  863. if (events->on_event_sample[i] == true) {
  864. event_mask |= (AC_EVCTRL_COMPEI0 << i);
  865. }
  866. if (events->generate_event_on_state[i] == true) {
  867. event_mask |= (AC_EVCTRL_COMPEO0 << i);
  868. }
  869. }
  870. ac_module->EVCTRL.reg |= event_mask;
  871. }
  872. /**
  873. * \brief Disables an Analog Comparator event input or output.
  874. *
  875. * Disables one or more input or output events to or from the Analog Comparator
  876. * module. See \ref ac_events for a list of events this module
  877. * supports.
  878. *
  879. * \note Events cannot be altered while the module is enabled.
  880. *
  881. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  882. * \param[in] events Struct containing flags of events to disable
  883. */
  884. static inline void ac_disable_events(
  885. struct ac_module *const module_inst,
  886. struct ac_events *const events)
  887. {
  888. /* Sanity check arguments */
  889. Assert(module_inst);
  890. Assert(module_inst->hw);
  891. Assert(events);
  892. Ac *const ac_module = module_inst->hw;
  893. uint32_t event_mask = 0;
  894. /* Configure window output events for each comparator pair */
  895. for (uint8_t i = 0; i < AC_PAIRS; i++) {
  896. if (events->generate_event_on_window[i] == true) {
  897. event_mask |= (AC_EVCTRL_WINEO0 << i);
  898. }
  899. }
  900. /* Configure sample input/output events for each comparator */
  901. for (uint8_t i = 0; i < AC_NUM_CMP; i++) {
  902. if (events->on_event_sample[i] == true) {
  903. event_mask |= (AC_EVCTRL_COMPEI0 << i);
  904. }
  905. if (events->generate_event_on_state[i] == true) {
  906. event_mask |= (AC_EVCTRL_COMPEO0 << i);
  907. }
  908. }
  909. ac_module->EVCTRL.reg &= ~event_mask;
  910. }
  911. /** @} */
  912. /**
  913. * \name Channel Configuration and Initialization
  914. * @{
  915. */
  916. /**
  917. * \brief Initializes all members of an Analog Comparator channel configuration
  918. * structure to safe defaults.
  919. *
  920. * Initializes all members of an Analog Comparator channel configuration
  921. * structure to safe defaults. This function should be called on all new
  922. * instances of these configuration structures before being modified by the
  923. * user application.
  924. *
  925. * The default configuration is as follows:
  926. * \li Continuous sampling mode
  927. * \li Majority of five sample output filter
  928. * \li Comparator disabled during sleep mode (if has this feature)
  929. * \li Hysteresis enabled on the input pins
  930. * \li Hysteresis level of 50mV if having this feature
  931. * \li Internal comparator output mode
  932. * \li Comparator pin multiplexer 0 selected as the positive input
  933. * \li Scaled V<SUB>CC</SUB> voltage selected as the negative input
  934. * \li V<SUB>CC</SUB> voltage scaler set for a division factor of two
  935. * \li Channel interrupt set to occur when the compare threshold is passed
  936. *
  937. * \param[out] config Channel configuration structure to initialize to
  938. * default values
  939. */
  940. static inline void ac_chan_get_config_defaults(
  941. struct ac_chan_config *const config)
  942. {
  943. /* Sanity check arguments */
  944. Assert(config);
  945. /* Default configuration values */
  946. config->sample_mode = AC_CHAN_MODE_CONTINUOUS;
  947. config->filter = AC_CHAN_FILTER_MAJORITY_5;
  948. config->enable_hysteresis = true;
  949. #ifdef FEATURE_AC_RUN_IN_STANDY_EACH_COMPARATOR
  950. config->run_in_standby = false;
  951. #endif
  952. #ifdef FEATURE_AC_HYSTERESIS_LEVEL
  953. config->hysteresis_level = AC_HYSTERESIS_LEVEL_50;
  954. #endif
  955. config->output_mode = AC_CHAN_OUTPUT_INTERNAL;
  956. config->positive_input = AC_CHAN_POS_MUX_PIN0;
  957. config->negative_input = AC_CHAN_NEG_MUX_SCALED_VCC;
  958. config->vcc_scale_factor = 32;
  959. config->interrupt_selection = AC_CHAN_INTERRUPT_SELECTION_TOGGLE;
  960. }
  961. enum status_code ac_chan_set_config(
  962. struct ac_module *const module_inst,
  963. const enum ac_chan_channel channel,
  964. struct ac_chan_config *const config);
  965. /**
  966. * \brief Enables an Analog Comparator channel that was previously configured.
  967. *
  968. * Enables an Analog Comparator channel that was previously
  969. * configured via a call to \ref ac_chan_set_config().
  970. *
  971. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  972. * \param[in] channel Comparator channel to enable
  973. */
  974. static inline void ac_chan_enable(
  975. struct ac_module *const module_inst,
  976. const enum ac_chan_channel channel)
  977. {
  978. /* Sanity check arguments */
  979. Assert(module_inst);
  980. Assert(module_inst->hw);
  981. Ac *const ac_module = module_inst->hw;
  982. while (ac_is_syncing(module_inst)) {
  983. /* Wait until synchronization is complete */
  984. }
  985. /* Write the new comparator module control configuration */
  986. ac_module->COMPCTRL[(uint8_t)channel].reg |= AC_COMPCTRL_ENABLE;
  987. }
  988. /**
  989. * \brief Disables an Analog Comparator channel that was previously enabled.
  990. *
  991. * Stops an Analog Comparator channel that was previously started via a call to
  992. * \ref ac_chan_enable().
  993. *
  994. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  995. * \param[in] channel Comparator channel to disable
  996. */
  997. static inline void ac_chan_disable(
  998. struct ac_module *const module_inst,
  999. const enum ac_chan_channel channel)
  1000. {
  1001. /* Sanity check arguments */
  1002. Assert(module_inst);
  1003. Assert(module_inst->hw);
  1004. Ac *const ac_module = module_inst->hw;
  1005. while (ac_is_syncing(module_inst)) {
  1006. /* Wait until synchronization is complete */
  1007. }
  1008. /* Write the new comparator module control configuration */
  1009. ac_module->COMPCTRL[(uint8_t)channel].reg &= ~AC_COMPCTRL_ENABLE;
  1010. }
  1011. /** @} */
  1012. /**
  1013. * \name Channel Control
  1014. * @{
  1015. */
  1016. /**
  1017. * \brief Triggers a comparison on a comparator that is configured in single shot mode.
  1018. *
  1019. * Triggers a single conversion on a comparator configured to compare on demand
  1020. * (single shot mode) rather than continuously.
  1021. *
  1022. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  1023. * \param[in] channel Comparator channel to trigger
  1024. */
  1025. static inline void ac_chan_trigger_single_shot(
  1026. struct ac_module *const module_inst,
  1027. const enum ac_chan_channel channel)
  1028. {
  1029. /* Sanity check arguments */
  1030. Assert(module_inst);
  1031. Assert(module_inst->hw);
  1032. Ac *const ac_module = module_inst->hw;
  1033. /* Write the new comparator module control configuration */
  1034. ac_module->CTRLB.reg |= (AC_CTRLB_START0 << (uint8_t)channel);
  1035. }
  1036. /**
  1037. * \brief Determines if a given comparator channel is ready for comparisons.
  1038. *
  1039. * Checks a comparator channel to see if the comparator is currently ready to
  1040. * begin comparisons.
  1041. *
  1042. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  1043. * \param[in] channel Comparator channel to test
  1044. *
  1045. * \return Comparator channel readiness state.
  1046. */
  1047. static inline bool ac_chan_is_ready(
  1048. struct ac_module *const module_inst,
  1049. const enum ac_chan_channel channel)
  1050. {
  1051. /* Sanity check arguments */
  1052. Assert(module_inst);
  1053. Assert(module_inst->hw);
  1054. Ac *const ac_module = module_inst->hw;
  1055. return (ac_module->STATUSB.reg & (AC_STATUSB_READY0 << (uint8_t)channel));
  1056. }
  1057. /**
  1058. * \brief Determines the output state of a comparator channel.
  1059. *
  1060. * Retrieves the last comparison value (after filtering) of a given comparator.
  1061. * If the comparator was not ready at the time of the check, the comparison
  1062. * result will be indicated as being unknown.
  1063. *
  1064. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  1065. * \param[in] channel Comparator channel to test
  1066. *
  1067. * \return Bit mask of comparator channel status flags.
  1068. */
  1069. static inline uint8_t ac_chan_get_status(
  1070. struct ac_module *const module_inst,
  1071. const enum ac_chan_channel channel)
  1072. {
  1073. /* Sanity check arguments */
  1074. Assert(module_inst);
  1075. Assert(module_inst->hw);
  1076. Ac *const ac_module = module_inst->hw;
  1077. uint8_t status_mask = 0;
  1078. if (ac_module->INTFLAG.reg & (1 << channel)) {
  1079. status_mask = AC_CHAN_STATUS_INTERRUPT_SET;
  1080. }
  1081. if (ac_chan_is_ready(module_inst, channel) == false) {
  1082. status_mask |= AC_CHAN_STATUS_UNKNOWN;
  1083. return status_mask;
  1084. }
  1085. if (ac_module->STATUSA.reg & (AC_STATUSA_STATE0 << (uint8_t)channel)) {
  1086. status_mask |= AC_CHAN_STATUS_POS_ABOVE_NEG;
  1087. } else {
  1088. status_mask |= AC_CHAN_STATUS_NEG_ABOVE_POS;
  1089. }
  1090. return status_mask;
  1091. }
  1092. /**
  1093. * \brief Clears an interrupt status flag.
  1094. *
  1095. * This function is used to clear the AC_CHAN_STATUS_INTERRUPT_SET flag
  1096. * it will clear the flag for the channel indicated by the channel argument.
  1097. *
  1098. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  1099. * \param[in] channel Comparator channel to clear
  1100. */
  1101. static inline void ac_chan_clear_status(
  1102. struct ac_module *const module_inst,
  1103. const enum ac_chan_channel channel)
  1104. {
  1105. Assert(module_inst);
  1106. Assert(module_inst->hw);
  1107. module_inst->hw->INTFLAG.reg = (1 << channel);
  1108. }
  1109. /** @} */
  1110. /**
  1111. * \name Window Mode Configuration and Initialization
  1112. * @{
  1113. */
  1114. /**
  1115. * \brief Initializes an Analog Comparator window configuration structure to defaults.
  1116. *
  1117. * Initializes a given Analog Comparator channel configuration structure to a
  1118. * set of known default values. This function should be called if window interrupts
  1119. * are needed and before ac_win_set_config().
  1120. *
  1121. * The default configuration is as follows:
  1122. * \li Channel interrupt set to occur when the measurement is above the window
  1123. *
  1124. * \param[out] config Window configuration structure to initialize to
  1125. * default values
  1126. */
  1127. static inline void ac_win_get_config_defaults(
  1128. struct ac_win_config *const config)
  1129. {
  1130. /* Sanity check arguments */
  1131. Assert(config);
  1132. /* Default configuration values */
  1133. config->interrupt_selection = AC_WIN_INTERRUPT_SELECTION_ABOVE;
  1134. }
  1135. enum status_code ac_win_set_config(
  1136. struct ac_module *const module_inst,
  1137. enum ac_win_channel const win_channel,
  1138. struct ac_win_config *const config);
  1139. enum status_code ac_win_enable(
  1140. struct ac_module *const module_inst,
  1141. const enum ac_win_channel win_channel);
  1142. void ac_win_disable(
  1143. struct ac_module *const module_inst,
  1144. const enum ac_win_channel win_channel);
  1145. /** @} */
  1146. /**
  1147. * \name Window Mode Control
  1148. * @{
  1149. */
  1150. /**
  1151. * \brief Determines if a given Window Comparator is ready for comparisons.
  1152. *
  1153. * Checks a Window Comparator to see if the both comparators used for window
  1154. * detection is currently ready to begin comparisons.
  1155. *
  1156. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  1157. * \param[in] win_channel Window Comparator channel to test
  1158. *
  1159. * \return Window Comparator channel readiness state.
  1160. */
  1161. static inline bool ac_win_is_ready(
  1162. struct ac_module *const module_inst,
  1163. const enum ac_win_channel win_channel)
  1164. {
  1165. /* Sanity check arguments */
  1166. Assert(module_inst);
  1167. Assert(module_inst->hw);
  1168. /* Convert a window channel index to the individual comparator channels */
  1169. enum ac_chan_channel win_pair_comp0 =
  1170. (enum ac_chan_channel)((uint8_t)win_channel * 2);
  1171. enum ac_chan_channel win_pair_comp1 =
  1172. (enum ac_chan_channel)(((uint8_t)win_channel * 2) + 1);
  1173. /* Check if the two comparators used in the window are ready */
  1174. bool win_pair_comp0_ready = ac_chan_is_ready(module_inst, win_pair_comp0);
  1175. bool win_pair_comp1_ready = ac_chan_is_ready(module_inst, win_pair_comp1);
  1176. /* If one or both window comparators not ready, return failure */
  1177. if ((win_pair_comp0_ready == false) || (win_pair_comp1_ready == false)) {
  1178. return false;
  1179. }
  1180. return true;
  1181. }
  1182. uint8_t ac_win_get_status(
  1183. struct ac_module *const module_inst,
  1184. const enum ac_win_channel win_channel);
  1185. /**
  1186. * \brief Clears an interrupt status flag.
  1187. *
  1188. * This function is used to clear the AC_WIN_STATUS_INTERRUPT_SET flag
  1189. * it will clear the flag for the channel indicated by the win_channel argument.
  1190. *
  1191. * \param[in] module_inst Software instance for the Analog Comparator peripheral
  1192. * \param[in] win_channel Window channel to clear
  1193. */
  1194. static inline void ac_win_clear_status(
  1195. struct ac_module *const module_inst,
  1196. const enum ac_win_channel win_channel)
  1197. {
  1198. Assert(module_inst);
  1199. Assert(module_inst->hw);
  1200. module_inst->hw->INTFLAG.reg = (1 << (win_channel + AC_INTFLAG_WIN0_Pos));
  1201. }
  1202. /** @} */
  1203. #ifdef __cplusplus
  1204. }
  1205. #endif
  1206. /** @} */
  1207. /**
  1208. * \page asfdoc_sam0_ac_extra Extra Information for AC Driver
  1209. *
  1210. * \section asfdoc_sam0_ac_extra_acronyms Acronyms
  1211. * Below is a table listing the acronyms used in this module, along with their
  1212. * intended meanings.
  1213. *
  1214. * <table>
  1215. * <tr>
  1216. * <th>Acronym</th>
  1217. * <th>Description</th>
  1218. * </tr>
  1219. * <tr>
  1220. * <td>AC</td>
  1221. * <td>Analog Comparator</td>
  1222. * </tr>
  1223. * <tr>
  1224. * <td>DAC</td>
  1225. * <td>Digital-to-Analog Converter</td>
  1226. * </tr>
  1227. * <tr>
  1228. * <td>MUX</td>
  1229. * <td>Multiplexer</td>
  1230. * </tr>
  1231. * </table>
  1232. *
  1233. *
  1234. * \section asfdoc_sam0_ac_extra_dependencies Dependencies
  1235. * This driver has the following dependencies:
  1236. *
  1237. * - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver"
  1238. *
  1239. *
  1240. * \section asfdoc_sam0_ac_extra_errata Errata
  1241. * There are no errata related to this driver.
  1242. *
  1243. *
  1244. * \section asfdoc_sam0_ac_extra_history Module History
  1245. * An overview of the module history is presented in the table below, with
  1246. * details on the enhancements and fixes made to the module since its first
  1247. * release. The current version of this corresponds to the newest version in
  1248. * the table.
  1249. *
  1250. * <table>
  1251. * <tr>
  1252. * <th>Changelog</th>
  1253. * </tr>
  1254. * <tr>
  1255. * <td>Initial Release</td>
  1256. * </tr>
  1257. * </table>
  1258. */
  1259. /**
  1260. * \page asfdoc_sam0_ac_exqsg Examples for AC Driver
  1261. *
  1262. * This is a list of the available Quick Start guides (QSGs) and example
  1263. * applications for \ref asfdoc_sam0_ac_group. QSGs are simple examples with
  1264. * step-by-step instructions to configure and use this driver in a selection of
  1265. * use cases. Note that a QSG can be compiled as a standalone application or be
  1266. * added to the user application.
  1267. *
  1268. * - \subpage asfdoc_sam0_ac_basic_use_case
  1269. * \if AC_CALLBACK_MODE
  1270. * - \subpage asfdoc_sam0_ac_callback_use_case
  1271. * \endif
  1272. *
  1273. * \page asfdoc_sam0_ac_document_revision_history Document Revision History
  1274. *
  1275. * <table>
  1276. * <tr>
  1277. * <th>Doc. Rev.</th>
  1278. * <th>Date</th>
  1279. * <th>Comments</th>
  1280. * </tr>
  1281. * <tr>
  1282. * <td>42106F</td>
  1283. * <td>12/2015</td>
  1284. * <td>Fixed typos and legal disclaimer</td>
  1285. * </tr>
  1286. * <tr>
  1287. * <td>42106E</td>
  1288. * <td>08/2015</td>
  1289. * <td>Added support for SAM L21, SAM C20/C21, and SAM DA1</td>
  1290. * </tr>
  1291. * <tr>
  1292. * <td>42106D</td>
  1293. * <td>12/2014</td>
  1294. * <td>Added support for SAM R21 and SAM D10/D11</td>
  1295. * </tr>
  1296. * <tr>
  1297. * <td>42106C</td>
  1298. * <td>01/2014</td>
  1299. * <td>Added support for SAM D21</td>
  1300. * </tr>
  1301. * <tr>
  1302. * <td>42106B</td>
  1303. * <td>06/2013</td>
  1304. * <td>Added additional documentation on the event system. Corrected
  1305. * documentation typos.</td>
  1306. * </tr>
  1307. * <tr>
  1308. * <td>42106A</td>
  1309. * <td>06/2013</td>
  1310. * <td>Initial release</td>
  1311. * </tr>
  1312. * </table>
  1313. */
  1314. #endif