diff --git a/CompleteApps/AstronautsGame/README_zh.md b/CompleteApps/AstronautsGame/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..2997f19eb5d446e24f1995016cb2e46547951bb5 --- /dev/null +++ b/CompleteApps/AstronautsGame/README_zh.md @@ -0,0 +1,60 @@ + + +# 太空人避障游戏代码介绍 + +### 简介 +本Sample是基于OpenHarmony轻量级系统,利用内核的实时性和丰富的外设拓展功能,运行在Hi3861 WLAN模组上的应用游戏。 + + +### 使用说明 + +##### 1. 编译步骤 + +1)拷贝本Sample目录下的common、astronauts_game 文件夹到OpenHarmony 系统源码中的applications/sample/wifi-iot/app目录下。 + +2) 修改applications/sample/wifi-iot/app/BUILD.gn 文件,在features字段中增加索引,使目标模块参与编译。features字段指定业务模块的路径和目标,具体配置如下。 + +``` + import("//build/lite/config/component/lite_component.gni") + + lite_component("app") { + features = [ + "astronauts_game", + ] + deps = [ "//applications/sample/wifi-iot/app/common/hals:hals" ] +} + +``` +3)修改hi3861 内核配置文件 + +​ 打开 device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk 文件 + +​ 将 CONFIG_I2C_SUPPORT is not set这一行, 改为CONFIG_I2C_SUPPORT=y + +​ 将 CONFIG_PWM_SUPPORT is not set这一行, 改为CONFIG_PWM_SUPPORT=y + +4) 代码编译和烧录请参考:[链接](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-connection.md) + +##### 2. 游戏玩法如下 + +1)上电后进入游戏初始界面,按下开发板中的user按键开始游戏。 + +2)使用OLED拓展板上的按键1、按键2左右移动来躲避随机落下的障碍物。 + +3) 屏幕右上角会记录得分,难度会随着分数的增加而提高。 + +4)如果碰撞到障碍物和OLED屏左右末端,则游戏结束。 + +5)按下user按键重新开始游戏。 + + + +### 约束限制 + +硬件:HiSpark Wi-Fi IoT 开发套件(本sample会用到 主控板、OLED拓展板、带蜂鸣器的拓展板) + +软件:OpenHarmony 2.0 Canary版本。[链接](https://device.harmonyos.com/cn/docs/start/get-code/sourcecode-acquire-0000001050769927) + +想获取更多的OpenHarmony轻量级开发指导,请访问:[链接](https://device.harmonyos.com/cn/docs/start/introduce/quickstart-lite-overview-0000001105598722) + +开发工具下载:[链接](https://device.harmnyos.com/cn/ide) \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/BUILD.gn b/CompleteApps/AstronautsGame/astronauts_game/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..41349bdf33d3d78d1acf5b6486ba8f3c9304673b --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +static_library("astronauts_game") { + sources = [ + "src/game_logic.c", + "src/button.c", + "src/common_init.c", + "src/main.c", + "src/oled.c", + "src/music.c" + ] + + include_dirs = [ + "//utils/native/lite/include", + "//kernel/liteos_m/components/cmsis/2.0", + "//base/iot_hardware/peripheral/interfaces/kits", + "//applications/sample/wifi-iot/app/common/include", + "//applications/sample/wifi-iot/app/astronauts_game/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/include" + ] +} diff --git a/CompleteApps/AstronautsGame/astronauts_game/include/button.h b/CompleteApps/AstronautsGame/astronauts_game/include/button.h new file mode 100644 index 0000000000000000000000000000000000000000..dfa57e03976baaf629982fb657265f5b0c8ddf94 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/include/button.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef BUTTON_H +#define BUTTON_H + +#include "ohos_types.h" + +typedef enum { + ADC_USR_MIN = 5, + ADC_USR_MAX = 228, + ADC_S1_MIN, + ADC_S1_MAX = 512, + ADC_S2_MIN, + ADC_S2_MAX = 854 +}AdcValue; + +typedef enum { + SSU_NONE, + SSU_USER, + SSU_S1, + SSU_S2 +}KeyCode; + +typedef void (*KeyEventCallback)(uint32 key); + +/** + * @brief Setting the param of button gpio. + * + * @since 1.0 + * @version 1.0 + */ +void ButtonInit(void); + +/** + * @brief Register the buttion interrupt. + * + * @param eventCall + * @since 1.0 + * @version 1.0 + */ +void RegButtonIrq(KeyEventCallback eventCall); +#endif // BUTTON_H diff --git a/CompleteApps/AstronautsGame/astronauts_game/include/code_tab.h b/CompleteApps/AstronautsGame/astronauts_game/include/code_tab.h new file mode 100644 index 0000000000000000000000000000000000000000..e4e3cc024eba05f1607ad84b2f5ed79aea699459 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/include/code_tab.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef CODE_TAB_H +#define CODE_TAB_H + +#include "ohos_types.h" + +const uint16 Font7x10 [] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ! + 0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " + 0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // # + 0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $ + 0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // % + 0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // & + 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' + 0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // ( + 0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // ) + 0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * + 0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // + + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // , + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // - + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // . + 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // / + 0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0 + 0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1 + 0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2 + 0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3 + 0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4 + 0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5 + 0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6 + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7 + 0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8 + 0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9 + 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // : + 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ; + 0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // < + 0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // = + 0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // > + 0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ? + 0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @ + 0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A + 0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B + 0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C + 0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D + 0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E + 0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F + 0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G + 0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H + 0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I + 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J + 0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L + 0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M + 0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P + 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q + 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R + 0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S + 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T + 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U + 0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V + 0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W + 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X + 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y + 0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z + 0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [ + 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */ + 0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ] + 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _ + 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` + 0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b + 0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c + 0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d + 0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e + 0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g + 0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i + 0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j + 0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k + 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l + 0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n + 0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o + 0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p + 0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q + 0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r + 0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s + 0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t + 0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v + 0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w + 0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x + 0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y + 0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z + 0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // { + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // | + 0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // } + 0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +#endif // CODE_TAB_H \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/include/common_init.h b/CompleteApps/AstronautsGame/astronauts_game/include/common_init.h new file mode 100644 index 0000000000000000000000000000000000000000..b5edc5906ed59f9c772f68eb26c7a9f4504a56df --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/include/common_init.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef COMMON_INIT_H +#define COMMON_INIT_H + +#include +#include "ohos_init.h" +#include "cmsis_os2.h" +#include "securec.h" +#include "ohos_types.h" +#include "iot_gpio.h" +#include "iot_errno.h" +#include "iot_i2c.h" + +/** + * @brief Init the device. Include the button 、Oled. + * + * @since 1.0 + * @version 1.0 + */ +void DeviceInit(void); + +#endif /* COMMON_INIT_H */ diff --git a/CompleteApps/AstronautsGame/astronauts_game/include/game_logic.h b/CompleteApps/AstronautsGame/astronauts_game/include/game_logic.h new file mode 100644 index 0000000000000000000000000000000000000000..8597770e258fa274782e0eab5bc4c33c26a71625 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/include/game_logic.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef GAME_LOGIC_H +#define GAME_LOGIC_H + +#include "ohos_types.h" + +typedef enum { + OBSTACLE_1, + OBSTACLE_2, + OBSTACLE_3 +}OBSTACLE_ID; + +void GameStart(void); + +int GameLoop(void); + +void DrawGameScreen(void); + +void GameOver(void); + +void AstronautMove(uint32 flag); + +void RefreshGameDifficulty(void); +#endif // GAME_LOGIC_H \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/include/main.h b/CompleteApps/AstronautsGame/astronauts_game/include/main.h new file mode 100644 index 0000000000000000000000000000000000000000..e1c0abe83f6aeb605dfc4d07e7fb681dcbd56891 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/include/main.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef MAIN_H +#define MAIN_H + +#define OLED_MODE 0 +#define SIZE 8 +#define X_Level_L 0x00 +#define X_Level_H 0x10 +#define MAX_COLUMN 128 +#define MAX_ROW 64 +#define BRIGHTNESS 0xFF +#define X_WIDTH 128 +#define Y_WIDTH 64 +#define OLED_CMD 0 // 写命令 +#define OLED_DATA 1 // 写数据 + +#define DELAY_TIMES_OF_GAME_PENDING 300 +#define DELAY_TIMES_OF_GAME_SCRREN_REFLASH 100 +#define MAIN_TASK_STACK_SIZE (1024*10) +#define MOVE_LEFT 0 +#define MOVE_RIGHT 1 + +#endif // MAIN_H \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/include/music.h b/CompleteApps/AstronautsGame/astronauts_game/include/music.h new file mode 100644 index 0000000000000000000000000000000000000000..468f20baf74c180092e9c172fa8ba8244e8aa36b --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/include/music.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef MUSIC_H +#define MUSIC_H + +void StartBeepMusicTask(void); + +void SetupMusicPlaybackFlag(bool flag); + +#endif // MUSIC_H \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/include/oled.h b/CompleteApps/AstronautsGame/astronauts_game/include/oled.h new file mode 100644 index 0000000000000000000000000000000000000000..391f90e77a5e5a096f27ac5de638f24e5bd0fc43 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/include/oled.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef OLED_H +#define OLED_H + +#include "ohos_types.h" + +#define SSD1306_I2C_ADDR (0x3C << 1) + +// SSD1306 OLED height in pixels +#ifndef SSD1306_HEIGHT +#define SSD1306_HEIGHT 64 +#endif + +// SSD1306 width in pixels +#ifndef SSD1306_WIDTH +#define SSD1306_WIDTH 128 +#endif + +#ifndef SSD1306_BUFFER_SIZE +#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT / 8) +#endif + +// Enumeration for screen colors +typedef enum { + Black = 0x00, // Black color, no pixel + White = 0x01 // Pixel is set. Color depends on OLED +} SSD1306_COLOR; +// Struct to store transformations + +typedef struct { + const uint8 FontWidth; /*!< Font width in pixels */ + uint8 FontHeight; /*!< Font height in pixels */ + const uint16 *data; /*!< Pointer to data font data array */ +} FontDef; + +typedef struct { + uint16 CurrentX; + uint16 CurrentY; + uint8 Inverted; + uint8 Initialized; + uint8 DisplayOn; +} SSD1306_t; + +typedef struct { + uint8 x; + uint8 y; +} SSD1306_VERTEX; + +void OledInit(void); + +void HAL_Delay(uint32 ms); +void ssd1306_Init(void); +void ssd1306_Fill(SSD1306_COLOR color); +void ssd1306_SetCursor(uint8 x, uint8 y); +void ssd1306_UpdateScreen(void); + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color); +char ssd1306_DrawString(char* str, uint32 size, SSD1306_COLOR color); + +void ssd1306_DrawPixel(uint8 x, uint8 y, SSD1306_COLOR color); +void ssd1306_DrawLine(uint8 x1, uint8 y1, uint8 x2, uint8 y2, SSD1306_COLOR color); +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16 par_size, SSD1306_COLOR color); +void ssd1306_DrawRectangle(uint8 x1, uint8 y1, uint8 x2, uint8 y2, SSD1306_COLOR color); +void ssd1306_DrawArc(uint8 x, uint8 y, uint8 radius, uint16 start_angle, uint16 sweep, SSD1306_COLOR color); +void ssd1306_DrawCircle(uint8 par_x, uint8 par_y, uint8 par_r, SSD1306_COLOR color); +void ssd1306_DrawBitmap(const uint8* bitmap, uint32 size); +void ssd1306_DrawBitmapAtPosition(const uint8* bitmap, uint8 width, uint8 height, int8 xo, int8 yo); + +#endif // OLED_H \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/src/button.c b/CompleteApps/AstronautsGame/astronauts_game/src/button.c new file mode 100644 index 0000000000000000000000000000000000000000..e71dc43f2bdb9ee9aeef1997da4963b219881167 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/src/button.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "cmsis_os2.h" +#include "button.h" +#include "common_log.h" +#include "peripheral_hal.h" + +#define BUTTON_TASK_STAK_SIZE (1024*4) +#define BUTTON_TASK_PRIORITY 24 +#define DELAY_200_MS 20 + +static KeyEventCallback g_buttonCallback = NULL; +void ButtonTask(void* arg) +{ + unsigned short data = 0; + int ret = SSU_NONE; + + while (1) { + if (HalAdcRead(HAL_WIFI_IOT_ADC_CHANNEL_2, &data, HAL_WIFI_IOT_ADC_EQU_MODEL_4, HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0) == 0) { + if ((ADC_USR_MIN <= data) && (data <= ADC_USR_MAX)) ret = SSU_USER; + if ((ADC_S1_MIN <= data) && (data <= ADC_S1_MAX)) ret = SSU_S1; + if ((ADC_S2_MIN <= data) && (data <= ADC_S2_MAX)) ret = SSU_S2; + } + if (ret != SSU_NONE) { + g_buttonCallback(ret); + ret = SSU_NONE; + } + osDelay(DELAY_200_MS); + } + return ret; +} + +void RegButtonIrq(KeyEventCallback buttonCallback) +{ + g_buttonCallback = buttonCallback; + osThreadAttr_t attr = {0}; + attr.name = (char*)"buttontask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = BUTTON_TASK_STAK_SIZE; + attr.priority = BUTTON_TASK_PRIORITY; + if (osThreadNew((osThreadFunc_t)ButtonTask, NULL, &attr) == NULL) { + LOG_E("Failed to create ControlSysTask !\n"); + } + return 0; +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/src/common_init.c b/CompleteApps/AstronautsGame/astronauts_game/src/common_init.c new file mode 100644 index 0000000000000000000000000000000000000000..7155c5bfe7d0cf6c9f031f9a7bfffa6fee9f3686 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/src/common_init.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "button.h" +#include "common_init.h" +#include "oled.h" +#include "common_log.h" +#include "peripheral_hal.h" + +#define I2C_IDX_BAUDRATE (400000) +#define WIFI_IOT_OLED_I2C_IDX_0 0 +#define WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA 6 +#define WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL 6 + +static void I2cBusInit(void) +{ + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_13); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA); // Set up the gpio funcion as i2c + + IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_14); + HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL); + IoTI2cInit(WIFI_IOT_OLED_I2C_IDX_0, I2C_IDX_BAUDRATE); // Rate: 400kbps + LOG_I("I2C0 bus init success !\n"); +} + +void DeviceInit(void) +{ + I2cBusInit(); + OledInit(); + LOG_I("Device init success !\n"); +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/src/game_logic.c b/CompleteApps/AstronautsGame/astronauts_game/src/game_logic.c new file mode 100644 index 0000000000000000000000000000000000000000..7939faca8744daaad045aa87e031cd8e46b1700a --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/src/game_logic.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include +#include +#include "game_logic.h" +#include "oled.h" +#include "common_log.h" + +typedef struct obstacleAttr { + short X; + short Y; + short width; + short height; + _Bool Inverse; // 0 障碍物在 右半边,1 障碍物在 左半边 +} ObstacleAttr; + +static const unsigned char g_bitmapAstronauts[] = { + 0x07, 0xE0, 0x0C, 0x30, + 0x13, 0xC8, 0x24, 0x24, + 0x68, 0x16, 0x5F, 0xFA, + 0x50, 0x0A, 0x50, 0x0A, + 0x5F, 0xFA, 0x68, 0x16, + 0x24, 0x24, 0x13, 0xC8, + 0x3C, 0x3C, 0x77, 0xEE, + 0x51, 0x8A, 0x52, 0x4A, + 0x72, 0x4E, 0x51, 0x8A, + 0x70, 0x0E, 0x13, 0xC8, + 0x12, 0x48, 0x1E, 0x78, + 0x12, 0x48, 0x1E, 0x78 +}; + +static const unsigned char g_bitmapObstacle1[] = { + 0x00, 0x00, 0x00, 0x00, + 0x03, 0xC0, 0x03, 0xC0, + 0x07, 0xE0, 0x07, 0xE0, + 0x0F, 0xF0, 0x0F, 0xF0, + 0x1F, 0xF8, 0x1F, 0xF8, + 0x3F, 0xFC, 0x3F, 0xFC, + 0x7F, 0xFE, 0x7F, 0xFE, + 0x3F, 0xFC, 0x00, 0x00 +}; + +static const unsigned char g_bitmapObstacle2[] = { + 0x0F, 0xF0, 0x3F, 0xFC, + 0x7F, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0x7F, 0xFE, + 0x3F, 0xFC, 0x0F, 0xF0 +}; + +static const unsigned char g_bitmapObstacle3[] = { + 0x07, 0xE0, 0x1F, 0xF8, + 0x3F, 0xFC, 0x7F, 0xFE, + 0x7F, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x7F, 0xFE, + 0x7F, 0xFE, 0x3F, 0xFC, + 0x1F, 0xF8, 0x07, 0xE0 +}; + +#define ASTRONAUTS_WIDTH 16 +#define ASTRONAUTS_HEIGHT 24 +#define ASTRONAUTS_DOWN_MARGIN 0 +#define OBSTACLE_INTERVAL 40 + +#define PIPES_COUNT 3 +#define ASTRONAUTS_INIT_POSITION_X 52 +#define ASTRONAUTS_INIT_POSITION_Y 40 +#define INIT_MOVE_SPEED_Y 1 +#define INIT_MOVE_SPEED_X 2 +#define OLED_WIDTH_DIVIDENDS 2 +#define X_POSITION_SHOW_GAME_OVER 10 +#define Y_POSITION_SHOW_GAME_OVER 20 +#define SPEED_LEVLE_1 1 +#define SPEED_LEVLE_2 2 +#define FLY_DISTANCE_TAG_1 50 +#define FLY_DISTANCE_TAG_2 200 + +static uint8 g_game_difficulty_flag = 0; +static uint8 g_isStarted = 0; +static short g_astronautsPositionX = ASTRONAUTS_INIT_POSITION_X; +static float g_moveSpeedY = INIT_MOVE_SPEED_Y; +static float g_moveSpeedX = INIT_MOVE_SPEED_X; +static uint32 g_flyDistance = 0; + +static ObstacleAttr g_obstacles[PIPES_COUNT]; + +static short g_obstacleParm [3][2] = { + {16, 16}, + {16, 8}, + {16, 14} +}; + +void SetRandPosition(ObstacleAttr *obstacle) +{ + if (obstacle->Inverse == 0) { + obstacle->X = (SSD1306_WIDTH / OLED_WIDTH_DIVIDENDS + + rand() % ((SSD1306_WIDTH / OLED_WIDTH_DIVIDENDS) - ASTRONAUTS_WIDTH)) - 1; + } else { + obstacle->X = (rand() % (SSD1306_WIDTH / OLED_WIDTH_DIVIDENDS)) + 1; // 随机数对64取余 + } +} + +void GameInit(void) +{ + srand((unsigned)time(NULL)); // 用当前时间,设置种子 + for (short i = 0; i < PIPES_COUNT; i++) { + g_obstacles[i].Y = -(i * OBSTACLE_INTERVAL); + g_obstacles[i].Inverse = i % OLED_WIDTH_DIVIDENDS; // 0, 1, 0, 1, 左右 半个区域内 + g_obstacles[i].width = g_obstacleParm[i][0]; + g_obstacles[i].height = g_obstacleParm[i][1]; + SetRandPosition(&g_obstacles[i]); // 设置障碍物X轴上的随机位置 + } + g_astronautsPositionX = ASTRONAUTS_INIT_POSITION_X; // 太空人在X轴上的初始位置 + g_flyDistance = 0; // 飞行距离 +} + +void GenerateObstacle(ObstacleAttr *obstacle) +{ + obstacle->Y = -(OBSTACLE_INTERVAL * (PIPES_COUNT - 1)); // 起始地址为-120 + SetRandPosition(obstacle); +} + +void GameStart(void) +{ + GameInit(); + g_isStarted = 1; +} + +int IsCollision(void) +{ + if (g_astronautsPositionX < 0 || g_astronautsPositionX > SSD1306_WIDTH - ASTRONAUTS_WIDTH) return 1; // 碰触边界 + for (int i = 0; i < PIPES_COUNT; i++) { + if (((g_obstacles[i].Y) % SSD1306_WIDTH < SSD1306_HEIGHT) && // 在此条件下,才能发生碰撞 + ((g_obstacles[i].Y) % SSD1306_WIDTH > SSD1306_HEIGHT - ASTRONAUTS_HEIGHT - g_obstacles[i].height)) { + if ((g_astronautsPositionX > g_obstacles[i].X + g_obstacles[i].width) || + (g_astronautsPositionX < g_obstacles[i].X - ASTRONAUTS_WIDTH)) { // 非碰触情景 + return 0; + } else { + return 1; + } + } + } + return 0; +} + +void GameOver(void) +{ + g_isStarted = 0; + ssd1306_SetCursor(X_POSITION_SHOW_GAME_OVER, Y_POSITION_SHOW_GAME_OVER); + ssd1306_DrawString("== GAME OVER ==", sizeof("== GAME OVER =="), White); + ssd1306_UpdateScreen(); + g_moveSpeedY = INIT_MOVE_SPEED_Y; + g_moveSpeedX = INIT_MOVE_SPEED_X; +} + +void RefreshGameDifficulty(void) +{ + if (g_game_difficulty_flag != SPEED_LEVLE_1) { + if ((g_flyDistance > FLY_DISTANCE_TAG_1) && (g_flyDistance < FLY_DISTANCE_TAG_2)) { + g_game_difficulty_flag = SPEED_LEVLE_1; + g_moveSpeedY += SPEED_LEVLE_1; + g_moveSpeedX += SPEED_LEVLE_1; + } + } else if (g_game_difficulty_flag != SPEED_LEVLE_2) { + if (g_flyDistance > FLY_DISTANCE_TAG_2) { + g_game_difficulty_flag = SPEED_LEVLE_2; + g_moveSpeedY += SPEED_LEVLE_2; + g_moveSpeedX += SPEED_LEVLE_2; + } + } +} + +int GameLoop(void) +{ + if (g_isStarted) { + g_flyDistance += g_moveSpeedY; // 统计飞行总距离,用来计算得分 + for (short i = 0; i < PIPES_COUNT; i++) { + g_obstacles[i].Y += g_moveSpeedY; // 刷新障碍物的Y轴坐标 + if (g_obstacles[i].Y > SSD1306_HEIGHT) { + GenerateObstacle(&g_obstacles[i]); // 重新生成障碍参数 + } + } + + if (IsCollision()) { // 判断是否发生了碰撞 + LOG_I("=====Collision!!!======"); + return 1; + } else { + return 0; + } + } + return 0; +} + +void DrawObstacle(int x, ObstacleAttr obstacles) +{ + if (x > SSD1306_WIDTH) return; + + switch (x) { + case OBSTACLE_1: + ssd1306_DrawBitmapAtPosition(g_bitmapObstacle1, obstacles.width, + obstacles.height, obstacles.X, obstacles.Y); + break; + case OBSTACLE_2: + ssd1306_DrawBitmapAtPosition(g_bitmapObstacle2, obstacles.width, + obstacles.height, obstacles.X, obstacles.Y); + break; + case OBSTACLE_3: + ssd1306_DrawBitmapAtPosition(g_bitmapObstacle3, obstacles.width, + obstacles.height, obstacles.X, obstacles.Y); + break; + default: + break; + } +} + +void AstronautMove(uint32 flag) +{ + if (flag == 0) { + g_astronautsPositionX -= g_moveSpeedX; // move left + } else { + g_astronautsPositionX += g_moveSpeedX; // move right + } +} + +#define SCORE_CONVERSION_PARM 10 +#define SCORE_SHOW_PARM 30 +#define EDGE_OF_OLED_X 127 +#define EDGE_OF_OLED_Y 63 + +void DrawGameScreen(void) +{ + ssd1306_DrawBitmapAtPosition(g_bitmapAstronauts, ASTRONAUTS_WIDTH, + ASTRONAUTS_HEIGHT, g_astronautsPositionX, ASTRONAUTS_INIT_POSITION_Y); + for (short i = 0; i < PIPES_COUNT; i++) { + DrawObstacle(i, g_obstacles[i]); + } + + char buf[5]; + if (sprintf_s(buf, sizeof(buf), "%d", g_flyDistance / SCORE_CONVERSION_PARM) == -1) { + LOG_E("setting the game score failed !\n"); + } + ssd1306_SetCursor(SSD1306_WIDTH - SCORE_SHOW_PARM, 1); + ssd1306_DrawString(buf, sizeof(buf), White); + + ssd1306_DrawLine(0, 0, 0, EDGE_OF_OLED_Y, White); + ssd1306_DrawLine(EDGE_OF_OLED_X, 0, EDGE_OF_OLED_X, EDGE_OF_OLED_Y, White); + ssd1306_UpdateScreen(); +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/src/main.c b/CompleteApps/AstronautsGame/astronauts_game/src/main.c new file mode 100644 index 0000000000000000000000000000000000000000..05fef30af5006972700ef5f19b4759b5762ad5e6 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/src/main.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include "stdio.h" +#include "ohos_init.h" +#include "cmsis_os2.h" + +#include "main.h" +#include "button.h" +#include "game_logic.h" +#include "common_init.h" +#include "common_log.h" +#include "oled.h" +#include "music.h" + +#include "ohos_types.h" +#include "iot_gpio.h" +#include "iot_watchdog.h" +#include "iot_errno.h" +#include "peripheral_hal.h" + +static int g_gameRunningStatus = 0; + +void Button_Callback(uint32 event) +{ + LOG_I("[Button] Button_Callback() : %d\n", event); + if (event == SSU_S1) { + AstronautMove(MOVE_LEFT); // press S1, move left + } else if (event == SSU_S2) { + AstronautMove(MOVE_RIGHT); // press S2, move right + } else if (event == SSU_USER) { + g_gameRunningStatus = 1; // game start + } else { + LOG_I("The useless button_callback! \n"); + } +} + +void GameTask(void* arg) +{ + (void)arg; + IoTWatchDogDisable(); + DeviceInit(); + RegButtonIrq(Button_Callback); + StartBeepMusicTask(); + + while (!g_gameRunningStatus) { + HAL_Delay(DELAY_TIMES_OF_GAME_PENDING); // Waiting game start + } + + GameStart(); + SetupMusicPlaybackFlag(true); + while (1) { + int isCollision = GameLoop(); + RefreshGameDifficulty(); + + ssd1306_Fill(Black); + DrawGameScreen(); + HAL_Delay(DELAY_TIMES_OF_GAME_SCRREN_REFLASH); // Free system resources + + if (isCollision) { + SetupMusicPlaybackFlag(true); + GameOver(); + g_gameRunningStatus = 0; + + while (!g_gameRunningStatus) { + HAL_Delay(DELAY_TIMES_OF_GAME_PENDING); + } + GameStart(); + SetupMusicPlaybackFlag(true); + } + } +} + +void AstronautsAvoidObstaclesGame(void) +{ + osThreadAttr_t attr; + + attr.name = "GameTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = MAIN_TASK_STACK_SIZE; + attr.priority = osPriorityNormal; + + if (osThreadNew(GameTask, NULL, &attr) == NULL) { + LOG_E("[Game] Falied to create GameTask!\n"); + } +} + +SYS_RUN(AstronautsAvoidObstaclesGame); \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/src/music.c b/CompleteApps/AstronautsGame/astronauts_game/src/music.c new file mode 100644 index 0000000000000000000000000000000000000000..13ec7f68ad4659c598389c8ef2da3a80b5efa429 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/src/music.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include + +#include "cmsis_os2.h" +#include "hi_pwm.h" +#include "common_log.h" + +#include "ohos_types.h" +#include "peripheral_hal.h" +#include "iot_gpio.h" +#include "iot_pwm.h" +#include "iot_errno.h" + +#define MUSIC_STACK_TASK_SIZE 1024 +#define WIFI_IOT_PWM_PORT_PWM0 0 +#define WIFI_IOT_IO_FUNC_GPIO_9_PWM0_OUT 5 +#define TIMES_OF_MUSICAL_NOTE_INTERVAL (125*1000) +#define THE_MULTIPLIER_OF_PWM_DUTY 0.5 +#define THE_TIMES_OF_RELEASE_CPU_RESOURCE (1000*1000) + +static bool music_playback_flag = false; + +static const uint16 g_tuneFreqs[] = { + 0, + 38223, // 1046.5 C + 34052, // 1174.7 D + 30338, // 1318.5 E + 28635, // 1396.9 F + 25511, // 1568 G + 22728, // 1760 A + 20249, // 1975.5 B + 19048 // Raise an octave of C +}; + +static const uint8 g_scoreNotes[] = { + 7, 4, 7, 4, +}; + +static const uint8 g_scoreDurations[] = { + 2, 2, 2, 2, +}; + +void PlaybackMusicSample(void) +{ + for (size_t i = 0; i < sizeof(g_scoreNotes) / sizeof(g_scoreNotes[0]); i++) { + uint32 tune = g_scoreNotes[i]; + uint16 freqDivisor = g_tuneFreqs[tune]; + uint32 tuneInterval = g_scoreDurations[i] * (TIMES_OF_MUSICAL_NOTE_INTERVAL); + HalPwmStart(WIFI_IOT_PWM_PORT_PWM0, freqDivisor * THE_MULTIPLIER_OF_PWM_DUTY, freqDivisor); // music playback + usleep(tuneInterval); + IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); // Turn off this tone play + } +} + +void SetupMusicPlaybackFlag(bool flag) +{ + music_playback_flag = flag; +} + +static void *BeeperMusicTask(const char *arg) +{ + (void)arg; + + LOG_D("BeeperMusicTask start!\r\n"); + hi_pwm_set_clock(PWM_CLK_XTAL); // Set the clock source as crystal clock 40Mhz + + while (1) { + if (music_playback_flag == true) { + PlaybackMusicSample(); + music_playback_flag = false; + } + usleep(THE_TIMES_OF_RELEASE_CPU_RESOURCE); + } + return NULL; +} + +void StartBeepMusicTask(void) +{ + osThreadAttr_t attr; + if (IoTGpioInit(HAL_WIFI_IOT_IO_NAME_GPIO_9) != IOT_SUCCESS) { + LOG_E("GPIO%d Init Failed !\n", HAL_WIFI_IOT_IO_NAME_GPIO_9); + } + + if (HalIoSetFunc(HAL_WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_PWM0_OUT) != IOT_SUCCESS) { + LOG_E("GPIO%d Set Func failed !\n", HAL_WIFI_IOT_IO_NAME_GPIO_9); + } + + if (IoTPwmInit(WIFI_IOT_PWM_PORT_PWM0) != IOT_SUCCESS) { + LOG_E("PWM%d Init Failed !\n", WIFI_IOT_PWM_PORT_PWM0); + } + + attr.name = "BeeperMusicTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = MUSIC_STACK_TASK_SIZE; + attr.priority = osPriorityNormal; + + if (osThreadNew((osThreadFunc_t)BeeperMusicTask, NULL, &attr) == NULL) { + LOG_E("[LedExample] Falied to create BeeperMusicTask!\n"); + } +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/astronauts_game/src/oled.c b/CompleteApps/AstronautsGame/astronauts_game/src/oled.c new file mode 100644 index 0000000000000000000000000000000000000000..f69c9e0fdd308ec0faf92235825bb9a985d5f8e9 --- /dev/null +++ b/CompleteApps/AstronautsGame/astronauts_game/src/oled.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "cmsis_os2.h" +#include "ohos_types.h" +#include "code_tab.h" +#include "oled.h" +#include "common_log.h" +#include "iot_i2c.h" + +#define BITS_NAMBER 8 +#define SSD1306_I2C_IDX 0 +#define SSD1306_CTRL_CMD 0x00 +#define SSD1306_CTRL_DATA 0x40 +#define SSD1306_MASK_CONT (0x1<<7) +#define TIME_CONVERSION_PARM 1000 +#define SSD1306_WRITEDATA_PARM 2 + +FontDef g_Font_7x10 = {7, 10, Font7x10}; + +// Screenbuffer +static uint8 SSD1306_Buffer[SSD1306_BUFFER_SIZE]; +// Screen object +static SSD1306_t SSD1306; + +void HAL_Delay(uint32 ms) +{ + const uint32 msPerTick = TIME_CONVERSION_PARM / osKernelGetTickFreq(); // 10ms + if (ms >= msPerTick) { + osDelay(ms / msPerTick); + } + + uint32 restMs = ms % msPerTick; + if (restMs > 0) { + usleep(restMs * TIME_CONVERSION_PARM); + } +} + +#define TIME_UNITS 1000 + +uint32 HAL_GetTick(void) +{ + const uint32 msPerTick = TIME_UNITS / osKernelGetTickFreq(); // 10ms + uint32 tickMs = osKernelGetTickCount() * msPerTick; + + uint32 csPerMs = osKernelGetSysTimerFreq() / TIME_UNITS; // 160K cycle/ms + uint32 csPerTick = csPerMs * msPerTick; // 1600K cycles/tick + uint32 restMs = osKernelGetSysTimerCount() % csPerTick / csPerMs; + + return tickMs + restMs; +} + +static uint32 ssd1306_SendData(uint8* data, size_t size) +{ + return IoTI2cWrite(SSD1306_I2C_IDX, SSD1306_I2C_ADDR, data, size); +} + +static uint32 ssd1306_WiteByte(uint8 regAddr, uint8 byte) +{ + uint8 buffer[] = {regAddr, byte}; + return ssd1306_SendData(buffer, sizeof(buffer)); +} + +// Send a byte to the command register +void ssd1306_WriteCommand(uint8 byte) +{ + ssd1306_WiteByte(SSD1306_CTRL_CMD, byte); +} + +void ssd1306_WriteData(uint8* buffer, size_t buff_size) +{ + uint8 data[SSD1306_WIDTH * SSD1306_WRITEDATA_PARM] = {0}; + for (size_t i = 0; i < buff_size; i++) { + data[i *SSD1306_WRITEDATA_PARM] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT; + data[i * SSD1306_WRITEDATA_PARM + 1] = buffer[i]; + } + data[(buff_size - 1) * SSD1306_WRITEDATA_PARM] = SSD1306_CTRL_DATA; + ssd1306_SendData(data, sizeof(data)); +} + +void ssd1306_SetDisplayOn(const uint8 on) +{ + uint8 value; + if (on) { + value = 0xAF; // Display on + SSD1306.DisplayOn = 1; + } else { + value = 0xAE; // Display off + SSD1306.DisplayOn = 0; + } + ssd1306_WriteCommand(value); +} + +void ssd1306_SetContrast(const uint8 value) +{ + const uint8 kSetContrastControlRegister = 0x81; + ssd1306_WriteCommand(kSetContrastControlRegister); + ssd1306_WriteCommand(value); +} + +void ssd1306_DrawPixel(uint8 x, uint8 y, SSD1306_COLOR color) +{ + if ((x >= SSD1306_WIDTH) || (y >= SSD1306_HEIGHT)) { + // Don't write outside the buffer + return; + } + + // Check if pixel should be inverted + if (SSD1306.Inverted) { + color = (SSD1306_COLOR)!color; + } + + // Draw in the right color + if (color == White) { + SSD1306_Buffer[x + (y / BITS_NAMBER) * SSD1306_WIDTH] |= 1 << (y % BITS_NAMBER); + } else { + SSD1306_Buffer[x + (y / BITS_NAMBER) * SSD1306_WIDTH] &= ~(1 << (y % BITS_NAMBER)); + } +} + +#define ACSII_CODE_SPACE 32 +#define ACSII_RANGE_DEL 127 + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) +{ + uint32 i, b, j; + + // Check if character is valid + if ((ch < ACSII_CODE_SPACE) || (ch > ACSII_RANGE_DEL - 1)) { return 0;} + + // Check remaining space on current line + if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) || + SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)) { + return 0; + } + // Use the font to write + for (i = 0; i < Font.FontHeight; i++) { + b = Font.data[(ch - ACSII_CODE_SPACE) * Font.FontHeight + i]; + for (j = 0; j < Font.FontWidth; j++) { + if ((b << j) & 0x8000) { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR) color); + } else { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); + } + } + } + // The current space is now taken + SSD1306.CurrentX += Font.FontWidth; + return ch; +} + +char ssd1306_DrawString(char* str, uint32 size, SSD1306_COLOR color) +{ + // Write until null-byte + (void)size; + while (*str) { + if (ssd1306_DrawChar(*str, g_Font_7x10, color) != *str) { + // Char could not be written + return *str; + } + // Next char + str++; + } + + return *str; +} + +void ssd1306_DrawBitmapAtPosition(const uint8* bitmap, uint8 width, uint8 height, int8 xo, int8 yo) +{ + for (uint8 y = 0; y < height; y++) { + if (yo + y > SSD1306_HEIGHT || yo + y < 0) continue; + for (uint8 x = 0; x < width; x++) { + if (xo + x > SSD1306_WIDTH || xo + x < 0) continue; + uint8 byte = bitmap[(y * width / BITS_NAMBER) + (x / BITS_NAMBER)]; + uint8 bit = byte & (0x80 >> (x % BITS_NAMBER)); + ssd1306_DrawPixel(xo + x, yo + y, bit ? White : Black); + } + } +} + +// Position the cursor +void ssd1306_SetCursor(uint8 x, uint8 y) +{ + SSD1306.CurrentX = x; + SSD1306.CurrentY = y; +} + +// Fill the whole screen with the given color +void ssd1306_Fill(SSD1306_COLOR color) +{ + /* Set memory */ + uint32 i; + + for (i = 0; i < sizeof(SSD1306_Buffer); i++) { + SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF; + } +} + +#define DRAW_LINE_CALC_PARM 2 +void ssd1306_DrawLine(uint8 x1, uint8 y1, uint8 x2, uint8 y2, SSD1306_COLOR color) +{ + int32 deltaX = abs(x2 - x1); + int32 deltaY = abs(y2 - y1); + int32 signX = ((x1 < x2) ? 1 : -1); + int32 signY = ((y1 < y2) ? 1 : -1); + int32 error = deltaX - deltaY; + + ssd1306_DrawPixel(x2, y2, color); + while ((x1 != x2) || (y1 != y2)) { + ssd1306_DrawPixel(x1, y1, color); + int32 error2 = error * DRAW_LINE_CALC_PARM; + if (error2 > -deltaY) { + error -= deltaY; + x1 += signX; + } + if (error2 < deltaX) { + error += deltaX; + y1 += signY; + } + } + return; +} + +#define CMD_SAVE_PARM 2 + +void ssd1306_UpdateScreen(void) +{ + // Write data to each page of RAM. Number of pages + uint8 cmd[] = { + 0X21, // Set column start and end addresses + 0X00, // Column start address 0 + 0X7F, // Column end address 127 + 0X22, // Set page start and end addresses + 0X00, // Column start address 0 + 0X07, // Column end address 7 + }; + uint32 count = 0; + uint8 data[sizeof(cmd) * CMD_SAVE_PARM + SSD1306_BUFFER_SIZE + 1] = {}; + + // copy cmd + for (uint32 i = 0; i < sizeof(cmd) / sizeof(cmd[0]); i++) { + data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT; + data[count++] = cmd[i]; + } + + // copy frame data + data[count++] = SSD1306_CTRL_DATA; + if (memcpy_s(&data[count], sizeof(SSD1306_Buffer), SSD1306_Buffer, sizeof(SSD1306_Buffer)) != 0) { + LOG_E("Copy the SSD1306_Buffer failed.\n"); + } + count += sizeof(SSD1306_Buffer); + + // send to i2c bus + uint32 retval = ssd1306_SendData(data, count); + if (retval != OHOS_SUCCESS) { + LOG_E("ssd1306_UpdateScreen send frame data failed: %d!\r\n", retval); + } +} + +#define TIMES_FOR_VOLTAGE_STABLE 100 + +void ssd1306_Init(void) +{ + // Wait for the screen to boot + HAL_Delay(TIMES_FOR_VOLTAGE_STABLE); + + // Init OLED + ssd1306_SetDisplayOn(0); // display off + ssd1306_WriteCommand(0x20); // Set Memory Addressing Mode + ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode + ssd1306_WriteCommand(0xB0); // Set Page Start Address for Page Addressing Mode,0-7 + ssd1306_WriteCommand(0xC8); // Set COM Output Scan Direction + ssd1306_WriteCommand(0x00); // ---set low column address + ssd1306_WriteCommand(0x10); // ---set high column address + ssd1306_WriteCommand(0x40); // --set start line address - CHECK + ssd1306_SetContrast(0xFF); + ssd1306_WriteCommand(0xA1); // --set segment re-map 0 to 127 - CHECK + ssd1306_WriteCommand(0xA6); // --set normal color + ssd1306_WriteCommand(0xA8); // --set multiplex ratio(1 to 64) - CHECK + ssd1306_WriteCommand(0x3F); // + ssd1306_WriteCommand(0xA4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content + ssd1306_WriteCommand(0xD3); // -set display offset - CHECK + ssd1306_WriteCommand(0x00); // -not offset + ssd1306_WriteCommand(0xD5); // --set display clock divide ratio/oscillator frequency + ssd1306_WriteCommand(0xF0); // --set divide ratio + ssd1306_WriteCommand(0xD9); // --set pre-charge period + ssd1306_WriteCommand(0x11); // 0x22 by default + ssd1306_WriteCommand(0xDA); // --set com pins hardware configuration - CHECK + ssd1306_WriteCommand(0x12); + ssd1306_WriteCommand(0xDB); // --set vcomh + ssd1306_WriteCommand(0x30); // 0x20,0.77xVcc, 0x30,0.83xVcc + ssd1306_WriteCommand(0x8D); // --set DC-DC enable + ssd1306_WriteCommand(0x14); + ssd1306_SetDisplayOn(1); // --turn on SSD1306 panel + + ssd1306_Fill(Black); // Clear screen + ssd1306_UpdateScreen(); // Flush buffer to screen + SSD1306.CurrentX = 0; // Set default values for screen object + SSD1306.CurrentY = 0; + SSD1306.Initialized = 1; +} + +#define SHOW_GAME_START_Y_1 10 +#define SHOW_GAME_START_Y_2 30 +#define OLED_VOLTAGE_STABLE_TIME 300 + +void OledInit(void) +{ + HAL_Delay(OLED_VOLTAGE_STABLE_TIME); + ssd1306_Init(); + ssd1306_Fill(Black); + ssd1306_SetCursor(0, SHOW_GAME_START_Y_1); + ssd1306_DrawString("== Game Start ==", sizeof("== Game Start =="), White); + ssd1306_SetCursor(0, SHOW_GAME_START_Y_2); + ssd1306_DrawString("Press button USER", sizeof("Press button USER"), White); + + uint32 start = HAL_GetTick(); + ssd1306_UpdateScreen(); + uint32 end = HAL_GetTick(); + LOG_I("ssd1306_UpdateScreen time cost: %d ms.\r\n", end - start); +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/hals/BUILD.gn b/CompleteApps/AstronautsGame/common/hals/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b82f85f4bbff5b0827cfd0a59fc4f6bfa3a777b6 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/hals/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +static_library("hals") { + sources = [ + "src/peripheral_hal.c", + "src/utils_hal.c" + ] + + include_dirs = [ + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//device/hisilicon/hispark_pegasus/sdk_liteos/include", + ] +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/hals/src/peripheral_hal.c b/CompleteApps/AstronautsGame/common/hals/src/peripheral_hal.c new file mode 100644 index 0000000000000000000000000000000000000000..28488ce9ae10d1f81b01a9515ba238e0fb967d40 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/hals/src/peripheral_hal.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "peripheral_hal.h" +#include "iot_errno.h" +#include "hi_io.h" +#include "hi_adc.h" +#include "hi_types_base.h" +#include "hi_watchdog.h" +#include "hi_pwm.h" + +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val) +{ + if (id == HAL_WIFI_IOT_IO_NAME_MAX) { + return IOT_FAILURE; + } + return hi_io_set_func((hi_io_name)id, val); +} + +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt) +{ + return hi_adc_read((hi_adc_channel_index)channel, (hi_u16*)data, (hi_adc_equ_model_sel)equModel, + (hi_adc_cur_bais)curBais, (hi_u16)rstCnt); +} + +void HalSetWatchDogEnable(int enable) +{ + if (enable == 0) { + hi_watchdog_disable(); + } else { + hi_watchdog_enable(); + } +} + +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq) +{ + return hi_pwm_start((hi_pwm_port)id, (hi_u16)duty, (hi_u16)freq); +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/hals/src/utils_hal.c b/CompleteApps/AstronautsGame/common/hals/src/utils_hal.c new file mode 100644 index 0000000000000000000000000000000000000000..ef34078b38618fb154a9eee05d30d31ab7026cbd --- /dev/null +++ b/CompleteApps/AstronautsGame/common/hals/src/utils_hal.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "ohos_types.h" +#include "hi_time.h" +#include "hi_types_base.h" +#include "utils_hal.h" + +void hal_udelay(uint32 us) +{ + hi_udelay((hi_u32)us); +} \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/include/common_log.h b/CompleteApps/AstronautsGame/common/include/common_log.h new file mode 100644 index 0000000000000000000000000000000000000000..3b2f4fc6b0a9dbc6c718194af54247d44fe1274c --- /dev/null +++ b/CompleteApps/AstronautsGame/common/include/common_log.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef __COMMON_LOG_H__ +#define __COMMON_LOG_H__ + +#include + +#define LOG_D(fmt, args...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_I(fmt, args...) printf("[INFO][%s|%d]" fmt, __func__, __LINE__, ##args) +#define LOG_E(fmt, args...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##args) + +#endif // __COMMON_LOG_H__ \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/include/network_manager_service.h b/CompleteApps/AstronautsGame/common/include/network_manager_service.h new file mode 100644 index 0000000000000000000000000000000000000000..911f7ebbb1f7548df30945e24d1789d427fd41e0 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/include/network_manager_service.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef __NETWORK_MANAGER_SERVICE_H__ +#define __NETWORK_MANAGER_SERVICE_H__ + +typedef enum { + NET_EVENT_NULL, + NET_EVENT_CONFIG, // Config wifi + NET_EVENT_CONFIG_FAIL, // Config wifi failed + NET_EVENT_CONFIG_SUCC, // Config wifi success + NET_EVENT_CONNECTTING, // connectting wifi + NET_EVENT_CONN_FAILED, // connect wifi failed + NET_EVENT_CONNECTTED, // Wifi connected + NET_EVENT_DISTCONNECT, // Wifi disconnected + NET_EVENT_RECV_DATA, // Recv message from FA + + NET_EVENT_TYPE_NBR +}NET_EVENT_TYPE; + +typedef enum { + NET_MODE_IDLE, // the idle mode + NET_MODE_CONFIG, // the netcfg in the AP mode + NET_MODE_STA, // the netcfg int the STA mode + + NET_MODE_NBR +}NET_MODE_TYPE; + +typedef enum { + NET_STA_NULL, + NET_STA_CONFIG, // Config wifi + NET_STA_CONNECTTING, // connectting wifi + NET_STA_CONNECTTED, // Wifi connected + NET_STA_DISTCONNECT, // Wifi disconnected + + NET_STA_TYPE_NBR +}NET_STA_TYPE; + +/** + * @brief: the network config service callback + * + * @param event reference {@link NET_EVENT_TYPE} + * @param data The data of the event: NET_EVENT_RECV_DATA or NET_EVENT_SEND_DATA + * @since 1.0 + * @version 1.0 + */ +typedef int (*NetManagerEventCallback)(NET_EVENT_TYPE event, void *data); + +/** + * @brief Register the network config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The callback of netcfg module + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief Set the network mode. + * + * @param mode : the network module, reference {@NET_MODE_TYPE} + * @since 1.0 + * @version 1.0 + */ +void NetManagerSetNetMode(int mode); + +/** + * @brief Send msg to FA. + * + * @param msg : the msg to send + * @since 1.0 + * @version 1.0 + * + * @return 0 -- success, others -- failed + */ +int NetManagerSendMsg(const char *msg); + +/** + * @brief UnRegister the network config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetManagerDeinit(void); + +#endif // __NETWORK_MANAGER_SERVICE_H__ \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/include/peripheral_hal.h b/CompleteApps/AstronautsGame/common/include/peripheral_hal.h new file mode 100644 index 0000000000000000000000000000000000000000..370cd942c8fcd2b155c772b6cc389deb87105d88 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/include/peripheral_hal.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef PERIPHERAL_HAL_H +#define PERIPHERAL_HAL_H + +#include "ohos_types.h" + +/* gpio start */ +typedef enum { + /** GPIO hardware pin 0 */ + HAL_WIFI_IOT_IO_NAME_GPIO_0, + /** GPIO hardware pin 1 */ + HAL_WIFI_IOT_IO_NAME_GPIO_1, + /** GPIO hardware pin 2 */ + HAL_WIFI_IOT_IO_NAME_GPIO_2, + /** GPIO hardware pin 3 */ + HAL_WIFI_IOT_IO_NAME_GPIO_3, + /** GPIO hardware pin 4 */ + HAL_WIFI_IOT_IO_NAME_GPIO_4, + /** GPIO hardware pin 5 */ + HAL_WIFI_IOT_IO_NAME_GPIO_5, + /** GPIO hardware pin 6 */ + HAL_WIFI_IOT_IO_NAME_GPIO_6, + /** GPIO hardware pin 7 */ + HAL_WIFI_IOT_IO_NAME_GPIO_7, + /** GPIO hardware pin 8 */ + HAL_WIFI_IOT_IO_NAME_GPIO_8, + /** GPIO hardware pin 9 */ + HAL_WIFI_IOT_IO_NAME_GPIO_9, + /** GPIO hardware pin 10 */ + HAL_WIFI_IOT_IO_NAME_GPIO_10, + /** GPIO hardware pin 11 */ + HAL_WIFI_IOT_IO_NAME_GPIO_11, + /** GPIO hardware pin 12 */ + HAL_WIFI_IOT_IO_NAME_GPIO_12, + /** GPIO hardware pin 13 */ + HAL_WIFI_IOT_IO_NAME_GPIO_13, + /** GPIO hardware pin 14 */ + HAL_WIFI_IOT_IO_NAME_GPIO_14, + /** Maximum value */ + HAL_WIFI_IOT_IO_NAME_MAX, +} HalWifiIotIoName; + +/** + * @brief set IO function. + * + * @param id -- IO number, reference {@ HalWifiIotIoName}. + * @param val -- the io function value which defined in {@ hi_io.h}. + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalIoSetFunc(HalWifiIotIoName id, const char *val); +/* gpio end */ + + +/* adc start */ + +/** + * @brief Enumerates ADC channel indexes. + * + */ +typedef enum { + /** Channel 0 */ + HAL_WIFI_IOT_ADC_CHANNEL_0, + /** Channel 1 */ + HAL_WIFI_IOT_ADC_CHANNEL_1, + /** Channel 2 */ + HAL_WIFI_IOT_ADC_CHANNEL_2, + /** Channel 3 */ + HAL_WIFI_IOT_ADC_CHANNEL_3, + /** Channel 4 */ + HAL_WIFI_IOT_ADC_CHANNEL_4, + /** Channel 5 */ + HAL_WIFI_IOT_ADC_CHANNEL_5, + /** Channel 6 */ + HAL_WIFI_IOT_ADC_CHANNEL_6, + /** Channel 7 */ + HAL_WIFI_IOT_ADC_CHANNEL_7, + /** Button value */ + HAL_WIFI_IOT_ADC_CHANNEL_BUTT, +} HalWifiIotAdcChannelIndex; + +/** + * @brief Enumerates analog power control modes. + */ +typedef enum { + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_DEFAULT, + /** Automatic control */ + HAL_WIFI_IOT_ADC_CUR_BAIS_AUTO, + /** Manual control (AVDD = 1.8 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_1P8V, + /** Manual control (AVDD = 3.3 V) */ + HAL_WIFI_IOT_ADC_CUR_BAIS_3P3V, + /** Button value */ + HAL_WIFI_IOT_ADC_CUR_BAIS_BUTT, +} HalWifiIotAdcCurBais; + +/** + * @brief Enumerates equation models. + */ +typedef enum { + /** One-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_1, + /** Two-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_2, + /** Four-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_4, + /** Eight-equation model */ + HAL_WIFI_IOT_ADC_EQU_MODEL_8, + /** Button value */ + HAL_WIFI_IOT_ADC_EQU_MODEL_BUTT, +} HalWifiIotAdcEquModelSel; + +/** + * @brief Reads a piece of sampled data from a specified ADC channel based on the input parameters. + * + * + * + * @param channel Indicates the ADC channel index. + * @param data Indicates the pointer to the address for storing the read data. + * @param equModel Indicates the equation model. + * @param curBais Indicates the analog power control mode. + * @param rstCnt Indicates the count of the time from reset to conversion start. + * One count is equal to 334 ns. The value must range from 0 to 0xFF0. + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalAdcRead(HalWifiIotAdcChannelIndex channel, unsigned short *data, HalWifiIotAdcEquModelSel equModel, + HalWifiIotAdcCurBais curBais, unsigned short rstCnt); +/** adc end ****/ + +/** + * @brief set WatchDog enable or disable. + * + * @param enable -- 1 enable, 0 disable. + * + * @since 1.0 + * @version 1.0 + */ +void HalSetWatchDogEnable(int enable); + +/** + * @brief start the pwm. + * + * @param id Port id of PWM + * @param duty The usefull cycles of PWM + * @param freq The total cycles of PWM + * + * @return Returns {@link WIFI_IOT_SUCCESS} if the operation is successful; + * returns an error code defined in {@link wifiiot_errno.h} otherwise. + * @since 1.0 + * @version 1.0 + */ +unsigned int HalPwmStart(uint32 id, uint16 duty, uint16 freq); + +#endif // PERIPHERAL_HAL_H \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/include/utils_hal.h b/CompleteApps/AstronautsGame/common/include/utils_hal.h new file mode 100644 index 0000000000000000000000000000000000000000..fb158c285296d1f53a06127802d4137125f91a4e --- /dev/null +++ b/CompleteApps/AstronautsGame/common/include/utils_hal.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef __UTILS_HAL_H__ +#define __UTILS_HAL_H__ + +void hal_udelay(uint32 us); + +#endif // __UTILS_HAL_H__ \ No newline at end of file diff --git a/CompleteApps/AstronautsGame/common/netcfg/BUILD.gn b/CompleteApps/AstronautsGame/common/netcfg/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..7375d33fa8447e4f8276a135d832e46452c45ffb --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# 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. + +static_library("netcfg") { + sources = [ + "src/network_config.c", + "src/network_server.c", + "src/network_manager_service.c", + "src/softap.c", + "src/wifi_sta.c" + ] + + include_dirs = [ + "include", + "//applications/sample/wifi-iot/app/common/include", + "//base/iot_hardware/peripheral/interfaces/kits", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//kernel/liteos_m/kal/cmsis", + "//kernel/liteos_m/cmsis", + "//third_party/mbedtls/include/mbedtls", + "//utils/native/lite/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/third_party/lwip_sack/include", + "//device/hisilicon/hispark_pegasus/sdk_liteos/platform/os/Huawei_LiteOS/components/lib/libsec/include", + "//base/security/deviceauth/frameworks/deviceauth_lite/source", + ] +} diff --git a/CompleteApps/AstronautsGame/common/netcfg/include/defines.h b/CompleteApps/AstronautsGame/common/netcfg/include/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..356434830bed9c80e306ad5d4ba0928cbd909421 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/include/defines.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ +#ifndef __DEFINES_H__ +#define __DEFINES_H__ + +#include +#include + +#include + +#define LOG_E(fmt, arg...) printf("[ERROR][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_D(fmt, arg...) printf("[DEBUG][%s|%d]" fmt, __func__, __LINE__, ##arg) +#define LOG_I(fmt, arg...) printf("[INFO ][%s|%d]" fmt, __func__, __LINE__, ##arg) + +#define REQUEST_OK 200 +#define REQUEST_ERR 401 + +#define BUF_SHORT_SIZE 256 +#define AP_NAME "HmosAP" + +#define DELAY_100MS 10 // for function osDelay(), unit 10ms +#define DELAY_200MS (DELAY_100MS * 2) +#define DELAY_500MS (DELAY_100MS * 5) +#define DELAY_1000MS (DELAY_100MS * 10) +#define DELAY_2000MS (DELAY_100MS * 20) +#define DELAY_5000MS (DELAY_100MS * 50) + +#define USLEEP_100MS 100000 // for function usleep(), unit 1us +#define USLEEP_200MS (USLEEP_100MS * 2) +#define USLEEP_500MS (USLEEP_100MS * 5) +#define USLEEP_1000MS (USLEEP_100MS * 10) +#define USLEEP_2000MS (USLEEP_100MS * 20) +#define USLEEP_2500MS (USLEEP_100MS * 25) +#define USLEEP_5000MS (USLEEP_100MS * 50) + +#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) + +#endif /* __DEFINES_H__ */ diff --git a/CompleteApps/AstronautsGame/common/netcfg/include/network_config.h b/CompleteApps/AstronautsGame/common/netcfg/include/network_config.h new file mode 100644 index 0000000000000000000000000000000000000000..3dc477b85d67eb30b0b6d961c683ba1d4b432e79 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/include/network_config.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef __NETWORK_CONFIG_H__ +#define __NETWORK_CONFIG_H__ + +#include "network_manager_service.h" + +#define NET_TASK_STACK_SIZE (1024*8) +#define NET_TASK_PRIO 31 + +/** + * @brief start net config task + * + * @param apName -- the name of the device for AP mode + * nEventCallback -- The NetEvent callback. event reference {@NET_EVENT_TYPE} + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback); + +/** + * @brief stop net config task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStop(void); + +/** + * @brief set net config mode + * @param mode -- reference {@NET_MODE_TYPE} + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgSetMode(int mode); + +/** + * @brief start connect the wifi + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + */ +void NetCfgStartConnect(const char *ssid, const char *pwd); + +#endif /* __NETWORK_CONFIG_H__ */ diff --git a/CompleteApps/AstronautsGame/common/netcfg/include/network_server.h b/CompleteApps/AstronautsGame/common/netcfg/include/network_server.h new file mode 100644 index 0000000000000000000000000000000000000000..fe90b807b629e8867b215c75eda792d9da18492f --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/include/network_server.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef __NETWORK_SERVER_H__ +#define __NETWORK_SERVER_H__ + +#include "network_manager_service.h" + +#define NETSERVER_TASK_STACK_SIZE (1024*4) +#define NETSERVER_TASK_PRIO 33 + + +/** + * @brief start netserver task + * + * @param nEventCallback -- The NetEvent callback, + * when the server recv data, + * it will be called with (@NET_EVENT_RECV_DATA) + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerInit(NetManagerEventCallback nEventCallback); + +/** + * @brief stop netserver task + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerDeinit(void); + +/** + * @brief set netserver task resume + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStart(void); + +/** + * @brief set netserver task suspend + * + * @since 1.0 + * @version 1.0 + * + */ +void NetServerStop(void); + +/** + * @brief check the netserver when suspend or not. + * + * @since 1.0 + * @version 1.0 + * + * @return true -- netserver task is activity, false -- netserver is suspend + */ +bool NetServerIsRun(void); + +/** + * @brief send msg to client + * @param msg -- The message to send + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int NetServerSendMsg(const char *msg); + +#endif /* __NETWORK_SERVER_H__ */ diff --git a/CompleteApps/AstronautsGame/common/netcfg/include/softap.h b/CompleteApps/AstronautsGame/common/netcfg/include/softap.h new file mode 100644 index 0000000000000000000000000000000000000000..020d475a3fd5c30d76f2fc8e3d228fa95de51290 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/include/softap.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef __SOFT_AP_H__ +#define __SOFT_AP_H__ + +/** + * @brief start ap mode. + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int SoftApStart(const char *ap_name); + +/** + * @brief stop ap mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void SoftApStop(void); + +#endif /* __SOFT_AP_H__ */ diff --git a/CompleteApps/AstronautsGame/common/netcfg/include/wifi_sta.h b/CompleteApps/AstronautsGame/common/netcfg/include/wifi_sta.h new file mode 100644 index 0000000000000000000000000000000000000000..8d05ee0cf2e2abc4fa242e0c3c3f8b41a18e7ea9 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/include/wifi_sta.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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. + */ + +#ifndef __WIFI_STA_H__ +#define __WIFI_STA_H__ + +#include "wifi_device.h" + +/** + * @brief wifi state change callback. + * @param state -- wifi state, 0 -- wifi not connect, 1 -- wifi connectted + * + * @since 1.0 + * @version 1.0 + * + */ +typedef void (*WifiChangeEvent)(int state); + +/** + * @brief start sta mode. + * @param WifiChange--wifi state changed callback + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaStart(WifiChangeEvent WifiChange); + +/** + * @brief start connect wifi. + * @param ssid -- wifi ssid, pwd -- wifi password + * + * @since 1.0 + * @version 1.0 + * + * @return 0 success, -1 failed + */ +int WifiStaConnect(const char *ssid, const char *pwd); + +/** + * @brief stop sta mode. + * + * @since 1.0 + * @version 1.0 + * + */ +void WifiStaStop(void); + +#endif /* __WIFI_STA_H__ */ diff --git a/CompleteApps/AstronautsGame/common/netcfg/src/network_config.c b/CompleteApps/AstronautsGame/common/netcfg/src/network_config.c new file mode 100644 index 0000000000000000000000000000000000000000..147bdf863e67d82d61383170a47535d2c133d92e --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/src/network_config.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include "errno.h" +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "softap.h" +#include "wifi_sta.h" + +#include "network_config.h" +#include "network_server.h" +#include "defines.h" + +#define SSID_MAX_LEN 32 +#define PWD_MAX_LEN 32 + +#define NET_PORT 8686 + +#define RETRY_TIMES 5 +#define CONNECT_TIMEOUT 20 + +#define CMD_KEY "cmd" +#define PAR_KEY "param" +#define VAL_KEY "wifiName" +#define PWD_KEY "wifiPassword" + +#define CMD_CONFIG 0x20 + +typedef struct { + NET_MODE_TYPE mode; + NET_STA_TYPE status; + bool netRun; + int timeCounts; + + NetManagerEventCallback gEventCall; +} NetManagerInfo; + +static NetManagerInfo g_netManager; +const char *g_apName = NULL; + +#define SET_NET_EVENT(s, e, d) ({ \ + if (g_netManager.gEventCall != NULL) { \ + g_netManager.gEventCall(e, d); \ + } \ + g_netManager.status = s; \ +}) + +static void NetCfgConnectStatus(int s) +{ + if (s == 1 && g_netManager.status != NET_STA_CONNECTTED) { + SET_NET_EVENT(NET_STA_CONNECTTED, NET_EVENT_CONNECTTED, NULL); + } else if (s == 0) { + SET_NET_EVENT(NET_STA_DISTCONNECT, NET_EVENT_DISTCONNECT, NULL); + g_netManager.mode = NET_MODE_IDLE; + } +} + +#define SHIFT_MASK 0xff +#define SHIFT_8BIT(a) (((a) >> 8) & (SHIFT_MASK)) +#define SHIFT_16BIT(a) (((a) >> 16) & (SHIFT_MASK)) +#define SHIFT_24BIT(a) (((a) >> 24) & (SHIFT_MASK)) + +static void GetIpString(uint32_t ip, char *ipAddr, int size) +{ + if (ipAddr == NULL || size <= 0) { + return; + } + + if (sprintf_s(ipAddr, size, "%d.%d.%d.%d", ip & SHIFT_MASK, SHIFT_8BIT(ip), SHIFT_16BIT(ip), SHIFT_24BIT(ip)) < 0) { + LOG_E("GetIpString failed! \n"); + } + LOG_D("ipAddr : %s \n", ipAddr); +} + +int DeviceGetIp(char *buff, int size) +{ + int ret; + long ip; + struct netif *netif_node = netif_find("wlan0"); + if (netif_node == NULL) { + LOG_E("GetLocalWifiIp netif get fail\r\n"); + return -1; + } + + ip4_addr_t ipAddr; + ip4_addr_t netMask; + ip4_addr_t gateWay; + + ret = netifapi_netif_get_addr(netif_node, &ipAddr, &netMask, &gateWay); + if (ret == 0) { + ip = ip4_addr_get_u32(&ipAddr); + GetIpString(ip, buff, size); + return 0; + } + return -1; +} + +static void SendLocalIp(int sockfd, int code) +{ + char ip[BUF_SHORT_SIZE] = {0}; + + if (code == REQUEST_OK) { + if (DeviceGetIp(ip, sizeof(ip)) < 0) { + LOG_E("get local ip failed! \n"); + return; + } + } + + json_pobject json = create_json_object(); + json_pobject obj = add_number_to_object(json, "code", code); + json_pobject obj1, obj2; + + if (code != REQUEST_OK) { + obj1 = add_string_to_object(json, "errmsg", "connect wifi failed!"); + obj1 = add_object_to_object(json, "result"); + } else { + obj1 = add_object_to_object(json, "result"); + obj2 = add_number_to_object(obj1, "cmd", CMD_CONFIG); + obj2 = add_string_to_object(obj1, "ip", (const char *)ip); + } + + char *msg = json_to_string(json); + const char *eof = "\r\n"; + LOG_D("send msg : %s \n", msg); + if (send(sockfd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return; + } + send(sockfd, eof, strlen(eof), 0); + + delete_json_object(json); +} + +static int NetCfgConnect(const char *ssid, const char *pwd, bool wait) +{ + int timecnt = 0; + int retval = 0; + if (WifiStaStart(NetCfgConnectStatus) < 0) { + LOG_E("wifista_start \n"); + return -1; + } + + if (WifiStaConnect((const char *)ssid, (const char *)pwd) < 0) { + LOG_E("hal_wifi_start_connect \n"); + return -1; + } + + if (wait) { + while (g_netManager.status != NET_STA_CONNECTTED) { + usleep(USLEEP_500MS); + if (++timecnt > CONNECT_TIMEOUT) { + retval = -1; + break; + } + } + } + + return retval; +} + +static int ParseWifiInfo(const char *psr, char *ssid, int sl, char *pwd, int pl) +{ + json_handle json; + json_pobject sub; + + int cmd; + char *ps = NULL; + char *pw = NULL; + + json = parse_json(psr); + if (json == NULL) { + LOG_E("parse_json\n"); + return -1; + } + + cmd = get_json_int(json, CMD_KEY); + if (cmd != CMD_CONFIG) { + LOG_E("CMD TYPE FAILED! cmd=%d \n", cmd); + return -1; + } + + sub = get_json_obj(json, PAR_KEY); + if (sub == NULL) { + LOG_E("get param obj failed! \n"); + free_json(json); + return -1; + } + ps = get_json_string(sub, VAL_KEY); + if (ps == NULL) { + LOG_E("get ssid failed! \n"); + free_json(json); + return -1; + } + + if (strncpy_s(ssid, sl, ps, strlen(ps)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + pw = get_json_string(sub, PWD_KEY); + if (pw != NULL) { + LOG_D("pw=%s\n", pw); + if (strncpy_s(pwd, pl, pw, strlen(pw)) < 0) { + LOG_E("strncpy_s failed! \n"); + free_json(json); + return -1; + } + } + + free_json(json); + return 0; +} + +static int NetCfgGetSocketValue(int sockfd) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + struct sockaddr_in addr; + socklen_t len; + int result = -1; + char ssid[SSID_MAX_LEN + 1] = {0}; + char pwd[PWD_MAX_LEN + 1] = {0}; + while (1) { + int readBytes; + len = sizeof(addr); + if (g_netManager.mode != NET_MODE_CONFIG) { + break; + } + if (memset_s(recvbuf, BUF_SHORT_SIZE, 0, BUF_SHORT_SIZE) < 0) { + break; + } + readBytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&addr, &len); + if (readBytes <= 0) { + LOG_E("socket disconnect! \n"); + break; + } + if (ParseWifiInfo((const char*)recvbuf, ssid, sizeof(ssid), pwd, sizeof(pwd)) == 0) { + result = 0; + break; + } + } + if (result != -1) { + int code = REQUEST_OK; + SET_NET_EVENT(NET_STA_CONNECTTING, NET_EVENT_CONNECTTING, NULL); + if (NetCfgConnect(ssid, pwd, true) < 0) { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONN_FAILED, NULL); + code = REQUEST_ERR; + WifiStaStop(); + result = -1; + } else { + SET_NET_EVENT(NET_STA_CONNECTTED, NET_EVENT_CONNECTTED, NULL); + } + + usleep(USLEEP_2500MS); // wait ip ready + SendLocalIp(sockfd, code); + usleep(USLEEP_1000MS); + if (result != -1) { + NetServerStart(); + } + } + if (memset_s(pwd, sizeof(pwd), 0x00, sizeof(pwd)) < 0) { + return -1; + } + return result; +} + +static int NetCfgSocket(void) +{ + int sockfd; + struct sockaddr_in servaddr; + + if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + LOG_E("socket error! \n"); + return -1; + } + + memset_s(&servaddr, sizeof(servaddr), 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(NET_PORT); + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + + LOG_D("监听%d端口\n", NET_PORT); + if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { + LOG_E("bind socket! \n"); + close(sockfd); + return -1; + } + + if (listen(sockfd, 1) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + close(sockfd); + return -1; + } + + while (g_netManager.mode == NET_MODE_CONFIG) { + int newfd, retval; + struct sockaddr_in client_addr; + socklen_t length = sizeof(client_addr); + newfd = accept(sockfd, (struct sockaddr *)&client_addr, &length); + LOG_D("new socket connect!\n"); + retval = NetCfgGetSocketValue(newfd); + close(newfd); + + if (retval == 0) { + LOG_D("config network success! \n"); + g_netManager.mode = NET_MODE_STA; + } + } + + close(sockfd); + + return 0; +} + +static void NetCfgStartConfig(void) +{ + SET_NET_EVENT(NET_STA_CONFIG, NET_EVENT_CONFIG, NULL); + WifiStaStop(); + if (SoftApStart(g_apName) < 0) { + LOG_E("start softap failed! \n"); + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + if (NetCfgSocket() < 0) { + SET_NET_EVENT(NET_STA_NULL, NET_EVENT_CONFIG_FAIL, NULL); + return; + } + + SoftApStop(); +} + +static void *NetCfgTask(void *arg) +{ + (void)arg; + int netCfgMode = NET_STA_NULL; + while (g_netManager.netRun) { + if (netCfgMode == g_netManager.mode && netCfgMode != NET_MODE_STA) { + usleep(USLEEP_1000MS); + continue; + } + if (netCfgMode != g_netManager.mode) { + netCfgMode = g_netManager.mode; + } + switch (netCfgMode) { + case NET_MODE_CONFIG: + NetCfgStartConfig(); + break; + default: + break; + } + usleep(USLEEP_1000MS); + } + + return NULL; +} + +int NetCfgStart(const char *apName, NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + + if (memset_s(&g_netManager, sizeof(g_netManager), 0x00, sizeof(g_netManager)) < 0) { + LOG_E("memset_s g_netManager \n"); + return -1; + } + + g_netManager.gEventCall = nEventCallback; + g_netManager.netRun = true; + g_netManager.mode = NET_STA_CONFIG; + g_apName = apName; + attr.name = "NetManagerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NET_TASK_STACK_SIZE; + attr.priority = NET_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)NetCfgTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetManagerTask!\n"); + return -1; + } + + return 0; +} + +void NetCfgStop(void) +{ + g_netManager.netRun = false; +} + +void NetCfgSetMode(int mode) +{ + g_netManager.mode = mode; +} + +void NetCfgStartConnect(const char *ssid, const char *pwd) +{ + NetCfgConnect(ssid, pwd, false); +} diff --git a/CompleteApps/AstronautsGame/common/netcfg/src/network_manager_service.c b/CompleteApps/AstronautsGame/common/netcfg/src/network_manager_service.c new file mode 100644 index 0000000000000000000000000000000000000000..85f2426d17cbde4f0f04a6273388bcea4e144305 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/src/network_manager_service.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" + +#include "json/jsonutil.h" +#include "ohos_types.h" +#include "common_log.h" +#include "network_server.h" +#include "network_config.h" +#include "defines.h" + +int NetManagerRegister(const char *apName, NetManagerEventCallback nEventCallback) +{ + if (NetServerInit(nEventCallback) < 0) { + LOG_E("NetServerInit \n"); + return -1; + } + + if (NetCfgStart(apName, nEventCallback) < 0) { + LOG_E("NetCfgStart \n"); + NetServerDeinit(); + return -1; + } + + return 0; +} + +void NetManagerUnRegister(void) +{ + NetServerDeinit(); + NetCfgStop(); +} + +void NetManagerSetNetMode(int mode) +{ + NetCfgSetMode(mode); +} + +int NetManagerSendMsg(const char *msg) +{ + return NetServerSendMsg(msg); +} diff --git a/CompleteApps/AstronautsGame/common/netcfg/src/network_server.c b/CompleteApps/AstronautsGame/common/netcfg/src/network_server.c new file mode 100644 index 0000000000000000000000000000000000000000..10642c95b5e70ce2d7801e0928baa6d95b5ddf80 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/src/network_server.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include "cmsis_os2.h" +#include "base64.h" +#include "sys/time.h" +#include "sys/socket.h" +#include "errno.h" +#include "common_log.h" +#include "netinet/in.h" +#include "lwip/inet.h" +#include "lwip/netdb.h" +#include "json/jsonutil.h" +#include "network_server.h" +#include "defines.h" + +#define SERVER_PORT 8787 +#define MAX_CONNECT 10 + +typedef struct { + int sockfd[MAX_CONNECT]; + int connAmount; + bool isActive; + bool serRun; + + NetManagerEventCallback g_call; +}NetServerInfo; + +static NetServerInfo g_netServer; + +static int NetServerSend(int fd, const char *msg) +{ + const char *eof = "\r\n"; + if (send(fd, msg, strlen(msg), 0) < 0) { + LOG_E("send failed! errno : %d \n", errno); + return -1; + } + LOG_D("send msg : %s \n", msg); + send(fd, eof, strlen(eof), 0); + + return 0; +} + +static void SendRequest(int sockfd, int code) +{ + json_pobject obj; + json_pobject json = create_json_object(); + + obj = add_number_to_object(json, "code", code); + if (code == REQUEST_OK) { + obj = add_string_to_object(json, "errmsg", ""); + } else { + obj = add_string_to_object(json, "errmsg", "explain params error!"); + } + + char *msg = json_to_string(json); + NetServerSend(sockfd, msg); + delete_json_object(json); +} + +static bool IsSpecialSocket(const char *msg) +{ + char buf[] = {0xff, 0x55, 0xaa, 0x55, 0x00}; + bool result = true; + if (msg == NULL || strlen(msg) < strlen(buf)) { + return false; + } + + for (int i = 0; i < strlen(buf); i++) { + if (msg[i] != buf[i]) { + result = false; + break; + } + } + + return result; +} + +static int ReadHandle(int *sockfd, fd_set *fdSet) +{ + char recvbuf[BUF_SHORT_SIZE] = {0}; + int recvbytes; + int fd = *sockfd; + int errcode = -1; + + recvbytes = recv(fd, recvbuf, sizeof(recvbuf) - 1, 0); + if (recvbytes <= 0) { + LOG_D("socket may quit!\n"); + FD_CLR(fd, fdSet); + close(fd); + *sockfd = -1; + g_netServer.connAmount--; + return -1; + } + + if (g_netServer.sockfd[0] == -1 && IsSpecialSocket(recvbuf)) { + *sockfd = -1; + g_netServer.sockfd[0] = fd; + return 0; + } + + LOG_D("recv msg[%d] : %s \n", recvbytes, recvbuf); + if (g_netServer.g_call) { + errcode = g_netServer.g_call(NET_EVENT_RECV_DATA, recvbuf); + } + + if (errcode == -1) { + errcode = REQUEST_ERR; + } else { + errcode = REQUEST_OK; + } + + SendRequest(fd, errcode); + + return 0; +} + +static void CheckNewSocket(int sockFd, fd_set *fdSet, int *maxFd) +{ + int newfd; + struct sockaddr_in client_addr; + socklen_t sin_size = sizeof(client_addr); + if (FD_ISSET(sockFd, fdSet) == 0) { + return; + } + + newfd = accept(sockFd, (struct sockaddr *)&client_addr, &sin_size); + LOG_D("accept:: sock_fd = %d, newfd = %d\n", sockFd, newfd); + if (newfd <= 0) { + LOG_E("accept:\n"); + return; + } + + g_netServer.connAmount++; + + if (g_netServer.connAmount < MAX_CONNECT) { + for (int i = 1; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] == -1) { + g_netServer.sockfd[i] = newfd; + break; + } + } + + if (newfd > *maxFd) { + *maxFd = newfd; + } + } else { + LOG_E("max connections arrive, exit\n"); + close(newfd); + } +} + +static void SocketListen(int sock_fd) +{ + fd_set fdset; + int maxsock; + maxsock = sock_fd; + + while (g_netServer.serRun) { + int ret; + struct timeval tv = {2, 0}; + FD_ZERO(&fdset); + FD_SET(sock_fd, &fdset); + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + FD_SET(g_netServer.sockfd[i], &fdset); + } + } + ret = select(maxsock + 1, &fdset, NULL, NULL, &tv); + if (ret <= 0) { + continue; + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1 && FD_ISSET(g_netServer.sockfd[i], &fdset)) { + LOG_D("g_netServer.sockfd[%d] = %d\n", i, g_netServer.sockfd[i]); + ReadHandle(&g_netServer.sockfd[i], &fdset); + continue; + } + } + + CheckNewSocket(sock_fd, &fdset, &maxsock); + } + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + close(g_netServer.sockfd[i]); + g_netServer.sockfd[i] = -1; + } + } +} + +static void StartServer(void) +{ + struct sockaddr_in serv_addr; + int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockfd < 0) { + LOG_E("socket failed! \n"); + g_netServer.serRun = false; + return; + } + + if (memset_s(&serv_addr, sizeof(serv_addr), 0, sizeof(serv_addr)) < 0) { + LOG_E("memset_s faield! \n"); + close(sockfd); + g_netServer.serRun = false; + return; + } + + serv_addr.sin_family = AF_INET; // 使用IPv4地址 + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(SERVER_PORT); // 端口 + if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + LOG_E("bind failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + if (listen(sockfd, MAX_CONNECT) < 0) { + LOG_E("listen failed! errno = %d \n", errno); + g_netServer.serRun = false; + close(sockfd); + return; + } + + SocketListen(sockfd); + + LOG_D("SOCKET SERVER QUIT! \n"); + + close(sockfd); +} + +static void *NetServerTask(void *param) +{ + while (g_netServer.isActive) { + if (g_netServer.serRun == false) { + usleep(USLEEP_100MS); + continue; + } + + StartServer(); + } + + return NULL; +} + +int NetServerInit(NetManagerEventCallback nEventCallback) +{ + osThreadAttr_t attr; + attr.name = "NetServerTask"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = NETSERVER_TASK_STACK_SIZE; + attr.priority = NETSERVER_TASK_PRIO; + + if (memset_s(&g_netServer, sizeof(g_netServer), 0x00, sizeof(g_netServer)) < 0) { + LOG_E("memset_s failed! \n"); + return -1; + } + for (int i = 0; i < MAX_CONNECT; i++) { + g_netServer.sockfd[i] = -1; + } + g_netServer.isActive = true; + g_netServer.g_call = nEventCallback; + if (osThreadNew((osThreadFunc_t)NetServerTask, NULL, &attr) == NULL) { + LOG_E("Falied to create NetServerTask!\n"); + g_netServer.isActive = false; + return -1; + } + + return 0; +} + +void NetServerDeinit(void) +{ + g_netServer.serRun = false; + for (int i = 0; i < MAX_CONNECT; i++) { + if (g_netServer.sockfd[i] != -1) { + shutdown(g_netServer.sockfd[i], SHUT_RDWR); + g_netServer.sockfd[i] = -1; + } + } + + osDelay(DELAY_200MS); + g_netServer.isActive = false; +} + +void NetServerStart(void) +{ + g_netServer.serRun = true; +} + +void NetServerStop(void) +{ + g_netServer.serRun = false; + osDelay(DELAY_200MS); +} + +bool NetServerIsRun(void) +{ + return g_netServer.serRun; +} + +int NetServerSendMsg(const char *msg) +{ + if (g_netServer.serRun == false || g_netServer.sockfd[0] == -1) { + LOG_E("net server is not run! \n"); + return -1; + } + + return NetServerSend(g_netServer.sockfd[0], msg); +} diff --git a/CompleteApps/AstronautsGame/common/netcfg/src/softap.c b/CompleteApps/AstronautsGame/common/netcfg/src/softap.c new file mode 100644 index 0000000000000000000000000000000000000000..38f44f1a50d0a8da124ca62d525db0bc1120b253 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/src/softap.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_hotspot.h" +#include "wifi_hotspot_config.h" +#include "softap.h" +#include "defines.h" + +static void ResetAddr(struct netif *pst_lwip_netif) +{ + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + + IP4_ADDR(&st_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&st_gw, 0, 0, 0, 0); + IP4_ADDR(&st_netmask, 0, 0, 0, 0); + + netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw); +} + +int SoftApStart(const char *ap_name) +{ + HotspotConfig config = {0}; + ip4_addr_t st_gw; + ip4_addr_t st_ipaddr; + ip4_addr_t st_netmask; + char *apName = ap_name; + char ifname[BUF_SHORT_SIZE] = {0}; + int retval; + + if (IsHotspotActive() == WIFI_HOTSPOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_ACTIVE \n"); + return -1; + } + if (apName == NULL) { + apName = AP_NAME; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), apName) != 0) { + printf("[sample] strcpy ssid fail.\n"); + return -1; + } + config.securityType = WIFI_SEC_TYPE_OPEN; + retval = SetHotspotConfig((const HotspotConfig *)(&config)); + if (retval != WIFI_SUCCESS) { + LOG_E("SetHotspotConfig \n"); + return -1; + } + + retval = EnableHotspot(); + if (retval != WIFI_SUCCESS) { + LOG_E("EnableHotspot failed! \n"); + return -1; + } + return 0; +} + +void SoftApStop(void) +{ + if (IsHotspotActive() == WIFI_HOTSPOT_NOT_ACTIVE) { + LOG_E("WIFI_HOTSPOT_NOT_ACTIVE \n"); + return; + } + + DisableHotspot(); +} diff --git a/CompleteApps/AstronautsGame/common/netcfg/src/wifi_sta.c b/CompleteApps/AstronautsGame/common/netcfg/src/wifi_sta.c new file mode 100644 index 0000000000000000000000000000000000000000..81852d56339767e7465c24e1d68da6bf321a2c07 --- /dev/null +++ b/CompleteApps/AstronautsGame/common/netcfg/src/wifi_sta.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 +#include "lwip/ip_addr.h" +#include "lwip/netifapi.h" +#include "wifi_sta.h" +#include "defines.h" + +#define TEST_CONNECT_RETRY_COUNT 5 + +static WifiEvent g_staEventHandler = {0}; +static WifiChangeEvent g_wifiChange = NULL; +static int g_connectRetryCount = 0; + +static void WifiConnectionChangedHandler(int state, WifiLinkedInfo *info) +{ + if (state == WIFI_STATE_AVALIABLE) { + LOG_I("WiFi: Connected.\n"); + g_connectRetryCount = 0; + } else if (state == WIFI_STATE_NOT_AVALIABLE) { + LOG_I("WiFi: Disconnected retry = %d, reason = %d\n", g_connectRetryCount, info->disconnectedReason); + if (g_connectRetryCount < TEST_CONNECT_RETRY_COUNT) { + g_connectRetryCount++; + return; + } + } + if (g_wifiChange) { + g_wifiChange(state); + } +} + +int WifiStaStart(WifiChangeEvent WifiChange) +{ + WifiErrorCode error; + + g_wifiChange = WifiChange; + + if (IsWifiActive() == WIFI_STA_ACTIVE) { + LOG_E("the wifi has been enabled! \n"); + return 1; + } + + error = EnableWifi(); + if (error != WIFI_SUCCESS) { + LOG_E("EnableWifi failed! \n"); + return -1; + } + + g_staEventHandler.OnWifiConnectionChanged = WifiConnectionChangedHandler; + error = RegisterWifiEvent(&g_staEventHandler); + if (error != WIFI_SUCCESS) { + LOG_E("RegisterWifiEvent fail, error = %d\n", error); + return -1; + } + + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return -1; + } + + return 0; +} + +int WifiStaConnect(const char *ssid, const char *pwd) +{ + WifiDeviceConfig config = {0}; + int netId = 0; + WifiErrorCode error; + + if (ssid == NULL) { + LOG_E("NULL POINT! \n"); + return -1; + } + if (strcpy_s(config.ssid, sizeof(config.ssid), ssid) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + + config.ipType = DHCP; + if (pwd == NULL || strlen(pwd) == 0) { + config.securityType = WIFI_SEC_TYPE_OPEN; + } else { + config.securityType = WIFI_SEC_TYPE_PSK; + if (strcpy_s(config.preSharedKey, sizeof(config.preSharedKey), pwd) < 0) { + LOG_E("strcpy_s! \n"); + return -1; + } + } + + error = AddDeviceConfig(&config, &netId); + if (error != WIFI_SUCCESS) { + LOG_E("AddDeviceConfig! \n"); + return -1; + } + + error = ConnectTo(netId); + if (error != WIFI_SUCCESS) { + LOG_E("ConnectTo! \n"); + return -1; + } + + return 0; +} + +void WifiStaStop(void) +{ + if (IsWifiActive() == WIFI_STA_NOT_ACTIVE) { + LOG_E("Wifi station is not actived.\n"); + return; + } + + DisableWifi(); + UnRegisterWifiEvent(&g_staEventHandler); +} + diff --git a/CompleteApps/AstronautsGame/screenshoot/device/Astronautsgame.png b/CompleteApps/AstronautsGame/screenshoot/device/Astronautsgame.png new file mode 100644 index 0000000000000000000000000000000000000000..7050f4bd5ef75d2489207011558ace1eb7347c55 Binary files /dev/null and b/CompleteApps/AstronautsGame/screenshoot/device/Astronautsgame.png differ