1 /**
2  *
3  * \file
4  *
5  * \brief SAM Segment Liquid Crystal Display(SLCD) Controller.
6  *
7  * Copyright (c) 2015 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 #include "slcd.h"
49 #include "slcd_callback.h"
50 
51 /**
52 * \internal
53 * \brief slcd callback function pointer
54 */
55 slcd_callback_t slcd_callback_pointer[SLCD_CALLBACK_TYPE_NUM];
56 
57 
58 /**
59  * \brief Registers a callback
60  *
61  * Registers a callback function which is implemented by the user.
62  *
63  * \note The callback must be enabled by \ref slcd_enable_callback,
64  * in order for the interrupt handler to call it when the conditions for the
65  * callback type is met.
66  *
67  * \param[in]     callback_func Pointer to callback function
68  * \param[in]     callback_type Callback type given by an enum
69  *
70  * \retval STATUS_OK  The function exited successfully
71  * \retval STATUS_ERR_INVALID_ARG  If an invalid callback type was supplied
72  */
73 
slcd_register_callback(const slcd_callback_t callback,const enum slcd_callback_type type)74 enum status_code slcd_register_callback(
75 	const slcd_callback_t callback,
76 	const enum slcd_callback_type type)
77 {
78 	if (type >= SLCD_CALLBACK_TYPE_NUM){
79 		return STATUS_ERR_INVALID_ARG;
80 	}
81 
82 	slcd_callback_pointer[type] = callback;
83 	return STATUS_OK;
84 }
85 
86 /**
87  * \brief Unregisters a callback
88  *
89  * Unregisters a callback function implemented by the user.
90  *
91  * \param[in]  callback_type Callback type given by an enum
92  *
93  * \retval STATUS_OK  The function exited successfully
94  * \retval STATUS_ERR_INVALID_ARG  If an invalid callback type was supplied
95  */
96 
slcd_unregister_callback(const slcd_callback_t callback,const enum slcd_callback_type type)97 enum status_code slcd_unregister_callback(
98 	const slcd_callback_t callback,
99 	const enum slcd_callback_type type)
100 {
101 	if (type >= SLCD_CALLBACK_TYPE_NUM){
102 		return STATUS_ERR_INVALID_ARG;
103 	}
104 
105 	slcd_callback_pointer[type] = NULL;
106 	return STATUS_OK;
107 }
108 
109 /**
110 * \internal The SLCD interrupt handler.
111 */
SLCD_Handler(void)112 void SLCD_Handler(void)
113 {
114 	uint32_t status = SLCD->INTFLAG.reg;
115 	for (uint8_t i = 0; i < SLCD_CALLBACK_TYPE_NUM; i++) {
116 		if (status & (1 << i)) {
117 			/* Clear the INTFLAG anyway */
118 			SLCD->INTFLAG.reg = 1 << i;
119 
120 			if (slcd_callback_pointer[i]) {
121 				slcd_callback_pointer[i]((enum slcd_callback_type)i);
122 			}
123 		}
124 	}
125 }
126