sdadc.h 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  1. /**
  2. * \file
  3. *
  4. * \brief SAM Sigma-Delta Analog-to-Digital Converter (SDADC) Driver
  5. *
  6. * Copyright (C) 2015-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 SDADC_H_INCLUDED
  47. #define SDADC_H_INCLUDED
  48. /**
  49. * \defgroup asfdoc_sam0_sdadc_group SAM Sigma-Delta Analog-to-Digital Converter (SDADC) Driver
  50. *
  51. * This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers provides an interface for the configuration
  52. * and management of the device's SDADC functionality.
  53. *
  54. * The following peripheral is used by this module:
  55. * - SDADC (Sigma-Delta Analog-to-Digital Converter)
  56. *
  57. * The following devices can use this module:
  58. * - Atmel | SMART SAM C21
  59. *
  60. * The outline of this documentation is as follows:
  61. * - \ref asfdoc_sam0_sdadc_prerequisites
  62. * - \ref asfdoc_sam0_sdadc_module_overview
  63. * - \ref asfdoc_sam0_sdadc_special_considerations
  64. * - \ref asfdoc_sam0_sdadc_extra_info
  65. * - \ref asfdoc_sam0_sdadc_examples
  66. * - \ref asfdoc_sam0_sdadc_api_overview
  67. *
  68. *
  69. * \section asfdoc_sam0_sdadc_prerequisites Prerequisites
  70. *
  71. * There are no prerequisites for this module.
  72. *
  73. *
  74. * \section asfdoc_sam0_sdadc_module_overview Module Overview
  75. *
  76. * The Sigma-Delta Analog-to-Digital Converter (SDADC) converts analog signals to
  77. * digital values. The sigma-delta architecture of the SDADC implies a filtering
  78. * and a decimation of the bitstream at the output of the SDADC. The input selection
  79. * is up to three input analog channels.
  80. *
  81. * The SDADC provides up to 16-bit resolution at about 1000 samples per second (1KSPS)
  82. * and sized 24 bits signed result to handle filtering and gain correction without overflow.
  83. * The SDADC measurements can be started by either application software or an incoming
  84. * event from another peripheral in the device.
  85. *
  86. * The conversion is performed on a full range between 0V and the reference voltage.
  87. * Both internal and external reference voltages can be selected. The reference range
  88. * must be set to match the voltage of the reference used. Analog inputs between
  89. * these voltages convert to values based on a linear conversion.
  90. *
  91. *
  92. * \subsection asfdoc_sam0_sdadc_module_overview_clock Sample Clock
  93. * A generic clock (GCLK_SDADC) is required to generate the CLK_SDADC to the SDADC
  94. * module. The SDADC features a prescaler, which enables conversion at lower clock
  95. * rates than the input Generic Clock to the SDADC module.
  96. *
  97. * The SDADC data sampling frequency (CLK_SDADC_FS) in the SDADC module is the
  98. * CLK_SDADC/4, the reduction comes from the phase generator between the prescaler
  99. * and the SDADC.
  100. *
  101. * OSR is the Over Sampling Ratio, which can be modified to change the output data
  102. * rate. The conversion time depends on the selected OSR and the sampling frequency
  103. * of the SDADC.
  104. * The conversion time can be described with:
  105. * \f[
  106. * t_{SAMPLE} = \frac {22 + 3 \times OSR} {CLK \_ SDADC \_ FS}
  107. * \f]
  108. * -# Initialization of the SDADC (22 sigma-delta samples).
  109. * -# Filling of the decimation filter (3*OSR sigma-delta samples).
  110. *
  111. * \subsection asfdoc_sam0_sdadc_module_overview_offset_corr Gain and Offset Correction
  112. * A specific offset, gain, and shift can be applied to each source of the SDADC
  113. * by performing the following operation:
  114. * \f[
  115. * Data = (Data_{0} + OFFSET) \times \frac {GAIN}{2^{SHIFT}}
  116. * \f]
  117. *
  118. *
  119. * \subsection asfdoc_sam0_sdadc_module_overview_window_monitor Window Monitor
  120. * The SDADC module window monitor function can be used to automatically compare
  121. * the conversion result against a predefined pair of upper and lower
  122. * threshold values.
  123. *
  124. *
  125. * \subsection asfdoc_sam0_sdadc_module_overview_events Events
  126. * Event generation and event actions are configurable in the SDADC.
  127. *
  128. * The SDADC has two actions that can be triggered upon event reception:
  129. * \li Start conversion
  130. * \li Conversion flush
  131. *
  132. * The SDADC can generate two kinds of events:
  133. * \li Window monitor
  134. * \li Result ready
  135. *
  136. * If the event actions are enabled in the configuration, any incoming event
  137. * will trigger the action.
  138. *
  139. * If the window monitor event is enabled, an event will be generated
  140. * when the configured window condition is detected.
  141. *
  142. * If the result ready event is enabled, an event will be generated when a
  143. * conversion is completed.
  144. *
  145. *
  146. * \section asfdoc_sam0_sdadc_special_considerations Special Considerations
  147. *
  148. * There are no special considerations for this module.
  149. *
  150. *
  151. * \section asfdoc_sam0_sdadc_extra_info Extra Information
  152. *
  153. * For extra information see \ref asfdoc_sam0_sdadc_extra. This includes:
  154. * - \ref asfdoc_sam0_sdadc_extra_acronyms
  155. * - \ref asfdoc_sam0_sdadc_extra_dependencies
  156. * - \ref asfdoc_sam0_sdadc_extra_errata
  157. * - \ref asfdoc_sam0_sdadc_extra_history
  158. *
  159. *
  160. * \section asfdoc_sam0_sdadc_examples Examples
  161. *
  162. * For a list of examples related to this driver, see
  163. * \ref asfdoc_sam0_sdadc_exqsg.
  164. *
  165. *
  166. * \section asfdoc_sam0_sdadc_api_overview API Overview
  167. * @{
  168. */
  169. #ifdef __cplusplus
  170. extern "C" {
  171. #endif
  172. #include <compiler.h>
  173. #include <system.h>
  174. #if SDADC_CALLBACK_MODE == true
  175. # include <system_interrupt.h>
  176. #if !defined(__DOXYGEN__)
  177. extern struct sdadc_module *_sdadc_instances[SDADC_INST_NUM];
  178. #endif
  179. /** Forward definition of the device instance. */
  180. struct sdadc_module;
  181. /** Type of the callback functions. */
  182. typedef void (*sdadc_callback_t)(const struct sdadc_module *const module);
  183. /**
  184. * \brief SDADC Callback enum.
  185. *
  186. * Callback types for SDADC callback driver.
  187. *
  188. */
  189. enum sdadc_callback {
  190. /** Callback for buffer received */
  191. SDADC_CALLBACK_READ_BUFFER,
  192. /** Callback when window is hit */
  193. SDADC_CALLBACK_WINDOW,
  194. /** Callback for error */
  195. SDADC_CALLBACK_ERROR,
  196. # if !defined(__DOXYGEN__)
  197. /** Number of available callbacks */
  198. SDADC_CALLBACK_N,
  199. # endif
  200. };
  201. #endif
  202. /**
  203. * \name Module Status Flags
  204. *
  205. * SDADC status flags, returned by \ref sdadc_get_status() and cleared by
  206. * \ref sdadc_clear_status().
  207. *
  208. * @{
  209. */
  210. /** SDADC result ready. */
  211. #define SDADC_STATUS_RESULT_READY (1UL << 0)
  212. /** SDADC result overwritten before read. */
  213. #define SDADC_STATUS_OVERRUN (1UL << 1)
  214. /** Window monitor match. */
  215. #define SDADC_STATUS_WINDOW (1UL << 2)
  216. /** @} */
  217. /**
  218. * \brief SDADC reference voltage enum.
  219. *
  220. * Enum for the possible reference voltages for the SDADC.
  221. *
  222. */
  223. enum sdadc_reference_select {
  224. /** Internal Bandgap Reference */
  225. SDADC_REFERENCE_INTREF = SDADC_REFCTRL_REFSEL(0),
  226. /** External reference B */
  227. SDADC_REFERENCE_AREFB = SDADC_REFCTRL_REFSEL(1),
  228. /** DACOUT */
  229. SDADC_REFERENCE_DACOUT = SDADC_REFCTRL_REFSEL(2),
  230. /** VDDANA */
  231. SDADC_REFERENCE_INTVCC = SDADC_REFCTRL_REFSEL(3),
  232. };
  233. /**
  234. * \brief SDADC reference range enum.
  235. *
  236. * Enum for the matched voltage range of the SDADC reference used.
  237. *
  238. */
  239. enum sdadc_reference_range {
  240. /** Vref < 1.4V */
  241. SDADC_REFRANGE_0 = SDADC_REFCTRL_REFRANGE(0),
  242. /** 1.4V < Vref < 2.4V */
  243. SDADC_REFRANGE_1 = SDADC_REFCTRL_REFRANGE(1),
  244. /** 2.4V < Vref < 3.6V */
  245. SDADC_REFRANGE_2 = SDADC_REFCTRL_REFRANGE(2),
  246. /** Vref > 3.6V */
  247. SDADC_REFRANGE_3 = SDADC_REFCTRL_REFRANGE(3),
  248. };
  249. /**
  250. * \brief SDADC over sampling ratio enum.
  251. *
  252. * Enum for the over sampling ratio, which change the output data rate.
  253. *
  254. */
  255. enum sdadc_over_sampling_ratio {
  256. /** SDADC over Sampling Ratio is 64 */
  257. SDADC_OVER_SAMPLING_RATIO64 = SDADC_CTRLB_OSR(0),
  258. /** SDADC over Sampling Ratio is 128 */
  259. SDADC_OVER_SAMPLING_RATIO128 = SDADC_CTRLB_OSR(1),
  260. /** SDADC over Sampling Ratio is 256 */
  261. SDADC_OVER_SAMPLING_RATIO256 = SDADC_CTRLB_OSR(2),
  262. /** SDADC over Sampling Ratio is 512 */
  263. SDADC_OVER_SAMPLING_RATIO512 = SDADC_CTRLB_OSR(3),
  264. /** SDADC over Sampling Ratio is 1024 */
  265. SDADC_OVER_SAMPLING_RATIO1024 = SDADC_CTRLB_OSR(4),
  266. };
  267. /**
  268. * \brief SDADC window monitor mode enum.
  269. *
  270. * Enum for the possible window monitor modes for the SDADC.
  271. *
  272. */
  273. enum sdadc_window_mode {
  274. /** No window mode */
  275. SDADC_WINDOW_MODE_DISABLE = SDADC_WINCTRL_WINMODE(0),
  276. /** RESULT > WINLT */
  277. SDADC_WINDOW_MODE_ABOVE = SDADC_WINCTRL_WINMODE(1),
  278. /** RESULT < WINUT */
  279. SDADC_WINDOW_MODE_BELOW = SDADC_WINCTRL_WINMODE(2),
  280. /** WINLT < RESULT < WINUT */
  281. SDADC_WINDOW_MODE_INSIDE = SDADC_WINCTRL_WINMODE(3),
  282. /** !(WINLT < RESULT < WINUT) */
  283. SDADC_WINDOW_MODE_OUTSIDE = SDADC_WINCTRL_WINMODE(4),
  284. };
  285. /**
  286. * \brief SDADC event action enum.
  287. *
  288. * Enum for the possible actions to take on an incoming event.
  289. *
  290. */
  291. enum sdadc_event_action {
  292. /** Event action disabled */
  293. SDADC_EVENT_ACTION_DISABLED = 0,
  294. /** Flush SDADC and start conversion */
  295. SDADC_EVENT_ACTION_FLUSH_START_CONV = SDADC_EVCTRL_FLUSHEI,
  296. /** Start conversion */
  297. SDADC_EVENT_ACTION_START_CONV = SDADC_EVCTRL_STARTEI,
  298. };
  299. /**
  300. * \brief SDADC MUX input selection enum.
  301. *
  302. * Enum for the possible MUX input selections for the SDADC.
  303. *
  304. */
  305. enum sdadc_mux_input {
  306. /** Select SDADC AINN0 and AINP0 pins */
  307. SDADC_MUX_INPUT_AIN0 = SDADC_INPUTCTRL_MUXSEL_AIN0,
  308. /** Select SDADC AINN1 and AINP1 pins */
  309. SDADC_MUX_INPUT_AIN1 = SDADC_INPUTCTRL_MUXSEL_AIN1,
  310. /** Select SDADC AINN2 and AINP2 pins */
  311. SDADC_MUX_INPUT_AIN2 = SDADC_INPUTCTRL_MUXSEL_AIN2,
  312. };
  313. #if SDADC_CALLBACK_MODE == true
  314. /**
  315. * Enum for the possible SDADC interrupt flags.
  316. */
  317. enum sdadc_interrupt_flag {
  318. /** SDADC result ready */
  319. SDADC_INTERRUPT_RESULT_READY = SDADC_INTFLAG_RESRDY,
  320. /** SDADC result overwritten before read */
  321. SDADC_INTERRUPT_OVERRUN = SDADC_INTFLAG_OVERRUN,
  322. /** Window monitor match */
  323. SDADC_INTERRUPT_WINDOW = SDADC_INTFLAG_WINMON,
  324. };
  325. #endif
  326. /**
  327. * \brief Reference configuration structure.
  328. *
  329. * Reference configuration structure.
  330. */
  331. struct sdadc_reference {
  332. /** Reference voltage selection */
  333. enum sdadc_reference_select ref_sel;
  334. /** Reference voltage range */
  335. enum sdadc_reference_select ref_range;
  336. /** Reference buffer turning switch */
  337. bool on_ref_buffer;
  338. };
  339. /**
  340. * \brief Window monitor configuration structure.
  341. *
  342. * Window monitor configuration structure.
  343. */
  344. struct sdadc_window_config {
  345. /** Selected window mode */
  346. enum sdadc_window_mode window_mode;
  347. /** Lower window value */
  348. int32_t window_lower_value;
  349. /** Upper window value */
  350. int32_t window_upper_value;
  351. };
  352. /**
  353. * \brief SDADC event enable/disable structure.
  354. *
  355. * Event flags for the SDADC module. This is used to enable and
  356. * disable events via \ref sdadc_enable_events() and \ref sdadc_disable_events().
  357. */
  358. struct sdadc_events {
  359. /** Enable event generation on conversion done */
  360. bool generate_event_on_conversion_done;
  361. /** Enable event generation on window monitor */
  362. bool generate_event_on_window_monitor;
  363. };
  364. /**
  365. * \brief SDADC correction configuration structure.
  366. *
  367. * Offset, gain, and shift correction configuration structure.
  368. * Part of the \ref sdadc_config struct will be initialized by
  369. * \ref sdadc_get_config_defaults.
  370. */
  371. struct sdadc_correction_config {
  372. /** Offset correction */
  373. int32_t offset_correction;
  374. /** Gain correction */
  375. uint16_t gain_correction;
  376. /** Shift correction */
  377. uint8_t shift_correction;
  378. };
  379. /**
  380. * \brief SDADC configuration structure.
  381. *
  382. * Configuration structure for an SDADC instance. This structure should be
  383. * initialized by the \ref sdadc_get_config_defaults()
  384. * function before being modified by the user application.
  385. */
  386. struct sdadc_config {
  387. /** GCLK generator used to clock the peripheral */
  388. enum gclk_generator clock_source;
  389. /** Voltage reference */
  390. struct sdadc_reference reference;
  391. /** Over sampling ratio */
  392. enum sdadc_over_sampling_ratio osr;
  393. /** Clock prescaler */
  394. uint8_t clock_prescaler;
  395. /** Skip Count */
  396. uint8_t skip_count;
  397. /** MUX input */
  398. enum sdadc_mux_input mux_input;
  399. /** Enables free running mode if true */
  400. bool freerunning;
  401. /** Enables SDADC in standby sleep mode if true */
  402. bool run_in_standby;
  403. /** Enables SDADC depend on other peripheral if true */
  404. bool on_command;
  405. /** Enables positive input in the sequence if true */
  406. bool seq_enable[3];
  407. /** Window monitor configuration structure */
  408. struct sdadc_window_config window;
  409. /** Gain and offset correction configuration structure */
  410. struct sdadc_correction_config correction;
  411. /** Event action to take on incoming event */
  412. enum sdadc_event_action event_action;
  413. };
  414. /**
  415. * \brief SDADC software device instance structure.
  416. *
  417. * SDADC software instance structure, used to retain software state information
  418. * of an associated hardware module instance.
  419. *
  420. * \note The fields of this structure should not be altered by the user
  421. * application; they are reserved for module-internal use only.
  422. */
  423. struct sdadc_module {
  424. #if !defined(__DOXYGEN__)
  425. /** Pointer to SDADC hardware module */
  426. Sdadc *hw;
  427. /** Keep reference configuration so we know when enable is called */
  428. struct sdadc_reference reference;
  429. # if SDADC_CALLBACK_MODE == true
  430. /** Array to store callback functions */
  431. sdadc_callback_t callback[SDADC_CALLBACK_N];
  432. /** Pointer to buffer used for SDADC results */
  433. volatile int32_t *job_buffer;
  434. /** Remaining number of conversions in current job */
  435. volatile uint16_t remaining_conversions;
  436. /** Bit mask for callbacks registered */
  437. uint8_t registered_callback_mask;
  438. /** Bit mask for callbacks enabled */
  439. uint8_t enabled_callback_mask;
  440. /** Holds the status of the ongoing or last conversion job */
  441. volatile enum status_code job_status;
  442. /** If software triggering is needed */
  443. bool software_trigger;
  444. # endif
  445. #endif
  446. };
  447. /**
  448. * \name Driver Initialization and Configuration
  449. * @{
  450. */
  451. enum status_code sdadc_init(
  452. struct sdadc_module *const module_inst,
  453. Sdadc *hw,
  454. struct sdadc_config *config);
  455. /**
  456. * \brief Initializes an SDADC configuration structure to defaults.
  457. *
  458. * Initializes a given SDADC configuration struct to a set of known default
  459. * values. This function should be called on any new instance of the
  460. * configuration struct before being modified by the user application.
  461. *
  462. * The default configuration is as follows:
  463. * \li GCLK generator 0 (GCLK main) clock source
  464. * \li Positive reference 1
  465. * \li Div 2 clock prescaler
  466. * \li Over Sampling Ratio is 64
  467. * \li Skip 0 samples
  468. * \li MUX input on SDADC AIN1
  469. * \li All events (input and generation) disabled
  470. * \li Free running disabled
  471. * \li Run in standby disabled
  472. * \li On command disabled
  473. * \li Disable all positive input in sequence
  474. * \li Window monitor disabled
  475. * \li No gain/offset/shift correction
  476. *
  477. * \param[out] config Pointer to configuration struct to initialize to
  478. * default values
  479. */
  480. static inline void sdadc_get_config_defaults(struct sdadc_config *const config)
  481. {
  482. Assert(config);
  483. config->clock_source = GCLK_GENERATOR_0;
  484. config->reference.ref_sel = SDADC_REFERENCE_INTREF;
  485. config->reference.ref_range = SDADC_REFRANGE_0;
  486. config->reference.on_ref_buffer = false;
  487. config->clock_prescaler = 2;
  488. config->osr = SDADC_OVER_SAMPLING_RATIO64;
  489. config->skip_count = 2;
  490. config->mux_input = SDADC_MUX_INPUT_AIN1;
  491. config->event_action = SDADC_EVENT_ACTION_DISABLED;
  492. config->freerunning = false;
  493. config->run_in_standby = false;
  494. config->on_command = false;
  495. config->seq_enable[0] = false;
  496. config->seq_enable[1] = false;
  497. config->seq_enable[2] = false;
  498. config->window.window_mode = SDADC_WINDOW_MODE_DISABLE;
  499. config->window.window_upper_value = 0;
  500. config->window.window_lower_value = 0;
  501. config->correction.gain_correction = 1;
  502. config->correction.offset_correction = SDADC_OFFSETCORR_RESETVALUE;
  503. config->correction.shift_correction = SDADC_SHIFTCORR_RESETVALUE;
  504. }
  505. /** @} */
  506. /**
  507. * \name Status Management
  508. * @{
  509. */
  510. /**
  511. * \brief Retrieves the current module status.
  512. *
  513. * Retrieves the status of the module, giving overall state information.
  514. *
  515. * \param[in] module_inst Pointer to the SDADC software instance struct
  516. *
  517. * \return Bitmask of \c SDADC_STATUS_* flags.
  518. *
  519. * \retval SDADC_STATUS_RESULT_READY SDADC result is ready to be read
  520. * \retval SDADC_STATUS_WINDOW SDADC has detected a value inside the set
  521. * window range
  522. * \retval SDADC_STATUS_OVERRUN SDADC result has overrun
  523. */
  524. static inline uint32_t sdadc_get_status(
  525. struct sdadc_module *const module_inst)
  526. {
  527. /* Sanity check arguments */
  528. Assert(module_inst);
  529. Assert(module_inst->hw);
  530. Sdadc *const sdadc_module = module_inst->hw;
  531. uint32_t int_flags = sdadc_module->INTFLAG.reg;
  532. uint32_t status_flags = 0;
  533. /* Check for SDADC Result Ready */
  534. if (int_flags & SDADC_INTFLAG_RESRDY) {
  535. status_flags |= SDADC_STATUS_RESULT_READY;
  536. }
  537. /* Check for SDADC Window Match */
  538. if (int_flags & SDADC_INTFLAG_WINMON) {
  539. status_flags |= SDADC_STATUS_WINDOW;
  540. }
  541. /* Check for SDADC Overrun */
  542. if (int_flags & SDADC_INTFLAG_OVERRUN) {
  543. status_flags |= SDADC_STATUS_OVERRUN;
  544. }
  545. return status_flags;
  546. }
  547. /**
  548. * \brief Clears a module status flag.
  549. *
  550. * Clears the given status flag of the module.
  551. *
  552. * \param[in] module_inst Pointer to the SDADC software instance struct
  553. * \param[in] status_flags Bitmask of \c SDADC_STATUS_* flags to clear
  554. */
  555. static inline void sdadc_clear_status(
  556. struct sdadc_module *const module_inst,
  557. const uint32_t status_flags)
  558. {
  559. /* Sanity check arguments */
  560. Assert(module_inst);
  561. Assert(module_inst->hw);
  562. Sdadc *const sdadc_module = module_inst->hw;
  563. uint32_t int_flags = 0;
  564. /* Check for SDADC Result Ready */
  565. if (status_flags & SDADC_STATUS_RESULT_READY) {
  566. int_flags |= SDADC_INTFLAG_RESRDY;
  567. }
  568. /* Check for SDADC Window Match */
  569. if (status_flags & SDADC_STATUS_WINDOW) {
  570. int_flags |= SDADC_INTFLAG_WINMON;
  571. }
  572. /* Check for SDADC Overrun */
  573. if (status_flags & SDADC_STATUS_OVERRUN) {
  574. int_flags |= SDADC_INTFLAG_OVERRUN;
  575. }
  576. /* Clear interrupt flag */
  577. sdadc_module->INTFLAG.reg = int_flags;
  578. }
  579. /**
  580. * \brief Get a module sequence flag.
  581. *
  582. * Get the given status flag of the module.
  583. *
  584. * \param[in] module_inst Pointer to the SDADC software instance struct
  585. * \param[out] seq_state Identifies the last conversion done in the sequence
  586. *
  587. * \return Status of the SDADC sequence conversion.
  588. *
  589. * \retval true When the sequence start
  590. * \retval false When the last conversion in a sequence is done
  591. */
  592. static inline bool sdadc_get_sequence_status(
  593. struct sdadc_module *const module_inst,
  594. uint8_t* seq_state)
  595. {
  596. /* Sanity check arguments */
  597. Assert(module_inst);
  598. Assert(module_inst->hw);
  599. Sdadc *const sdadc_module = module_inst->hw;
  600. /* Get SDADC result */
  601. *seq_state = sdadc_module->SEQSTATUS.reg & SDADC_SEQSTATUS_SEQSTATE_Msk;
  602. return ((sdadc_module->SEQSTATUS.bit.SEQBUSY == 1) ? true : false);
  603. }
  604. /** @} */
  605. /**
  606. * \name Enable, Disable, and Reset SDADC Module, Start Conversion and Read Result
  607. * @{
  608. */
  609. /**
  610. * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
  611. *
  612. * Checks to see if the underlying hardware peripheral module(s) are currently
  613. * synchronizing across multiple clock domains to the hardware bus. This
  614. * function can be used to delay further operations on a module until such time
  615. * that it is ready, to prevent blocking delays for synchronization in the
  616. * user application.
  617. *
  618. * \param[in] module_inst Pointer to the SDADC software instance struct
  619. *
  620. * \return Synchronization status of the underlying hardware module(s).
  621. *
  622. * \retval true If the module synchronization is ongoing
  623. * \retval false If the module has completed synchronization
  624. */
  625. static inline bool sdadc_is_syncing(
  626. struct sdadc_module *const module_inst)
  627. {
  628. /* Sanity check arguments */
  629. Assert(module_inst);
  630. Sdadc *const sdadc_module = module_inst->hw;
  631. if (sdadc_module->SYNCBUSY.reg) {
  632. return true;
  633. }
  634. return false;
  635. }
  636. /**
  637. * \brief Enables the SDADC module.
  638. *
  639. * Enables an SDADC module that has previously been configured. If any internal reference
  640. * is selected it will be enabled.
  641. *
  642. * \param[in] module_inst Pointer to the SDADC software instance struct
  643. */
  644. static inline enum status_code sdadc_enable(
  645. struct sdadc_module *const module_inst)
  646. {
  647. Assert(module_inst);
  648. Assert(module_inst->hw);
  649. Sdadc *const sdadc_module = module_inst->hw;
  650. while (sdadc_is_syncing(module_inst)) {
  651. /* Wait for synchronization */
  652. }
  653. #if SDADC_CALLBACK_MODE == true
  654. system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_SDADC);
  655. #endif
  656. sdadc_module->CTRLA.reg |= SDADC_CTRLA_ENABLE;
  657. return STATUS_OK;
  658. }
  659. /**
  660. * \brief Disables the SDADC module.
  661. *
  662. * Disables an SDADC module that was previously enabled.
  663. *
  664. * \param[in] module_inst Pointer to the SDADC software instance struct
  665. */
  666. static inline enum status_code sdadc_disable(
  667. struct sdadc_module *const module_inst)
  668. {
  669. Assert(module_inst);
  670. Assert(module_inst->hw);
  671. Sdadc *const sdadc_module = module_inst->hw;
  672. #if SDADC_CALLBACK_MODE == true
  673. system_interrupt_disable(SYSTEM_INTERRUPT_MODULE_SDADC);
  674. #endif
  675. while (sdadc_is_syncing(module_inst)) {
  676. /* Wait for synchronization */
  677. }
  678. /* Disbale interrupt */
  679. sdadc_module->INTENCLR.reg = SDADC_INTENCLR_MASK;
  680. /* Clear interrupt flag */
  681. sdadc_module->INTFLAG.reg = SDADC_INTFLAG_MASK;
  682. sdadc_module->CTRLA.reg &= ~SDADC_CTRLA_ENABLE;
  683. return STATUS_OK;
  684. }
  685. /**
  686. * \brief Resets the SDADC module.
  687. *
  688. * Resets an SDADC module, clearing all module state, and registers to their
  689. * default values.
  690. *
  691. * \param[in] module_inst Pointer to the SDADC software instance struct
  692. */
  693. static inline enum status_code sdadc_reset(
  694. struct sdadc_module *const module_inst)
  695. {
  696. /* Sanity check arguments */
  697. Assert(module_inst);
  698. Assert(module_inst->hw);
  699. Sdadc *const sdadc_module = module_inst->hw;
  700. /* Disable to make sure the pipeline is flushed before reset */
  701. sdadc_disable(module_inst);
  702. while (sdadc_is_syncing(module_inst)) {
  703. /* Wait for synchronization */
  704. }
  705. /* Software reset the module */
  706. sdadc_module->CTRLA.reg |= SDADC_CTRLA_SWRST;
  707. return STATUS_OK;
  708. }
  709. /**
  710. * \brief Enables an SDADC event input or output.
  711. *
  712. * Enables one or more input or output events to or from the SDADC module. See
  713. * \ref sdadc_events for a list of events this module supports.
  714. *
  715. * \note Events cannot be altered while the module is enabled.
  716. *
  717. * \param[in] module_inst Software instance for the SDADC peripheral
  718. * \param[in] events Struct containing flags of events to enable
  719. */
  720. static inline void sdadc_enable_events(
  721. struct sdadc_module *const module_inst,
  722. struct sdadc_events *const events)
  723. {
  724. /* Sanity check arguments */
  725. Assert(module_inst);
  726. Assert(module_inst->hw);
  727. Assert(events);
  728. Sdadc *const sdadc_module = module_inst->hw;
  729. uint32_t event_mask = 0;
  730. /* Configure Window Monitor event */
  731. if (events->generate_event_on_window_monitor) {
  732. event_mask |= SDADC_EVCTRL_WINMONEO;
  733. }
  734. /* Configure Result Ready event */
  735. if (events->generate_event_on_conversion_done) {
  736. event_mask |= SDADC_EVCTRL_RESRDYEO;
  737. }
  738. sdadc_module->EVCTRL.reg |= event_mask;
  739. }
  740. /**
  741. * \brief Disables an SDADC event input or output.
  742. *
  743. * Disables one or more input or output events to or from the SDADC module. See
  744. * \ref sdadc_events for a list of events this module supports.
  745. *
  746. * \note Events cannot be altered while the module is enabled.
  747. *
  748. * \param[in] module_inst Software instance for the SDADC peripheral
  749. * \param[in] events Struct containing flags of events to disable
  750. */
  751. static inline void sdadc_disable_events(
  752. struct sdadc_module *const module_inst,
  753. struct sdadc_events *const events)
  754. {
  755. /* Sanity check arguments */
  756. Assert(module_inst);
  757. Assert(module_inst->hw);
  758. Assert(events);
  759. Sdadc *const sdadc_module = module_inst->hw;
  760. uint32_t event_mask = 0;
  761. /* Configure Window Monitor event */
  762. if (events->generate_event_on_window_monitor) {
  763. event_mask |= SDADC_EVCTRL_WINMONEO;
  764. }
  765. /* Configure Result Ready event */
  766. if (events->generate_event_on_conversion_done) {
  767. event_mask |= SDADC_EVCTRL_RESRDYEO;
  768. }
  769. sdadc_module->EVCTRL.reg &= ~event_mask;
  770. }
  771. /**
  772. * \brief Starts an SDADC conversion.
  773. *
  774. * Starts a new SDADC conversion.
  775. *
  776. * \param[in] module_inst Pointer to the SDADC software instance struct
  777. */
  778. static inline void sdadc_start_conversion(
  779. struct sdadc_module *const module_inst)
  780. {
  781. Assert(module_inst);
  782. Assert(module_inst->hw);
  783. Sdadc *const sdadc_module = module_inst->hw;
  784. while (sdadc_is_syncing(module_inst)) {
  785. /* Wait for synchronization */
  786. }
  787. sdadc_module->SWTRIG.reg |= SDADC_SWTRIG_START;
  788. }
  789. /**
  790. * \brief Reads the SDADC result.
  791. *
  792. * Reads the result from an SDADC conversion that was previously started.
  793. *
  794. * \param[in] module_inst Pointer to the SDADC software instance struct
  795. * \param[out] result Pointer to store the result value in
  796. *
  797. * \return Status of the SDADC read request.
  798. * \retval STATUS_OK The result was retrieved successfully
  799. * \retval STATUS_BUSY A conversion result was not ready
  800. * \retval STATUS_ERR_OVERFLOW The result register has been overwritten by the
  801. * SDADC module before the result was read by the software
  802. */
  803. static inline enum status_code sdadc_read(
  804. struct sdadc_module *const module_inst,
  805. int32_t *result)
  806. {
  807. Assert(module_inst);
  808. Assert(module_inst->hw);
  809. Assert(result);
  810. if (!(sdadc_get_status(module_inst) & SDADC_STATUS_RESULT_READY)) {
  811. /* Result not ready */
  812. return STATUS_BUSY;
  813. }
  814. Sdadc *const sdadc_module = module_inst->hw;
  815. /* Get SDADC result */
  816. *result = ((int32_t)(sdadc_module->RESULT.reg << 8)) >> 8;
  817. /* Reset ready flag */
  818. sdadc_clear_status(module_inst, SDADC_STATUS_RESULT_READY);
  819. if (sdadc_get_status(module_inst) & SDADC_STATUS_OVERRUN) {
  820. sdadc_clear_status(module_inst, SDADC_STATUS_OVERRUN);
  821. return STATUS_ERR_OVERFLOW;
  822. }
  823. return STATUS_OK;
  824. }
  825. /** @} */
  826. /**
  827. * \name Runtime Changes of SDADC Module
  828. * @{
  829. */
  830. /**
  831. * \brief Flushes the SDADC pipeline.
  832. *
  833. * Flushes the pipeline and restart the SDADC clock on the next peripheral clock
  834. * edge. All conversions in progress will be lost. When flush is complete, the
  835. * module will resume where it left off.
  836. *
  837. * \param[in] module_inst Pointer to the SDADC software instance struct
  838. */
  839. static inline void sdadc_flush(
  840. struct sdadc_module *const module_inst)
  841. {
  842. Assert(module_inst);
  843. Assert(module_inst->hw);
  844. Sdadc *const sdadc_module = module_inst->hw;
  845. while (sdadc_is_syncing(module_inst)) {
  846. /* Wait for synchronization */
  847. }
  848. sdadc_module->SWTRIG.reg |= SDADC_SWTRIG_FLUSH;
  849. }
  850. /**
  851. * \brief Sets the SDADC window mode.
  852. *
  853. * Sets the SDADC window mode to a given mode and value range.
  854. *
  855. * \param[in] module_inst Pointer to the SDADC software instance struct
  856. * \param[in] window_mode Window monitor mode to set
  857. * \param[in] window_lower_value Lower window monitor threshold value
  858. * \param[in] window_upper_value Upper window monitor threshold value
  859. */
  860. static inline void sdadc_set_window_mode(
  861. struct sdadc_module *const module_inst,
  862. const enum sdadc_window_mode window_mode,
  863. const int16_t window_lower_value,
  864. const int16_t window_upper_value)
  865. {
  866. /* Sanity check arguments */
  867. Assert(module_inst);
  868. Assert(module_inst->hw);
  869. Sdadc *const sdadc_module = module_inst->hw;
  870. while (sdadc_is_syncing(module_inst)) {
  871. /* Wait for synchronization */
  872. }
  873. /* Set window mode */
  874. sdadc_module->WINCTRL.reg = window_mode << SDADC_WINCTRL_WINMODE_Pos;
  875. while (sdadc_is_syncing(module_inst)) {
  876. /* Wait for synchronization */
  877. }
  878. /* Set lower window monitor threshold value */
  879. sdadc_module->WINLT.reg = window_lower_value << SDADC_WINLT_WINLT_Pos;
  880. while (sdadc_is_syncing(module_inst)) {
  881. /* Wait for synchronization */
  882. }
  883. /* Set upper window monitor threshold value */
  884. sdadc_module->WINUT.reg = window_upper_value << SDADC_WINUT_WINUT_Pos;
  885. }
  886. /**
  887. * \brief Sets MUX SDADC input pin.
  888. *
  889. * Sets the MUX SDADC input pin selection.
  890. *
  891. * \param[in] module_inst Pointer to the SDADC software instance struct
  892. * \param[in] mux_input MUX input pin
  893. */
  894. static inline void sdadc_set_mux_input(
  895. struct sdadc_module *const module_inst,
  896. const enum sdadc_mux_input mux_input)
  897. {
  898. /* Sanity check arguments */
  899. Assert(module_inst);
  900. Assert(module_inst->hw);
  901. Sdadc *const sdadc_module = module_inst->hw;
  902. while (sdadc_is_syncing(module_inst)) {
  903. /* Wait for synchronization */
  904. }
  905. /* Set mux input pin */
  906. sdadc_module->INPUTCTRL.reg =
  907. (sdadc_module->INPUTCTRL.reg & ~SDADC_INPUTCTRL_MUXSEL_Msk) | mux_input;
  908. }
  909. /** @} */
  910. #if SDADC_CALLBACK_MODE == true
  911. /**
  912. * \name Enable and Disable Interrupts
  913. * @{
  914. */
  915. /**
  916. * \brief Enable interrupt.
  917. *
  918. * Enable the given interrupt request from the SDADC module.
  919. *
  920. * \param[in] module_inst Pointer to the SDADC software instance struct
  921. * \param[in] interrupt Interrupt to enable
  922. */
  923. static inline void sdadc_enable_interrupt(struct sdadc_module *const module_inst,
  924. enum sdadc_interrupt_flag interrupt)
  925. {
  926. /* Sanity check arguments */
  927. Assert(module_inst);
  928. Assert(module_inst->hw);
  929. Sdadc *const sdadc_module = module_inst->hw;
  930. /* Enable interrupt */
  931. sdadc_module->INTENSET.reg = interrupt;
  932. }
  933. /**
  934. * \brief Disable interrupt.
  935. *
  936. * Disable the given interrupt request from the SDADC module.
  937. *
  938. * \param[in] module_inst Pointer to the SDADC software instance struct
  939. * \param[in] interrupt Interrupt to disable
  940. */
  941. static inline void sdadc_disable_interrupt(struct sdadc_module *const module_inst,
  942. enum sdadc_interrupt_flag interrupt)
  943. {
  944. /* Sanity check arguments */
  945. Assert(module_inst);
  946. Assert(module_inst->hw);
  947. Sdadc *const sdadc_module = module_inst->hw;
  948. /* Enable interrupt */
  949. sdadc_module->INTENCLR.reg = interrupt;
  950. }
  951. /** @} */
  952. #endif /* SDADC_CALLBACK_MODE == true */
  953. #ifdef __cplusplus
  954. }
  955. #endif
  956. /** @} */
  957. /**
  958. * \page asfdoc_sam0_sdadc_extra Extra Information for SDADC Driver
  959. *
  960. * \section asfdoc_sam0_sdadc_extra_acronyms Acronyms
  961. * Below is a table listing the acronyms used in this module, along with their
  962. * intended meanings.
  963. *
  964. * <table>
  965. * <tr>
  966. * <th>Acronym</th>
  967. * <th>Description</th>
  968. * </tr>
  969. * <tr>
  970. * <td>SDADC</td>
  971. * <td>Sigma-Delta Analog-to-Digital Converter</td>
  972. * </tr>
  973. * <tr>
  974. * <td>OSR</td>
  975. * <td>Over Sampling Ratio</td>
  976. * </tr>
  977. * </table>
  978. *
  979. *
  980. * \section asfdoc_sam0_sdadc_extra_dependencies Dependencies
  981. * This driver has no dependencies.
  982. *
  983. *
  984. * \section asfdoc_sam0_sdadc_extra_errata Errata
  985. * There are no errata related to this driver.
  986. *
  987. *
  988. * \section asfdoc_sam0_sdadc_extra_history Module History
  989. * An overview of the module history is presented in the table below, with
  990. * details on the enhancements and fixes made to the module since its first
  991. * release. The current version of this corresponds to the newest version in
  992. * the table.
  993. *
  994. * <table>
  995. * <tr>
  996. * <th>Changelog</th>
  997. * </tr>
  998. * <tr>
  999. * <td>Initial Release</td>
  1000. * </tr>
  1001. * </table>
  1002. */
  1003. /**
  1004. * \page asfdoc_sam0_sdadc_exqsg Examples for SDADC Driver
  1005. *
  1006. * This is a list of the available Quick Start guides (QSGs) and example
  1007. * applications for \ref asfdoc_sam0_sdadc_group. QSGs are simple examples with
  1008. * step-by-step instructions to configure and use this driver in a selection of
  1009. * use cases. Note that a QSG can be compiled as a standalone application or be
  1010. * added to the user application.
  1011. *
  1012. * - \subpage asfdoc_sam0_sdadc_basic_use_case
  1013. * \if SDADC_CALLBACK_MODE
  1014. * - \subpage asfdoc_sam0_sdadc_basic_use_case_callback
  1015. * \endif
  1016. *
  1017. * \page asfdoc_sam0_sdadc_document_revision_history Document Revision History
  1018. *
  1019. * <table>
  1020. * <tr>
  1021. * <th>Doc. Rev.</td>
  1022. * <th>Date</td>
  1023. * <th>Comments</td>
  1024. * </tr>
  1025. * <tr>
  1026. * <td>42496A</td>
  1027. * <td>09/2015</td>
  1028. * <td>Initial document release</td>
  1029. * </tr>
  1030. * </table>
  1031. */
  1032. #endif /* SDADC_H_INCLUDED */