Contiki-NG
Loading...
Searching...
No Matches
ac-dimmer.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016, Zolertia - http://www.zolertia.com
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30/*---------------------------------------------------------------------------*/
31/**
32 * \addtogroup zoul-ac-dimmer
33 * @{
34 *
35 * \file
36 * Driver for the Krida Electronics AC light dimmer with zero-crossing, using
37 * a 50Hz frequency as reference (1/50Hz) ~20ms and 10ms half-cycle
38 */
39/*---------------------------------------------------------------------------*/
40#include "contiki.h"
41#include "ac-dimmer.h"
42#include "dev/gpio.h"
43#include "dev/gpio-hal.h"
44#include "lib/sensors.h"
45#include "dev/ioc.h"
46/*---------------------------------------------------------------------------*/
47#define DIMMER_SYNC_PORT_BASE GPIO_PORT_TO_BASE(DIMMER_SYNC_PORT)
48#define DIMMER_SYNC_PIN_MASK GPIO_PIN_MASK(DIMMER_SYNC_PIN)
49#define DIMMER_GATE_PORT_BASE GPIO_PORT_TO_BASE(DIMMER_GATE_PORT)
50#define DIMMER_GATE_PIN_MASK GPIO_PIN_MASK(DIMMER_GATE_PIN)
51/*---------------------------------------------------------------------------*/
52static uint8_t enabled;
53static uint8_t dimming;
54/*---------------------------------------------------------------------------*/
55PROCESS(ac_dimmer_int_process, "AC Dimmer zero-cross interrupt process");
56/*---------------------------------------------------------------------------*/
57PROCESS_THREAD(ac_dimmer_int_process, ev, data)
58{
61
62 int dimtime;
63
64 while(1) {
65 PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
66 dimtime = (uint8_t)(100 - dimming);
67 dimtime *= 100;
68
69 /* Off cycle */
70 clock_delay_usec(dimtime);
71 GPIO_SET_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK);
72 /* Triac on propagation delay */
73 clock_delay_usec(DIMMER_DEFAULT_GATE_PULSE_US);
74 GPIO_CLR_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK);
75 }
77}
78/*---------------------------------------------------------------------------*/
79static void
80dimmer_zero_cross_int_handler(gpio_hal_pin_mask_t pin_mask)
81{
82 process_poll(&ac_dimmer_int_process);
83}
84/*---------------------------------------------------------------------------*/
85static gpio_hal_event_handler_t dimmer_handler = {
86 .next = NULL,
87 .handler = dimmer_zero_cross_int_handler,
88 .pin_mask = gpio_hal_pin_to_mask(DIMMER_SYNC_PIN) << (DIMMER_SYNC_PORT << 3),
89};
90/*---------------------------------------------------------------------------*/
91static int
92status(int type)
93{
94 switch(type) {
95 case SENSORS_ACTIVE:
96 return dimming;
97 case SENSORS_READY:
98 return enabled;
99 }
100 return DIMMER_ERROR;
101}
102/*---------------------------------------------------------------------------*/
103static int
104value(int type)
105{
106 if(!enabled) {
107 return DIMMER_ERROR;
108 }
109
110 dimming = (uint8_t)type;
111 return DIMMER_SUCCESS;
112}
113/*---------------------------------------------------------------------------*/
114static int
115configure(int type, int value)
116{
117 if(type != SENSORS_ACTIVE) {
118 return DIMMER_ERROR;
119 }
120
121 if(value) {
122 /* This is the Triac's gate pin */
123 GPIO_SOFTWARE_CONTROL(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK);
124 GPIO_SET_OUTPUT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK);
125 ioc_set_over(DIMMER_GATE_PORT, DIMMER_GATE_PIN, IOC_OVERRIDE_OE);
126 GPIO_CLR_PIN(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK);
127
128 /* This is the zero-crossing pin and interrupt */
129 GPIO_SOFTWARE_CONTROL(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
130 GPIO_SET_INPUT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
131
132 /* Pull-up resistor, detect rising edge */
133 GPIO_DETECT_EDGE(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
134 GPIO_TRIGGER_SINGLE_EDGE(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
135 GPIO_DETECT_RISING(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
136 gpio_hal_register_handler(&dimmer_handler);
137
138 /* Spin process until an interrupt is received */
139 process_start(&ac_dimmer_int_process, NULL);
140
141 /* Enable interrupts */
142 GPIO_ENABLE_INTERRUPT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
143 // ioc_set_over(DIMMER_SYNC_PORT, DIMMER_SYNC_PIN, IOC_OVERRIDE_PUE);
144 NVIC_EnableIRQ(DIMMER_INT_VECTOR);
145
146 enabled = 1;
147 dimming = DIMMER_DEFAULT_START_VALUE;
148 return DIMMER_SUCCESS;
149 }
150
151 /* Disable interrupt and pins */
152
153 GPIO_DISABLE_INTERRUPT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
154 GPIO_SET_INPUT(DIMMER_GATE_PORT_BASE, DIMMER_GATE_PIN_MASK);
155 GPIO_SET_OUTPUT(DIMMER_SYNC_PORT_BASE, DIMMER_SYNC_PIN_MASK);
156 process_exit(&ac_dimmer_int_process);
157
158 enabled = 0;
159 dimming = 0;
160 return DIMMER_SUCCESS;
161}
162/*---------------------------------------------------------------------------*/
163SENSORS_SENSOR(ac_dimmer, AC_DIMMER_ACTUATOR, value, configure, status);
164/*---------------------------------------------------------------------------*/
165/** @} */
Header file for an AC light dimmer with zero-crossing driver.
Header file for the GPIO HAL.
Header file with register and macro declarations for the cc2538 GPIO module.
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
Definition clock.c:150
#define GPIO_SOFTWARE_CONTROL(PORT_BASE, PIN_MASK)
Configure the pin to be software controlled with PIN_MASK of port with PORT_BASE.
Definition gpio.h:258
#define GPIO_DISABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Disable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
Definition gpio.h:209
#define GPIO_SET_INPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to input.
Definition gpio.h:78
#define GPIO_DETECT_EDGE(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to detect edge.
Definition gpio.h:154
#define GPIO_SET_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE high.
Definition gpio.h:106
#define GPIO_DETECT_RISING(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to trigger an interrupt on rising edge.
Definition gpio.h:185
#define GPIO_CLR_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE low.
Definition gpio.h:113
#define GPIO_TRIGGER_SINGLE_EDGE(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to trigger an interrupt on single edge (controlled by G...
Definition gpio.h:177
#define GPIO_SET_OUTPUT(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE to output.
Definition gpio.h:85
#define GPIO_ENABLE_INTERRUPT(PORT_BASE, PIN_MASK)
Enable interrupt triggering for pins with PIN_MASK of port with PORT_BASE.
Definition gpio.h:201
#define IOC_OVERRIDE_OE
Output Enable.
Definition ioc.h:222
void ioc_set_over(uint8_t port, uint8_t pin, uint8_t over)
Set Port:Pin override function.
Definition ioc.c:54
void gpio_hal_register_handler(gpio_hal_event_handler_t *handler)
Register a function to be called whenever a pin triggers an event.
Definition gpio-hal.c:55
uint32_t gpio_hal_pin_mask_t
GPIO pin mask representation.
Definition gpio-hal.h:142
#define gpio_hal_pin_to_mask(pin)
Convert a pin to a pin mask.
Definition gpio-hal.h:255
#define PROCESS(name, strname)
Declare a process.
Definition process.h:307
#define PROCESS_EXITHANDLER(handler)
Specify an action when a process exits.
Definition process.h:254
void process_exit(struct process *p)
Cause a process to exit.
Definition process.c:212
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition process.h:120
#define PROCESS_END()
Define the end of a process.
Definition process.h:131
void process_start(struct process *p, process_data_t data)
Start a process.
Definition process.c:107
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition process.h:273
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition process.h:178
void process_poll(struct process *p)
Request a process to be polled.
Definition process.c:375
Header file with declarations for the I/O Control module.
Datatype for GPIO event handlers.
Definition gpio-hal.h:180