1 /**
2  *
3  * \file
4  *
5  * \brief SAM Segment Liquid Crystal Display(SLCD) Controller.
6  *
7  * Copyright (c) 2015-2016 Atmel Corporation. All rights reserved.
8  *
9  * \asf_license_start
10  *
11  * \page License
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  *    this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright notice,
20  *    this list of conditions and the following disclaimer in the documentation
21  *    and/or other materials provided with the distribution.
22  *
23  * 3. The name of Atmel may not be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * 4. This software may only be redistributed and used in connection with an
27  *    Atmel microcontroller product.
28  *
29  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
30  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
32  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
33  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39  * POSSIBILITY OF SUCH DAMAGE.
40  *
41  * \asf_license_stop
42  *
43  */
44 /*
45  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
46  */
47 
48 #ifndef SLCD_H_INCLUDED
49 #define SLCD_H_INCLUDED
50 
51 /**
52  * \defgroup asfdoc_sam0_drivers_slcd_group SAM Segment Liquid Crystal Display(SLCD) Controller
53  *
54  * This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers provides an interface for the configuration
55  * and management of the device's SLCD functionality. The following
56  * driver API modes are covered by this manual:
57  *
58  *  - Polled APIs
59  *  - Callback APIs
60  *
61  *
62  * The following peripheral is used by this module:
63  *  - Segment Liquid Crystal Display(SLCD)
64  *
65  * The following devices can use this module:
66  *  - Atmel | SMART SAM L22
67  *
68  * The outline of this documentation is as follows:
69  *  - \ref asfdoc_sam0_drivers_slcd_prerequisites
70  *  - \ref asfdoc_sam0_drivers_slcd_module_overview
71  *  - \ref asfdoc_sam0_drivers_slcd_special_considerations
72  *  - \ref asfdoc_sam0_drivers_slcd_extra_info
73  *  - \ref asfdoc_sam0_drivers_slcd_examples
74  *  - \ref asfdoc_sam0_drivers_slcd_api_overview
75  *
76  *
77  * \section asfdoc_sam0_drivers_slcd_prerequisites Prerequisites
78  *
79  * There are no prerequisites for this module.
80  *
81  *
82  * \section asfdoc_sam0_drivers_slcd_module_overview Module Overview
83  *
84  * \subsection asfdoc_sam0_drivers_slcd_module_overview_internal Display Overview
85  *
86  * A LCD display is made of several segments (pixels or complete symbols)
87  * which can be visible or invisible. A segment has two electrodes with liquid
88  * crystal between them. These electrodes are the common terminal (COM pin) and
89  * the segment terminal (SEG pin). When a voltage above a threshold voltage is applied
90  * across the liquid crystal, the segment becomes visible. The voltage must alternate,
91  * to avoid an electrophoresis effect in the liquid crystal, which degrades the
92  * display.
93  *
94  * The LCD controller is intended for monochrome passive liquid crystal display (LCD)
95  * with up to 8 common terminals and up to 44 segment terminals. A charge pump provides
96  * LCD display supply which can be higher than supply voltage of the device.
97  * Each LCD pin, segment or common terminals, can be configured as general purpose I/O pins
98  * if not driven by LCD controller.
99  *
100  * \section asfdoc_sam0_drivers_slcd_special_considerations Special Considerations
101  *
102  * \subsection asfdoc_sam0_drivers_slcd_special_considerations_io I/O Lines
103  *
104  * The SLCD pins (SEG and COM) are multiplexed with other peripherals. The
105  * user application must first configure the I/O controller, to give control of
106  * the requisite pins to the SLCD.
107  *
108  * \subsection asfdoc_sam0_drivers_slcd_special_considerations_power Power Management
109  *
110  * The SLCD will continue to operate in any sleep mode where the selected source clock
111  * is running. The SLCD interrupts can be used to wake up the device from sleep modes.
112  * Events connected to the event system can trigger other operations in the system
113  * without exiting sleep modes.
114  *
115  * The power consumption of SLCD itself can be minimized by:
116  * - Using the lowest acceptable frame rate (refer to the LCD glass technical
117  * characteristics)
118  * - Using the low-power waveform (default mode)
119  * - Using automated modes of operation
120  * - Configuring the lowest possible contrast value
121  *
122  * \section asfdoc_sam0_drivers_slcd_extra_info Extra Information
123  *
124  * For extra information, see \ref asfdoc_sam0_drivers_slcd_extra. This includes:
125  *  - \ref asfdoc_sam0_drivers_slcd_extra_acronyms
126  *  - \ref asfdoc_sam0_drivers_slcd_extra_dependencies
127  *  - \ref asfdoc_sam0_drivers_slcd_extra_errata
128  *  - \ref asfdoc_sam0_drivers_slcd_extra_history
129  *
130  * \section asfdoc_sam0_drivers_slcd_examples Examples
131  *
132  * For a list of examples related to this driver, see
133  * \ref asfdoc_sam0_drivers_slcd_exqsg.
134  *
135  *
136  * \section asfdoc_sam0_drivers_slcd_api_overview API Overview
137  * @{
138  */
139 
140 #include <compiler.h>
141 #include <system.h>
142 
143 #ifdef __cplusplus
144 extern "C" {
145 #endif
146 
147 /**
148  * \brief SLCD frame counter definition
149  *
150  * Enum SLCD frame counter definition.
151  */
152 enum slcd_frame_counter {
153 	/** SLCD frame counter 0 */
154 	SLCD_FRAME_COUNTER_0,
155 	/** SLCD frame counter 1 */
156 	SLCD_FRAME_COUNTER_1,
157 	/** SLCD frame counter 2 */
158 	SLCD_FRAME_COUNTER_2,
159 };
160 
161 /**
162  * \brief Waveform mode
163  *
164  * Enum waveform mode.
165  */
166 enum slcd_waveform_mode {
167 	/** Low power waveform mode */
168 	SLCD_LOW_POWER_WAVEFORM_MODE = 0,
169 	/** Standard waveform mode */
170 	SLCD_STANDARD_WAVEFORM_MODE,
171 };
172 
173 /**
174  * \brief SLCD configuration structure
175  *
176  * Basic configuration for SLCDC.
177  */
178 struct slcd_config {
179 	/** Keep SLCD enabled in standby sleep mode if true */
180 	bool run_in_standby;
181 	/** waveform mode selection */
182 	enum slcd_waveform_mode waveform_mode;
183 
184 	/** Low resistance network duration */
185 	uint8_t low_resistance_duration;
186 	/** Enable Low resistance if true */
187 	bool enable_low_resistance;
188 	/** Bias buffer duration */
189 	uint8_t bias_buffer_duration;
190 	/** Enable bias buffer if true */
191 	bool enable_bias_buffer;
192 };
193 /**
194  * \brief SLCD event enable/disable structure
195  *
196  * Event flags for the SLCD module. This is used to enable and
197  * disable events via \ref slcd_enable_events() and \ref slcd_disable_events().
198  */
199 struct slcd_events {
200 	/** Enable event generation on frame counter 0 overflow */
201 	bool generate_event_on_fc0_overflow;
202 	/** Enable event generation on frame counter 1 overflow */
203 	bool generate_event_on_fc1_overflow;
204 	/** Enable event generation on frame counter 2 overflow */
205 	bool generate_event_on_fc2_overflow;
206 };
207 
208 /**
209  * \brief SLCD blink configuration
210  *
211  * SLCD blink configuration.
212  */
213 struct slcd_blink_config {
214 	/** Frame counter selection for blinking */
215 	enum slcd_frame_counter fc;
216 	/** All segments are allowed to blink if true, else only
217 	  Selected segments are allowed to blink */
218 	bool blink_all_seg;
219 };
220 
221 /**
222  * \brief SLCD circular shift direction
223  *
224  * Enum SLCD circular shift direction.
225  */
226 enum slcd_circular_shift_dir {
227 	/** Circular shift direction is left */
228 	SLCD_CIRCULAR_SHIFT_LEFT = 0,
229 	/** Circular shift direction is right */
230 	SLCD_CIRCULAR_SHIFT_RIGHT,
231 };
232 
233 /**
234  * \brief SLCD circular shift configuration
235  *
236  * SLCD circular shift configuration.
237  */
238 struct slcd_circular_shift_config {
239 	/** Frame counter selection for circular shift */
240 	enum slcd_frame_counter fc;
241 	/** Shift direction */
242 	enum slcd_circular_shift_dir dir;
243 	/** Size of the circular shift register, MAX. size is 16 */
244 	uint8_t size;
245 	/** Circular shift register value */
246 	uint16_t data;
247 };
248 
249 /**
250  * \brief Automated char  order
251  *
252  * Enum automated char order.
253  */
254 enum slcd_automated_char_order {
255 	/** Segment is starting from bottom right */
256 	SLCD_AUTOMATED_CHAR_START_FROM_BOTTOM_RIGHT = 0,
257 	/** Segment is starting from bottom left */
258 	SLCD_AUTOMATED_CHAR_START_FROM_BOTTOM_LEFT,
259 };
260 
261 /**
262  * \brief Automated char display mode
263  *
264  * Enum automated char display mode.
265  */
266 enum slcd_automated_char_mode {
267 	/** Sequential Display Mode */
268 	SLCD_AUTOMATED_CHAR_SEQ = 0,
269 	/** Scrolling Display Mode */
270 	SLCD_AUTOMATED_CHAR_SCROLL,
271 };
272 
273 /**
274  * \brief Automated char configuration
275  *
276  * SLCD automated char configuration.
277  */
278 struct slcd_automated_char_config {
279 	/** Mapping order in automated char mode */
280 	enum slcd_automated_char_order order;
281 	/** Frame counter selection for automated character mapping */
282 	enum slcd_frame_counter fc;
283 	/** Display mode */
284 	enum slcd_automated_char_mode mode;
285 	/** Define the number of SEG line per digit,
286 		it equal to number of SEG line - 1 */
287 	uint8_t seg_line_num;
288 	/** Define the index of the first segment terminal of the digit to display */
289 	uint8_t start_seg_line;
290 	/** Define the number of digit per row */
291 	uint8_t row_digit_num;
292 	/** Define the number of digit, it must be greater than 1 */
293 	uint8_t digit_num;
294 	/** Define the number of steps in scrolling mode.
295 		scrolling_step = character string length - digit_num + 1 */
296 	uint8_t scrolling_step;
297 	/** Define the number of COM line per row,
298 		it equal to number of COM line - 1 */
299 	uint8_t com_line_num;
300 	/** Segments data mask */
301 	uint32_t data_mask;
302 
303 };
304 
305 /**
306  * \name SLCD Basic Operation Functions
307  * @{
308  */
309 
310 void slcd_get_config_defaults(struct slcd_config *config);
311 enum status_code slcd_init(struct slcd_config *const config);
312 void slcd_enable(void);
313 void slcd_disable(void);
314 bool slcd_is_enabled(void);
315 void slcd_reset(void);
316 enum status_code slcd_set_contrast(uint8_t contrast);
317 
318 /**
319  * \brief Determines if SLCD module is currently synchronizing to the bus
320  *
321  * Checks to see if the underlying hardware peripheral module(s) are currently
322  * synchronizing across multiple clock domains to the hardware bus, This
323  * function can be used to delay further operations on a module until such time
324  * that it is ready, to prevent blocking delays for synchronization in the
325  * user application.
326  *
327  * \return Synchronization status of the underlying hardware module.
328  *
329  * \retval true  If the module synchronization is ongoing
330  * \retval false If the module has completed synchronization
331  */
slcd_is_syncing(void)332 static inline bool slcd_is_syncing(void)
333 {
334 
335 	if (SLCD->SYNCBUSY.reg) {
336 		return true;
337 	}
338 
339 	return false;
340 }
341 
342 /**
343  * \brief Lock shadow memory
344  *
345  * It allows update of shadow display memory. If the display memory
346  * is modified, the display remains unchanged when locked.
347  */
slcd_lock_shadow_memory(void)348 static inline void slcd_lock_shadow_memory(void)
349 {
350 	SLCD->CTRLC.reg |= SLCD_CTRLC_LOCK;
351 }
352 
353 /**
354  * \brief Unlock shadow memory
355  *
356  * Unlock the shadow display memory.
357  */
slcd_unlock_shadow_memory(void)358 static inline void slcd_unlock_shadow_memory(void)
359 {
360 	SLCD->CTRLC.reg &= (SLCD_CTRLC_MASK & ( ~SLCD_CTRLC_LOCK));
361 }
362 
363 /**
364  * \brief Clear display memory
365  *
366  * Clears immediately the display memory.
367  */
slcd_clear_display_memory(void)368 static inline void slcd_clear_display_memory(void)
369 {
370 	SLCD->CTRLC.reg |= SLCD_CTRLC_CLEAR;
371 }
372 
373 /**
374  * \brief Display enable
375  *
376  * Enable COM/SEG signal output.
377  */
slcd_enable_display(void)378 static inline void slcd_enable_display(void)
379 {
380 	SLCD->CTRLD.reg |= SLCD_CTRLD_DISPEN;
381 	while (slcd_is_syncing()) {
382 		/* Wait for synchronization */
383 	}
384 }
385 
386 /**
387  * \brief Display disable
388  *
389  * Disable COM/SEG signal output.
390  */
slcd_disable_display(void)391 static inline void slcd_disable_display(void)
392 {
393 	SLCD->CTRLD.reg &= (SLCD_CTRLD_MASK & ( ~SLCD_CTRLD_DISPEN));
394 	while (slcd_is_syncing()) {
395 		/* Wait for synchronization */
396 	}
397 }
398 /**
399  * \brief  DMA display memory update frame counter selection
400  *
401  * It's used to select the frame counter for DMA to update the display memory.
402  *
403  *  \note It can be called only before the module is enabled.
404  *
405  *  \param[in] fc Frame coungter index
406  */
slcd_dma_display_memory_update_fc_sel(enum slcd_frame_counter fc)407 static inline void slcd_dma_display_memory_update_fc_sel(enum slcd_frame_counter fc)
408 {
409 	SLCD->CTRLA.bit.DMFCS = fc;
410 }
411 
412 /** @} */
413 
414 /**
415  * \name SLCD Blink Functions
416  * @{
417  */
418 
419 /**
420  * \brief Blink mode enable
421  *
422  * Enable blink mode.
423  */
slcd_enable_blink(void)424 static inline void slcd_enable_blink(void)
425 {
426 	SLCD->CTRLD.reg |= SLCD_CTRLD_BLINK;
427 	while (slcd_is_syncing()) {
428 		/* Wait for synchronization */
429 	}
430 }
431 
432 /**
433  * \brief Blink mode disable
434  *
435  * Disable blink mode.
436  */
slcd_disable_blink(void)437 static inline void slcd_disable_blink(void)
438 {
439 	SLCD->CTRLD.reg &= ~SLCD_CTRLD_BLINK;
440 	while (slcd_is_syncing()) {
441 		/* Wait for synchronization */
442 	}
443 }
444 
445 void slcd_blink_get_config_defaults(struct slcd_blink_config *blink_config);
446 enum status_code slcd_blink_set_config(struct slcd_blink_config *const blink_config);
447 
448 void slcd_clear_blink_all_pixel(void);
449 void slcd_clear_blink_pixel(uint8_t pix_com,uint8_t pix_seg);
450 void slcd_set_blink_pixel(uint8_t pix_com,uint8_t pix_seg);
451 
452 /** @} */
453 
454 /**
455  * \name SLCD Blank Functions
456  * @{
457  */
458 
459 /**
460  * \brief Blank mode enable
461  *
462  * Enable blank mode.
463  */
slcd_enable_blank(void)464 static inline void slcd_enable_blank(void)
465 {
466 	SLCD->CTRLD.reg |= SLCD_CTRLD_BLANK;
467 	while (slcd_is_syncing()) {
468 		/* Wait for synchronization */
469 	}
470 }
471 /**
472  * \brief Blank mode disable
473  *
474  * Disable blank mode.
475  */
slcd_disable_blank(void)476 static inline void slcd_disable_blank(void)
477 {
478 	SLCD->CTRLD.reg &= ~SLCD_CTRLD_BLANK;
479 	while (slcd_is_syncing()) {
480 		/* Wait for synchronization */
481 	}
482 }
483 /** @} */
484 
485 /**
486  * \name SLCD Event Functions
487  * @{
488  */
489 
490 /**
491  * \brief Enables a SLCD event output
492  *
493  *  Enables one or more output events.
494  *
495  *  \note Events cannot be altered while the module is enabled.
496  *
497  *  \param[in] events       Struct containing flags of events to enable
498  */
slcd_enable_events(struct slcd_events * const events)499 static inline void slcd_enable_events(struct slcd_events *const events)
500 {
501 
502 	Assert(hw);
503 	Assert(events);
504 
505 	uint8_t event_mask = 0;
506 
507 	if (events->generate_event_on_fc0_overflow) {
508 		event_mask |= SLCD_EVCTRL_FC0OEO;
509 	}
510 
511 	if (events->generate_event_on_fc1_overflow) {
512 		event_mask |= SLCD_EVCTRL_FC1OEO;
513 	}
514 
515 	if (events->generate_event_on_fc2_overflow) {
516 		event_mask |= SLCD_EVCTRL_FC2OEO;
517 	}
518 
519 	SLCD->EVCTRL.reg |= event_mask;
520 }
521 
522 /**
523  * \brief Disables a SLCD event output
524  *
525  *  Disables one or more SLCD events output.
526  *
527  *  \param[in] events Struct containing flags of events to disable
528  */
slcd_disable_events(struct slcd_events * const events)529 static inline void slcd_disable_events(struct slcd_events *const events)
530 {
531 
532 	Assert(events);
533 
534 	uint8_t event_mask = 0;
535 
536 	if (events->generate_event_on_fc0_overflow) {
537 		event_mask |= SLCD_EVCTRL_FC0OEO;
538 	}
539 
540 	if (events->generate_event_on_fc1_overflow) {
541 		event_mask |= SLCD_EVCTRL_FC1OEO;
542 	}
543 
544 	if (events->generate_event_on_fc2_overflow) {
545 		event_mask |= SLCD_EVCTRL_FC2OEO;
546 	}
547 
548 	SLCD->EVCTRL.reg &= ~event_mask;
549 }
550 
551 /** @} */
552 
553 /**
554  * \name SLCD Frame Counter Functions
555  * @{
556  */
557 
558 /**
559  * \brief Frame counter configuration
560  *
561  *  Config frame counter.
562  *
563  *  \note Frame counter cannot be set while it is enabled.
564  *
565  *  \param[in] fc Frame counter index
566  *  \param[in] presc_bypass_enable Bypass of the frame counter prescaler
567  *  \param[in] overflow_value  Frame counter overflow value. The number of frame
568  *		before overflow is ((overflow_value+1)*8) when presc_bypass_enable=0
569  		else (overflow_value+1). The MAX. overflow value is 0x1FFFF.
570  */
slcd_set_frame_counter(enum slcd_frame_counter fc,bool presc_bypass_enable,uint16_t overflow_value)571 static inline void slcd_set_frame_counter(enum slcd_frame_counter fc,
572 										   bool  presc_bypass_enable,
573 										   uint16_t overflow_value)
574 {
575 	*(&(SLCD->FC0.reg) + fc) =  (presc_bypass_enable << SLCD_FC0_PB_Pos)
576 							 | SLCD_FC0_OVF(overflow_value);
577 }
578 
579 /**
580  * \brief Enables a frame counter
581  *
582  *  Enables one frame counter.
583  *
584  *	\param[in] fc Frame counter index
585  */
slcd_enable_frame_counter(enum slcd_frame_counter fc)586 static inline void slcd_enable_frame_counter(enum slcd_frame_counter fc)
587 {
588 
589 	switch(fc) {
590 		case SLCD_FRAME_COUNTER_0:
591 			SLCD->CTRLD.reg |= SLCD_CTRLD_FC0EN;
592 			break;
593 		case SLCD_FRAME_COUNTER_1:
594 			SLCD->CTRLD.reg |= SLCD_CTRLD_FC1EN;
595 			break;
596 		case SLCD_FRAME_COUNTER_2:
597 			SLCD->CTRLD.reg |= SLCD_CTRLD_FC2EN;
598 			break;
599 		default :
600 			break;
601 	}
602 	while (slcd_is_syncing()) {
603 		/* Wait for synchronization */
604 	}
605 }
606 
607 /**
608  * \brief Disable a frame counter.
609  *
610  *  Disable one frame counter.
611  *
612  *	\param[in] fc Frame counter index
613  */
slcd_disable_frame_counter(enum slcd_frame_counter fc)614 static inline void slcd_disable_frame_counter(enum slcd_frame_counter fc)
615 {
616 	switch(fc) {
617 		case SLCD_FRAME_COUNTER_0:
618 			SLCD->CTRLD.reg &= ~SLCD_CTRLD_FC0EN;
619 			break;
620 		case SLCD_FRAME_COUNTER_1:
621 			SLCD->CTRLD.reg &= ~SLCD_CTRLD_FC1EN;
622 			break;
623 		case SLCD_FRAME_COUNTER_2:
624 			SLCD->CTRLD.reg &= ~SLCD_CTRLD_FC2EN;
625 			break;
626 		default :
627 			break;
628 	}
629 	while (slcd_is_syncing()) {
630 		/* Wait for synchronization */
631 	}
632 }
633 /** @} */
634 
635 /**
636  * \name Display Memory Functions
637  * CPU can access display memory in direct access or in indirect access.
638  * @{
639  */
640 void slcd_set_display_memory(void);
641 void slcd_set_pixel(uint8_t pix_com, uint8_t pix_seg);
642 void slcd_clear_pixel(uint8_t pix_com, uint8_t pix_seg);
643 
644 void slcd_set_seg_data(uint8_t seg_data, uint8_t byte_offset, uint8_t seg_mask);
645 /** @} */
646 
647 /**
648  * \name Character Mapping Functions
649  * @{
650  */
651 
652 void slcd_character_map_set(
653 		enum slcd_automated_char_order order,
654 		uint8_t seg_line_num);
655 void slcd_character_write_data(uint8_t com_line_index,
656 							uint8_t seg_line_index,
657 							uint32_t seg_data,
658 							uint32_t data_mask);
659 
660 /**
661  * \brief Enables automated character display
662  *
663  *  Enables automated character display.
664  */
slcd_enable_automated_character(void)665 static inline void slcd_enable_automated_character(void)
666 {
667 	SLCD->CTRLC.reg |= SLCD_CTRLC_ACMEN;
668 }
669 
670 /**
671  * \brief Disables automated character display
672  *
673  *  Disables automated character display.
674  */
slcd_disable_automated_character(void)675 static inline void slcd_disable_automated_character(void)
676 {
677 	SLCD->CTRLC.reg &= ~SLCD_CTRLC_ACMEN;
678 }
679 void slcd_automated_char_get_config_default(
680 		struct slcd_automated_char_config *config);
681 enum status_code slcd_automated_char_set_config(
682 		struct slcd_automated_char_config *const config);
683 /** @} */
684 
685 /**
686  * \name Automated Bit Mapping Functions
687  * @{
688  */
689 
690 /**
691  * \brief Enables automated bit display
692  *
693  *  Enables automated bit display.
694  */
slcd_enable_automated_bit(void)695 static inline void slcd_enable_automated_bit(void)
696 {
697 	SLCD->CTRLC.reg |= SLCD_CTRLC_ABMEN;
698 }
699 
700 /**
701  * \brief Disables automated bit display
702  *
703  *  Disables automated bit display.
704  */
slcd_disable_automated_bit(void)705 static inline void slcd_disable_automated_bit(void)
706 {
707 	SLCD->CTRLC.reg &= ~SLCD_CTRLC_ABMEN;
708 }
709 
710 /**
711  * \brief Sets automated bit display
712  *
713  *  Sets automated bit display.
714  *
715  *  \note Automated bit cannot be set while it is enabled or busy.
716  */
slcd_set_automated_bit(uint8_t size,enum slcd_frame_counter fc)717 static inline void slcd_set_automated_bit(uint8_t size,enum slcd_frame_counter fc)
718 {
719 	if(size > 0 && size < 0x3f) {
720 		SLCD->ABMCFG.reg = SLCD_ABMCFG_SIZE(size) | SLCD_ABMCFG_FCS(fc);
721 	}
722 }
723 
724 /** @} */
725 
726 /**
727  * \name Autonomous Segment Animation
728  * @{
729  */
730 
731 /**
732  * \brief Enable SLCD circular shift mode
733  */
slcd_enable_circular_shift(void)734 static inline void slcd_enable_circular_shift(void)
735 {
736 	SLCD->CTRLD.reg |= SLCD_CTRLD_CSREN;
737 	while (slcd_is_syncing()) {
738 		/* Wait for synchronization */
739 	}
740 }
741 /**
742  * \brief Disable SLCD circular shift mode
743  */
slcd_disable_circular_shift(void)744 static inline void slcd_disable_circular_shift(void)
745 {
746 	SLCD->CTRLD.reg &= ~SLCD_CTRLD_CSREN;
747 	while (slcd_is_syncing()) {
748 		/* Wait for synchronization */
749 	}
750 }
751 void slcd_circular_shift_get_config_defaults(
752 		struct slcd_circular_shift_config *const config);
753 
754 enum status_code slcd_circular_shift_set_config(
755 		struct slcd_circular_shift_config *const config);
756 
757 /** @} */
758 
759 /**
760  * \name SLCD Status
761  * @{
762  */
763 
764 /**
765  * \brief Checks if auto bit mapping state machine is busy
766  *
767  * Checks if  auto bit mapping state machine is busy or not.
768  *
769  * \retval true   Auto bit mapping state machine is busy
770  * \retval false  Auto bit mapping state machine is idle
771  */
772 
slcd_get_auto_bit_status(void)773 static inline bool slcd_get_auto_bit_status(void)
774 {
775 	return ((SLCD->STATUS.reg & SLCD_STATUS_ABMBUSY) == SLCD_STATUS_ABMBUSY);
776 }
777 
778 /**
779  * \brief Checks if auto character mapping state machine is busy
780  *
781  * Checks if  auto character state machine is busy or not.
782  *
783  * \retval true   Auto character mapping state machine is busy
784  * \retval false  Auto character mapping state machine is idle
785  */
786 
slcd_get_auto_char_status(void)787 static inline bool slcd_get_auto_char_status(void)
788 {
789 	return ((SLCD->STATUS.reg & SLCD_STATUS_ACMBUSY) == SLCD_STATUS_ACMBUSY);
790 }
791 
792 /**
793  * \brief Checks if character writing function is busy
794  *
795  * Checksif character writing function is busy or not.
796  *
797  * \retval true   Character writting function is busy
798  * \retval false  Character writting function is ready for use
799  */
800 
slcd_get_char_writing_status(void)801 static inline bool slcd_get_char_writing_status(void)
802 {
803 	return ((SLCD->STATUS.reg & SLCD_STATUS_CMWRBUSY) == SLCD_STATUS_CMWRBUSY);
804 }
805 
806 /**
807  * \brief Checks VLCD and VDD33 status
808  *
809  * Checks VLCD and VDD33 status.
810  *
811  * \retval true   VDD33 is greater than target VLCD
812  * \retval false  Target VLCD is greater than vdd33
813  */
814 
slcd_get_vlcd_vdd33_status(void)815 static inline bool slcd_get_vlcd_vdd33_status(void)
816 {
817 	return ((SLCD->STATUS.reg & SLCD_STATUS_VLCDS) == SLCD_STATUS_VLCDS);
818 }
819 
820 /**
821  * \brief Checks LCD charge pump status
822  *
823  * Checks LCD Charge Pump Status.
824  *
825  * \retval true   LCD power charge pump is running
826  * \retval false  LCD power charge pump is stopped
827  */
828 
slcd_get_charge_pump_status(void)829 static inline bool slcd_get_charge_pump_status(void)
830 {
831 	return ((SLCD->STATUS.reg & SLCD_STATUS_PRUN) == SLCD_STATUS_PRUN);
832 }
833 
834 /**
835  * \brief Checks if VLCD  is ready
836  *
837  * Checks if VLCD is well regulated to the target value.
838  *
839  * \retval true   VLCD is well regulated to the target value
840  * \retval false  VLCD is not well regulated to the target value
841  */
842 
slcd_get_vlcd_ready_status(void)843 static inline bool slcd_get_vlcd_ready_status(void)
844 {
845 	return ((SLCD->STATUS.reg & SLCD_STATUS_VLCDR) == SLCD_STATUS_VLCDR);
846 }
847 
848 /** @} */
849 
850 #ifdef __cplusplus
851 }
852 #endif
853 
854 /** @} */
855 
856 /**
857  * \page asfdoc_sam0_drivers_slcd_extra Extra Information for SLCD
858  *
859  * \section asfdoc_sam0_drivers_slcd_extra_acronyms Acronyms
860  * Below is a table listing the acronyms used in this module, along with their
861  * intended meanings.
862  *
863  * <table>
864  *  <tr>
865  *      <th>Acronym</th>
866  *      <th>Definition</th>
867  *  </tr>
868  *  <tr>
869  *      <td>SLCD</td>
870  *      <td>Segment Liquid Crystal Display</td>
871  * </tr>
872  *  <tr>
873  *      <td>COM</td>
874  *      <td>Common, denotes how many segments are connected to a segment terminal</td>
875  * </tr>
876  *  <tr>
877  *      <td>SEG</td>
878  *      <td>Segment, the least viewing element (pixel) which can be on or off</td>
879  * </tr>
880  *  <tr>
881  *      <td>Duty</td>
882  *      <td> 1/(Number of common terminals on an actual LCD display)</td>
883  * </tr>
884  *  <tr>
885  *      <td>Bias</td>
886  *      <td>1/(Number of voltage levels used driving a LCD display -1)</td>
887  * </tr>
888  *  <tr>
889  *      <td>Frame Rate</td>
890  *      <td>Number of times the LCD segments are energized per second</td>
891  * </tr>
892  * </table>
893  *
894  *
895  * \section asfdoc_sam0_drivers_slcd_extra_dependencies Dependencies
896  * This driver has the following dependencies:
897  *
898  *  - None
899  *
900  *
901  * \section asfdoc_sam0_drivers_slcd_extra_errata Errata
902  * There are no errata related to this driver.
903  *
904  *
905  * \section asfdoc_sam0_drivers_slcd_extra_history Module History
906  * An overview of the module history is presented in the table below, with
907  * details on the enhancements and fixes made to the module since its first
908  * release. The current version of this corresponds to the newest version in
909  * the table.
910  *
911  * <table>
912  *	<tr>
913  *		<th>Changelog</th>
914  *	</tr>
915  *	<tr>
916  *		<td>Initial release</td>
917  *	</tr>
918  * </table>
919  */
920 
921 /**
922  * \page asfdoc_sam0_drivers_slcd_exqsg Examples for SLCD
923  *
924  * This is a list of the available Quick Start Guides (QSGs) and example
925  * applications for \ref asfdoc_sam0_drivers_slcd_group. QSGs are simple examples with
926  * step-by-step instructions to configure and use this driver in a selection of
927  * use cases. Note that a QSG can be compiled as a standalone application or be
928  * added to the user application.
929  *
930  *  - \subpage asfdoc_sam0_slcd_basic_use_case
931  *
932  * \page asfdoc_sam0_drivers_slcd_document_revision_history Document Revision History
933  *
934  * <table>
935  *	<tr>
936  *		<th>Doc. rev.</th>
937  *		<th>Date</th>
938  *		<th>Comments</th>
939  *	</tr>
940  *	<tr>
941  *      <td>42605A</td>
942  *		<td>12/2015</td>
943  *		<td>Initial release</td>
944  *	</tr>
945  * </table>
946  *
947  */
948 
949 #endif  /* SLCD_H_INCLUDED */
950