C++程序  |  131行  |  3.31 KB

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>

#include <eventnums.h>
#include <gpio.h>
#include <hostIntf.h>
#include <leds_gpio.h>
#include <nanohubPacket.h>
#include <sensors.h>
#include <seos.h>
#include <plat/gpio.h>
#include <plat/exti.h>
#include <plat/syscfg.h>
#include <variant/variant.h>

#define LEDS_GPIO_APP_ID	APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 20)
#define LEDS_GPIO_APP_VERSION	1

#define DBG_ENABLE		0

static struct LedsTask
{
    struct Gpio *led[LEDS_GPIO_MAX];
    uint32_t num;

    uint32_t id;
    uint32_t sHandle;
} mTask;

static bool sensorConfigLedsGpio(void *cfgData, void *buf)
{
    struct LedsCfg *lcfg = (struct LedsCfg *)cfgData;

    if (lcfg->led_num >= mTask.num) {
        osLog(LOG_INFO, "Wrong led number %"PRIu32"\n", lcfg->led_num);
        return false;
    }
    gpioSet(mTask.led[lcfg->led_num], lcfg->value ? 1 : 0);
    osLog(LOG_INFO, "Set led[%"PRIu32"]=%"PRIu32"\n", lcfg->led_num, lcfg->value);
    return true;
}

static bool sensorSelfTestLedsGpio(void *buf)
{
    uint32_t i;

    gpioSet(mTask.led[0], 1);
    for (i=1; i < mTask.num; i++) {
        gpioSet(mTask.led[i-1], 0);
        gpioSet(mTask.led[i], 1);
    }
    gpioSet(mTask.led[i-1], 0);
    return true;
}

static const struct SensorInfo sensorInfoLedsGpio = {
    .sensorName = "Leds-Gpio",
    .sensorType = SENS_TYPE_LEDS,
};

static const struct SensorOps sensorOpsLedsGpio = {
    .sensorCfgData = sensorConfigLedsGpio,
    .sensorSelfTest = sensorSelfTestLedsGpio,
};

static void handleEvent(uint32_t evtType, const void *evtData)
{
    switch (evtType) {
    case EVT_APP_START:
        osEventUnsubscribe(mTask.id, EVT_APP_START);
        /* Test leds */
        if (DBG_ENABLE)
            sensorSelfTest(mTask.sHandle);
        osLog(LOG_INFO, "[Leds-Gpio] detected\n");
        break;
    }
}

static bool startTask(uint32_t taskId)
{
    const struct LedsGpio *leds;
    struct Gpio *led;
    uint32_t i;

    mTask.id = taskId;
    mTask.num = 0;

    leds = ledsGpioBoardCfg();
    for (i=0; i < leds->num && i < LEDS_GPIO_MAX; i++) {
        led = gpioRequest(leds->leds_array[i]);
        if (!led)
            continue;
        mTask.led[mTask.num++] = led;
        gpioConfigOutput(led, GPIO_SPEED_LOW, GPIO_PULL_NONE, GPIO_OUT_PUSH_PULL, 0);
    }
    if (mTask.num == 0)
        return false;
    mTask.sHandle = sensorRegister(&sensorInfoLedsGpio, &sensorOpsLedsGpio, NULL, true);
    osEventSubscribe(taskId, EVT_APP_START);
    return true;
}

static void endTask(void)
{
    uint32_t i;

    sensorUnregister(mTask.sHandle);
    for (i=0; i < mTask.num; i++) {
        gpioSet(mTask.led[i], 0);
        gpioRelease(mTask.led[i]);
    }
}

INTERNAL_APP_INIT(LEDS_GPIO_APP_ID, LEDS_GPIO_APP_VERSION, startTask, endTask, handleEvent);