更新硬件SDK

This commit is contained in:
kerwincui
2023-03-04 03:44:56 +08:00
parent dcdf6e1b7c
commit e39d3d2f03
1900 changed files with 663153 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
/*********************************************************************
* function 设备AP配网
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "ApConfig.h"
String randomName = "wumei-device" + (String)random(1000);
const char *ap_ssid = randomName.c_str();
//开放式网络,不设置密码
const char *ap_password = "";
IPAddress local_IP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
ESP8266WebServer server(80);
/**
* 启动AP配网
*/
void startApConfig() {
ledStatus(true);
WiFi.mode(WIFI_AP_STA);
WiFi.softAPConfig(local_IP, gateway, subnet);
WiFi.softAP(ap_ssid, ap_password);
printMsg("已启动AP配网IP地址" + WiFi.softAPIP().toString() + " 热点名称:" + (String)ap_ssid);
// 启动web服务
startWebServer();
}
/**
* 启动Web服务
*/
void startWebServer() {
isApMode = true;
server.on("/status", HTTP_GET, handleStatus);
server.on("/config", HTTP_POST, handleConfig);
server.onNotFound(handleNotFound);
server.enableCORS(true);
server.begin();
printMsg("HTTP服务已启动");
}
/**
* 检测设备接口
*/
void handleStatus() {
server.send(200, "text/plain;charset=utf-8", "AP配网已准备就绪");
}
/**
* AP配网接口
*/
void handleConfig() {
printMsg("进入配网......");
config_type config;
// wifi名称、wifi密码、用户编号
if (server.hasArg("SSID") && server.hasArg("password") && server.hasArg("userId")) {
// 分配空间
wifiSsid = (char *)malloc(32 * sizeof(char));
wifiPwd = (char *)malloc(64 * sizeof(char));
userId = (char *)malloc(16 * sizeof(char));
strcpy(config.stassid, server.arg("SSID").c_str());
strcpy(wifiSsid, server.arg("SSID").c_str());
strcpy(config.stapsw, server.arg("password").c_str());
strcpy(wifiPwd, server.arg("password").c_str());
strcpy(config.userId, server.arg("userId").c_str());
strcpy(userId, server.arg("userId").c_str());
printMsg("收到WIFI名称" + (String)config.stassid);
printMsg("收到WIFI密码" + (String)config.stapsw);
printMsg("收到用户编号:" + (String)config.userId);
} else {
printMsg("配网必须传递用户编号、WIFI名称和WIFI密码,配网失败");
server.send(500, "text/plain;charset=utf-8", "配网必须传递用户编号、WIFI名称和WIFI密码配网失败");
return;
}
// 可选字段
if (server.hasArg("deviceNum")) {
deviceNum = (char *)malloc(32 * sizeof(char));
strcpy(config.deviceNum, server.arg("deviceNum").c_str());
strcpy(deviceNum, server.arg("deviceNum").c_str());
printMsg("收到设备编号:" + server.arg("deviceNum"));
}
if (server.hasArg("authCode")) {
authCode = (char *)malloc(32 * sizeof(char));
strcpy(config.authCode, server.arg("authCode").c_str());
strcpy(authCode, server.arg("authCode").c_str());
printMsg("收到产品授权码:" + server.arg("authCode"));
}
if (server.hasArg("extra")) {
printMsg("收到补充信息:" + server.arg("extra"));
}
server.send(200, "text/plain;charset=utf-8", "设备已更新WIFI配置开始连接WIFI...");
// 统一设置Mqtt消息主题前缀
prefix = "/" + (String)productId + "/" + (String)deviceNum;
// 存储配置
saveConfig(config);
// 连接Wifi
connectWifi();
}
/**
* 找不到页面和跨域处理
*/
void handleNotFound() {
printMsg("进入预检请求或请求地址找不到");
if (server.method() == HTTP_OPTIONS) {
// 处理浏览器跨域问题
server.sendHeader("Access-Control-Max-Age", "10000");
server.sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS");
server.sendHeader("Access-Control-Allow-Headers", "*");
server.send(204);
} else {
server.send(404, "text/plain;charset=utf-8", "请求的地址找不到或无法访问");
}
}

View File

@@ -0,0 +1,28 @@
/*********************************************************************
* function 设备AP配网
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _APCONFIG_H
#define _APCONFIG_H
#include "Config.h"
#include <ESP8266WebServer.h>
extern ESP8266WebServer server;
// 启动AP配网
void startApConfig();
// 启动Web服务
void startWebServer();
// 配网接口
void handleConfig();
// 检测设备接口
void handleStatus();
// 找不到页面和浏览器跨域处理
void handleNotFound();
#endif

View File

@@ -0,0 +1,156 @@
/*********************************************************************
* function 设备认证
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Auth.h"
/*
* 连接MQTT加密认证
*/
void connectMqtt() {
printMsg("连接Mqtt服务器...");
mqttClient.setClient(wifiClient);
mqttClient.setServer(mqttHost, mqttPort);
mqttClient.setBufferSize(1024);
mqttClient.setKeepAlive(5);
// 设置Mqtt回调函数
mqttClient.setCallback(mqttCallback);
// 生成mqtt加密密码
String aesPassword = generationAESPwd();
// 连接 设备mqtt客户端Id格式为认证类型(E=加密、S=简单) & 设备编号 & 产品ID & 用户ID
String clientId = "E&" + (String)deviceNum + "&" + (String)productId + "&" + (String)userId;
printMsg("客户端ID" + clientId);
bool connectResult = mqttClient.connect(clientId.c_str(), mqttUserName, aesPassword.c_str());
if (connectResult) {
printMsg("连接Mqtt成功");
// 订阅系统主题
subscribeTopic();
// 发布设备信息,设备上电都需要发布一次
publishInfo();
} else {
printMsg("连接失败, rc=");
Serial.print(mqttClient.state());
}
}
/*
* 生成加密密码
*/
String generationAESPwd() {
// 获取NTP时间
String jsonTime = getTime();
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, jsonTime);
if (error) {
printMsg("Json解析失败");
Serial.print(error.f_str());
return "";
}
// 获取NTP时间=(设备发送消息时间 + 服务器接收消息时间 + 服务器发送消息时间 - 设备接收时间 最后除于2
float deviceSendTime = doc["deviceSendTime"];
float serverSendTime = doc["serverSendTime"];
float serverRecvTime = doc["serverRecvTime"];
float deviceRecvTime = millis();
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
// 过期时间 = 当前时间 + 1小时
float expireTime = now + 1 * 60 * 60 * 1000;
// 加密认证密码格式为mqtt密码 & 过期时间 & 授权码(可选),如果产品启用了授权码就必须加上
String password = "";
if (authCode == "") {
password = (String)mqttPwd + "&" + String(expireTime, 0);
} else {
password = (String)mqttPwd + "&" + String(expireTime, 0) + "&" + authCode;
}
// 密码加密
printMsg("密码(未加密):" + password);
String encryptPassword = encrypt(password, mqttSecret, wumei_iv);
printMsg("密码(已加密)" + encryptPassword);
return encryptPassword;
}
/*
* 通过HTTP获取NTP时间
*/
String getTime() {
while (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
printMsg("获取时间...");
if (http.begin(wifiClient, (ntpServer + (String)millis()).c_str())) {
// 发送请求
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
printMsg("获取时间成功data:");
Serial.print(http.getString());
return http.getString();
}
} else {
printMsg("获取时间失败error:");
Serial.printf(http.errorToString(httpCode).c_str());
}
http.end();
} else {
printMsg("连接Http失败");
}
delay(500);
}
return "1672524366000";
}
/*
* AES加密 (AES-CBC-128-pkcs5padding)
*/
String encrypt(String plain_data, char *wumei_key, char *wumei_iv) {
int i;
// pkcs7padding填充 Block Size : 16
int len = plain_data.length();
int n_blocks = len / 16 + 1;
uint8_t n_padding = n_blocks * 16 - len;
uint8_t data[n_blocks * 16];
memcpy(data, plain_data.c_str(), len);
for (i = len; i < n_blocks * 16; i++) {
data[i] = n_padding;
}
uint8_t key[16], iv[16];
memcpy(key, wumei_key, 16);
memcpy(iv, wumei_iv, 16);
// 加密
br_aes_big_cbcenc_keys encCtx;
br_aes_big_cbcenc_init(&encCtx, key, 16);
br_aes_big_cbcenc_run(&encCtx, iv, data, n_blocks * 16);
// Base64编码
len = n_blocks * 16;
char encoded_data[base64_enc_len(len)];
base64_encode(encoded_data, (char *)data, len);
return String(encoded_data);
}
/*
* AES解密 (AES-CBC-128-pkcs5padding)
*/
String decrypt(String encoded_data_str, char *wumei_key, char *wumei_iv) {
int input_len = encoded_data_str.length();
char *encoded_data = const_cast<char *>(encoded_data_str.c_str());
int len = base64_dec_len(encoded_data, input_len);
uint8_t data[len];
base64_decode((char *)data, encoded_data, input_len);
uint8_t key[16], iv[16];
memcpy(key, wumei_key, 16);
memcpy(iv, wumei_iv, 16);
int n_blocks = len / 16;
br_aes_big_cbcdec_keys decCtx;
br_aes_big_cbcdec_init(&decCtx, key, 16);
br_aes_big_cbcdec_run(&decCtx, iv, data, n_blocks * 16);
// PKCS#7 Padding 填充
uint8_t n_padding = data[n_blocks * 16 - 1];
len = n_blocks * 16 - n_padding;
char plain_data[len + 1];
memcpy(plain_data, data, len);
plain_data[len] = '\0';
return String(plain_data);
}

View File

@@ -0,0 +1,29 @@
/*********************************************************************
* function 设备认证
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _AUTH_H
#define _AUTH_H
#include "Config.h"
#include "User.h"
#include "Mqtt.h"
#include <Ethernet.h>
#include <ESP8266HTTPClient.h>
// 连接mqtt, AES加密认证
void connectMqtt();
// 生成加密密码
String generationAESPwd();
// 获取时间
String getTime();
// AES加密
String encrypt(String plain_data, char *wumei_key, char *wumei_iv);
// AES解密
String decrypt(String encoded_data_str, char *wumei_key, char *wumei_iv);
#endif

View File

@@ -0,0 +1,173 @@
/*********************************************************************
* function Base64编码和解码
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: Copyright (c) 2013 Adam Rudd.
********************************************************************/
#include "Base64.h"
#if (defined(__AVR__))
#include <avr\pgmspace.h>
#else
#include <pgmspace.h>
#endif
const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
/* 'Private' declarations */
inline void a3_to_a4(unsigned char *a4, unsigned char *a3);
inline void a4_to_a3(unsigned char *a3, unsigned char *a4);
inline unsigned char b64_lookup(char c);
int base64_encode(char *output, char *input, int inputLen)
{
int i = 0, j = 0;
int encLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--)
{
a3[i++] = *(input++);
if (i == 3)
{
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++)
{
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]);
}
i = 0;
}
}
if (i)
{
for (j = i; j < 3; j++)
{
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++)
{
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]);
}
while ((i++ < 3))
{
output[encLen++] = '=';
}
}
output[encLen] = '\0';
return encLen;
}
int base64_decode(char *output, char *input, int inputLen)
{
int i = 0, j = 0;
int decLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--)
{
if (*input == '=')
{
break;
}
a4[i++] = *(input++);
if (i == 4)
{
for (i = 0; i < 4; i++)
{
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3, a4);
for (i = 0; i < 3; i++)
{
output[decLen++] = a3[i];
}
i = 0;
}
}
if (i)
{
for (j = i; j < 4; j++)
{
a4[j] = '\0';
}
for (j = 0; j < 4; j++)
{
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3, a4);
for (j = 0; j < i - 1; j++)
{
output[decLen++] = a3[j];
}
}
output[decLen] = '\0';
return decLen;
}
int base64_enc_len(int plainLen)
{
int n = plainLen;
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}
int base64_dec_len(char *input, int inputLen)
{
int i = 0;
int numEq = 0;
for (i = inputLen - 1; input[i] == '='; i--)
{
numEq++;
}
return ((6 * inputLen) / 8) - numEq;
}
inline void a3_to_a4(unsigned char *a4, unsigned char *a3)
{
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
inline void a4_to_a3(unsigned char *a3, unsigned char *a4)
{
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
inline unsigned char b64_lookup(char c)
{
if (c >= 'A' && c <= 'Z')
return c - 'A';
if (c >= 'a' && c <= 'z')
return c - 71;
if (c >= '0' && c <= '9')
return c + 4;
if (c == '+')
return 62;
if (c == '/')
return 63;
return -1;
}

View File

@@ -0,0 +1,84 @@
/*********************************************************************
* function Base64编码和解码
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: Copyright (c) 2013 Adam Rudd.
********************************************************************/
#ifndef _BASE64_H
#define _BASE64_H
/* b64_alphabet:
* Description: Base64 alphabet table, a mapping between integers
* and base64 digits
* Notes: This is an extern here but is defined in Base64.c
*/
extern const char b64_alphabet[];
/* base64_encode:
* Description:
* Encode a string of characters as base64
* Parameters:
* output: the output buffer for the encoding, stores the encoded string
* input: the input buffer for the encoding, stores the binary to be encoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the encoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_encode(char *output, char *input, int inputLen);
/* base64_decode:
* Description:
* Decode a base64 encoded string into bytes
* Parameters:
* output: the output buffer for the decoding,
* stores the decoded binary
* input: the input buffer for the decoding,
* stores the base64 string to be decoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the decoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_decode(char *output, char *input, int inputLen);
/* base64_enc_len:
* Description:
* Returns the length of a base64 encoded string whose decoded
* form is inputLen bytes long
* Parameters:
* inputLen: the length of the decoded string
* Return value:
* The length of a base64 encoded string whose decoded form
* is inputLen bytes long
* Requirements:
* None
*/
int base64_enc_len(int inputLen);
/* base64_dec_len:
* Description:
* Returns the length of the decoded form of a
* base64 encoded string
* Parameters:
* input: the base64 encoded string to be measured
* inputLen: the length of the base64 encoded string
* Return value:
* Returns the length of the decoded form of a
* base64 encoded string
* Requirements:
* 1. input must not be null
* 2. input must be greater than or equal to zero
*/
int base64_dec_len(char *input, int inputLen);
#endif // _BASE64_H

View File

@@ -0,0 +1,175 @@
/*********************************************************************
* function 设备配置和系统功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Config.h"
#define LED 15 // LED指示灯引脚
WiFiClient wifiClient;
PubSubClient mqttClient;
float rssi = 0;
char wumei_iv[17] = "wumei-smart-open";
int monitorCount = 0;
long monitorInterval = 1000;
bool isApMode = false;
// Mqtt订阅的主题前缀格式为 /productId/devicenumber
String prefix = "";
String sInfoTopic = "/info/get";
String sOtaTopic = "/ota/get";
String sNtpTopic = "/ntp/get";
String sPropertyTopic = "/property/get";
String sFunctionTopic = "/function/get";
String sPropertyOnline = "/property-online/get";
String sFunctionOnline = "/function-online/get";
String sMonitorTopic = "/monitor/get";
// Mqtt发布的主题
String pInfoTopic = "/info/post";
String pNtpTopic = "/ntp/post";
String pPropertyTopic = "/property/post";
String pFunctionTopic = "/function/post";
String pMonitorTopic = "/monitor/post";
String pEventTopic = "/event/post";
/********************************** begin 可配置的项 **********************************/
// wifi信息
char *wifiSsid = "MERCURY100";
char *wifiPwd = "164770707";
char *userId = "1";
// 产品启用授权码,则授权码不能为空
char *authCode = "";
// 设备信息配置
char *deviceNum = "D1H2584G22Q2";
char *productId = "41";
float firmwareVersion = 1.0;
// 经度和纬度可选,如果产品使用设备定位,则必须传
float latitude = 0;
float longitude = 0;
// Mqtt配置
char *mqttHost = "43.143.82.218";
int mqttPort = 1883;
char *mqttUserName = "wumei-smart";
char *mqttPwd = "P47T6OD5IPFWHUM6";
char mqttSecret[17] = "KX3TSH4Q4OS835DO";
// NTP地址用于获取时间,修改为自己部署项目的接口地址)
String ntpServer = "http://wumei.live:8080/iot/tool/ntp?deviceSendTime=";
/********************************** end 可配置的项 **********************************/
// 连接wifi
void connectWifi() {
if (isApMode) {
// 关闭AP配网模式延迟2秒确保返回状态码给手机
isApMode = false;
delay(2000);
server.stop();
ledStatus(false);
}
printMsg("连接Wifi ");
Serial.print(wifiSsid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifiSsid, wifiPwd);
}
// 存储配置
void saveConfig(config_type config) {
// 标识为已经存储数据
config.flag = 1;
EEPROM.begin(240);
printMsg("存储配置...");
uint8_t *p = (uint8_t *)(&config);
for (int i = 0; i < sizeof(config); i++) {
EEPROM.write(i, *(p + i));
}
EEPROM.end();
}
// 加载配置
void loadConfig() {
config_type config;
EEPROM.begin(240);
printMsg("加载配置...");
uint8_t *p = (uint8_t *)(&config);
for (int i = 0; i < sizeof(config); i++) {
*(p + i) = EEPROM.read(i);
}
if (config.flag != 1) {
printMsg("flash暂无数据");
return;
}
// wifi名称
if (strlen(config.stassid) != 0) {
wifiSsid = (char *)malloc(32 * sizeof(char));
strcpy(wifiSsid, config.stassid);
}
// wifi密码
if (strlen(config.stapsw) != 0) {
wifiPwd = (char *)malloc(64 * sizeof(char));
strcpy(wifiPwd, config.stapsw);
}
// 设备编号
if (strlen(config.deviceNum) != 0) {
deviceNum = (char *)malloc(32 * sizeof(char));
strcpy(deviceNum, config.deviceNum);
}
// 用户编号
if (strlen(config.userId) != 0) {
userId = (char *)malloc(16 * sizeof(char));
strcpy(userId, config.userId);
}
// 授权码
if (strlen(config.authCode) != 0) {
authCode = (char *)malloc(32 * sizeof(char));
strcpy(authCode, config.authCode);
}
// 统一设置Mqtt消息主题前缀
prefix = "/" + (String)productId + "/" + (String)deviceNum;
}
// 清空配置
void clearConfig() {
EEPROM.begin(240);
for (int i = 0; i < 240; i++) {
EEPROM.write(i, 0);
}
EEPROM.end();
}
//打印提示信息
void printMsg(String msg) {
Serial.print("\r\n[");
Serial.print(millis());
Serial.print("ms]");
Serial.print(msg);
}
// 控制指示灯闪烁
void blink() {
printMsg("指示灯闪烁...");
pinMode(LED, OUTPUT);
for (int i = 0; i < 2; i++) {
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
}
}
// 控制指示灯状态
void ledStatus(bool status) {
printMsg("更改指示灯状态");
pinMode(LED, OUTPUT);
if (status) {
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}

View File

@@ -0,0 +1,87 @@
/*********************************************************************
* function 设备配置和系统功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _CONFIG_H
#define _CONFIG_H
#include "Apconfig.h"
#include "Base64.h"
#include <ESP8266WiFi.h>
#include <EEPROM.h>
#include <PubSubClient.h> // 版本2.8.0
#include <ArduinoJson.h> // 版本6.19.1
// 存储的配置类型结构
struct config_type {
char flag; // 是否有数据标识等于1表示有数据
char stassid[32]; // SSID配置项
char stapsw[64]; // Password配置项
char deviceNum[32]; // 设备编号配置项
char userId[16]; // 用户ID配置项
char authCode[32]; // 授权码配置项
};
extern WiFiClient wifiClient;
extern PubSubClient mqttClient;
// 全局变量
extern char *deviceNum; // 设备编号重要同时是Mqtt的clientId
extern char *userId; // 用户ID
extern char *productId; // 产品ID
extern float rssi; // 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85]
extern float firmwareVersion; // 固件版本
extern float latitude; // 设备精度
extern float longitude; // 设备维度
extern char *wifiSsid; // WIFI的SSID
extern char *wifiPwd; // WIFI的密码
extern char *mqttHost; // Mqtt消息服务器地址
extern int mqttPort; // Mqtt消息服务器端口
extern char *mqttUserName; // Mqtt消息服务器账号
extern char *mqttPwd; // Mqtt消息服务器密码
extern char mqttSecret[17]; // Mqtt秘钥,16位
extern char wumei_iv[17]; // AES加密偏移量固定值16位
extern char *authCode; // 产品授权码,产品未启用时为空字符串
extern String ntpServer; // NTP服务地址用于获取当前时间
extern int monitorCount; // 发布监测数据的最大次数
extern long monitorInterval; // 发布监测数据的间隔默认1000毫秒
extern bool isApMode; // 是否进入AP配网模式
// 订阅的主题
extern String prefix; // Mqtt消息主题前缀
extern String sInfoTopic; // 订阅设备信息
extern String sOtaTopic; // 订阅OTA升级
extern String sNtpTopic; // 订阅NTP时间
extern String sPropertyTopic; // 订阅属性
extern String sFunctionTopic; // 订阅功能
extern String sPropertyOnline; // 订阅属性-在线模式
extern String sFunctionOnline; // 订阅功能-在线模式
extern String sMonitorTopic; // 订阅实时监测
// 发布的主题
extern String pInfoTopic; // 发布设备信息
extern String pNtpTopic; // 发布NTP时间
extern String pPropertyTopic; // 发布属性
extern String pFunctionTopic; // 发布功能
extern String pMonitorTopic; // 发布实时监测数据
extern String pEventTopic; // 发布事件
// 连接WIFI
void connectWifi();
// 加载配置
void loadConfig();
// 保存配置
void saveConfig(config_type config);
// 清空配置
void clearConfig();
//打印提示信息
void printMsg(String msg);
// 控制指示灯闪烁
void blink();
// 控制指示灯状态
void ledStatus(bool status);
#endif

View File

@@ -0,0 +1,126 @@
/*********************************************************************
* function 程序入口
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Config.h"
#include "Auth.h"
#include "Apconfig.h"
#include "User.h"
long lastWifiConn; // 上次wifi连接时间
long lastMqttConn; // 上次mqtt连接时间
long lastPublishMonitor; // 上次发布监测数据时间
long lastPublishSimulateData; // 上次发布测试数据时间
/**
* 启动
*/
void setup() {
//打开串行端口:
Serial.begin(115200);
printMsg("FastBee device starting...");
// 加载配置
loadConfig();
// 初始化用户配置
initUser();
if (strcmp(wifiSsid, "") == 0) {
// 启动配网
startApConfig();
} else {
// 连接Wifi
connectWifi();
}
}
/**
* 循环执行
*/
void loop() {
// 监测按钮
button.tick();
if (isApMode) {
// 配网时的Web服务
server.handleClient();
} else {
// Wifi重连
wifiReconnectionClient();
// Mqtt连接
mqttReconnectionClient();
// 发布实时监测数据
publicMonitorClient();
// 发布模拟数据,测试用
publishSimulateDataClient();
}
}
/*
* Wifi掉线重连(非阻塞间隔5s)
*/
void wifiReconnectionClient() {
long now = millis();
if (WiFi.status() != WL_CONNECTED) {
if (now - lastWifiConn > 5000) {
lastWifiConn = now;
WiFi.reconnect();
}
}
}
/*
* mqtt连接(非阻塞、间隔5s)
*/
void mqttReconnectionClient() {
if (WiFi.status() == WL_CONNECTED) {
long now = millis();
if (!mqttClient.connected()) {
if (now - lastMqttConn > 5000) {
lastMqttConn = now;
connectMqtt();
}
} else {
mqttClient.loop();
}
}
}
/*
* 发布实时监测数据非阻塞、间隔默认1秒
*/
void publicMonitorClient() {
if (WiFi.status() == WL_CONNECTED && monitorCount > 0) {
long now = millis();
if (now - lastPublishMonitor > monitorInterval) {
lastPublishMonitor = now;
monitorCount--;
String msg = randomPropertyData();
publishMonitor(msg);
}
}
}
/*
* 发布模拟数据非阻塞、仅用于测试间隔3600秒
*/
void publishSimulateDataClient() {
if (WiFi.status() == WL_CONNECTED) {
long now = millis();
if (now - lastPublishSimulateData > 3600000) {
lastPublishSimulateData = now;
printMsg("执行定时上报");
// 发布事件
processEvent();
// 发布时钟同步
publishNtp();
// 发布属性(监测值)
String msg = randomPropertyData();
publishProperty(msg);
}
}
}

View File

@@ -0,0 +1,87 @@
/*********************************************************************
* function 设备交互
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Mqtt.h"
// 订阅系统主题
void subscribeTopic() {
mqttClient.subscribe((prefix + sInfoTopic).c_str(), 1);
mqttClient.subscribe((prefix + sOtaTopic).c_str(), 1);
mqttClient.subscribe((prefix + sNtpTopic).c_str(), 1);
mqttClient.subscribe((prefix + sPropertyTopic).c_str(), 1);
mqttClient.subscribe((prefix + sFunctionTopic).c_str(), 1);
mqttClient.subscribe((prefix + sPropertyOnline).c_str(), 1);
mqttClient.subscribe((prefix + sFunctionOnline).c_str(), 1);
mqttClient.subscribe((prefix + sMonitorTopic).c_str(), 1);
printMsg("订阅主题完成");
}
// 1.发布设备信息
void publishInfo() {
StaticJsonDocument<256> doc;
doc["rssi"] = WiFi.RSSI();
doc["firmwareVersion"] = firmwareVersion;
doc["status"] = 3; // 1-未激活2-禁用3-在线4-离线)
doc["userId"] = (String)userId;
doc["longitude"] = longitude; //经度 可选
doc["latitude"] = latitude; // 纬度 可选
// 设备摘要,可选(自定义配置信息)
JsonObject summary = doc.createNestedObject("summary");
summary["name"] = "wumei-smart";
summary["chip"] = "esp8266";
summary["author"] = "kerwincui";
summary["version"] = 1.6;
summary["create"] = "2022-06-06";
printMsg("发布设备信息:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
printMsg("主题为:" + prefix + pInfoTopic);
mqttClient.publish((prefix + pInfoTopic).c_str(), output.c_str());
}
// 2.发布时钟同步信,用于获取当前时间(可选)
void publishNtp() {
StaticJsonDocument<128> doc;
doc["deviceSendTime"] = millis();
printMsg("发布主题:" + prefix + pNtpTopic);
printMsg("信息:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
mqttClient.publish((prefix + pNtpTopic).c_str(), output.c_str());
}
// 3.发布属性
void publishProperty(String msg) {
printMsg("发布属性:" + prefix + pPropertyTopic);
printMsg("消息:" + msg);
mqttClient.publish((prefix + pPropertyTopic).c_str(), msg.c_str());
}
// 4.发布功能
void publishFunction(String msg) {
printMsg("发布功能:" + prefix + pFunctionTopic);
printMsg("消息:" + msg);
mqttClient.publish((prefix + pFunctionTopic).c_str(), msg.c_str());
}
// 5.发布事件
void publishEvent(String msg) {
printMsg("发布事件:" + prefix + pEventTopic);
printMsg("消息:" + msg);
mqttClient.publish((prefix + pEventTopic).c_str(), msg.c_str());
}
// 6.发布实时监测数据
void publishMonitor(String msg) {
// 发布实时监测数据(不会存储,需要实时存储则发布为属性)
printMsg("发布实时监测消息:" + msg);
mqttClient.publish((prefix + pMonitorTopic).c_str(), msg.c_str());
}

View File

@@ -0,0 +1,29 @@
/*********************************************************************
* function 设备交互
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _MQTT_H
#define _MQTT_H
#include "Config.h"
// 订阅系统主题
void subscribeTopic();
// 发布设备信息
void publishInfo();
// 发布时钟同步信息
void publishNtp();
// 发布事件
void publishEvent(String msg);
// 发布实时监测数据(不会存储,需要实时存储则发布属性)
void publishMonitor(String msg);
// 发布属性
void publishProperty(String msg);
// 发布功能
void publishFunction(String msg);
#endif

View File

@@ -0,0 +1,255 @@
/*********************************************************************
* function 用户自定义功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "User.h"
#define BUTTON 14 // 按键引脚
#define RELAY 12 // 继电器引脚
OneButton button;
// 按钮单击事件
static void buttonClick();
// 按钮双击事件
static void buttonDoubleClick();
// 按钮长按事件
static void buttonLongPress();
// 初始化用户配置
void initUser() {
// 初始化按键为低电平,并添加单击、双击、长按事件
button = OneButton(BUTTON, true, true);
button.attachClick(buttonClick);
button.attachDoubleClick(buttonDoubleClick);
button.attachLongPressStart(buttonLongPress);
}
// Mqtt回调
void mqttCallback(char *topic, byte *payload, unsigned int length) {
blink();
printMsg("接收数据:");
String data = "";
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
data += (char)payload[i];
}
if (strcmp(topic, (prefix + sOtaTopic).c_str()) == 0) {
printMsg("订阅到设备升级指令...");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
String newVersion = doc["version"];
String downloadUrl = doc["downloadUrl"];
printMsg("固件版本:" + newVersion);
printMsg("下载地址:" + downloadUrl);
} else if (strcmp(topic, (prefix + sInfoTopic).c_str()) == 0) {
printMsg("订阅到设备信息...");
// 发布设备信息
publishInfo();
} else if (strcmp(topic, (prefix + sNtpTopic).c_str()) == 0) {
printMsg("订阅到NTP时间...");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
// 计算设备当前时间:(${serverRecvTime} + ${serverSendTime} + ${deviceRecvTime} - ${deviceSendTime}) / 2
float deviceSendTime = doc["deviceSendTime"];
float serverSendTime = doc["serverSendTime"];
float serverRecvTime = doc["serverRecvTime"];
float deviceRecvTime = millis();
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
printMsg("当前时间:" + String(now, 0));
} else if (strcmp(topic, (prefix + sPropertyTopic).c_str()) == 0 || strcmp(topic, (prefix + sPropertyOnline).c_str()) == 0) {
printMsg("订阅到属性指令...");
processProperty(data);
} else if (strcmp(topic, (prefix + sFunctionTopic).c_str()) == 0 || strcmp(topic, (prefix + sFunctionOnline).c_str()) == 0) {
printMsg("订阅到功能指令...");
processFunction(data);
} else if (strcmp(topic, (prefix + sMonitorTopic).c_str()) == 0) {
printMsg("订阅到实时监测指令...");
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
monitorCount = doc["count"];
monitorInterval = doc["interval"];
}
}
// 随机生成监测值
String randomPropertyData() {
// 匹配云端定义的监测数据,随机数代替监测值
float randFloat = 0;
int randInt = 0;
StaticJsonDocument<1024> doc;
JsonObject objTmeperature = doc.createNestedObject();
objTmeperature["id"] = "temperature";
randFloat = random(1000, 3000);
objTmeperature["value"] = (String)(randFloat / 100);
objTmeperature["remark"] = (String)millis();
JsonObject objHumidity = doc.createNestedObject();
objHumidity["id"] = "humidity";
randFloat = random(3000, 6000);
objHumidity["value"] = (String)(randFloat / 100);
objHumidity["remark"] = (String)millis();
JsonObject objCo2 = doc.createNestedObject();
objCo2["id"] = "co2";
randInt = random(400, 1000);
objCo2["value"] = (String)(randInt);
objCo2["remark"] = (String)millis();
JsonObject objBrightness = doc.createNestedObject();
objBrightness["id"] = "brightness";
randInt = random(1000, 10000);
objBrightness["value"] = (String)(randInt);
objBrightness["remark"] = (String)millis();
printMsg("模拟监测数据值:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
return output;
}
// 物模型-属性处理
void processProperty(String msg) {
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, msg);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
for (JsonObject object : doc.as<JsonArray>()) {
// 匹配云端定义的属性(不包含属性中的监测数据)
const char *id = object["id"];
const char *value = object["value"];
printMsg((String)id + "" + (String)value);
}
// 最后发布属性,服务端订阅存储(重要)
publishProperty(msg);
}
// 物模型-功能处理
void processFunction(String msg) {
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, msg);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
for (JsonObject object : doc.as<JsonArray>()) {
// 匹配云端定义的功能
const char *id = object["id"];
const char *value = object["value"];
if (strcmp(id, "switch") == 0) {
printMsg("开关 switch" + (String)value);
if (strcmp(value, "1") == 0) {
// 打开继电器
relayStatus(true);
} else if (strcmp(value, "0") == 0) {
// 关闭继电器
relayStatus(false);
}
} else if (strcmp(id, "gear") == 0) {
printMsg("档位 gear" + (String)value);
} else if (strcmp(id, "light_color") == 0) {
printMsg("灯光颜色 light_color" + (String)value);
} else if (strcmp(id, "message") == 0) {
printMsg("屏显消息 message" + (String)value);
} else if (strcmp(id, "report_monitor") == 0) {
int number = atoi(value);
number > 10 ? number = 10 : number;
for (int i = 0; i < number; i++) {
Serial.println(number);
String msg = randomPropertyData();
printMsg("订阅到上报监测数据指令,上报数据:");
printMsg(msg);
publishProperty(msg);
delay(1000);
}
}
}
// 最后发布功能,服务端订阅存储(重要)
publishFunction(msg);
}
// 物模型-事件上传
void processEvent() {
// 匹配云端的事件
StaticJsonDocument<512> doc;
JsonObject objTmeperature = doc.createNestedObject();
objTmeperature["id"] = "height_temperature";
objTmeperature["value"] = "40";
objTmeperature["remark"] = "温度过高警告";
JsonObject objException = doc.createNestedObject();
objException["id"] = "exception";
objException["value"] = "异常消息消息内容XXXXXXXX";
objException["remark"] = "设备发生错误";
printMsg("发布事件:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
// 最后发布功能,服务端订阅存储(重要)
publishEvent(output);
}
//打开继电器A
void relayStatus(bool status) {
pinMode(RELAY, OUTPUT);
if (status) {
digitalWrite(RELAY, HIGH);
} else {
digitalWrite(RELAY, LOW);
}
}
// 按钮单击事件
static void buttonClick() {
printMsg("检测到按键单击,打开继电器");
relayStatus(true);
// 匹配云端定义的开关,格式如:[{"id":"switch","value":"1"}]
String msg = "[{\"id\":\"switch\",\"value\":\"1\"}]";
publishProperty(msg);
}
// 按钮双击事件
static void buttonDoubleClick() {
printMsg("检测到按键双击,关闭继电器");
relayStatus(false);
// 匹配云端定义的开关,格式如:[{"id":"switch","value":"0"}]
String msg = "[{\"id\":\"switch\",\"value\":\"0\"}]";
publishProperty(msg);
}
// 按钮长按事件,进入配网模式
static void buttonLongPress() {
printMsg("检测到按键长按");
if (isApMode) {
printMsg("设备重启...");
ESP.restart();
} else {
printMsg("开始AP配网");
startApConfig();
}
}

View File

@@ -0,0 +1,33 @@
/*********************************************************************
* function 用户自定义功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _USER_H
#define _USER_H
#include "Config.h"
#include "Mqtt.h"
#include <OneButton.h> // 版本2.0.4
extern OneButton button;
// 初始化用户配置
void initUser();
// Mqtt回调
void mqttCallback(char *topic, byte *payload, unsigned int length);
// 属性处理(物模型)
void processProperty(String msg);
// 功能处理(物模型)
void processFunction(String msg);
// 事件处理(无模型)
void processEvent();
// 模拟监测值
String randomPropertyData();
// 控制继电器状态
void relayStatus(bool status);
#endif

View File

@@ -0,0 +1,120 @@
/*********************************************************************
* function 设备AP配网
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "ApConfig.h"
String randomName = "wumei-device" + (String)random(1000);
const char *ap_ssid = randomName.c_str();
//开放式网络,不设置密码
const char *ap_password = "";
IPAddress local_IP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
ESP8266WebServer server(80);
/**
* 启动AP配网
*/
void startApConfig() {
ledStatus(true);
WiFi.mode(WIFI_AP_STA);
WiFi.softAPConfig(local_IP, gateway, subnet);
WiFi.softAP(ap_ssid, ap_password);
printMsg("已启动AP配网IP地址" + WiFi.softAPIP().toString() + " 热点名称:" + (String)ap_ssid);
// 启动web服务
startWebServer();
}
/**
* 启动Web服务
*/
void startWebServer() {
isApMode = true;
server.on("/status", HTTP_GET, handleStatus);
server.on("/config", HTTP_POST, handleConfig);
server.onNotFound(handleNotFound);
server.enableCORS(true);
server.begin();
printMsg("HTTP服务已启动");
}
/**
* 检测设备接口
*/
void handleStatus() {
server.send(200, "text/plain;charset=utf-8", "AP配网已准备就绪");
}
/**
* AP配网接口
*/
void handleConfig() {
printMsg("进入配网......");
config_type config;
// wifi名称、wifi密码、用户编号
if (server.hasArg("SSID") && server.hasArg("password") && server.hasArg("userId")) {
// 分配空间
wifiSsid = (char *)malloc(32 * sizeof(char));
wifiPwd = (char *)malloc(64 * sizeof(char));
userId = (char *)malloc(16 * sizeof(char));
strcpy(config.stassid, server.arg("SSID").c_str());
strcpy(wifiSsid, server.arg("SSID").c_str());
strcpy(config.stapsw, server.arg("password").c_str());
strcpy(wifiPwd, server.arg("password").c_str());
strcpy(config.userId, server.arg("userId").c_str());
strcpy(userId, server.arg("userId").c_str());
printMsg("收到WIFI名称" + (String)config.stassid);
printMsg("收到WIFI密码" + (String)config.stapsw);
printMsg("收到用户编号:" + (String)config.userId);
} else {
printMsg("配网必须传递用户编号、WIFI名称和WIFI密码,配网失败");
server.send(500, "text/plain;charset=utf-8", "配网必须传递用户编号、WIFI名称和WIFI密码配网失败");
return;
}
// 可选字段
if (server.hasArg("deviceNum")) {
deviceNum = (char *)malloc(32 * sizeof(char));
strcpy(config.deviceNum, server.arg("deviceNum").c_str());
strcpy(deviceNum, server.arg("deviceNum").c_str());
printMsg("收到设备编号:" + server.arg("deviceNum"));
}
if (server.hasArg("authCode")) {
authCode = (char *)malloc(32 * sizeof(char));
strcpy(config.authCode, server.arg("authCode").c_str());
strcpy(authCode, server.arg("authCode").c_str());
printMsg("收到产品授权码:" + server.arg("authCode"));
}
if (server.hasArg("extra")) {
printMsg("收到补充信息:" + server.arg("extra"));
}
server.send(200, "text/plain;charset=utf-8", "设备已更新WIFI配置开始连接WIFI...");
// 统一设置Mqtt消息主题前缀
prefix = "/" + (String)productId + "/" + (String)deviceNum;
// 存储配置
saveConfig(config);
// 连接Wifi
connectWifi();
}
/**
* 找不到页面和跨域处理
*/
void handleNotFound() {
printMsg("进入预检请求或请求地址找不到");
if (server.method() == HTTP_OPTIONS) {
// 处理浏览器跨域问题
server.sendHeader("Access-Control-Max-Age", "10000");
server.sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS");
server.sendHeader("Access-Control-Allow-Headers", "*");
server.send(204);
} else {
server.send(404, "text/plain;charset=utf-8", "请求的地址找不到或无法访问");
}
}

View File

@@ -0,0 +1,28 @@
/*********************************************************************
* function 设备AP配网
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _APCONFIG_H
#define _APCONFIG_H
#include "Config.h"
#include <ESP8266WebServer.h>
extern ESP8266WebServer server;
// 启动AP配网
void startApConfig();
// 启动Web服务
void startWebServer();
// 配网接口
void handleConfig();
// 检测设备接口
void handleStatus();
// 找不到页面和浏览器跨域处理
void handleNotFound();
#endif

View File

@@ -0,0 +1,156 @@
/*********************************************************************
* function 设备认证
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Auth.h"
/*
* 连接MQTT加密认证
*/
void connectMqtt() {
printMsg("连接Mqtt服务器...");
mqttClient.setClient(wifiClient);
mqttClient.setServer(mqttHost, mqttPort);
mqttClient.setBufferSize(1024);
mqttClient.setKeepAlive(5);
// 设置Mqtt回调函数
mqttClient.setCallback(mqttCallback);
// 生成mqtt加密密码
String aesPassword = generationAESPwd();
// 连接 设备mqtt客户端Id格式为认证类型(E=加密、S=简单) & 设备编号 & 产品ID & 用户ID
String clientId = "E&" + (String)deviceNum + "&" + (String)productId + "&" + (String)userId;
printMsg("客户端ID" + clientId);
bool connectResult = mqttClient.connect(clientId.c_str(), mqttUserName, aesPassword.c_str());
if (connectResult) {
printMsg("连接Mqtt成功");
// 订阅系统主题
subscribeTopic();
// 发布设备信息,设备上电都需要发布一次
publishInfo();
} else {
printMsg("连接失败, rc=");
Serial.print(mqttClient.state());
}
}
/*
* 生成加密密码
*/
String generationAESPwd() {
// 获取NTP时间
String jsonTime = getTime();
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, jsonTime);
if (error) {
printMsg("Json解析失败");
Serial.print(error.f_str());
return "";
}
// 获取NTP时间=(设备发送消息时间 + 服务器接收消息时间 + 服务器发送消息时间 - 设备接收时间 最后除于2
float deviceSendTime = doc["deviceSendTime"];
float serverSendTime = doc["serverSendTime"];
float serverRecvTime = doc["serverRecvTime"];
float deviceRecvTime = millis();
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
// 过期时间 = 当前时间 + 1小时
float expireTime = now + 1 * 60 * 60 * 1000;
// 加密认证密码格式为mqtt密码 & 过期时间 & 授权码(可选),如果产品启用了授权码就必须加上
String password = "";
if (authCode == "") {
password = (String)mqttPwd + "&" + String(expireTime, 0);
} else {
password = (String)mqttPwd + "&" + String(expireTime, 0) + "&" + authCode;
}
// 密码加密
printMsg("密码(未加密):" + password);
String encryptPassword = encrypt(password, mqttSecret, wumei_iv);
printMsg("密码(已加密)" + encryptPassword);
return encryptPassword;
}
/*
* 通过HTTP获取NTP时间
*/
String getTime() {
while (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
printMsg("获取时间...");
if (http.begin(wifiClient, (ntpServer + (String)millis()).c_str())) {
// 发送请求
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
printMsg("获取时间成功data:");
Serial.print(http.getString());
return http.getString();
}
} else {
printMsg("获取时间失败error:");
Serial.printf(http.errorToString(httpCode).c_str());
}
http.end();
} else {
printMsg("连接Http失败");
}
delay(500);
}
return "1672524366000";
}
/*
* AES加密 (AES-CBC-128-pkcs5padding)
*/
String encrypt(String plain_data, char *wumei_key, char *wumei_iv) {
int i;
// pkcs7padding填充 Block Size : 16
int len = plain_data.length();
int n_blocks = len / 16 + 1;
uint8_t n_padding = n_blocks * 16 - len;
uint8_t data[n_blocks * 16];
memcpy(data, plain_data.c_str(), len);
for (i = len; i < n_blocks * 16; i++) {
data[i] = n_padding;
}
uint8_t key[16], iv[16];
memcpy(key, wumei_key, 16);
memcpy(iv, wumei_iv, 16);
// 加密
br_aes_big_cbcenc_keys encCtx;
br_aes_big_cbcenc_init(&encCtx, key, 16);
br_aes_big_cbcenc_run(&encCtx, iv, data, n_blocks * 16);
// Base64编码
len = n_blocks * 16;
char encoded_data[base64_enc_len(len)];
base64_encode(encoded_data, (char *)data, len);
return String(encoded_data);
}
/*
* AES解密 (AES-CBC-128-pkcs5padding)
*/
String decrypt(String encoded_data_str, char *wumei_key, char *wumei_iv) {
int input_len = encoded_data_str.length();
char *encoded_data = const_cast<char *>(encoded_data_str.c_str());
int len = base64_dec_len(encoded_data, input_len);
uint8_t data[len];
base64_decode((char *)data, encoded_data, input_len);
uint8_t key[16], iv[16];
memcpy(key, wumei_key, 16);
memcpy(iv, wumei_iv, 16);
int n_blocks = len / 16;
br_aes_big_cbcdec_keys decCtx;
br_aes_big_cbcdec_init(&decCtx, key, 16);
br_aes_big_cbcdec_run(&decCtx, iv, data, n_blocks * 16);
// PKCS#7 Padding 填充
uint8_t n_padding = data[n_blocks * 16 - 1];
len = n_blocks * 16 - n_padding;
char plain_data[len + 1];
memcpy(plain_data, data, len);
plain_data[len] = '\0';
return String(plain_data);
}

View File

@@ -0,0 +1,29 @@
/*********************************************************************
* function 设备认证
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _AUTH_H
#define _AUTH_H
#include "Config.h"
#include "User.h"
#include "Mqtt.h"
#include <Ethernet.h>
#include <ESP8266HTTPClient.h>
// 连接mqtt, AES加密认证
void connectMqtt();
// 生成加密密码
String generationAESPwd();
// 获取时间
String getTime();
// AES加密
String encrypt(String plain_data, char *wumei_key, char *wumei_iv);
// AES解密
String decrypt(String encoded_data_str, char *wumei_key, char *wumei_iv);
#endif

View File

@@ -0,0 +1,173 @@
/*********************************************************************
* function Base64编码和解码
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: Copyright (c) 2013 Adam Rudd.
********************************************************************/
#include "Base64.h"
#if (defined(__AVR__))
#include <avr\pgmspace.h>
#else
#include <pgmspace.h>
#endif
const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
/* 'Private' declarations */
inline void a3_to_a4(unsigned char *a4, unsigned char *a3);
inline void a4_to_a3(unsigned char *a3, unsigned char *a4);
inline unsigned char b64_lookup(char c);
int base64_encode(char *output, char *input, int inputLen)
{
int i = 0, j = 0;
int encLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--)
{
a3[i++] = *(input++);
if (i == 3)
{
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++)
{
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]);
}
i = 0;
}
}
if (i)
{
for (j = i; j < 3; j++)
{
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++)
{
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]);
}
while ((i++ < 3))
{
output[encLen++] = '=';
}
}
output[encLen] = '\0';
return encLen;
}
int base64_decode(char *output, char *input, int inputLen)
{
int i = 0, j = 0;
int decLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--)
{
if (*input == '=')
{
break;
}
a4[i++] = *(input++);
if (i == 4)
{
for (i = 0; i < 4; i++)
{
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3, a4);
for (i = 0; i < 3; i++)
{
output[decLen++] = a3[i];
}
i = 0;
}
}
if (i)
{
for (j = i; j < 4; j++)
{
a4[j] = '\0';
}
for (j = 0; j < 4; j++)
{
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3, a4);
for (j = 0; j < i - 1; j++)
{
output[decLen++] = a3[j];
}
}
output[decLen] = '\0';
return decLen;
}
int base64_enc_len(int plainLen)
{
int n = plainLen;
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}
int base64_dec_len(char *input, int inputLen)
{
int i = 0;
int numEq = 0;
for (i = inputLen - 1; input[i] == '='; i--)
{
numEq++;
}
return ((6 * inputLen) / 8) - numEq;
}
inline void a3_to_a4(unsigned char *a4, unsigned char *a3)
{
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
inline void a4_to_a3(unsigned char *a3, unsigned char *a4)
{
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
inline unsigned char b64_lookup(char c)
{
if (c >= 'A' && c <= 'Z')
return c - 'A';
if (c >= 'a' && c <= 'z')
return c - 71;
if (c >= '0' && c <= '9')
return c + 4;
if (c == '+')
return 62;
if (c == '/')
return 63;
return -1;
}

View File

@@ -0,0 +1,84 @@
/*********************************************************************
* function Base64编码和解码
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: Copyright (c) 2013 Adam Rudd.
********************************************************************/
#ifndef _BASE64_H
#define _BASE64_H
/* b64_alphabet:
* Description: Base64 alphabet table, a mapping between integers
* and base64 digits
* Notes: This is an extern here but is defined in Base64.c
*/
extern const char b64_alphabet[];
/* base64_encode:
* Description:
* Encode a string of characters as base64
* Parameters:
* output: the output buffer for the encoding, stores the encoded string
* input: the input buffer for the encoding, stores the binary to be encoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the encoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_encode(char *output, char *input, int inputLen);
/* base64_decode:
* Description:
* Decode a base64 encoded string into bytes
* Parameters:
* output: the output buffer for the decoding,
* stores the decoded binary
* input: the input buffer for the decoding,
* stores the base64 string to be decoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the decoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_decode(char *output, char *input, int inputLen);
/* base64_enc_len:
* Description:
* Returns the length of a base64 encoded string whose decoded
* form is inputLen bytes long
* Parameters:
* inputLen: the length of the decoded string
* Return value:
* The length of a base64 encoded string whose decoded form
* is inputLen bytes long
* Requirements:
* None
*/
int base64_enc_len(int inputLen);
/* base64_dec_len:
* Description:
* Returns the length of the decoded form of a
* base64 encoded string
* Parameters:
* input: the base64 encoded string to be measured
* inputLen: the length of the base64 encoded string
* Return value:
* Returns the length of the decoded form of a
* base64 encoded string
* Requirements:
* 1. input must not be null
* 2. input must be greater than or equal to zero
*/
int base64_dec_len(char *input, int inputLen);
#endif // _BASE64_H

View File

@@ -0,0 +1,175 @@
/*********************************************************************
* function 设备配置和系统功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Config.h"
#define LED 15 // LED指示灯引脚
WiFiClient wifiClient;
PubSubClient mqttClient;
float rssi = 0;
char wumei_iv[17] = "wumei-smart-open";
int monitorCount = 0;
long monitorInterval = 1000;
bool isApMode = false;
// Mqtt订阅的主题前缀格式为 /productId/devicenumber
String prefix = "";
String sInfoTopic = "/info/get";
String sOtaTopic = "/ota/get";
String sNtpTopic = "/ntp/get";
String sPropertyTopic = "/property/get";
String sFunctionTopic = "/function/get";
String sPropertyOnline = "/property-online/get";
String sFunctionOnline = "/function-online/get";
String sMonitorTopic = "/monitor/get";
// Mqtt发布的主题
String pInfoTopic = "/info/post";
String pNtpTopic = "/ntp/post";
String pPropertyTopic = "/property/post";
String pFunctionTopic = "/function/post";
String pMonitorTopic = "/monitor/post";
String pEventTopic = "/event/post";
/********************************** begin 可配置的项 **********************************/
// wifi信息
char *wifiSsid = "MERCURY100";
char *wifiPwd = "FastBee";
char *userId = "1";
// 产品启用授权码,则授权码不能为空
char *authCode = "";
// 设备信息配置
char *deviceNum = "D1PGLPG58KZ2";
char *productId = "96";
float firmwareVersion = 1.0;
// 经度和纬度可选,如果产品使用设备定位,则必须传
float latitude = 0;
float longitude = 0;
// Mqtt配置
char *mqttHost = "43.143.82.218";
int mqttPort = 1883;
char *mqttUserName = "FastBee";
char *mqttPwd = "P467433O1MT8MXS2";
char mqttSecret[17] = "KWF32S3H95LH14LO";
// NTP地址用于获取时间,修改为自己部署项目的接口地址)
String ntpServer = "http://wumei.live:8080/iot/tool/ntp?deviceSendTime=";
/********************************** end 可配置的项 **********************************/
// 连接wifi
void connectWifi() {
if (isApMode) {
// 关闭AP配网模式延迟2秒确保返回状态码给手机
isApMode = false;
delay(2000);
server.stop();
ledStatus(false);
}
printMsg("连接Wifi ");
Serial.print(wifiSsid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifiSsid, wifiPwd);
}
// 存储配置
void saveConfig(config_type config) {
// 标识为已经存储数据
config.flag = 1;
EEPROM.begin(240);
printMsg("存储配置...");
uint8_t *p = (uint8_t *)(&config);
for (int i = 0; i < sizeof(config); i++) {
EEPROM.write(i, *(p + i));
}
EEPROM.end();
}
// 加载配置
void loadConfig() {
config_type config;
EEPROM.begin(240);
printMsg("加载配置...");
uint8_t *p = (uint8_t *)(&config);
for (int i = 0; i < sizeof(config); i++) {
*(p + i) = EEPROM.read(i);
}
if (config.flag != 1) {
printMsg("flash暂无数据");
return;
}
// wifi名称
if (strlen(config.stassid) != 0) {
wifiSsid = (char *)malloc(32 * sizeof(char));
strcpy(wifiSsid, config.stassid);
}
// wifi密码
if (strlen(config.stapsw) != 0) {
wifiPwd = (char *)malloc(64 * sizeof(char));
strcpy(wifiPwd, config.stapsw);
}
// 设备编号
if (strlen(config.deviceNum) != 0) {
deviceNum = (char *)malloc(32 * sizeof(char));
strcpy(deviceNum, config.deviceNum);
}
// 用户编号
if (strlen(config.userId) != 0) {
userId = (char *)malloc(16 * sizeof(char));
strcpy(userId, config.userId);
}
// 授权码
if (strlen(config.authCode) != 0) {
authCode = (char *)malloc(32 * sizeof(char));
strcpy(authCode, config.authCode);
}
// 统一设置Mqtt消息主题前缀
prefix = "/" + (String)productId + "/" + (String)deviceNum;
}
// 清空配置
void clearConfig() {
EEPROM.begin(240);
for (int i = 0; i < 240; i++) {
EEPROM.write(i, 0);
}
EEPROM.end();
}
//打印提示信息
void printMsg(String msg) {
Serial.print("\r\n[");
Serial.print(millis());
Serial.print("ms]");
Serial.print(msg);
}
// 控制指示灯闪烁
void blink() {
printMsg("指示灯闪烁...");
pinMode(LED, OUTPUT);
for (int i = 0; i < 2; i++) {
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
delay(100);
}
}
// 控制指示灯状态
void ledStatus(bool status) {
printMsg("更改指示灯状态");
pinMode(LED, OUTPUT);
if (status) {
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}

View File

@@ -0,0 +1,87 @@
/*********************************************************************
* function 设备配置和系统功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _CONFIG_H
#define _CONFIG_H
#include "Apconfig.h"
#include "Base64.h"
#include <ESP8266WiFi.h>
#include <EEPROM.h>
#include <PubSubClient.h> // 版本2.8.0
#include <ArduinoJson.h> // 版本6.19.1
// 存储的配置类型结构
struct config_type {
char flag; // 是否有数据标识等于1表示有数据
char stassid[32]; // SSID配置项
char stapsw[64]; // Password配置项
char deviceNum[32]; // 设备编号配置项
char userId[16]; // 用户ID配置项
char authCode[32]; // 授权码配置项
};
extern WiFiClient wifiClient;
extern PubSubClient mqttClient;
// 全局变量
extern char *deviceNum; // 设备编号重要同时是Mqtt的clientId
extern char *userId; // 用户ID
extern char *productId; // 产品ID
extern float rssi; // 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85]
extern float firmwareVersion; // 固件版本
extern float latitude; // 设备精度
extern float longitude; // 设备维度
extern char *wifiSsid; // WIFI的SSID
extern char *wifiPwd; // WIFI的密码
extern char *mqttHost; // Mqtt消息服务器地址
extern int mqttPort; // Mqtt消息服务器端口
extern char *mqttUserName; // Mqtt消息服务器账号
extern char *mqttPwd; // Mqtt消息服务器密码
extern char mqttSecret[17]; // Mqtt秘钥,16位
extern char wumei_iv[17]; // AES加密偏移量固定值16位
extern char *authCode; // 产品授权码,产品未启用时为空字符串
extern String ntpServer; // NTP服务地址用于获取当前时间
extern int monitorCount; // 发布监测数据的最大次数
extern long monitorInterval; // 发布监测数据的间隔默认1000毫秒
extern bool isApMode; // 是否进入AP配网模式
// 订阅的主题
extern String prefix; // Mqtt消息主题前缀
extern String sInfoTopic; // 订阅设备信息
extern String sOtaTopic; // 订阅OTA升级
extern String sNtpTopic; // 订阅NTP时间
extern String sPropertyTopic; // 订阅属性
extern String sFunctionTopic; // 订阅功能
extern String sPropertyOnline; // 订阅属性-在线模式
extern String sFunctionOnline; // 订阅功能-在线模式
extern String sMonitorTopic; // 订阅实时监测
// 发布的主题
extern String pInfoTopic; // 发布设备信息
extern String pNtpTopic; // 发布NTP时间
extern String pPropertyTopic; // 发布属性
extern String pFunctionTopic; // 发布功能
extern String pMonitorTopic; // 发布实时监测数据
extern String pEventTopic; // 发布事件
// 连接WIFI
void connectWifi();
// 加载配置
void loadConfig();
// 保存配置
void saveConfig(config_type config);
// 清空配置
void clearConfig();
//打印提示信息
void printMsg(String msg);
// 控制指示灯闪烁
void blink();
// 控制指示灯状态
void ledStatus(bool status);
#endif

View File

@@ -0,0 +1,126 @@
/*********************************************************************
* function 程序入口
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Config.h"
#include "Auth.h"
#include "Apconfig.h"
#include "User.h"
long lastWifiConn; // 上次wifi连接时间
long lastMqttConn; // 上次mqtt连接时间
long lastPublishMonitor; // 上次发布监测数据时间
long lastPublishSimulateData; // 上次发布测试数据时间
/**
* 启动
*/
void setup() {
//打开串行端口:
Serial.begin(115200);
printMsg("FastBee device starting...");
// 加载配置
loadConfig();
// 初始化用户配置
initUser();
if (strcmp(wifiSsid, "") == 0) {
// 启动配网
startApConfig();
} else {
// 连接Wifi
connectWifi();
}
}
/**
* 循环执行
*/
void loop() {
// 监测按钮
button.tick();
if (isApMode) {
// 配网时的Web服务
server.handleClient();
} else {
// Wifi重连
wifiReconnectionClient();
// Mqtt连接
mqttReconnectionClient();
// 发布实时监测数据
publicMonitorClient();
// 上报监测数据
publishReportDataClient();
}
}
/*
* Wifi掉线重连(非阻塞间隔5s)
*/
void wifiReconnectionClient() {
long now = millis();
if (WiFi.status() != WL_CONNECTED) {
if (now - lastWifiConn > 5000) {
lastWifiConn = now;
WiFi.reconnect();
}
}
}
/*
* mqtt连接(非阻塞、间隔5s)
*/
void mqttReconnectionClient() {
if (WiFi.status() == WL_CONNECTED) {
long now = millis();
if (!mqttClient.connected()) {
if (now - lastMqttConn > 5000) {
lastMqttConn = now;
connectMqtt();
}
} else {
mqttClient.loop();
}
}
}
/*
* 发布实时监测数据非阻塞、间隔默认1秒
*/
void publicMonitorClient() {
if (WiFi.status() == WL_CONNECTED && monitorCount > 0) {
long now = millis();
if (now - lastPublishMonitor > monitorInterval) {
lastPublishMonitor = now;
monitorCount--;
String msg = randomMonitorData();
publishMonitor(msg);
}
}
}
/*
* 上报监测数据非阻塞、仅用于测试间隔3600秒
*/
void publishReportDataClient() {
if (WiFi.status() == WL_CONNECTED) {
long now = millis();
if (now - lastPublishSimulateData > 3600000) {
lastPublishSimulateData = now;
printMsg("执行定时上报");
// 发布事件
processEvent();
// 发布时钟同步
publishNtp();
// 发布属性(监测值)
String msg = randomPropertyData();
publishProperty(msg);
}
}
}

View File

@@ -0,0 +1,87 @@
/*********************************************************************
* function 设备交互
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "Mqtt.h"
// 订阅系统主题
void subscribeTopic() {
mqttClient.subscribe((prefix + sInfoTopic).c_str(), 1);
mqttClient.subscribe((prefix + sOtaTopic).c_str(), 1);
mqttClient.subscribe((prefix + sNtpTopic).c_str(), 1);
mqttClient.subscribe((prefix + sPropertyTopic).c_str(), 1);
mqttClient.subscribe((prefix + sFunctionTopic).c_str(), 1);
mqttClient.subscribe((prefix + sPropertyOnline).c_str(), 1);
mqttClient.subscribe((prefix + sFunctionOnline).c_str(), 1);
mqttClient.subscribe((prefix + sMonitorTopic).c_str(), 1);
printMsg("订阅主题完成");
}
// 1.发布设备信息
void publishInfo() {
StaticJsonDocument<256> doc;
doc["rssi"] = WiFi.RSSI();
doc["firmwareVersion"] = firmwareVersion;
doc["status"] = 3; // 1-未激活2-禁用3-在线4-离线)
doc["userId"] = (String)userId;
doc["longitude"] = longitude; //经度 可选
doc["latitude"] = latitude; // 纬度 可选
// 设备摘要,可选(自定义配置信息)
JsonObject summary = doc.createNestedObject("summary");
summary["name"] = "wumei-smart";
summary["chip"] = "esp8266";
summary["author"] = "kerwincui";
summary["version"] = 1.6;
summary["create"] = "2022-06-06";
printMsg("发布设备信息:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
printMsg("主题为:" + prefix + pInfoTopic);
mqttClient.publish((prefix + pInfoTopic).c_str(), output.c_str());
}
// 2.发布时钟同步信,用于获取当前时间(可选)
void publishNtp() {
StaticJsonDocument<128> doc;
doc["deviceSendTime"] = millis();
printMsg("发布主题:" + prefix + pNtpTopic);
printMsg("信息:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
mqttClient.publish((prefix + pNtpTopic).c_str(), output.c_str());
}
// 3.发布属性
void publishProperty(String msg) {
printMsg("发布属性:" + prefix + pPropertyTopic);
printMsg("消息:" + msg);
mqttClient.publish((prefix + pPropertyTopic).c_str(), msg.c_str());
}
// 4.发布功能
void publishFunction(String msg) {
printMsg("发布功能:" + prefix + pFunctionTopic);
printMsg("消息:" + msg);
mqttClient.publish((prefix + pFunctionTopic).c_str(), msg.c_str());
}
// 5.发布事件
void publishEvent(String msg) {
printMsg("发布事件:" + prefix + pEventTopic);
printMsg("消息:" + msg);
mqttClient.publish((prefix + pEventTopic).c_str(), msg.c_str());
}
// 6.发布实时监测数据
void publishMonitor(String msg) {
// 发布实时监测数据(不会存储,需要实时存储则发布为属性)
printMsg("发布实时监测消息:" + msg);
mqttClient.publish((prefix + pMonitorTopic).c_str(), msg.c_str());
}

View File

@@ -0,0 +1,29 @@
/*********************************************************************
* function 设备交互
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _MQTT_H
#define _MQTT_H
#include "Config.h"
// 订阅系统主题
void subscribeTopic();
// 发布设备信息
void publishInfo();
// 发布时钟同步信息
void publishNtp();
// 发布事件
void publishEvent(String msg);
// 发布实时监测数据(不会存储,需要实时存储则发布属性)
void publishMonitor(String msg);
// 发布属性
void publishProperty(String msg);
// 发布功能
void publishFunction(String msg);
#endif

View File

@@ -0,0 +1,506 @@
/*********************************************************************
* function 用户自定义功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#include "User.h"
#define BUTTON 14 // 按键引脚
#define RELAY 12 // 继电器引脚
OneButton button;
// 按钮单击事件
static void buttonClick();
// 按钮双击事件
static void buttonDoubleClick();
// 按钮长按事件
static void buttonLongPress();
// 初始化用户配置
void initUser() {
// 初始化按键为低电平,并添加单击、双击、长按事件
button = OneButton(BUTTON, true, true);
button.attachClick(buttonClick);
button.attachDoubleClick(buttonDoubleClick);
button.attachLongPressStart(buttonLongPress);
}
// Mqtt回调
void mqttCallback(char *topic, byte *payload, unsigned int length) {
blink();
printMsg("接收数据:");
String data = "";
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
data += (char)payload[i];
}
if (strcmp(topic, (prefix + sOtaTopic).c_str()) == 0) {
printMsg("订阅到设备升级指令...");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
String newVersion = doc["version"];
String downloadUrl = doc["downloadUrl"];
printMsg("固件版本:" + newVersion);
printMsg("下载地址:" + downloadUrl);
} else if (strcmp(topic, (prefix + sInfoTopic).c_str()) == 0) {
printMsg("订阅到设备信息...");
// 发布设备信息
publishInfo();
} else if (strcmp(topic, (prefix + sNtpTopic).c_str()) == 0) {
printMsg("订阅到NTP时间...");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
// 计算设备当前时间:(${serverRecvTime} + ${serverSendTime} + ${deviceRecvTime} - ${deviceSendTime}) / 2
float deviceSendTime = doc["deviceSendTime"];
float serverSendTime = doc["serverSendTime"];
float serverRecvTime = doc["serverRecvTime"];
float deviceRecvTime = millis();
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
printMsg("当前时间:" + String(now, 0));
} else if (strcmp(topic, (prefix + sPropertyTopic).c_str()) == 0 || strcmp(topic, (prefix + sPropertyOnline).c_str()) == 0) {
printMsg("订阅到属性指令...");
processProperty(data);
} else if (strcmp(topic, (prefix + sFunctionTopic).c_str()) == 0 || strcmp(topic, (prefix + sFunctionOnline).c_str()) == 0) {
printMsg("订阅到功能指令...");
processFunction(data);
} else if (strcmp(topic, (prefix + sMonitorTopic).c_str()) == 0) {
printMsg("订阅到实时监测指令...");
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
monitorCount = doc["count"];
monitorInterval = doc["interval"];
}
}
// 随机生成属性值
String randomPropertyData() {
// 匹配云端定义的数据,随机数代替传感器值
float randFloat = 0;
int randInt = 0;
StaticJsonDocument<1024> doc;
JsonObject objTmeperature = doc.createNestedObject();
objTmeperature["id"] = "temperature";
randFloat = random(1000, 3000);
objTmeperature["value"] = (String)(randFloat / 100);
objTmeperature["remark"] = (String)millis();
JsonObject objBrightness = doc.createNestedObject();
objBrightness["id"] = "brightness";
randInt = random(1000, 10000);
objBrightness["value"] = (String)(randInt);
objBrightness["remark"] = (String)millis();
JsonObject category_light = doc.createNestedObject();
category_light["id"] = "category_light";
randInt = random(0, 100);
category_light["value"] = (String)(randInt);
category_light["remark"] = (String)millis();
JsonObject category_humidity = doc.createNestedObject();
category_humidity["id"] = "category_humidity";
randInt = random(0, 100);
category_humidity["value"] = (String)(randInt);
category_humidity["remark"] = (String)millis();
JsonObject category_temperature = doc.createNestedObject();
category_temperature["id"] = "category_temperature";
randInt = random(0, 100);
category_temperature["value"] = (String)(randInt);
category_temperature["remark"] = (String)millis();
// 子设备数据,使用前缀array_00标识
JsonObject array_00_device_co2 = doc.createNestedObject();
array_00_device_co2["id"] = "array_00_device_co2";
randInt = random(100, 6000);
array_00_device_co2["value"] = (String)(randInt);
array_00_device_co2["remark"] = (String)millis();
JsonObject array_00_device_temperature = doc.createNestedObject();
array_00_device_temperature["id"] = "array_00_device_temperature";
randInt = random(0, 100);
array_00_device_temperature["value"] = (String)(randInt);
array_00_device_temperature["remark"] = (String)millis();
JsonObject array_01_device_co2 = doc.createNestedObject();
array_01_device_co2["id"] = "array_01_device_co2";
randInt = random(100, 6000);
array_01_device_co2["value"] = (String)(randInt);
array_01_device_co2["remark"] = (String)millis();
JsonObject array_01_device_temperature = doc.createNestedObject();
array_01_device_temperature["id"] = "array_01_device_temperature";
randInt = random(0, 100);
array_01_device_temperature["value"] = (String)(randInt);
array_01_device_temperature["remark"] = (String)millis();
JsonObject array_02_device_co2 = doc.createNestedObject();
array_02_device_co2["id"] = "array_02_device_co2";
randInt = random(100, 6000);
array_02_device_co2["value"] = (String)(randInt);
array_02_device_co2["remark"] = (String)millis();
JsonObject array_02_device_temperature = doc.createNestedObject();
array_02_device_temperature["id"] = "array_02_device_temperature";
randInt = random(0, 100);
array_02_device_temperature["value"] = (String)(randInt);
array_02_device_temperature["remark"] = (String)millis();
JsonObject array_03_device_co2 = doc.createNestedObject();
array_03_device_co2["id"] = "array_03_device_co2";
randInt = random(100, 6000);
array_03_device_co2["value"] = (String)(randInt);
array_03_device_co2["remark"] = (String)millis();
JsonObject array_03_device_temperature = doc.createNestedObject();
array_03_device_temperature["id"] = "array_03_device_temperature";
randInt = random(0, 100);
array_03_device_temperature["value"] = (String)(randInt);
array_03_device_temperature["remark"] = (String)millis();
JsonObject array_04_device_co2 = doc.createNestedObject();
array_04_device_co2["id"] = "array_04_device_co2";
randInt = random(100, 6000);
array_04_device_co2["value"] = (String)(randInt);
array_04_device_co2["remark"] = (String)millis();
JsonObject array_04_device_temperature = doc.createNestedObject();
array_04_device_temperature["id"] = "array_04_device_temperature";
randInt = random(0, 100);
array_04_device_temperature["value"] = (String)(randInt);
array_04_device_temperature["remark"] = (String)millis();
printMsg("模拟监测数据值:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
return output;
}
// 随机生成实时监测值
String randomMonitorData() {
// 匹配云端定义的监测数据,随机数代替监测值
float randFloat = 0;
int randInt = 0;
StaticJsonDocument<1024> doc;
JsonObject objTmeperature = doc.createNestedObject();
objTmeperature["id"] = "temperature";
randFloat = random(1000, 3000);
objTmeperature["value"] = (String)(randFloat / 100);
objTmeperature["remark"] = (String)millis();
JsonObject objBrightness = doc.createNestedObject();
objBrightness["id"] = "brightness";
randInt = random(1000, 10000);
objBrightness["value"] = (String)(randInt);
objBrightness["remark"] = (String)millis();
JsonObject category_light = doc.createNestedObject();
category_light["id"] = "category_light";
randInt = random(0, 100);
category_light["value"] = (String)(randInt);
category_light["remark"] = (String)millis();
JsonObject category_humidity = doc.createNestedObject();
category_humidity["id"] = "category_humidity";
randInt = random(0, 100);
category_humidity["value"] = (String)(randInt);
category_humidity["remark"] = (String)millis();
// 子设备数据,使用前缀array_00标识
JsonObject array_00_device_co2 = doc.createNestedObject();
array_00_device_co2["id"] = "array_00_device_co2";
randInt = random(100, 6000);
array_00_device_co2["value"] = (String)(randInt);
array_00_device_co2["remark"] = (String)millis();
JsonObject array_01_device_co2 = doc.createNestedObject();
array_01_device_co2["id"] = "array_01_device_co2";
randInt = random(100, 6000);
array_01_device_co2["value"] = (String)(randInt);
array_01_device_co2["remark"] = (String)millis();
JsonObject array_02_device_co2 = doc.createNestedObject();
array_02_device_co2["id"] = "array_02_device_co2";
randInt = random(100, 6000);
array_02_device_co2["value"] = (String)(randInt);
array_02_device_co2["remark"] = (String)millis();
JsonObject array_03_device_co2 = doc.createNestedObject();
array_03_device_co2["id"] = "array_03_device_co2";
randInt = random(100, 6000);
array_03_device_co2["value"] = (String)(randInt);
array_03_device_co2["remark"] = (String)millis();
JsonObject array_04_device_co2 = doc.createNestedObject();
array_04_device_co2["id"] = "array_04_device_co2";
randInt = random(100, 6000);
array_04_device_co2["value"] = (String)(randInt);
array_04_device_co2["remark"] = (String)millis();
printMsg("模拟监测数据值:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
return output;
}
// 物模型-属性处理
void processProperty(String msg) {
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, msg);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
for (JsonObject object : doc.as<JsonArray>()) {
// 匹配云端定义的属性(不包含属性中的监测数据)
const char *id = object["id"];
const char *value = object["value"];
printMsg((String)id + "" + (String)value);
// 处理子设备的数据上报
processSubDeviceReport(id, value);
}
// 最后发布属性,服务端订阅存储(重要)
publishProperty(msg);
}
// 处理子设备和功能分组数据上报
void processSubDeviceReport(const char *id, const char *value) {
int number = atoi(value);
number = number > 10 ? 10 : number;
int randInt = 0;
for (int i = 0; i < number; i++) {
StaticJsonDocument<1024> doc;
if (strcmp(id, "array_00_device_report_monitor") == 0) {
JsonObject array_00_device_co2 = doc.createNestedObject();
array_00_device_co2["id"] = "array_00_device_co2";
randInt = random(100, 6000);
array_00_device_co2["value"] = (String)(randInt);
array_00_device_co2["remark"] = (String)millis();
JsonObject array_00_device_temperature = doc.createNestedObject();
array_00_device_temperature["id"] = "array_00_device_temperature";
randInt = random(0, 100);
array_00_device_temperature["value"] = (String)(randInt);
array_00_device_temperature["remark"] = (String)millis();
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
publishProperty(output);
delay(1000);
} else if (strcmp(id, "array_01_device_report_monitor") == 0) {
JsonObject array_01_device_co2 = doc.createNestedObject();
array_01_device_co2["id"] = "array_01_device_co2";
randInt = random(100, 6000);
array_01_device_co2["value"] = (String)(randInt);
array_01_device_co2["remark"] = (String)millis();
JsonObject array_01_device_temperature = doc.createNestedObject();
array_01_device_temperature["id"] = "array_01_device_temperature";
randInt = random(0, 100);
array_01_device_temperature["value"] = (String)(randInt);
array_01_device_temperature["remark"] = (String)millis();
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
publishProperty(output);
delay(1000);
} else if (strcmp(id, "array_02_device_report_monitor") == 0) {
JsonObject array_02_device_co2 = doc.createNestedObject();
array_02_device_co2["id"] = "array_02_device_co2";
randInt = random(100, 6000);
array_02_device_co2["value"] = (String)(randInt);
array_02_device_co2["remark"] = (String)millis();
JsonObject array_02_device_temperature = doc.createNestedObject();
array_02_device_temperature["id"] = "array_02_device_temperature";
randInt = random(0, 100);
array_02_device_temperature["value"] = (String)(randInt);
array_02_device_temperature["remark"] = (String)millis();
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
publishProperty(output);
delay(1000);
} else if (strcmp(id, "array_03_device_report_monitor") == 0) {
JsonObject array_03_device_co2 = doc.createNestedObject();
array_03_device_co2["id"] = "array_03_device_co2";
randInt = random(100, 6000);
array_03_device_co2["value"] = (String)(randInt);
array_03_device_co2["remark"] = (String)millis();
JsonObject array_03_device_temperature = doc.createNestedObject();
array_03_device_temperature["id"] = "array_03_device_temperature";
randInt = random(0, 100);
array_03_device_temperature["value"] = (String)(randInt);
array_03_device_temperature["remark"] = (String)millis();
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
publishProperty(output);
delay(1000);
} else if (strcmp(id, "array_04_device_report_monitor") == 0) {
JsonObject array_04_device_co2 = doc.createNestedObject();
array_04_device_co2["id"] = "array_04_device_co2";
randInt = random(100, 6000);
array_04_device_co2["value"] = (String)(randInt);
array_04_device_co2["remark"] = (String)millis();
JsonObject array_04_device_temperature = doc.createNestedObject();
array_04_device_temperature["id"] = "array_04_device_temperature";
randInt = random(0, 100);
array_04_device_temperature["value"] = (String)(randInt);
array_04_device_temperature["remark"] = (String)millis();
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
publishProperty(output);
delay(1000);
} else if (strcmp(id, "category_report_monitor") == 0) {
JsonObject category_light = doc.createNestedObject();
category_light["id"] = "category_light";
randInt = random(0, 100);
category_light["value"] = (String)(randInt);
category_light["remark"] = (String)millis();
JsonObject category_humidity = doc.createNestedObject();
category_humidity["id"] = "category_humidity";
randInt = random(0, 100);
category_humidity["value"] = (String)(randInt);
category_humidity["remark"] = (String)millis();
JsonObject category_temperature = doc.createNestedObject();
category_temperature["id"] = "category_temperature";
randInt = random(0, 100);
category_temperature["value"] = (String)(randInt);
category_temperature["remark"] = (String)millis();
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
publishProperty(output);
delay(1000);
}
}
}
// 物模型-功能处理
void processFunction(String msg) {
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, msg);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
for (JsonObject object : doc.as<JsonArray>()) {
// 匹配云端定义的功能
const char *id = object["id"];
const char *value = object["value"];
if (strcmp(id, "switch") == 0) {
printMsg("开关 switch" + (String)value);
if (strcmp(value, "1") == 0) {
// 打开继电器
relayStatus(true);
} else if (strcmp(value, "0") == 0) {
// 关闭继电器
relayStatus(false);
}
} else if (strcmp(id, "gear") == 0) {
printMsg("档位 gear" + (String)value);
} else if (strcmp(id, "light_color") == 0) {
printMsg("灯光颜色 light_color" + (String)value);
} else if (strcmp(id, "message") == 0) {
printMsg("屏显消息 message" + (String)value);
} else if (strcmp(id, "report_monitor") == 0) {
int number = atoi(value);
number > 10 ? number = 10 : number;
for (int i = 0; i < number; i++) {
Serial.println(number);
String msg = randomPropertyData();
printMsg("订阅到上报监测数据指令,上报数据:");
printMsg(msg);
publishProperty(msg);
delay(1000);
}
}
}
// 最后发布功能,服务端订阅存储(重要)
publishFunction(msg);
}
// 物模型-事件上传
void processEvent() {
// 匹配云端的事件
StaticJsonDocument<512> doc;
JsonObject objTmeperature = doc.createNestedObject();
objTmeperature["id"] = "height_temperature";
objTmeperature["value"] = "40";
objTmeperature["remark"] = "温度过高警告";
JsonObject objException = doc.createNestedObject();
objException["id"] = "exception";
objException["value"] = "异常消息消息内容XXXXXXXX";
objException["remark"] = "设备发生错误";
printMsg("发布事件:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
// 最后发布功能,服务端订阅存储(重要)
publishEvent(output);
}
//打开继电器A
void relayStatus(bool status) {
pinMode(RELAY, OUTPUT);
if (status) {
digitalWrite(RELAY, HIGH);
} else {
digitalWrite(RELAY, LOW);
}
}
// 按钮单击事件
static void buttonClick() {
printMsg("检测到按键单击,打开继电器");
relayStatus(true);
// 匹配云端定义的开关,格式如:[{"id":"switch","value":"1"}]
String msg = "[{\"id\":\"switch\",\"value\":\"1\"}]";
publishProperty(msg);
}
// 按钮双击事件
static void buttonDoubleClick() {
printMsg("检测到按键双击,关闭继电器");
relayStatus(false);
// 匹配云端定义的开关,格式如:[{"id":"switch","value":"0"}]
String msg = "[{\"id\":\"switch\",\"value\":\"0\"}]";
publishProperty(msg);
}
// 按钮长按事件,进入配网模式
static void buttonLongPress() {
printMsg("检测到按键长按");
if (isApMode) {
printMsg("设备重启...");
ESP.restart();
} else {
printMsg("开始AP配网");
startApConfig();
}
}

View File

@@ -0,0 +1,37 @@
/*********************************************************************
* function 用户自定义功能
* board: esp8266 core for arduino v3.0.2
* library PubSubClient2.8.0 & ArduinoJson6.19.1 & OneButton2.0.4
* source: https://gitee.com/kerwincui/wumei-smart
* copyright: FastBee and kerwincui all rights reserved.
********************************************************************/
#ifndef _USER_H
#define _USER_H
#include "Config.h"
#include "Mqtt.h"
#include <OneButton.h> // 版本2.0.4
extern OneButton button;
// 初始化用户配置
void initUser();
// Mqtt回调
void mqttCallback(char *topic, byte *payload, unsigned int length);
// 属性处理(物模型)
void processProperty(String msg);
// 处理子设备数据上报
void processSubDeviceReport(const char *id, const char *value);
// 功能处理(物模型)
void processFunction(String msg);
// 事件处理(无模型)
void processEvent();
// 模拟属性值
String randomPropertyData();
// 模拟实时监测值
String randomMonitorData();
// 控制继电器状态
void relayStatus(bool status);
#endif

View File

@@ -0,0 +1,32 @@
## AIR780E CSDK说明
#### 一、开发环境
1. 安装 相关驱动 参考 https://doc.openluat.com/wiki/37?wiki_page_id=4454
2. 根据自己的习惯选择代码编辑器 vscoode vs2022 si等
3. 编译参考 https://gitee.com/openLuat/luatos-soc-2022
4. 使用luatools
#### 二、物美CSDK 说明
1. 工程路径 sdk\合宙\air780e\csdk\wu_mei
2. 这个路径下面包含了头文件目录 源文件目录 xmake 管理工程文件
#### 三、代码文件说明
1. app.c 对封装好的物美通信sdk 进行的应用开发。比如采集温度 平台下发控制指令等 都会在这个文件里面处理
2. base64.c 用于处理物美认证所有的base64 编码
3. comAuth.c 用于物美的http 同步授时mqtt的客户端ID 的加密生成
4. comInteraction.c 封装的物美平台的物模型进行的一些交互
5. main.c 程序入口 里面为air780e的标准开发入口里面创建一个线程 运行起来
6. optocoupler.c 物美配air780e开发板 光耦采集代码
7. relay.c 物美配air780e开发板 继电器操作代码
8. uart.c 物美配air780e开发板 串口代码 支持rs485 控制
9. wuMeiLed.c 物美配air780e开发板 LED 灯代码
10. wuMeiMqtt.c sdk 与平台通信的一些参数配置 已经mqtt 通信管理在里面
#### 四、必坑指南
1. air780e csdk mqtt 订阅数量有限制。可以在 sdk\合宙\air780e\csdk\luatos-soc-2022\thirdparty\mqtt\MQTTClient-C\src\MQTTClient.h 文件调整
#define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */
2. 注意air780e mqtt 内部是开启的线程 注意过来的数据处理 封装好了合宙sdk 是避免了这个坑的
3. 标准cjson 不支持 64位number类型但是同步时间的时候使用到了。这个问题已经解决 且提交到了合宙官方代码仓库 直接拉去就行
#### 四、必坑指南
1. 配套开发原理图路径 sdk\合宙\air780e\开发板原理图\wumeiair780e.pdf

View File

@@ -0,0 +1,32 @@
kind: pipeline
type: exec
name: shell
concurrency:
limit: 1
platform:
os: windows
arch: amd64
steps:
- name: build
commands:
- cd ..
- git clone https://gitee.com/openLuat/LuatOS.git
- cd src
- $env:PROJECT_NAME="luatos"
- $env:ROOT_PATH="$(Get-Location)/"
- $env:XMAKE_GLOBALDIR="C:/Users/14917/Desktop"
- xmake; if($?){echo success}else{echo fail; exit -1}
- name: notify
when:
status:
- failure
environment:
token:
from_secret: github_token
commands:
- 'curl.exe -X POST -H "Accept: application/vnd.github.v3+json" -H "Content-Type: application/json" https://api.github.com/repos/openLuat/LuatOS/dispatches -H "Authorization: token $env:token " -d "{`\`"event_type`\`": `\`"webhook_air780ci_notify`\`"}"'

View File

@@ -0,0 +1,32 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
# Other files and folders
.settings/
# Executables
*.swf
*.air
*.ipa
*.apk
out/
build/
.xmake/
*.o
.sconsign.dblite
__py_cache__/
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
/*.map
tools//PLAT/core/ld/ec618_0h00_flash.ld
/PLAT/core/ld/ec618_0h00_flash.ld
tools/
/PLAT/libs/libmbedtls.a
/PLAT/libs/liblfs.a
/PLAT/libs/libmbedtls.a
/PLAT/libs/liblfs.a

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-2022 openLuat & AirM2M
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,604 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __BSP_COMMON_H__
#define __BSP_COMMON_H__
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include "cmsis_compiler.h"
typedef struct
{
uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
uint32_t CRC32; //后续字节的CRC32校验所有CRC32规则与ZIP压缩一致
uint32_t Param1; //升级参数其中byte0升级类型byte1升级包存放位置byte2外设总线序号和platform_define里的外设序号一致
uint32_t Param2; //额外的参数需要和外置存储总线配合使用一般是外置存储总线的PIN
uint32_t DataStartAddress;//升级包在flash中的起始地址外部和内部都可以用
uint32_t DataLen;//升级包大小
uint32_t DataCRC32;//升级包整包数据的CRC32
char FilePath[100];//升级包在文件系统中的绝对路径如果在flash中则随意填写
}CoreUpgrade_HeadStruct;
typedef struct
{
uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
uint32_t CRC32; //后续字节的CRC32校验所有CRC32规则与ZIP压缩一致
uint32_t Param1; //升级参数其中byte0升级类型byte1升级包存放位置byte2外设总线序号和platform_define里的外设序号一致
uint32_t Param2; //额外的参数需要和外置存储总线配合使用一般是外置存储总线的PIN
uint32_t DataStartAddress;//升级包在flash中的起始地址外部和内部都可以用
uint32_t DataLen;//升级包大小
uint32_t MainVersion[5];//目标的底层版本升级成功的话就是这个版本号了有些SDK无法提供版本号用MD5代替
uint8_t CommonMD5[16];//升级包整体数据的MD5
char FilePath[100];//升级包在文件系统中的绝对路径如果在flash中则随意填写
}CoreUpgrade_HeadCalMD5Struct;
typedef struct
{
uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
uint32_t CRC32; //后续字节的CRC32校验
uint32_t MainVersion;//目标的底层版本,升级成功的话就是这个版本号了
uint32_t AppVersion;//整包的版本号
uint32_t STDVersion;//允许升级的底层版本号
uint32_t DataLen;//升级包大小
uint32_t DataCRC32;//升级包整包数据的CRC32这里验证传输的准确性
}CoreUpgrade_FileHeadStruct;
typedef struct
{
uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
uint32_t CRC32; //后续字节的CRC32校验
uint32_t MainVersion[5];//目标的底层版本升级成功的话就是这个版本号了有些SDK无法提供版本号用MD5代替
uint32_t AppVersion;//整包的版本号
uint32_t STDVersion[5];//允许升级的底层版本号有些SDK无法提供版本号用MD5代替
uint32_t CommonDataLen; //通用升级包数据长度内容是CoreUpgrade_SectorStruct或者CoreUpgrade_SectorCalMD5Struct
uint32_t SDKDataLen; //特殊升级包数据长度一般是SDK闭源的升级包
uint8_t CommonMD5[16]; //通用升级包数据的MD5这里验证传输的准确性
uint8_t SDKMD5[16]; //特殊升级包数据的MD5这里验证传输的准确性
}CoreUpgrade_FileHeadCalMD5Struct;
typedef struct
{
uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
uint32_t TotalLen; //解压前占据的空间
uint32_t DataLen; //解压后占据的空间如果和TotalLen一样则表示未启用压缩不需要解压也没有压缩参数
//如果是0则表示是差分升级
//其他表示是整包升级数据包经过了lzma压缩
uint32_t DataCRC32; //解压后的数据的CRC32这里验证烧录的正确性
uint32_t StartAddress; //烧写的起始地址
}CoreUpgrade_SectorStruct;
typedef struct
{
uint32_t MaigcNum; //升级包标识,标识不对直接抛弃
uint32_t TotalLen; //解压前占据的空间
uint32_t DataLen; //解压后占据的空间如果和TotalLen一样则表示未启用压缩不需要解压也没有压缩参数
//如果是0则表示是差分升级
//其他表示是整包升级数据包经过了lzma压缩
uint8_t MD5[16]; //解压后的数据的MD5这里验证烧录的正确性
uint32_t BlockLen; //压缩时分隔的大小一般是64K128K或者256K
uint32_t StartAddress; //烧写的起始地址
}CoreUpgrade_SectorCalMD5Struct;
typedef struct
{
uint32_t param_max_num;
uint32_t param_max_len;
uint32_t param_num;
int8_t *param_str;
}CmdParam;
typedef struct
{
uint8_t Sec;
uint8_t Min;
uint8_t Hour;
uint8_t Week;//表示日期0~6,sun~sat表示预约时bit0~bit6,sun~sat
}Time_UserDataStruct;
typedef struct
{
uint16_t Year;
uint8_t Mon;
uint8_t Day;
}Date_UserDataStruct;
typedef union
{
uint32_t dwTime;
Time_UserDataStruct Time;
}Time_Union;
typedef union
{
uint32_t dwDate;
Date_UserDataStruct Date;
}Date_Union;
typedef struct
{
uint8_t *Data;
uint32_t Len;
uint32_t Offset;
uint32_t MaxLength;
uint32_t DataSize;
}Loop_Buffer;
typedef struct
{
uint8_t *Data;
uint32_t Pos;
uint32_t MaxLen;
}Buffer_Struct;
typedef struct
{
uint8_t *pCache[2];
uint32_t pCacheLen[2];
uint32_t MaxLen;
uint8_t CurCacheSn;
}DBuffer_Struct;
typedef union
{
void *p;
char *pc8;
uint8_t *pu8;
uint16_t *pu16;
uint32_t *pu32;
uint32_t u32;
uint8_t u8[4];
uint16_t u16[2];
}PV_Union;
enum
{
ERROR_NONE,
ERROR_NO_SUCH_ID,
ERROR_PERMISSION_DENIED,
ERROR_PARAM_INVALID,
ERROR_PARAM_OVERFLOW,
ERROR_DEVICE_BUSY,
ERROR_OPERATION_FAILED,
ERROR_BUFFER_FULL,
ERROR_NO_MEMORY,
ERROR_CMD_NOT_SUPPORT,
ERROR_NO_DATA,
ERROR_NO_FLASH,
ERROR_NO_TIMER,
ERROR_TIMEOUT,
ERROR_SSL_HANDSHAKE,
ERROR_PROTOCL,
ERROR_ID_INVALID,
ERROR_MID_INVALID,
ERROR_RETRY_TOO_MUCH,
ERROR_CMD_BLOCK,
LIST_FIND = 1,
LIST_PASS = 0,
LIST_DEL = -1,
DMA_CB_DONE = 0,
UART_CB_TX_BUFFER_DONE,
UART_CB_TX_ALL_DONE,
UART_CB_RX_NEW,
UART_CB_RX_TIMEOUT,
UART_CB_RX_BUFFER_FULL,
UART_CB_ERROR,
UART_CB_CONNECTED, //串口工具对方已经打开
DMA_CB_ERROR = 0xffffffff,
CORE_EVENT_ID_ANY = 0,
CORE_EVENT_ID_START = 0xf0000000,
CORE_EVENT_TIMEOUT,
CORE_TIMER_TIMEOUT = 0xf0010000,
SERVICE_EVENT_ID_START = 0xf0100000,
DEV_EVENT_ID_START = 0xf0200000,
DEV_SPIFLASH_SPI_DONE,
DEV_SDHC_SPI_DONE,
USB_APP_EVENT_ID_START = 0xf0300000,
USER_EVENT_ID_START = 0xf1000000,
INVALID_EVENT_ID = 0xffffffff,
NW_EVENT_SENT = 0,
NW_EVENT_RECV,
NW_EVENT_ERR,
NW_EVENT_CONNECTED,
NW_EVENT_REMOTE_CLOSE,
NW_EVENT_ACCEPT,
NW_EVENT_CLOSE_OK,
};
#define INVALID_HANDLE_VALUE ((void *)0xffffffff)
#define INVALID_PARAM (0xffffffff)
#define CRC32_GEN (0x04C11DB7)
#define CRC32_START (0xffffffff)
#define CRC16_CCITT_GEN (0x1021)
#define CRC16_MODBUS_GEN (0x8005)
#define CRC16_START (0xffff)
#define CRC16_IBM_SEED (0xffff)
#define CRC16_CCITT_SEED (0x1D0F)
#define HANDLE void *
#ifndef BIT
#define BIT(n) (1UL << (n))
#endif
#ifndef MIN
#define MIN(X,Y) (((X) < (Y))?(X):(Y))
#endif
typedef void (*IrqHandler)(int32_t IrqLine, void *pData);
typedef void (* TaskFun_t)( void * );
typedef void (* CommonFun_t)(void);
typedef void(* CBDataFun_t)(uint8_t *Data, uint32_t Len);
typedef int32_t(*CBFuncEx_t)(void *pData, void *pParam);
typedef uint64_t LongInt;
#define INIT_FUN_EXPORT(fn, location, level) const CommonFun_t __ex_init_##fn __attribute__((section(location level))) = fn
#define INIT_HW_EXPORT(fn, level) INIT_FUN_EXPORT(fn, ".preinit_fun_array.", level)
#define INIT_DRV_EXPORT(fn, level) INIT_FUN_EXPORT(fn, ".drv_init_fun_array.", level)
#define INIT_TASK_EXPORT(fn, level) INIT_FUN_EXPORT(fn, ".task_fun_array.", level)
/* board init routines will be called in board_init() function */
#define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1")
/* pre/device/component/env/app init routines will be called in init_thread */
/* components pre-initialization (pure software initilization) */
#define INIT_PREV_EXPORT(fn) INIT_EXPORT(fn, "2")
/* device initialization */
#define INIT_DEVICE_EXPORT(fn) INIT_EXPORT(fn, "3")
/* components initialization (dfs, lwip, ...) */
#define INIT_COMPONENT_EXPORT(fn) INIT_EXPORT(fn, "4")
/* environment initialization (mount disk, ...) */
#define INIT_ENV_EXPORT(fn) INIT_EXPORT(fn, "5")
/* appliation initialization (rtgui application etc ...) */
#define INIT_APP_EXPORT(fn) INIT_EXPORT(fn, "6")
typedef struct
{
uint32_t ID;
uint32_t Param1;
uint32_t Param2;
uint32_t Param3;
}OS_EVENT;
typedef struct
{
CBFuncEx_t CB;
union {
void *pParam; //用户回调模式
uint32_t MaxCnt; //设置捕获模式时的最大tick捕获时的tick
}uParam;
union {
struct {
uint8_t Level; //IO输入输出电平捕获模式下中断时IO电平
uint8_t PullMode; //IO上下拉控制
} IOArg;
struct {
uint8_t ExtiMode; //中断模式
uint8_t PullMode; //IO上下拉控制
} ExitArg;
uint16_t Time; //delay时间us
} uArg;
uint8_t Operation; //操作类型
uint8_t PinOrDelay; //IO操作时为IOpindelay操作时则为微调值0~4748为1us
}OPQueue_CmdStruct;
enum
{
UDATA_TYPE_UNDEFINED = 0,
UDATA_MULTIPLE_RESOURCE,
UDATA_TYPE_STRING,
UDATA_TYPE_OPAQUE,
UDATA_TYPE_INTEGER,
UDATA_TYPE_DWORD,
UDATA_TYPE_WORD,
UDATA_TYPE_BYTE,
UDATA_TYPE_FLOAT,
UDATA_TYPE_BOOLEAN,
UDATA_TYPE_UNSIGNED,
UDATA_TYPE_UNUSD
};
typedef struct _u_data_t uData_t;
struct _u_data_t
{
union
{
uint8_t asBoolean;
uint64_t asUnsigned;
int64_t asInteger;
PV_Union asDword;
double asFloat;
struct
{
size_t length;
uint8_t *buffer;
} asBuffer;
struct
{
size_t count;
uData_t *array;
} asChildren;
} value;
uint32_t ID;
uint8_t Type;
};
__attribute__((weak)) uint8_t OS_CheckInIrq(void);
#define __BUILD_OS__
#ifdef __BUILD_OS__
HANDLE OS_MutexCreate(void);
HANDLE OS_MutexCreateUnlock(void);
void OS_MutexLock(HANDLE Sem);
int32_t OS_MutexLockWtihTime(HANDLE Sem, uint32_t TimeoutMs);
void OS_MutexRelease(HANDLE Sem);
void OS_MutexDelete(HANDLE Sem);
void OS_SuspendTask(HANDLE taskHandle);
void OS_ResumeTask(HANDLE taskHandle);
uint8_t OS_IsSchedulerRun(void);
#endif
uint32_t OS_EnterCritical(void);
void OS_ExitCritical(uint32_t Critical);
void OS_MemInfo(uint32_t *curalloc, uint32_t *totfree, uint32_t *maxfree);
int32_t OS_InitBuffer(Buffer_Struct *Buf, uint32_t Size);
void OS_DeInitBuffer(Buffer_Struct *Buf);
int32_t OS_ReInitBuffer(Buffer_Struct *Buf, uint32_t Size);
int32_t OS_ReSizeBuffer(Buffer_Struct *Buf, uint32_t Size);
int32_t OS_BufferWrite(Buffer_Struct *Buf, void *Data, uint32_t Len);
int32_t OS_BufferWriteLimit(Buffer_Struct *Buf, void *Data, uint32_t Len);
void OS_BufferRemove(Buffer_Struct *Buf, uint32_t Len);
void DBuffer_Init(DBuffer_Struct *DBuf, uint32_t Size);
void DBuffer_ReInit(DBuffer_Struct *DBuf, uint32_t Size);
void DBuffer_DeInit(DBuffer_Struct *DBuf);
void *DBuffer_GetCache(DBuffer_Struct *DBuf, uint8_t IsCurrent);
void DBuffer_SwapCache(DBuffer_Struct *DBuf);
void DBuffer_SetDataLen(DBuffer_Struct *DBuf, uint32_t Len, uint8_t IsCurrent);
uint32_t DBuffer_GetDataLen(DBuffer_Struct *DBuf, uint8_t IsCurrent);
void Buffer_StaticInit(Buffer_Struct *Buf, void *Src, uint32_t MaxLen);
int32_t Buffer_StaticWrite(Buffer_Struct *Buf, void *Data, uint32_t Len);
void Buffer_Remove(Buffer_Struct *Buf, uint32_t Len);
void LoopBuffer_Init(Loop_Buffer *Buf, void *Src, uint32_t MaxLen, uint32_t DataSize);
uint32_t LoopBuffer_Query(Loop_Buffer *Buf, void *Src, uint32_t Len);
uint32_t LoopBuffer_Read(Loop_Buffer *Buf, void *Src, uint32_t Len);
void LoopBuffer_Del(Loop_Buffer *Buf, uint32_t Len);
uint32_t LoopBuffer_Write(Loop_Buffer *Buf, void *Src, uint32_t Len);
int32_t BSP_SetBit(uint8_t *Data, uint32_t Sn, uint8_t Value);
int32_t BSP_GetBit(uint8_t *Data, uint32_t Sn, uint8_t *Value);
uint8_t BSP_TestBit(uint8_t *Data, uint32_t Sn);
uint8_t XorCheck(void *Src, uint32_t Len, uint8_t CheckStart);
uint8_t SumCheck(uint8_t *Data, uint32_t Len);
uint16_t CRC16Cal(void *Data, uint16_t Len, uint16_t CRC16Last, uint16_t CRCRoot, uint8_t IsReverse);
uint32_t AsciiToU32(uint8_t *Src, uint32_t Len);
void CRC32_CreateTable(uint32_t *Tab, uint32_t Gen);
uint32_t CRC32_Cal(uint32_t * CRC32_Table, uint8_t *Buf, uint32_t Size, uint32_t CRC32Last);
uint32_t CmdParseParam(int8_t* pStr, CmdParam *CmdParam, int8_t Cut);
uint8_t IsLeapYear(uint32_t Year);
LongInt UTC2Tamp(Date_UserDataStruct *Date, Time_UserDataStruct *Time);
uint32_t Tamp2UTC(LongInt Sec, Date_UserDataStruct *Date, Time_UserDataStruct *Time, uint32_t LastDDay);
uint32_t TransferPack(uint8_t Flag, uint8_t Code, uint8_t F1, uint8_t F2, uint8_t *InBuf, uint32_t Len, uint8_t *OutBuf);
/*
* 转义解包
* 标识Flag即包头包尾加入Flag
* 数据中遇到Code F1 -> Flag
* 数据中遇到Code F2 -> Code
* 数据中遇到Flag 出错返回0
*/
uint32_t TransferUnpack(uint8_t Flag, uint8_t Code, uint8_t F1, uint8_t F2, uint8_t *InBuf, uint32_t Len, uint8_t *OutBuf);
/*
* llist相关代码大部分来自linux内核
*/
/**
* container_of - cast a member of a structure out to the containing structure
*
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized llist entries.
*/
#define LLIST_POISON1 (0)
#define LLIST_POISON2 (0)
/*
* Simple doubly linked llist implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole llists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
typedef struct llist_head_t{
struct llist_head_t *next, *prev;
}llist_head;
#define LLIST_HEAD_INIT(name) { &(name), &(name) }
#define LLIST_HEAD(name) \
llist_head name = LLIST_HEAD_INIT(name)
#define INIT_LLIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
void __llist_add(llist_head *p,
llist_head *prev,
llist_head *next);
/**
* llist_add - add a new entry
* @new: new entry to be added
* @head: llist head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
void llist_add(llist_head *p, llist_head *head);
/**
* llist_add_tail - add a new entry
* @new: new entry to be added
* @head: llist head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
void llist_add_tail(llist_head *p, llist_head *head);
/*
* Delete a llist entry by making the prev/next entries
* point to each other.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
void __llist_del(llist_head * prev, llist_head * next);
/**
* llist_del - deletes entry from llist.
* @entry: the element to delete from the llist.
* Note: llist_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
void llist_del(llist_head *entry);
/**
* llist_del_init - deletes entry from llist and reinitialize it.
* @entry: the element to delete from the llist.
*/
void llist_del_init(llist_head *entry);
/**
* llist_move - delete from one llist and add as another's head
* @llist: the entry to move
* @head: the head that will precede our entry
*/
void llist_move(llist_head *llist, llist_head *head);
/**
* llist_move_tail - delete from one llist and add as another's tail
* @llist: the entry to move
* @head: the head that will follow our entry
*/
void llist_move_tail(llist_head *llist,
llist_head *head);
/**
* llist_empty - tests whether a llist is empty
* @head: the llist to test.
*/
int llist_empty(const llist_head *head);
uint32_t llist_num(const llist_head *head);
void *llist_traversal(llist_head *head, CBFuncEx_t cb, void *pData);
/**
* llist_entry - get the struct for this entry
* @ptr: the &llist_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the llist_struct within the struct.
*/
#define llist_entry(ptr, type, member) \
container_of(ptr, type, member)
uint16_t BSP_Swap16(uint16_t n);
uint32_t BSP_Swap32(uint32_t n);
uint8_t BytesGet8(const void *ptr);
void BytesPut8(void *ptr, uint8_t v);
uint16_t BytesGetBe16(const void *ptr);
void BytesPutBe16(void *ptr, uint16_t v);
uint32_t BytesGetBe32(const void *ptr);
void BytesPutBe32(void *ptr, uint32_t v);
uint16_t BytesGetLe16(const void *ptr);
void BytesPutLe16(void *ptr, uint16_t v);
uint32_t BytesGetLe32(const void *ptr);
void BytesPutLe32(void *ptr, uint32_t v);
uint64_t BytesGetLe64(const void *ptr);
void BytesPutLe64(void *ptr, uint64_t v);
uint8_t BytesGet8FromBuf(Buffer_Struct *Buf);
void BytesPut8ToBuf(Buffer_Struct *Buf, uint8_t v);
uint16_t BytesGetBe16FromBuf(Buffer_Struct *Buf);
void BytesPutBe16ToBuf(Buffer_Struct *Buf, uint16_t v);
uint32_t BytesGetBe32FromBuf(Buffer_Struct *Buf);
void BytesPutBe32ToBuf(Buffer_Struct *Buf, uint32_t v);
uint16_t BytesGetLe16FromBuf(Buffer_Struct *Buf);
void BytesPutLe16ToBuf(Buffer_Struct *Buf, uint16_t v);
uint32_t BytesGetLe32FromBuf(Buffer_Struct *Buf);
void BytesPutLe32ToBuf(Buffer_Struct *Buf, uint32_t v);
uint64_t BytesGetLe64FromBuf(Buffer_Struct *Buf);
void BytesPutLe64ToBuf(Buffer_Struct *Buf, uint64_t v);
float BytesGetFloatFromBuf(Buffer_Struct *Buf);
void BytesPutFloatToBuf(Buffer_Struct *Buf, float v);
double BytesGetDoubleFromBuf(Buffer_Struct *Buf);
void BytesPutDoubleToBuf(Buffer_Struct *Buf, double v);
/*************************************************************************/
extern uint64_t GetSysTickMS();
//void *__wrap_malloc(size_t Size);
//void *__wrap_zalloc(size_t Size);
//void *__wrap_calloc(size_t count, size_t eltsize);
//void *__wrap_realloc(void *buf, size_t size);
//void __wrap_free(void *p);
#ifndef ASSERT
#if defined(__DEBUG__)
#define ASSERT( x ) if( ( x ) == 0 ) { __disable_irq(); DBG_Trace("\r\nassert %s,%d", __FUNCTION__, __LINE__); for( ;; ); }
#else
#define ASSERT( x )
#endif
#endif
#endif

View File

@@ -0,0 +1,20 @@
#ifndef BSP_CUSTOM_H
#define BSP_CUSTOM_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bsp.h"
void BSP_CustomInit(void);
uint32_t BSP_UsbGetVBUSMode(void);
uint32_t BSP_UsbGetVBUSWkupPad(void);
void Usim1GpioConfig(BOOL bSetUsimFunc);
#ifdef __cplusplus
}
#endif
#endif /* BSP_CUSTOM_H */

View File

@@ -0,0 +1,181 @@
#ifndef __COMMON_API_H__
#define __COMMON_API_H__
#include "stdint.h"
#include "stdarg.h"
#include "string.h"
#include "stdio.h"
#include "stdbool.h"
#include "bsp_common.h"
#include "platform_define.h"
#ifdef LOW_SPEED_SERVICE_ONLY
#define PS_DIAL_PS_UP_MEM_SIZE 248000
#else //Full speed version
#define PS_DIAL_PS_UP_MEM_SIZE 421000
#endif
enum
{
I2S_MODE_I2S,
I2S_MODE_LSB,
I2S_MODE_MSB,
I2S_FRAME_SIZE_16_16,
I2S_FRAME_SIZE_16_32,
I2S_FRAME_SIZE_24_32,
I2S_FRAME_SIZE_32_32,
};
typedef void (* usb_serial_in)(uint8_t channel, uint8_t *input, uint32_t len);
typedef void (*pad_wakeup_fun_t)(uint32_t pad_num);
/**
* @brief 格式化打印输出log在EPAT工具里是customer luatos
* @param fmt 打印格式
* @param ... 参数
*/
void soc_printf(const char *fmt, ...);
/**
* @brief 直接输出string在EPAT工具里是customer luatos
*
* @param string 需要输出的字符串
* @param size 字符串长度可以选为0
*/
void soc_debug_out(char *string, uint32_t size);
/**
* @brief 设置USB串口输入的回调函数
*
* @param cb_fun 回调函数
*/
void soc_set_usb_serial_input_callback(usb_serial_in cb_fun);
#define set_usb_serial_input_callback(x) soc_set_usb_serial_input_callback(x)
/**
* @brief USB串口输出
*
* @param channel USB串口通道目前默认是4或者与输入时的channel保持一致 * @param output 输出的数据
* @param len 输出的数据长度
* @return int 0成功其他失败
*/
int soc_usb_serial_output(uint8_t channel, uint8_t *output, uint32_t len);
#define usb_serial_output(x,y,z) soc_usb_serial_output(x,y,z)
/**
* @brief 设置低功耗模式下,wakeuppad唤醒中断回调注意这是在中断回调
*
* @param cb_fun
*/
void soc_set_pad_wakeup_callback(pad_wakeup_fun_t cb_fun);
#define set_pad_wakeup_callback(x) soc_set_pad_wakeup_callback(x)
/**
* @brief 创建一个带event收发机制的taskevent就是一个16byte的queue在创建task的时候同时创建好了一个queueevent结构见OS_EVENT
*
* @param task_fun task的入口函数
* @param param task的入口参数
* @param stack_bytes task的堆栈长度单位byte会强制4字节对齐
* @param priority task的任务优先级注意是百分比0~100100为底层OS允许的最高级0为底层OS允许的最低级
* @param task_name task的name
* @param event_max_cnt如果OS不带mailbox就需要本参数来创建queue
* @return void* task的句柄后续收发event都需要这个参数NULL为创建失败
*/
void *create_event_task(TaskFun_t task_fun, void *param, uint32_t stack_bytes, uint8_t priority, uint16_t event_max_cnt, const char *task_name);
/**
* @brief 删除掉一个带event收发机制的task比正常删除task多了一步删除event queue。
*
* @param task_handle task的句柄
*/
void delete_event_task(void *task_handle);
/**
* @brief 发送一个event给task
*
* @param task_handle task的句柄
* @param event 一个已经构建好的event如果传入指针不为NULL将忽略后续4个参数反之会由后续4个参数构建一个event每个函数参数对应event内同名参数
* @param event_id 需要构建的event id
* @param param1 需要构建的param1
* @param param2 需要构建的param2
* @param param3 需要构建的param3
* @param timeout_ms 发送的超时时间0不等待0xffffffff永远等待建议就直接写0
* @return int 成功返回0其他都是失败
*/
int send_event_to_task(void *task_handle, OS_EVENT *event, uint32_t event_id, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t timeout_ms);
/**
* @brief 获取一个event并根据需要返回
* 如果target_event_id != 0 && != 0xffffffff那么收到对应event id时返回如果不是则由callback交给用户临时处理如果callback为空则抛弃掉
* 如果target_event_id == 0收到消息就返回
* 如果target_event_id == 0xffffffff收到消息则由callback交给用户临时处理如果callback为空则抛弃掉
*
* @param task_handle task的句柄
* @param target_event_id 指定收到的event id
* @param event 缓存event的空间当收到需要的event时缓存在这里
* @param callback 在收到不需要的event时回调给用户处理回调函数中的第一个参数就是event指针第二个参数是task句柄。这里可以为NULL直接抛弃event
* @param timeout_ms 0和0xffffffff永远等待建议就直接写0
* @return int 收到需要的event返回0
*/
int get_event_from_task(void *task_handle, uint32_t target_event_id, OS_EVENT *event, CBFuncEx_t callback, uint32_t timeout_ms);
/**
* @brief 获取开机到现在的ms时间
*
* @return uint64_t
*/
uint64_t soc_get_poweron_time_ms(void);
uint64_t soc_get_poweron_time_tick(void);
/**
* @brief 获取堆信息
*
* @param total 总量
* @param total_free 剩余量
* @param min_free 历史最小运行量,同时也对应历史最大使用量
*/
void soc_get_heap_info(uint32_t *total, uint32_t *total_free, uint32_t *min_free);
/**
* @brief 请求改变全局低功耗状态
*
* @param state 0全速 1IDLE 2SLEEP
*/
void soc_require_lowpower_state(uint8_t state);
/**
* @brief 初始成sleep1必须在init fun里在task里就无效了
*/
void soc_force_init_sleep(void);
/**
* @brief usb交由用户决定开启和关闭必须在init fun里在task里就无效了
*/
void soc_force_usb_user_ctrl(void);
/**
* @brief 用户手动控制USB开关
*
* @param onoff 1打开0关闭
*/
void soc_usb_onoff(uint8_t onoff);
uint8_t soc_usb_stack_onoff_state(void);
uint32_t soc_get_utc(void);
uint64_t soc_get_utc_ms(void);
int soc_get_sn(char *sn, uint8_t buf_size);
/**
* @brief 中断里释放动态分配的ram本质上是放到一个专门的task里去free
*
* @param point malloc得到的指针
* @return 0成功其他失败
*/
int soc_free_later(void *point);
/*
* 函数放到系统服务里运行,堆栈小,优先级高
*/
int soc_call_function_in_service(CBDataFun_t CB, uint32_t data, uint32_t param, uint32_t timeout);
/*
* 函数放到audio服务里运行堆栈大优先级低必须先初始化audio
*/
int soc_call_function_in_audio(CBDataFun_t CB, uint32_t data, uint32_t param, uint32_t timeout);
/**
* @brief 带函数名称和位置的格式化打印
*
*/
#define DBG(X,Y...) soc_printf("%s %d:"X, __FUNCTION__,__LINE__,##Y)
#endif

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __PLATFORM_DEFINE_H__
#define __PLATFORM_DEFINE_H__
enum
{
UART_DATA_BIT5 = 5,
UART_DATA_BIT6 = 6,
UART_DATA_BIT7 = 7,
UART_DATA_BIT8 = 8,
UART_DATA_BIT9 = 9,
UART_PARITY_NONE = 0,
UART_PARITY_ODD,
UART_PARITY_EVEN,
UART_STOP_BIT1 = 0,
UART_STOP_BIT1_5,
UART_STOP_BIT2,
I2C_OP_READ_REG = 0, //i2c通用读寄存器一写一读自动带start信号
I2C_OP_READ, //i2c通用读只读
I2C_OP_WRITE, //i2c通用写只写
OP_QUEUE_CMD_END = 0,
OP_QUEUE_CMD_ONE_TIME_DELAY, //只有一次delay
OP_QUEUE_CMD_CONTINUE_DELAY, //连续delay配合OP_QUEUE_CMD_REPEAT_DELAY使用
OP_QUEUE_CMD_REPEAT_DELAY, //重复OP_QUEUE_CMD_CONTINUE_DELAY
OP_QUEUE_CMD_SET_GPIO_DIR_OUT,
OP_QUEUE_CMD_SET_GPIO_DIR_IN,
OP_QUEUE_CMD_GPIO_OUT,
OP_QUEUE_CMD_GPIO_IN,
OP_QUEUE_CMD_GPIO_IN_CB,
OP_QUEUE_CMD_CB,
OP_QUEUE_CMD_CAPTURE_SET,
OP_QUEUE_CMD_CAPTURE,
OP_QUEUE_CMD_CAPTURE_CB,
OP_QUEUE_CMD_CAPTURE_END,
OP_QUEUE_CMD_IO_PULL_NONE = 0,
OP_QUEUE_CMD_IO_PULL_UP,
OP_QUEUE_CMD_IO_PULL_DOWN,
OP_QUEUE_CMD_IO_EXTI_UP = 0, //上升沿中断
OP_QUEUE_CMD_IO_EXTI_DOWN, //下降沿中断
OP_QUEUE_CMD_IO_EXTI_BOTH, //双边沿中断
COLOR_MODE_RGB_565 = 0,
COLOR_MODE_GRAY,
COLOR_MODE_RGB_888,
COLOR_MODE_YCBCR_422_UYVY,
COLOR_MODE_YCBCR_422_YUYV,
COLOR_MODE_YCBCR_422_CBYCRY,
CORE_OTA_MODE_FULL = 0, //param1的byte0
CORE_OTA_MODE_DIFF,
CORE_OTA_IN_FLASH = 0, //param1的byte1
CORE_OTA_OUT_SPI_FLASH,
CORE_OTA_IN_FILE,
};
enum
{
I2C_ID0 = 0,
I2C_ID1,
I2C_MAX,
UART_ID0 = 0,
UART_ID1,
UART_ID2,
// UART_ID4,
// UART_ID5,
UART_MAX,
VIRTUAL_UART0 = 0,
VIRTUAL_UART_MAX,
SPI_ID0 = 0,
SPI_ID1,
SPI_MAX,
I2S_ID0 = 0,
I2S_ID1,
I2S_MAX,
SPI_MODE_0 = 0,
SPI_MODE_1,
SPI_MODE_2,
SPI_MODE_3,
//
// HW_TIMER0 = 0,
// HW_TIMER1,
// HW_TIMER2,
// HW_TIMER3,
// HW_TIMER4,
// HW_TIMER5,
// HW_TIMER_MAX,
//
// ADC_CHANNEL_0 = 0,
// ADC_CHANNEL_1,
// ADC_CHANNEL_2,
// ADC_CHANNEL_3,
// ADC_CHANNEL_4,
// ADC_CHANNEL_5,
// ADC_CHANNEL_6,
// ADC_CHANNEL_MAX,
HAL_GPIO_0 = 0,
HAL_GPIO_1,
HAL_GPIO_2,
HAL_GPIO_3,
HAL_GPIO_4,
HAL_GPIO_5,
HAL_GPIO_6,
HAL_GPIO_7,
HAL_GPIO_8,
HAL_GPIO_9,
HAL_GPIO_10,
HAL_GPIO_11,
HAL_GPIO_12,
HAL_GPIO_13,
HAL_GPIO_14,
HAL_GPIO_15,
HAL_GPIO_16,
HAL_GPIO_17,
HAL_GPIO_18,
HAL_GPIO_19,
HAL_GPIO_20,
HAL_GPIO_21,
HAL_GPIO_22,
HAL_GPIO_23,
HAL_GPIO_24,
HAL_GPIO_25,
HAL_GPIO_26,
HAL_GPIO_27,
HAL_GPIO_28,
HAL_GPIO_29,
HAL_GPIO_30,
HAL_GPIO_31,
HAL_GPIO_MAX,
HAL_GPIO_NONE = HAL_GPIO_MAX, //大于等于HAL_GPIO_NONE说明不存在
HAL_WAKEUP_0 = HAL_GPIO_MAX, //EC618特殊的几个输入IOWAKEUPPAD0~2和PWRKEY
HAL_WAKEUP_1,
HAL_WAKEUP_2,
HAL_WAKEUP_PWRKEY,
HAL_GPIO_QTY,
};
#define SOC_TICK_1US (26ul)
#define SOC_TICK_1MS (26000ul)
#define SOC_TICK_1S (26000000ul)
#define SOC_TICK_TIMER (3)
#define CP_VERSION 0x01130001
#define __FLASH_BLOCK_SIZE__ (0x00010000)
#define __FLASH_SECTOR_SIZE__ (0x00001000)
#define __FLASH_PAGE_SIZE__ (0x00000100)
#define __APP_START_MAGIC__ (0xeaf18c16)
#define __AP_FLASH_SAVE_ADDR__ (0x00024000)
#define __BL_FLASH_SAVE_ADDR__ (0x00004000)
#define __SOC_OTA_INFO_DATA_LOAD_ADDRESS__ (__BL_FLASH_SAVE_ADDR__ + BOOTLOADER_FLASH_LOAD_SIZE + AP_FLASH_XIP_ADDR)
#define __SOC_OTA_INFO_DATA_SAVE_ADDRESS__ (__BL_FLASH_SAVE_ADDR__ + BOOTLOADER_FLASH_LOAD_SIZE)
#endif

View File

@@ -0,0 +1,175 @@
/**
* @file driver_gpio.h
* @brief 使用本模块API时不可以使用原厂的GPIO API不能用wakeupPAD相关API但是能使用PAD 普通API。所有API都是任务不安全的和中断不安全的
* @version 0.1
* @date 2022-10-25
*
* @copyright
*
*/
#ifndef __CORE_GPIO_H__
#define __CORE_GPIO_H__
#include "bsp_common.h"
/**
* @brief GPIO全局初始化
*
* @param Fun 中断回调函数回调时PIN序号是pDatavoid *->uint32_t。这里是给全部的GPIO统一设置可以留空然后给每个GPIO单独配置
*/
void GPIO_GlobalInit(CBFuncEx_t Fun);
/**
* @brief GPIO初始化
*
* @param Pin Pin序号
* @param IsInput 是否为输入功能1是0否
* @param InitValue 初始电平1高0低只对输出有效
*/
void GPIO_Config(uint32_t Pin, uint8_t IsInput, uint8_t InitValue);
/**
* @brief GPIO初始化并且同步控制上下拉电阻增强驱动力
*
* @param Pin Pin序号
* @param IsInput 是否为输入功能1是0否
* @param InitValue 初始电平1高并且上拉0低并且下拉
* @param AltFun 复用功能大部分Pad和GPIO是一一对应的如果出现多个Pad对应1个GPIO如果AltFun不能匹配则默认用Alt0的PAD
*/
void GPIO_ConfigWithPullEC618(uint32_t Pin, uint8_t IsInput, uint8_t InitValue, uint8_t AltFun);
/**
* @brief GPIO上下拉控制
*
* @param Pad Pad序号注意这个不是Pin序号
* @param IsPull 是否需要上下拉
* @param IsUp 是否上拉
*/
void GPIO_PullConfig(uint32_t Pad, uint8_t IsPull, uint8_t IsUp);
/**
* @brief GPIO外部中断初始化GPIO20~22只有配置成双边沿中断时因为开启了wakeuppad功能才有了弱上拉
*
* @param Pin Pin序号
* @param IsLevel 是否是电平中断0边沿型1电平型
* @param IsRiseHigh 上升沿或者高电平EC618的大部分GPIO只能单边沿中断所以上升沿和下降沿同时配置设置成上升沿。GPIO20~22由于和wakeuppad重叠才能实现双边沿触发
* @param IsFallLow 下降沿或者低电平
*/
void GPIO_ExtiConfig(uint32_t Pin, uint8_t IsLevel, uint8_t IsRiseHigh, uint8_t IsFallLow);
/**
* @brief GPIO复用功能
*
* @param Pad Pad序号注意这个不是Pin序号
* @param Function 复用功能这个需要根据芯片实际情况决定当前是0~7
* @param AutoPull 上下拉是否启动外设功能的默认配置1启动0关闭调用GPIO_PullConfig时会自动关闭如果配置成外设功能建议开启
* @param IsInputBuffer 输入是否启用缓冲功能1开启0关闭如果是中断建议开启
*
*/
void GPIO_IomuxEC618(uint32_t Pad, uint32_t Function, uint8_t AltFunctionPull, uint8_t IsInputBuffer);
/**
* @brief GPIO输出电平
*
* @param Pin Pin序号
* @param Level 1高电平0低电平
*/
void GPIO_Output(uint32_t Pin, uint8_t Level);
void GPIO_FastOutput(uint32_t Pin, uint8_t Level);
/**
* @brief GPIO输出电平并且同步控制上下拉电阻增强驱动力同时希望能接解决休眠无法保持电平的问题
*
* @param Pin Pin序号
* @param Level 1高电平0低电平
* @param AltFun 复用功能大部分Pad和GPIO是一一对应的如果出现多个Pad对应1个GPIO如果AltFun不能匹配则默认用Alt0的PAD
*/
void GPIO_OutputWithPullEC618(uint32_t Pin, uint8_t Level, uint8_t AltFun);
/**
* @brief 读取GPIO输入电平
*
* @param Pin Pin序号
* @return 1高电平 0低电平其他无效
*/
uint8_t GPIO_Input(uint32_t Pin);
/**
* @brief 翻转GPIO输出电平
*
* @param Pin Pin序号
* @return 无
*/
void GPIO_Toggle(uint32_t Pin);
/**
* @brief GPIO同一端口多个pin输出电平针对类似STM32GPIO分布有效
*
* @param Port 端口号 0或者1
* @param Pins Pin序号组合
* @param Level 1高电平0低电平
*/
void GPIO_OutputMulti(uint32_t Port, uint32_t Pins, uint32_t Level);
/**
* @brief 读取GPIO同一端口多个pin输入电平如果是端口1GPIO20~GPIO22对应的bit可能是不正常的需要用GPIO_Input
*
* @param Port 端口号 0或者1
* @return 0x0000~0xffff每个bit代表一个pin的电平
*/
uint32_t GPIO_InputMulti(uint32_t Port);
/**
* @brief 翻转GPIO同一端口多个pin输出电平
* @param Port 端口号
* @param Pins Pin序号组合
* @return 无
*/
void GPIO_ToggleMulti(uint32_t Port, uint32_t Pins);
/**
* @brief GPIO模拟单线输出模式
* @param Pin Pin序号
* @param Data 输出电平序列
* @param BitLen 输出电平序列中一共有几个bit
* @param Delay 每个bit之间的delay
* @return 无
*/
void GPIO_OutPulse(uint32_t Pin, uint8_t *Data, uint16_t BitLen, uint16_t Delay);
/**
* @brief 设置外部中断注意低功耗模式下普通GPIO是不能用的只能用wakepad唤醒
* @param Pin Pin序号WAKEUPPAD3~5已经和GPIO复用了额外可以用HAL_WAKEUP_0~HAL_WAKEUP_2
* @param CB 中断回调函数
* @param Pins 中断回调时的param
* @return 无
*/
void GPIO_ExtiSetCB(uint32_t Pin, CBFuncEx_t CB, void *pParam);
/**
* @brief GPIO初始化成OD门输出
* @param Pin Pin序号
* @param InitValue 初始电平
* @return 无
*/
void GPIO_ODConfig(uint32_t Pin, uint8_t InitValue);
/**
* @brief 从GPIO序号转换出Pad序号如果有多个Pad序号则会通过AltFun决定用哪个
*
* @param Pin Pin序号
* @param AltFun 复用功能大部分Pad和GPIO是一一对应的如果出现多个Pad对应1个GPIO如果AltFun不能匹配则默认用Alt0的PAD
* @return Pad序号
*/
uint32_t GPIO_ToPadEC618(uint32_t Pin, uint8_t AltFun);
/**
* @brief 设置WAKEUPPAD0,1,2
*
* @param Pin Pin序号HAL_WAKEUP_0~HAL_WAKEUP_2
* @param IsRiseHigh 上升沿触发
* @param IsFallLow 下降沿触发
* @param Pullup 上拉
* @param Pulldown 下拉
*/
void GPIO_WakeupPadConfig(uint32_t Pin, uint8_t IsRiseHigh, uint8_t IsFallLow, uint8_t Pullup, uint8_t Pulldown);
#endif

View File

@@ -0,0 +1,25 @@
/**
* @file driver_i2s.h
* @brief 使用本模块API时不可以使用原厂的I2S API。所有API都是任务不安全的和中断不安全的
* @version 0.1
* @date 2023-1-9
*
* @copyright
*
*/
#ifndef __CORE_I2S_H__
#define __CORE_I2S_H__
#include "bsp_common.h"
#include "i2s.h"
void I2S_FullConfig(uint8_t I2SID, i2sDataFmt_t DataFmt, i2sSlotCtrl_t SlotCtrl, i2sBclkFsCtrl_t BclkFsCtrl, i2sDmaCtrl_t DmaCtrl);
void I2S_BaseConfig(uint8_t I2SID, uint8_t Mode, uint8_t FrameSize);
int32_t I2S_Start(uint8_t I2SID, uint8_t IsPlay, uint32_t SampleRate, uint8_t ChannelNum);
void I2S_Tx(uint8_t I2SID, uint8_t* Data, uint32_t ByteLen, CBFuncEx_t cb, void *param);
void I2S_Rx(uint8_t I2SID, uint32_t ByteLen, CBFuncEx_t cb, void *param);
void I2S_TxStop(uint8_t I2SID);
void I2S_RxStop(uint8_t I2SID);
void I2S_TxPause(uint8_t I2SID);
void I2S_TxDebug(uint8_t I2SID);
void I2S_RxDebug(uint8_t I2SID);
#endif

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2022 OpenLuat & AirM2M
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __CORE_UART_H__
#define __CORE_UART_H__
#include "bsp_common.h"
/**
* @brief 对串口做基本的初始化工作
*
* @param UartID 串口号 0~MAX对应USART1~UARTX0默认用于log输出
* @param BaudRate 波特率
* @param TxCacheLen 发送初始缓存如果是unilog可以写0
* @param RxCacheLen 接收初始缓存
* @param DataBits 数据位5~8
* @param Parity 奇偶校验,可选下列
* UART_PARITY_NONE,
UART_PARITY_ODD,
UART_PARITY_EVEN,
* @param StopBits 停止位
* UART_STOP_BIT1,
UART_STOP_BIT1_5,
UART_STOP_BIT2,
* @param CB 回调函数用于通知是否有新数据达到DMA TX或者RX完成是否有错误
*/
void Uart_BaseInitEx(uint8_t UartID, uint32_t BaudRate, uint32_t TxCacheLen, uint32_t RxCacheLen, uint8_t DataBits, uint8_t Parity, uint8_t StopBits, CBFuncEx_t CB);
void Uart_SetCb(uint8_t UartID, CBFuncEx_t CB);
void Uart_DeInit(uint8_t UartID);
uint8_t Uart_IsTSREmpty(uint8_t UartID);
//void Uart_Tx(uint8_t UartID, const uint8_t *Data, uint32_t Len);
int Uart_RxBufferCB(uint8_t UartID, CBFuncEx_t CB);
int Uart_TxTaskSafe(uint8_t UartID, const void *Data, uint32_t Len);
uint32_t Uart_RxTaskSafe(uint8_t UartID, uint8_t *Data, uint32_t Len);
void Uart_TxStop(uint8_t UartID);
int Uart_RxBufferRead(uint8_t UartID, uint8_t *Data, uint32_t Len);
void Uart_RxBufferClear(uint8_t UartID);
void Uart_PrintReg(uint8_t UartID);
void Uart_ChangeBR(uint8_t UartID, uint32_t BaudRate);
uint32_t Uart_GetLastError(uint8_t UartID);
void Uart_Sleep(uint8_t UartID, uint8_t OnOff);
#endif

View File

@@ -0,0 +1,5 @@
#ifndef __SOC_DMA_H__
#define __SOC_DMA_H__
#include "dma.h"
void DMA_ForceStartStream(uint8_t DMAStream, uint8_t TxDir, const void *Data, uint32_t Len, DmaTransferConfig_t* Config, uint8_t NeedIrq);
#endif

View File

@@ -0,0 +1,62 @@
/**
* @file driver_gpio.h
* @brief 使用本模块API时不可以使用原厂的I2C API所有API都是任务不安全的和中断不安全的
* @version 0.1
* @date 2022-10-25
*
* @copyright
*
*/
#ifndef __CORE_I2C_H__
#define __CORE_I2C_H__
#include "bsp_common.h"
/**
* @brief i2c主机配置
*
* @param I2CID I2C通道号
* @param Speed 速度只有100000和400000
*/
void I2C_MasterSetup(uint8_t I2CID, uint32_t Speed);
/*
* @brief i2c传输前配置如果配置和上次一致则不用设置
*
* @param I2CID I2C通道号
* @param ChipAddress I2C设备地址
* @param ChipAddressLen I2C设备地址长度 1或者2
* @param CB 完成后回调函数
* @param pParam 完成后回调函数中的pParam
*/
void I2C_Prepare(uint8_t I2CID, uint16_t ChipAddress, uint8_t ChipAddressLen, CBFuncEx_t CB, void *pParam);
/**
* @brief i2c主机传输兼容直接读写和先写寄存器地址后读数据
*
* @param I2CID I2C通道号
* @param Operate 操作类型
* I2C_OP_READ_REG = 0, //i2c通用读寄存器一写一读自动带start信号
I2C_OP_READ, //i2c通用读只读
I2C_OP_WRITE, //i2c通用写只写
* @param RegAddress 寄存器地址的数据缓存,在通用读和通用写时忽略
* @param RegLen 寄存器地址长度,在通用读和通用写时忽略
* @param Data 读写数据缓存,直接使用用户的空间,在完成前不可以释放空间
* @param Len 读写数据长度
* @param Toms 传输单个字节超时时间单位ms
*/
void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t *RegAddress, uint32_t RegLen, uint8_t *Data, uint32_t Len, uint16_t Toms);
/**
* @brief i2c主机传输结果查询
*
* @param I2CID I2C通道号
* @param Result 传输结果 =0成功其他失败只有return != 0才有效
* @return =0 传输还未完成 其他已完成
*/
int I2C_WaitResult(uint8_t I2CID, int32_t *Result);
int32_t I2C_BlockWrite(uint8_t I2CID, uint16_t ChipAddress, uint8_t *Data, uint32_t Len, uint16_t Toms, CBFuncEx_t CB, void *pParam);
int32_t I2C_BlockRead(uint8_t I2CID, uint16_t ChipAddress, uint8_t *Reg, uint32_t RegLen, uint8_t *Data, uint32_t Len, uint16_t Toms, CBFuncEx_t CB, void *pParam);
void I2C_ChangeBR(uint8_t I2CID, uint32_t Baudrate);
#endif

View File

@@ -0,0 +1,15 @@
#ifndef __SOC_SPI_H__
#define __SOC_SPI_H__
#include "bsp_common.h"
void SPI_MasterInit(uint8_t SpiID, uint8_t DataBit, uint8_t Mode, uint32_t Speed, CBFuncEx_t CB, void *pUserData);
void SPI_SetCallbackFun(uint8_t SpiID, CBFuncEx_t CB, void *pUserData);
int32_t SPI_TransferEx(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len, uint8_t IsBlock, uint8_t UseDMA);
int32_t SPI_BlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len);
void SPI_FastTransfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len);
void SPI_SetNoBlock(uint8_t SpiID);
int32_t SPI_FlashBlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint32_t WLen, uint8_t *RxData, uint32_t RLen);
void SPI_TransferStop(uint8_t SpiID);
uint8_t SPI_IsTransferBusy(uint8_t SpiID);
void SPI_SetNewConfig(uint8_t SpiID, uint32_t Speed, uint8_t NewMode);
void SPI_SetDMATrigger(uint8_t SpiID, uint32_t UpValue, uint32_t DownValue);
#endif

View File

@@ -0,0 +1,356 @@
#include "mem_map.h"
/* Entry Point */
ENTRY(Reset_Handler)
/* Specify the memory areas */
MEMORY
{
ASMB_AREA(rwx) : ORIGIN = 0x00000000, LENGTH = 0x010000 /* 64KB */
MSMB_AREA(rwx) : ORIGIN = 0x00400000, LENGTH = 0x140000 /* 1.25MB */
#ifdef __LUATOS__
FLASH_AREA(rx) : ORIGIN = 0x00824000, LENGTH = 2212K /* 2212K */
#else
FLASH_AREA(rx) : ORIGIN = 0x00824000, LENGTH = 2944K /* 2944K */
#endif
}
/* Define output sections */
SECTIONS
{
. = AP_FLASH_LOAD_ADDR;
.vector :
{
KEEP(*(.isr_vector))
} >FLASH_AREA
.cache : ALIGN(128)
{
Image$$UNLOAD_NOCACHE$$Base = .;
*libdriver*.a:cache.o(.text*)
} >FLASH_AREA
.load_bootcode 0x0 :
{
. = ALIGN(4);
Load$$LOAD_BOOTCODE$$Base = LOADADDR(.load_bootcode);
Image$$LOAD_BOOTCODE$$Base = .;
KEEP(*(.mcuVector))
*(.ramBootCode)
*libdriver*.a:qspi.o(.text*)
*libdriver*.a:flash.o(.text*)
. = ALIGN(4);
} >ASMB_AREA AT>FLASH_AREA
Image$$LOAD_BOOTCODE$$Length = SIZEOF(.load_bootcode);
.load_ap_piram_asmb 0x1400 :
{
. = ALIGN(4);
Load$$LOAD_AP_PIRAM_ASMB$$Base = LOADADDR(.load_ap_piram_asmb);
Image$$LOAD_AP_PIRAM_ASMB$$Base = .;
*(.psPARamcode)
*(.platPARamcode)
*libc*.a:*memset.o(.text*)
*memcpy-armv7m.o(.text*)
. = ALIGN(4);
} >ASMB_AREA AT>FLASH_AREA
Image$$LOAD_AP_PIRAM_ASMB$$Length = SIZEOF(.load_ap_piram_asmb);
.load_ap_firam_asmb : ALIGN(4)
{
. = ALIGN(4);
Load$$LOAD_AP_FIRAM_ASMB$$Base = LOADADDR(.load_ap_firam_asmb);
Image$$LOAD_AP_FIRAM_ASMB$$Base = .;
*(.psFARamcode)
*(.platFARamcode)
. = ALIGN(4);
} >ASMB_AREA AT>FLASH_AREA
Image$$LOAD_AP_FIRAM_ASMB$$Length = SIZEOF(.load_ap_firam_asmb);
.load_ap_rwdata_asmb : ALIGN(4)
{
. = ALIGN(4);
Load$$LOAD_AP_FDATA_ASMB$$RW$$Base = LOADADDR(.load_ap_rwdata_asmb);
Image$$LOAD_AP_FDATA_ASMB$$RW$$Base = .;
*(.platFARWData)
. = ALIGN(4);
} >ASMB_AREA AT>FLASH_AREA
Image$$LOAD_AP_FDATA_ASMB$$Length = SIZEOF(.load_ap_rwdata_asmb);
.load_ps_rwdata_asmb : ALIGN(4)
{
Load$$LOAD_PS_FDATA_ASMB$$RW$$Base = LOADADDR(.load_ps_rwdata_asmb);
Image$$LOAD_PS_FDATA_ASMB$$RW$$Base = .;
*(.psFARWData)
. = ALIGN(4);
} >ASMB_AREA AT>FLASH_AREA
Image$$LOAD_PS_FDATA_ASMB$$RW$$Length = SIZEOF(.load_ps_rwdata_asmb);
.load_ap_zidata_asmb (NOLOAD):
{
. = ALIGN(4);
Image$$LOAD_AP_FDATA_ASMB$$ZI$$Base = .;
*(.platFAZIData)
. = ALIGN(4);
Image$$LOAD_AP_FDATA_ASMB$$ZI$$Limit = .;
Image$$LOAD_PS_FDATA_ASMB$$ZI$$Base = .;
*(.psFAZIData)
. = ALIGN(4);
Image$$LOAD_PS_FDATA_ASMB$$ZI$$Limit = .;
*(.exceptCheck)
} >ASMB_AREA
.load_rrcmem 0xB000 (NOLOAD):
{
*(.rrcMem)
} >ASMB_AREA
.load_flashmem 0xC000 (NOLOAD):
{
*(.apFlashMem)
} >ASMB_AREA
.load_ap_piram_msmb MSMB_START_ADDR :
{
. = ALIGN(4);
Load$$LOAD_AP_PIRAM_MSMB$$Base = LOADADDR(.load_ap_piram_msmb);
Image$$LOAD_AP_PIRAM_MSMB$$Base = .;
*(.psPMRamcode)
*(.platPMRamcode)
*(.platPMRamcodeFCLK)
*(.recordNodeRO)
. = ALIGN(4);
} >MSMB_AREA AT>FLASH_AREA
Image$$LOAD_AP_PIRAM_MSMB$$Length = SIZEOF(.load_ap_piram_msmb);
.load_ap_firam_msmb : ALIGN(4)
{
. = ALIGN(4);
Load$$LOAD_AP_FIRAM_MSMB$$Base = LOADADDR(.load_ap_firam_msmb);
Image$$LOAD_AP_FIRAM_MSMB$$Base = .;
*(.ramCode2)
*(.upRamCode)
*(.psFMRamcode)
*(.platFMRamcode)
. = ALIGN(4);
} >MSMB_AREA AT>FLASH_AREA
Image$$LOAD_AP_FIRAM_MSMB$$Length = SIZEOF(.load_ap_firam_msmb);
.load_apos : ALIGN(4)
{
. = ALIGN(4);
Load$$LOAD_APOS$$Base = LOADADDR(.load_apos);
Image$$LOAD_APOS$$Base = .;
*libfreertos.a:event_groups.o(.text*)
*libfreertos.a:heap_6.o(.text*)
*libfreertos.a:tlsf.o(.text*)
*libfreertos.a:list.o(.text*)
*libfreertos.a:queue.o(.text*)
*libfreertos.a:tasks.o(.text*)
*libfreertos.a:timers.o(.text*)
*libfreertos.a:port.o(.text*)
*libfreertos.a:port_asm.o(.text*)
*libfreertos.a:cmsis_os2.o(.text*)
. = ALIGN(4);
} >MSMB_AREA AT>FLASH_AREA
Image$$LOAD_APOS$$Length = SIZEOF(.load_apos);
.load_dram_bsp : ALIGN(4)
{
. = ALIGN(4);
Load$$LOAD_DRAM_BSP$$Base = LOADADDR(.load_dram_bsp);
Image$$LOAD_DRAM_BSP$$Base = .;
*libdriver*:bsp_spi.o(.data*)
*libdriver*:flash.o(.data*)
*libdriver*:flash_rt.o(.data*)
*libdriver*:gpr.o(.data*)
*libdriver*:apmu.o(.data*)
*libdriver*:apmuTiming.o(.data*)
*libdriver*:bsp.o(.data*)
*libdriver*:plat_config.o(.data*)
*libstartup*:system_ec618.o(.data*)
*libdriver*:unilog.o(.data*)
*libdriver*:pad.o(.data*)
*libdriver*:ic.o(.data*)
*libdriver*:ec_main.o(.data*)
*libdriver*:slpman.o(.data*)
*libdriver*:bsp_usart.o(.data*)
*libdriver*:bsp_lpusart.o(.data*)
*libdriver*:timer.o(.data*)
*libdriver*:dma.o(.data*)
*libdriver*:adc.o(.data*)
*libdriver*:wdt.o(.data*)
*libmiddleware_ec*:usb_device.o(.data*)
*libmiddleware_ec*:uart_device.o(.data*)
*libdriver*:clock.o(.data*)
*libdriver*:hal_adc.o(.data*)
*libdriver*:hal_adcproxy.o(.data*)
*libdriver*:hal_alarm.o(.data*)
*libdriver*:exception_process.o(.data*)
*libdriver*:exception_dump.o(.data*)
. = ALIGN(4);
} >MSMB_AREA AT>FLASH_AREA
Image$$LOAD_DRAM_BSP$$Length = SIZEOF(.load_dram_bsp);
.load_dram_bsp_zi (NOLOAD):
{
. = ALIGN(4);
Image$$LOAD_DRAM_BSP$$ZI$$Base = .;
*libdriver*:bsp_spi.o(.bss*)
*libdriver*:flash.o(.bss*)
*libdriver*:flash_rt.o(.bss*)
*libdriver*:gpr.o(.bss*)
*libdriver*:apmu.o(.bss*)
*libdriver*:apmuTiming.o(.bss*)
*libdriver*:bsp.o(.bss*)
*libdriver*:plat_config.o(.bss*)
*libstartup*:system_ec618.o(.bss*)
*libdriver*:unilog.o(.bss*)
*libdriver*:pad.o(.bss*)
*libdriver*:ic.o(.bss*)
*libdriver*:ec_main.o(.bss*)
*libdriver*:slpman.o(.bss*)
*libdriver*:bsp_usart.o(.bss*)
*libdriver*:bsp_lpusart.o(.bss*)
*libdriver*:timer.o(.bss*)
*libdriver*:dma.o(.bss*)
*libdriver*:adc.o(.bss*)
*libdriver*:wdt.o(.bss*)
*libmiddleware_ec*:usb_device.o(.bss*)
*libmiddleware_ec*:uart_device.o(.bss*)
*libdriver*:clock.o(.bss*)
*libdriver*:hal_adc.o(.bss*)
*libdriver*:hal_trim.o(.bss*)
*libdriver*:hal_adcproxy.o(.bss*)
*libdriver*:hal_alarm.o(.bss*)
*libdriver*:exception_process.o(.bss*)
*libdriver*:exception_dump.o(.bss*)
*(.recordNodeZI)
. = ALIGN(4);
Image$$LOAD_DRAM_BSP$$ZI$$Limit = .;
} >MSMB_AREA
.unload_slpmem (NOLOAD):
{
*(.sleepmem)
} >MSMB_AREA
.load_dram_shared : ALIGN(4)
{
. = ALIGN(4);
Load$$LOAD_DRAM_SHARED$$Base = LOADADDR(.load_dram_shared);
Image$$LOAD_DRAM_SHARED$$Base = .;
*(.data*)
. = ALIGN(4);
} >MSMB_AREA AT>FLASH_AREA
Image$$LOAD_DRAM_SHARED$$Length = SIZEOF(.load_dram_shared);
.load_dram_shared_zi (NOLOAD):
{
. = ALIGN(4);
Image$$LOAD_DRAM_SHARED$$ZI$$Base = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
*(.stack) /* stack should be 4 byte align */
Image$$LOAD_DRAM_SHARED$$ZI$$Limit = .;
*(.USB_NOINIT_DATA_BUF)
} >MSMB_AREA
PROVIDE(end_ap_data = . );
PROVIDE(start_up_buffer = up_buf_start);
.load_up_buffer start_up_buffer(NOLOAD):
{
*(.catShareBuf)
Image$$LOAD_UP_BUFFER$$Limit = .;
} >MSMB_AREA
PROVIDE(end_up_buffer = . );
heap_size = start_up_buffer - end_ap_data;
ASSERT(heap_size>=min_heap_size_threshold,"ap use too much ram, heap less than min_heap_size_threshold!")
ASSERT(end_up_buffer<=MSMB_APMEM_END_ADDR,"ap use too much ram, exceed to MSMB_APMEM_END_ADDR")
.text :
{
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.vfpll_veneer)
*(.v4_bx)
*(.init*)
*(.fini*)
*(.iplt)
*(.igot.plt)
*(.rel.iplt)
} >FLASH_AREA
.preinit_fun_array :
{
. = ALIGN(4);
__preinit_fun_array_start = .;
KEEP (*(SORT(.preinit_fun_array.*)))
KEEP (*(.preinit_fun_array*))
__preinit_fun_array_end = .;
. = ALIGN(4);
} > FLASH_AREA
.drv_init_fun_array :
{
. = ALIGN(4);
__drv_init_fun_array_start = .;
KEEP (*(SORT(.drv_init_fun_array.*)))
KEEP (*(.drv_init_fun_array*))
__drv_init_fun_array_end = .;
. = ALIGN(4);
} > FLASH_AREA
.task_fun_array :
{
. = ALIGN(4);
__task_fun_array_start = .;
KEEP (*(SORT(.task_fun_array.*)))
KEEP (*(.task_fun_array*))
__task_fun_array_end = .;
. = ALIGN(4);
} > FLASH_AREA
PROVIDE(totalFlashLimit = .);
.unload_cpaon CP_AONMEMBACKUP_START_ADDR (NOLOAD):
{
} >MSMB_AREA
.load_xp_sharedinfo XP_SHAREINFO_BASE_ADDR (NOLOAD):
{
*(.shareInfo)
} >MSMB_AREA
.load_dbg_area XP_DBGRESERVED_BASE_ADDR (NOLOAD):
{
*(.resetFlag)
} >MSMB_AREA
.unload_xp_ipcmem IPC_SHAREDMEM_START_ADDR (NOLOAD):
{
} >MSMB_AREA
}
GROUP(
libgcc.a
libc.a
libm.a
)

View File

@@ -0,0 +1,116 @@
/**
* @file audio_ll_drv.h
* @brief 音频数据对接到底层硬件驱动的中间层,为了兼容多种情况并不是最优化,由于硬件驱动代码是开源的,用户可以不用,自己对接驱动代码
* @version 0.1
* @date 2022-10-23
*
* @copyright
*
*/
#ifndef __AUDIO_LL_DRV_H__
#define __AUDIO_LL_DRV_H__
typedef enum
{
AUSTREAM_FORMAT_UNKNOWN, ///< placeholder for unknown format
AUSTREAM_FORMAT_PCM, ///< raw PCM data
AUSTREAM_FORMAT_WAVPCM, ///< WAV, PCM inside
AUSTREAM_FORMAT_MP3, ///< MP3
AUSTREAM_FORMAT_AMRNB, ///< AMR-NB
AUSTREAM_FORMAT_AMRWB, ///< AMR_WB
AUSTREAM_FORMAT_SBC, ///< bt SBC
} auStreamFormat_t;
typedef enum
{
AUSTREAM_BUS_DAC,
AUSTREAM_BUS_I2S,
} auStreamBusType_t;
typedef struct
{
CBFuncEx_t CB; //pData是自身Audio_StreamStruct指针
CBFuncEx_t Decoder;
CBFuncEx_t Encoder;
void *pParam;
void *fd;
void *CoderParam;
void *UserParam;
Buffer_Struct FileDataBuffer;
Buffer_Struct AudioDataBuffer;
Buffer_Struct RomDataBuffer;
llist_head DataHead;
uint32_t SampleRate;
uint32_t waitRequire;
uint8_t BitDepth;
uint8_t ChannelCount; //声道目前只有1或者2
auStreamFormat_t Format;
auStreamBusType_t BusType; //音频总线类型DAC, IIS之类的
uint8_t BusID; //音频总线ID
uint8_t IsDataSigned; //数据是否是有符号的
uint8_t IsHardwareRun;
uint8_t IsPause;
uint8_t IsStop;
uint8_t IsPlaying;
uint8_t IsFileNotEnd;
uint8_t DecodeStep;
}Audio_StreamStruct;
/**
* @brief 音频驱动初始化
*
*/
void Audio_GlobalInit(void);
/**
* @brief 基于I2S总线的外部codec相关I2S总线模式配置并不对codec的I2C处理
*
* @param bus_id I2S总线序号0或者1
* @param mode I2S模式I2S_MODE_I2SI2S_MODE_MSBI2S_MODE_LSB一般常见MODE_I2S和MODE_MSB
* @param frame_size I2S帧模式I2S_FRAME_SIZE_16_16I2S_FRAME_SIZE_16_32I2S_FRAME_SIZE_24_32I2S_FRAME_SIZE_32_32目前只用到
* I2S_FRAME_SIZE_16_16
*/
void Audio_CodecI2SInit(uint8_t bus_id, uint8_t mode, uint8_t frame_size);
/**
* @brief 开始播放原始音频流
*
* @param pStream 原始音频流数据结构, 底层不保存这个结构,需要用户保存
* @return =0 成功 < 0失败错误码
*/
int32_t Audio_StartRaw(Audio_StreamStruct *pStream);
/**
* @brief 写入原始音频数据到底层
*
* @param pStream 原始音频流数据结构
* @param pByteData 原始音频数据
* @param ByteLen 原始音频数据字节长度
* @param AddHead 是否插入到开头播放序列1插入开头0插入结尾。一般用于开始/恢复播放时插入空白段以消除爆破音,正常数据不要插入开头
* @return int32_t =0 成功 < 0失败错误码
*/
int32_t Audio_WriteRaw(Audio_StreamStruct *pStream, uint8_t *pByteData, uint32_t ByteLen, uint8_t AddHead);
/**
* @brief 终止音频数据播放
*
* @param pStream 原始音频流数据结构
*/
void Audio_Stop(Audio_StreamStruct *pStream);
/**
* @brief 清除播放完的数据,需要在任务中进行
*
* @param pStream 原始音频流数据结构
*/
void Audio_DeleteOldData(Audio_StreamStruct *pStream);
/**
* @brief 暂停播放音频数据,只是设置停止标志,已经在驱动中的数据仍然会播放
*
* @param pStream 原始音频流数据结构
*/
void Audio_Pause(Audio_StreamStruct *pStream);
/**
* @brief 恢复播放音频数据
*
* @param pStream 原始音频流数据结构
*/
void Audio_Resume(Audio_StreamStruct *pStream);
#endif

View File

@@ -0,0 +1,191 @@
/**
* @file audio_play.h
* @brief 音频播放层需要配合tts库audio_decoder库和audio_ll_drv使用
* @version 0.1
* @date 2022-10-23
*
* @copyright
*
*/
#ifndef __AUDIO_PLAY_H__
#define __AUDIO_PLAY_H__
typedef struct
{
char *path; //文件路径如果为NULL则表示是ROM数组
uint32_t address; //ROM数组地址
uint32_t rom_data_len; //ROM数组长度
uint8_t fail_continue; //如果解码失败是否跳过继续下一个,如果是最后一个文件,强制停止并设置错误信息
uint8_t dummy[3];
}audio_play_info_t;
enum
{
MULTIMEDIA_DATA_TYPE_NONE,
MULTIMEDIA_DATA_TYPE_PCM,
MULTIMEDIA_DATA_TYPE_MP3,
MULTIMEDIA_DATA_TYPE_WAV,
MULTIMEDIA_DATA_TYPE_AMR_NB,
MULTIMEDIA_DATA_TYPE_AMR_WB,
};
enum
{
MULTIMEDIA_CB_AUDIO_DECODE_START, //开始解码文件
MULTIMEDIA_CB_AUDIO_OUTPUT_START, //开始输出解码后的音数据
MULTIMEDIA_CB_AUDIO_NEED_DATA, //底层驱动播放播放完一部分数据,需要更多数据
MULTIMEDIA_CB_AUDIO_DONE, //底层驱动播放完全部数据了
MULTIMEDIA_CB_DECODE_DONE, //音频解码完成
MULTIMEDIA_CB_TTS_INIT, //TTS做完了必要的初始化用户可以通过audio_play_tts_set_param做个性化配置
MULTIMEDIA_CB_TTS_DONE, //TTS编码完成了。注意不是播放完成
};
extern const unsigned char ivtts_8k[];
extern const unsigned char ivtts_8k_lite[];
extern const unsigned char ivtts_16k_lite[];
extern const unsigned char ivtts_16k[];
extern const unsigned char ivtts_8k_tz_data[];
extern const unsigned char ivtts_8k_tz_frags[];
extern const unsigned char ivtts_16k_tz_data[];
extern const unsigned char ivtts_16k_tz_frags[];
/**
* @brief 播放时event回调见MULTIMEDIA_CB_XXXuser_param就是初始化时传入的user_param
*
*/
typedef void (*audio_play_event_cb_fun_t)(uint32_t cb_audio_event, void *user_param);
/**
* @brief 播放文件时在数据解码出来后会回调给用户做进一步处理比如音量的软件增减软件静音当然也可以不处理。数据长度是字节数bits是量化位数一般是16channels是声道数1或者2
*
*/
typedef void (*audio_play_data_cb_fun_t)(uint8_t *data, uint32_t data_len, uint8_t bits, uint8_t channels);
typedef void (*audio_play_default_fun_t)(void *param);
/**
* @brief 音频播放初始化
*
* @param event_cb 播放时event回调函数
* @param data_cb 数据解码回调函数,如果是直接播放原始数据流就不会用到
* @param user_param 回调函数的用户参数
*/
void audio_play_global_init(audio_play_event_cb_fun_t event_cb, audio_play_data_cb_fun_t data_cb, void *user_param);
/**
* @brief 播放指定数量的文件或者ROM数组文件数据直接写成数组形式
*
* @param multimedia_id 多媒体通道目前只有0
* @param info 文件信息文件路径或者ROM信息
* @param files_num 文件数量
* @return int =0成功其他失败
*/
int audio_play_multi_files(uint32_t multimedia_id, audio_play_info_t info[], uint32_t files_num);
/**
* @brief 是否播放完全部数据
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @return uint8_t =1是=0没有
*/
uint8_t audio_play_is_finish(uint32_t multimedia_id);
/**
* @brief 强制停止播放文件,但是不会停止已经输出到底层驱动的数据播放
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @return int =0成功其他失败
*/
int audio_play_stop(uint32_t multimedia_id);
/**
* @brief 暂停/恢复播放
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @param is_pause 0恢复其他暂停
* @return int =0成功其他失败
*/
int audio_play_pause_raw(uint32_t multimedia_id, uint8_t is_pause);
/**
* @brief 获取上一次播放结果在MULTIMEDIA_CB_AUDIO_DONE回调时调用最佳
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @return int =0完整的播放完成<0被用户停止了>0 TTS失败或者第几个音频文件解码失败用户在play_info未设置了解码失败后继续文件位置+1
*/
int audio_play_get_last_error(uint32_t multimedia_id);
/**
* @brief 插入多段空白数据每段数据约100ms
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @param cnt 段数
* @return int =0成功其他失败
*/
int audio_play_write_blank_raw(uint32_t multimedia_id, uint8_t cnt);
/**
* @brief 立刻初始化播放未编码的原始音频数据流
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @param audio_format 音频数据格式目前只支持PCM即需要手动解码
* @param num_channels 声道数目前只能1或2
* @param sample_rate 采样率注意只有8K,16K,32K,48K,96K,22.05K,44.1K这些能被支持
* @param bits_per_sample 量化bit只能是16
* @param is_signed 量化数据是否带符号只能是1
* @return int =0成功其他失败
*/
int audio_play_start_raw(uint32_t multimedia_id, uint8_t audio_format, uint8_t num_channels, uint32_t sample_rate, uint8_t bits_per_sample, uint8_t is_signed);
/**
* @brief 向底层驱动传入一段原始音频数据
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @param data 原始音频数据
* @param len 原始音频数据长度
* @return int =0成功其他失败
*/
int audio_play_write_raw(uint32_t multimedia_id, uint8_t *data, uint32_t len);
/**
* @brief 强制停止所有播放,同时底层驱动也会停止输出,不要用于播放文件的结束
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @return int =0成功其他失败
*/
int audio_play_stop_raw(uint32_t multimedia_id);
/**
* @brief 编码并播放一段文字
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @param text 文字数据
* @param text_bytes 文字数据长度
* @return int =0成功其他失败
*/
int audio_play_tts_text(uint32_t multimedia_id, void *text, uint32_t text_bytes);
/**
* @brief 在收到MULTIMEDIA_CB_TTS_INIT回调时可以设置TTS参数等同于ivTTS_SetParam
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @param param_id 见ivTTS_PARAM_XXX
* @param param_value param_id对应的value
* @return int =0成功其他失败
*/
int audio_play_tts_set_param(uint32_t multimedia_id, uint32_t param_id, uint32_t param_value);
/**
* @brief 设置TTS的资源和对应SDKIDTTS资源有很多种。
*
* @param address 资源的flash或者ram地址
* @param sdk_id 本质上就是传入AISOUND_SDK_USERID
*/
void audio_play_tts_set_resource(void *address, void *sdk_id);
/**
* @brief 获取当前播放的音频的采样率
*
* @param multimedia_id multimedia_id 多媒体通道目前只有0
* @return uint32_t 采样率
*/
uint32_t audio_play_get_sample_rate(uint32_t multimedia_id);
void audio_play_file_default_fun(void *param);
void audio_play_TTS_default_fun(void *param);
void audio_play_tts_set_resource_ex(void *address, void *sdk_id, void *read_resource_fun);
void audio_play_global_init_ex(audio_play_event_cb_fun_t event_cb, audio_play_data_cb_fun_t data_cb, audio_play_default_fun_t play_file_fun, audio_play_default_fun_t play_tts_fun, void *user_param);
int audio_play_write_blank_raw_ex(uint32_t multimedia_id, uint8_t cnt, uint8_t add_font);
#endif

View File

@@ -0,0 +1,15 @@
#include "psdial_ps_ctrl.h"
#include "cms_comm.h"
#include "common_api.h"
ALIGNED_4BYTE CAT_PSPHY_SHAREDATA UINT8 psUpMem[PS_DIAL_PS_UP_MEM_SIZE];
void *psDialGetUpMemAndSize(UINT32 *pUpMemSize)
{
if (pUpMemSize != PNULL)
{
*pUpMemSize = sizeof(psUpMem);
}
return (void *)psUpMem;
}

View File

@@ -0,0 +1,9 @@
/* SDK ID */
#ifndef AISOUND_5_0_SDK_CONSISTENCE__H
#define AISOUND_5_0_SDK_CONSISTENCE__H
#define AISOUND_SDK_USERID ((ivCStrA)"\x35\x30\x63\x32\x63\x34\x63\x65\x66\x31\x61\x39\x34\x30\x31\x66\x61\x61\x31\x30\x66\x64\x61\x30\x36\x31\x61\x61\x37\x66\x62\x34")
#endif /* !AISOUND_SDK_CONSISTENCE__H */

View File

@@ -0,0 +1,9 @@
/* SDK ID */
#ifndef AISOUND_5_0_SDK_CONSISTENCE__H
#define AISOUND_5_0_SDK_CONSISTENCE__H
#define AISOUND_SDK_USERID ((ivCStrA)"\x32\x65\x36\x31\x31\x32\x62\x65\x32\x30\x31\x64\x34\x34\x63\x39\x61\x30\x61\x66\x36\x65\x64\x30\x66\x62\x61\x64\x62\x64\x37\x00")
#endif /* !AISOUND_SDK_CONSISTENCE__H */

View File

@@ -0,0 +1,388 @@
/*--------------------------------------------------------------+
| |
| ivDefine.h - Basic Definitions |
| |
| Copyright (c) 1999-2008, ANHUI USTC iFLYTEK CO.,LTD. |
| All rights reserved. |
| |
+--------------------------------------------------------------*/
#ifndef IFLYTEK_VOICE__DEFINE__H
#define IFLYTEK_VOICE__DEFINE__H
#include "ivPlatform.h"
#define IV_CHECK_RES_READ 1 /* <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Դ<EFBFBD>ijɹ<C4B3><C9B9><EFBFBD> */
/*
* <09><><EFBFBD>η<EFBFBD>
*/
#define ivConst IV_CONST
#define ivStatic IV_STATIC
#ifdef IV_INLINE
#define ivInline IV_STATIC IV_INLINE
#else
#define ivInline IV_STATIC
#endif
#define ivExtern IV_EXTERN
#define ivPtr IV_PTR_PREFIX*
#define ivCPtr ivConst ivPtr
#define ivPtrC ivPtr ivConst
#define ivCPtrC ivConst ivPtr ivConst
#define ivCall IV_CALL_STANDARD /* <20>ǵݹ<C7B5><DDB9><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) */
#define ivReentrant IV_CALL_REENTRANT /* <20>ݹ<EFBFBD><DDB9><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) */
#define ivVACall IV_CALL_VAR_ARG /* ֧<>ֱ<EFBFBD><D6B1>ε<EFBFBD> */
#define ivProc ivCall ivPtr
/*
* <09><><EFBFBD><EFBFBD>
*/
#define ivNull (0)
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ֵ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ̨<C6BD><CCA8><EFBFBD><EFBFBD>) */
typedef int ivBool;
#define ivTrue (~0)
#define ivFalse (0)
/* <20>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ֵ */
typedef int ivComp;
#define ivGreater (1)
#define ivEqual (0)
#define ivLesser (-1)
#define ivIsGreater(v) ((v)>0)
#define ivIsEqual(v) (0==(v))
#define ivIsLesser(v) ((v)<0)
/*
* <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
/* <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> */
typedef signed IV_TYPE_INT8 ivInt8; /* 8-bit */
typedef unsigned IV_TYPE_INT8 ivUInt8; /* 8-bit */
typedef signed IV_TYPE_INT16 ivInt16; /* 16-bit */
typedef unsigned IV_TYPE_INT16 ivUInt16; /* 16-bit */
typedef signed IV_TYPE_INT24 ivInt24; /* 24-bit */
typedef unsigned IV_TYPE_INT24 ivUInt24; /* 24-bit */
typedef signed IV_TYPE_INT32 ivInt32; /* 32-bit */
typedef unsigned IV_TYPE_INT32 ivUInt32; /* 32-bit */
#ifdef IV_TYPE_INT48
typedef signed IV_TYPE_INT48 ivInt48; /* 48-bit */
typedef unsigned IV_TYPE_INT48 ivUInt48; /* 48-bit */
#endif
#ifdef IV_TYPE_INT64
typedef signed IV_TYPE_INT64 ivInt64; /* 64-bit */
typedef unsigned IV_TYPE_INT64 ivUInt64; /* 64-bit */
#endif
/* <20><>Ӧ<EFBFBD><D3A6>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
typedef ivInt8 ivPtr ivPInt8; /* 8-bit */
typedef ivUInt8 ivPtr ivPUInt8; /* 8-bit */
typedef ivInt16 ivPtr ivPInt16; /* 16-bit */
typedef ivUInt16 ivPtr ivPUInt16; /* 16-bit */
typedef ivInt24 ivPtr ivPInt24; /* 24-bit */
typedef ivUInt24 ivPtr ivPUInt24; /* 24-bit */
typedef ivInt32 ivPtr ivPInt32; /* 32-bit */
typedef ivUInt32 ivPtr ivPUInt32; /* 32-bit */
#ifdef IV_TYPE_INT48
typedef ivInt48 ivPtr ivPInt48; /* 48-bit */
typedef ivUInt48 ivPtr ivPUInt48; /* 48-bit */
#endif
#ifdef IV_TYPE_INT64
typedef ivInt64 ivPtr ivPInt64; /* 64-bit */
typedef ivUInt64 ivPtr ivPUInt64; /* 64-bit */
#endif
/* <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
typedef ivInt8 ivCPtr ivPCInt8; /* 8-bit */
typedef ivUInt8 ivCPtr ivPCUInt8; /* 8-bit */
typedef ivInt16 ivCPtr ivPCInt16; /* 16-bit */
typedef ivUInt16 ivCPtr ivPCUInt16; /* 16-bit */
typedef ivInt24 ivCPtr ivPCInt24; /* 24-bit */
typedef ivUInt24 ivCPtr ivPCUInt24; /* 24-bit */
typedef ivInt32 ivCPtr ivPCInt32; /* 32-bit */
typedef ivUInt32 ivCPtr ivPCUInt32; /* 32-bit */
#ifdef IV_TYPE_INT48
typedef ivInt48 ivCPtr ivPCInt48; /* 48-bit */
typedef ivUInt48 ivCPtr ivPCUInt48; /* 48-bit */
#endif
#ifdef IV_TYPE_INT64
typedef ivInt64 ivCPtr ivPCInt64; /* 64-bit */
typedef ivUInt64 ivCPtr ivPCUInt64; /* 64-bit */
#endif
/* <20>߽<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> */
#define IV_SBYTE_MAX (+127)
#define IV_MAX_INT16 (+32767)
#define IV_INT_MAX (+8388607L)
#define IV_MAX_INT32 (+2147483647L)
#define IV_SBYTE_MIN (-IV_SBYTE_MAX - 1)
#define IV_MIN_INT16 (-IV_MAX_INT16 - 1)
#define IV_INT_MIN (-IV_INT_MAX - 1)
#define IV_MIN_INT32 (-IV_MAX_INT32 - 1)
#define IV_BYTE_MAX (0xffU)
#define IV_USHORT_MAX (0xffffU)
#define IV_UINT_MAX (0xffffffUL)
#define IV_ULONG_MAX (0xffffffffUL)
/* <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ */
typedef ivUInt8 ivByte;
typedef ivPUInt8 ivPByte;
typedef ivPCUInt8 ivPCByte;
typedef signed ivInt;
typedef signed ivPtr ivPInt;
typedef signed ivCPtr ivPCInt;
typedef unsigned ivUInt;
typedef unsigned ivPtr ivPUInt;
typedef unsigned ivCPtr ivPCUInt;
/* ָ<><D6B8> */
typedef void ivPtr ivPointer;
typedef void ivCPtr ivCPointer;
/* <20><><EFBFBD><EFBFBD> */
typedef ivPointer ivHandle;
/* <20><>ַ<EFBFBD><D6B7><EFBFBD>ߴ<EFBFBD><DFB4><EFBFBD><EFBFBD><EFBFBD> */
typedef IV_TYPE_ADDRESS ivAddress;
typedef IV_TYPE_SIZE ivSize;
typedef ivAddress ivPtr ivPAddress;
/*
* <09>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ض<EFBFBD><D8B6><EFBFBD>
*/
/* <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD> */
typedef ivInt8 ivCharA;
typedef ivUInt16 ivCharW;
#if IV_UNICODE
typedef ivCharW ivChar;
#else
typedef ivCharA ivChar;
#endif
/* <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD> */
typedef ivCharA ivPtr ivStrA;
typedef ivCharA ivCPtr ivCStrA;
typedef ivCharW ivPtr ivStrW;
typedef ivCharW ivCPtr ivCStrW;
typedef ivChar ivPtr ivStr;
typedef ivChar ivCPtr ivCStr;
/* <20>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define ivTextA(s) ((ivCStrA)s)
#define ivTextW(s) ((ivCStrW)L##s)
#if IV_UNICODE
#define ivText(s) ivTextW(s)
#else
#define ivText(s) ivTextA(s)
#endif
/*
* <09><>Դ<EFBFBD><D4B4>ַ<EFBFBD><D6B7><EFBFBD>ߴ<EFBFBD><DFB4><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
*/
typedef ivUInt32 ivResAddress;
typedef ivUInt32 ivResSize;
#define ivResSize_Int8 1
#define ivResSize_Int16 2
#define ivResSize_Int32 4
/* read resource callback type */
#if IV_UNIT_BITS == 16
/* #if IV_CHECK_RES_READ */
typedef ivBool (ivProc ivCBReadResExt)(
ivPointer pParameter, /* [in] user callback parameter */
ivPointer pBuffer, /* [out] read resource buffer */
ivResAddress iPos, /* [in] read start position */
ivResSize nSize, /* [in] read size */
ivSize nCount ); /* [in] read count */
/* #else */
typedef void (ivProc ivCBReadRes)(
ivPointer pParameter, /* [in] user callback parameter */
ivPointer pBuffer, /* [out] read resource buffer */
ivResAddress iPos, /* [in] read start position */
ivResSize nSize, /* [in] read size */
ivSize nCount ); /* [in] read count */
/* #endif */
#else
/* #if IV_CHECK_RES_READ */
typedef ivBool (ivProc ivCBReadResExt)(
ivPointer pParameter, /* [in] user callback parameter */
ivPointer pBuffer, /* [out] read resource buffer */
ivResAddress iPos, /* [in] read start position */
ivResSize nSize ); /* [in] read size */
/* #else */
typedef void (ivProc ivCBReadRes)(
ivPointer pParameter, /* [in] user callback parameter */
ivPointer pBuffer, /* [out] read resource buffer */
ivResAddress iPos, /* [in] read start position */
ivResSize nSize ); /* [in] read size */
/* #endif */
#endif
/* map resource callback type */
typedef ivCPointer (ivProc ivCBMapRes)(
ivPointer pParameter, /* [in] user callback parameter */
ivResAddress iPos, /* [in] map start position */
ivResSize nSize ); /* [in] map size */
/* log callback type */
typedef ivUInt16 (ivProc ivCBLogExt)
(
ivPointer pParameter, /* [out] user callback parameter */
ivCPointer pcData, /* [in] output data buffer */
ivSize nSize /* [in] output data size */
);
/* resource pack description */
typedef struct tagResPackDescExt ivTResPackDescExt, ivPtr ivPResPackDescExt;
struct tagResPackDescExt
{
ivPointer pCBParam; /* resource callback parameter */
ivCBReadResExt pfnRead; /* read resource callback entry */
ivCBMapRes pfnMap; /* map resource callback entry (optional) */
ivResSize nSize; /* resource pack size (optional, 0 for null) */
ivPUInt8 pCacheBlockIndex; /* cache block index (optional, size = dwCacheBlockCount) */
ivPointer pCacheBuffer; /* cache buffer (optional, size = dwCacheBlockSize * dwCacheBlockCount) */
ivSize nCacheBlockSize; /* cache block size (optional, must be 2^N) */
ivSize nCacheBlockCount; /* cache block count (optional, must be 2^N) */
ivSize nCacheBlockExt; /* cache block ext (optional) */
};
/* ESR resource pack description */
typedef struct tagResPackDesc ivTResPackDesc, ivPtr ivPResPackDesc;
struct tagResPackDesc
{
ivPointer pCBParam; /* resource callback parameter */
ivCBReadRes pfnRead; /* read resource callback entry */
ivCBMapRes pfnMap; /* map resource callback entry (optional) */
ivResSize nSize; /* resource pack size (optional, 0 for null) */
ivPUInt8 pCacheBlockIndex; /* cache block index (optional, size = dwCacheBlockCount) */
ivPointer pCacheBuffer; /* cache buffer (optional, size = dwCacheBlockSize * dwCacheBlockCount) */
ivSize nCacheBlockSize; /* cache block size (optional, must be 2^N) */
ivSize nCacheBlockCount; /* cache block count (optional, must be 2^N) */
ivSize nCacheBlockExt; /* cache block ext (optional) */
};
/* Save data callback type */
typedef ivBool (ivProc ivCBSaveData)(
ivPointer pUserParam,
ivPointer pSrcBuffer,
ivSize nBufferBytes
);
/* Load data callback type */
typedef ivBool (ivProc ivCBLoadData)(
ivPointer pUserParam,
ivPointer pDstBuffer,
ivSize ivPtr pnBufferBytes
);
/* LOG output callback type */
typedef void (ivProc ivCBLog)(
ivPointer pUserParam,
ivCPointer pLogData,
ivSize nBytes
);
typedef ivPointer (ivProc ivCBRealloc)(
ivPointer pUserParam,
ivPointer pMemblock,
ivSize nBytes
);
typedef void (ivProc ivCBFree)(
ivPointer pUserParam,
ivPointer pBuffer
);
typedef ivBool (ivProc ivCBStartRecord)(
ivPointer pUserParam
);
typedef ivBool (ivProc ivCBStopRecord)(
ivPointer pUserParam
);
typedef struct tagUserSys
{
ivPointer pWorkBuffer;
ivSize nWorkBufferBytes;
ivPointer pResidentBuffer;
ivSize nResidentBufferBytes;
ivBool bCheckResource;
ivPointer pCBParam;
ivCBSaveData pfnSaveData;
ivCBLoadData pfnLoadData;
ivCBRealloc pfnRealloc;
ivCBFree pfnFree;
ivCBStartRecord pfnStartRecord;
ivCBStopRecord pfnStopRecord;
ivCBLog pfnLog;
}TUserSys, ivPtr PUserSys, ivPtr ivPUserSys;
#endif /* !IFLYTEK_VOICE__DEFINE__H */

View File

@@ -0,0 +1,77 @@
/*--------------------------------------------------------------+
| |
| ivPlatform.h - Platform Config |
| |
| Platform: Win32 (X86) |
| |
| Copyright (c) 1999-2008, ANHUI USTC iFLYTEK CO.,LTD. |
| All rights reserved. |
| |
+--------------------------------------------------------------*/
/*
* TODO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>ƽ̨<C6BD><CCA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD>
*/
//#include <crtdbg.h>
//#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <tchar.h>
//#include <windows.h>
/*
* TODO: <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>ƽ̨<C6BD><CCA8><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
*/
#define IV_UNIT_BITS 8 /* <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫλ<D4AA><CEBB> */
#define IV_BIG_ENDIAN 0 /* <20>Ƿ<EFBFBD><C7B7><EFBFBD> Big-Endian <20>ֽ<EFBFBD><D6BD><EFBFBD> */
#define IV_PTR_GRID 4 /* <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
#define IV_PTR_PREFIX /* ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD>ιؼ<CEB9><D8BC><EFBFBD>(<28><><EFBFBD><EFBFBD>ȡֵ<C8A1><D6B5> near | far, <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_CONST const /* <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD>(<28><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_EXTERN extern /* <20>ⲿ<EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> */
#define IV_STATIC static /* <20><>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD>(<28><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_INLINE __inline /* <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD>(<28><><EFBFBD><EFBFBD>ȡֵ<C8A1><D6B5> inline, <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_CALL_STANDARD /* <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ιؼ<CEB9><D8BC><EFBFBD>(<28><><EFBFBD><EFBFBD>ȡֵ<C8A1><D6B5> stdcall | fastcall | pascal, <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_CALL_REENTRANT /* <20>ݹ麯<DDB9><E9BAAF><EFBFBD><EFBFBD><EFBFBD>ιؼ<CEB9><D8BC><EFBFBD>(<28><><EFBFBD><EFBFBD>ȡֵ<C8A1><D6B5> stdcall | reentrant, <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_CALL_VAR_ARG /* <20><><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ιؼ<CEB9><D8BC><EFBFBD>(<28><><EFBFBD><EFBFBD>ȡֵ<C8A1><D6B5> cdecl, <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_TYPE_INT8 char /* 8λ<38><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_TYPE_INT16 short /* 16λ<36><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_TYPE_INT24 int /* 24λ<34><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_TYPE_INT32 long /* 32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#if 1 /* 48/64 λ<><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ѡ<EFBFBD><D1A1>, <20><><EFBFBD>DZ<EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>, <20><>ijЩ 32 λƽ̨<C6BD><CCA8>, ʹ<><CAB9>ģ<EFBFBD>ʽ<E2B7BD><EFBFBD><E1B9A9> 48/64 λ<><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>ʺܵ<CABA> */
#define IV_TYPE_INT48 long long /* 48λ<38><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_TYPE_INT64 long long /* 64λ<34><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#endif
#define IV_TYPE_ADDRESS long /* <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_TYPE_SIZE long /* <20><>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_ANSI_MEMORY 1 /* <20>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9> ANSI <20>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_ANSI_STRING 0 /* <20>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9> ANSI <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IV_ASSERT(exp) /* <20><><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD>(<28><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_YIELD /* <20><><EFBFBD>в<EFBFBD><D0B2><EFBFBD>(<28><>Э<EFBFBD><D0AD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>) */
#define IV_TTS_ARM_CODECACHE 0 /* <20>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD>Cache */
/* TTS<54><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD> */
#define IV_DEBUG 0 /* <20>Ƿ<EFBFBD>֧<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD> */
/* <20><><EFBFBD>Է<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ */
#ifndef IV_LOG
#define IV_LOG IV_DEBUG /* <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ */
#endif
/* <20>ں<EFBFBD>֧<EFBFBD><D6A7>Unicode<64><65><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ΪUnicode<64><65> */
#if defined(UNICODE) || defined(_UNICODE)
#define IV_UNICODE 1 /* <20>Ƿ<EFBFBD><C7B7><EFBFBD> Unicode <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> */
#else
#define IV_UNICODE 0 /* <20>Ƿ<EFBFBD><C7B7><EFBFBD> Unicode <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> */
#endif

View File

@@ -0,0 +1,451 @@
/*--------------------------------------------------------------+
| |
| ivTTS.h - AiSound 4 Kernel API |
| |
| Copyright (c) 1999-2008, ANHUI USTC iFLYTEK CO.,LTD. |
| All rights reserved. |
| |
+--------------------------------------------------------------*/
#ifndef IFLYTEK_VOICE__TTS__H
#define IFLYTEK_VOICE__TTS__H
#include "ivDefine.h"
#include "ivTTSSDKID.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* COMMON DEFINES
*/
typedef ivUInt16 ivTTSErrID;
typedef ivPointer ivHTTS;
/*
* TTS User Info
*/
typedef struct tagTTSUserInfo ivTTTsUserInfo, ivPtr ivPTTSUserInfo;
struct tagTTSUserInfo
{
ivPointer pCBLogParameter; /* log callback parameter */
ivCBLogExt pfnLog; /* write log callback entry */
ivPointer pCheckoutInfo; /* Checkout Info to TTS */
};
/*
* FUNCTION ENTRIES
*/
/* 返回值:-1服务内部未知异常
0鉴权通过
1当前应用无授权
2应用总授权超限
3当前设备刷机次数超限
4当前设备或应用授权已被禁止使用
5设备参数异常或丢失
6数据解析失败秘钥不匹配
7服务流控限制请退避重试
*/
int ivTTS_Auth(void);
/* get SDK version */
ivTTSErrID ivCall ivTTS_GetVersion(
ivPUInt8 piMajor, /* [out] major version number */
ivPUInt8 piMinor, /* [out] minor version number */
ivPUInt16 piRevision); /* [out] revision number */
/* create an instance */
#define ivTTS_Create(phTTS, pHeap, nHeapSize, pCBParam, pResPackDesc, nResPackCount,pUserInfo) \
ivTTS_CreateG(phTTS, pHeap, nHeapSize, pCBParam, pResPackDesc, nResPackCount,pUserInfo, AISOUND_SDK_USERID)
/* create an instance (Decrypt version) */
#define ivTTS_Create_Decrypt(phTTS, pHeap, nHeapSize, pCBParam, pResPackDesc, nResPackCount,pUserInfo) \
ivTTS_CreateGecrypt(phTTS, pHeap, nHeapSize, pCBParam, pResPackDesc, nResPackCount,pUserInfo, AISOUND_SDK_USERID)
ivTTSErrID ivCall ivTTS_CreateGecrypt(
ivHTTS ivPtr phTTS, /* [out] handle to an instance */
ivPointer pHeap, /* [in] heap for instance */
ivSize nHeapSize, /* [in] size of the heap */
ivPointer pCBParam, /* [in] user callback parameter */
ivPResPackDescExt pResPackDesc, /* [in] resource pack description array */
ivSize nResPackCount, /* [in] resource pack count */
ivPTTSUserInfo pUserInfo, /* [in] TTS User Info */
ivCStrA pUserID); /* [in] SDK ID */
ivTTSErrID ivCall ivTTS_CreateG(
ivHTTS ivPtr phTTS, /* [out] handle to an instance */
ivPointer pHeap, /* [in] heap for instance */
ivSize nHeapSize, /* [in] size of the heap */
ivPointer pCBParam, /* [in] user callback parameter */
ivPResPackDescExt pResPackDesc, /* [in] resource pack description array */
ivSize nResPackCount, /* [in] resource pack count */
ivPTTSUserInfo pUserInfo, /* [in] TTS User Info */
ivCStrA pUserID); /* [in] SDK ID */
/* destroy an instance */
ivTTSErrID ivCall ivTTS_Destroy(
ivHTTS hTTS ); /* [in] handle to an instance */
/* get a parameter associated with an instance */
ivTTSErrID ivCall ivTTS_GetParam(
ivHTTS hTTS, /* [in] handle to an instance */
ivUInt32 nParamID, /* [in] parameter ID */
ivPAddress pnParamValue ); /* [out] buffer to receive the parameter value */
/* set a parameter associated with an instance */
ivTTSErrID ivCall ivTTS_SetParam(
ivHTTS hTTS, /* [in] handle to an instance */
ivUInt32 nParamID, /* [in] parameter ID */
ivSize nParamValue ); /* [in] parameter value */
/* run an instance and hold current thread's control */
ivTTSErrID ivCall ivTTS_Run(
ivHTTS hTTS ); /* [in] handle to an instance */
/* exit running of an instance and leave current thread's control */
ivTTSErrID ivCall ivTTS_Exit(
ivHTTS hTTS ); /* [in] handle to an instance */
/* synthesize a buffer of text on an instance */
ivTTSErrID ivCall ivTTS_SynthText(
ivHTTS hTTS, /* [in] handle to an instance */
ivCPointer pcData, /* [in] pointer of text buffer data to be synthesized */
ivSize nSize ); /* [in] size of text buffer data to be synthesized */
/* begin to synthesize from callback on an instance */
ivTTSErrID ivCall ivTTS_SynthStart(
ivHTTS hTTS ); /* [in] handle to an instance */
/*
* ERROR CODES
*/
#define ivTTS_ERR_OK 0x0000 /* success */
#define ivTTS_ERR_FAILED 0xFFFF /* failed */
#define ivTTS_ERR_END_OF_INPUT 0x0001 /* end of input stream */
#define ivTTS_ERR_EXIT 0x0002 /* exit TTS */
#define ivTTS_STATE_BASE 0x0100 /* state base */
#define ivTTS_STATE_INVALID_DATA ivTTS_STATE_BASE + 2 /* invalid data */
#define ivTTS_STATE_TTS_STOP ivTTS_STATE_BASE + 3 /* TTS stop */
#define ivTTS_ERR_BASE 0x8000 /* error number base */
#define ivTTS_ERR_UNIMPEMENTED ivTTS_ERR_BASE + 0 /* unimplemented function */
#define ivTTS_ERR_UNSUPPORTED ivTTS_ERR_BASE + 1 /* unsupported on this platform */
#define ivTTS_ERR_INVALID_HANDLE ivTTS_ERR_BASE + 2 /* invalid handle */
#define ivTTS_ERR_INVALID_PARAMETER ivTTS_ERR_BASE + 3 /* invalid parameter(s) */
#define ivTTS_ERR_INSUFFICIENT_HEAP ivTTS_ERR_BASE + 4 /* insufficient heap size */
#define ivTTS_ERR_STATE_REFUSE ivTTS_ERR_BASE + 5 /* refuse to do in current state */
#define ivTTS_ERR_INVALID_PARAM_ID ivTTS_ERR_BASE + 6 /* invalid parameter ID */
#define ivTTS_ERR_INVALID_PARAM_VALUE ivTTS_ERR_BASE + 7 /* invalid parameter value */
#define ivTTS_ERR_RESOURCE ivTTS_ERR_BASE + 8 /* Resource is error */
#define ivTTS_ERR_RESOURCE_READ ivTTS_ERR_BASE + 9 /* read resource error */
#define ivTTS_ERR_LBENDIAN ivTTS_ERR_BASE + 10 /* the Endian of SDK is error */
#define ivTTS_ERR_HEADFILE ivTTS_ERR_BASE + 11 /* the HeadFile is different of the SDK */
#define ivTTS_ERR_SIZE_EXCEED_BUFFER ivTTS_ERR_BASE + 12 /* get data size exceed the data buffer */
#define ivTTS_ERR_RESOURCE_LICENSE ivTTS_ERR_BASE + 13 /* some Resources haven't license */
/*
* INSTANCE PARAMETERS
*/
/* constants for values of field nParamID */
#define ivTTS_PARAM_PARAMCH_CALLBACK 0x00000000 /* parameter change callback entry */
#define ivTTS_PARAM_LANGUAGE 0x00000100 /* language, e.g. Chinese */
#define ivTTS_PARAM_INPUT_CODEPAGE 0x00000101 /* input code page, e.g. GBK */
#define ivTTS_PARAM_TEXT_MARK 0x00000102 /* text mark, e.g. CSSML */
#define ivTTS_PARAM_USE_PROMPTS 0x00000104 /* whether use prompts */
#define ivTTS_PARAM_RECOGNIZE_PHONEME 0x00000105 /* how to recognize phoneme input */
#define ivTTS_PARAM_INPUT_MODE 0x00000200 /* input mode, e.g. from fixed buffer, from callback */
#define ivTTS_PARAM_INPUT_TEXT_BUFFER 0x00000201 /* input text buffer */
#define ivTTS_PARAM_INPUT_TEXT_SIZE 0x00000202 /* input text size */
#define ivTTS_PARAM_INPUT_CALLBACK 0x00000203 /* input callback entry */
#define ivTTS_PARAM_PROGRESS_BEGIN 0x00000204 /* current processing position */
#define ivTTS_PARAM_PROGRESS_LENGTH 0x00000205 /* current processing length */
#define ivTTS_PARAM_PROGRESS_CALLBACK 0x00000206 /* progress callback entry */
#define ivTTS_PARAM_READ_AS_NAME 0x00000301 /* whether read as name */
#define ivTTS_PARAM_READ_DIGIT 0x00000302 /* how to read digit, e.g. read as number, read as value */
#define ivTTS_PARAM_CHINESE_NUMBER_1 0x00000303 /* how to read number "1" in Chinese */
#define ivTTS_PARAM_MANUAL_PROSODY 0x00000304 /* whether use manual prosody */
#define ivTTS_PARAM_ENGLISH_NUMBER_0 0x00000305 /* how to read number "0" in Englsih */
#define ivTTS_PARAM_READ_WORD 0x00000306 /* how to read word in Englsih, e.g. read by word, read as alpha */
#define ivTTS_PARAM_OUTPUT_CALLBACK 0x00000401 /* output callback entry */
#define ivTTS_PARAM_ROLE 0x00000500 /* speaker role */
#define ivTTS_PARAM_SPEAK_STYLE 0x00000501 /* speak style */
#define ivTTS_PARAM_VOICE_SPEED 0x00000502 /* voice speed */
#define ivTTS_PARAM_VOICE_PITCH 0x00000503 /* voice tone */
#define ivTTS_PARAM_VOLUME 0x00000504 /* volume value */
#define ivTTS_PARAM_CHINESE_ROLE 0x00000510 /* Chinese speaker role */
#define ivTTS_PARAM_ENGLISH_ROLE 0x00000511 /* English speaker role */
#define ivTTS_PARAM_VEMODE 0x00000600 /* voice effect - predefined mode */
#define ivTTS_PARAM_USERMODE 0x00000701 /* user's mode */
#define ivTTS_PARAM_NAVIGATION_MODE 0x00000701 /* Navigation Version*/
#define ivTTS_PARAM_EVENT_CALLBACK 0x00001001 /* sleep callback entry */
#define ivTTS_PARAM_OUTPUT_BUF 0x00001002 /* output buffer */
#define ivTTS_PARAM_OUTPUT_BUFSIZE 0x00001003 /* output buffer size */
#define ivTTS_PARAM_DELAYTIME 0x00001004 /* delay time */
/* constants for values of parameter ivTTS_PARAM_LANGUAGE */
#define ivTTS_LANGUAGE_AUTO 0 /* Detect language automatically */
#define ivTTS_LANGUAGE_CHINESE 1 /* Chinese (with English) */
#define ivTTS_LANGUAGE_ENGLISH 2 /* English */
/* constants for values of parameter ivTTS_PARAM_INPUT_CODEPAGE */
#define ivTTS_CODEPAGE_ASCII 437 /* ASCII */
#define ivTTS_CODEPAGE_GBK 936 /* GBK (default) */
#define ivTTS_CODEPAGE_BIG5 950 /* Big5 */
#define ivTTS_CODEPAGE_UTF16LE 1200 /* UTF-16 little-endian */
#define ivTTS_CODEPAGE_UTF16BE 1201 /* UTF-16 big-endian */
#define ivTTS_CODEPAGE_UTF8 65001 /* UTF-8 */
#define ivTTS_CODEPAGE_GB2312 ivTTS_CODEPAGE_GBK
#define ivTTS_CODEPAGE_GB18030 ivTTS_CODEPAGE_GBK
#if IV_BIG_ENDIAN
#define ivTTS_CODEPAGE_UTF16 ivTTS_CODEPAGE_UTF16BE
#else
#define ivTTS_CODEPAGE_UTF16 ivTTS_CODEPAGE_UTF16LE
#endif
#define ivTTS_CODEPAGE_UNICODE ivTTS_CODEPAGE_UTF16
#define ivTTS_CODEPAGE_PHONETIC_PLAIN 23456 /* Kingsoft Phonetic Plain */
/* constants for values of parameter ivTTS_PARAM_TEXT_MARK */
#define ivTTS_TEXTMARK_NONE 0 /* none */
#define ivTTS_TEXTMARK_SIMPLE_TAGS 1 /* simple tags (default) */
/* constants for values of parameter ivTTS_PARAM_INPUT_MODE */
#define ivTTS_INPUT_FIXED_BUFFER 0 /* from fixed buffer */
#define ivTTS_INPUT_CALLBACK 1 /* from callback */
/* constants for values of parameter ivTTS_PARAM_READ_DIGIT */
#define ivTTS_READDIGIT_AUTO 0 /* decide automatically (default) */
#define ivTTS_READDIGIT_AS_NUMBER 1 /* say digit as number */
#define ivTTS_READDIGIT_AS_VALUE 2 /* say digit as value */
/* constants for values of parameter ivTTS_PARAM_CHINESE_NUMBER_1 */
#define ivTTS_CHNUM1_READ_YAO 0 /* read number "1" [yao1] in chinese (default) */
#define ivTTS_CHNUM1_READ_YI 1 /* read number "1" [yi1] in chinese */
/* constants for values of parameter ivTTS_PARAM_ENGLISH_NUMBER_0 */
#define ivTTS_ENNUM0_READ_ZERO 0 /* read number "0" [zero] in english (default) */
#define ivTTS_ENNUM0_READ_O 1 /* read number "0" [o] in englsih */
/* constants for values of parameter ivTTS_PARAM_SPEAKER */
#define ivTTS_ROLE_TIANCHANG 1 /* Tianchang (female, Chinese) */
#define ivTTS_ROLE_WENJING 2 /* Wenjing (female, Chinese) */
#define ivTTS_ROLE_XIAOYAN 3 /* Xiaoyan (female, Chinese) */
#define ivTTS_ROLE_YANPING 3 /* Xiaoyan (female, Chinese) */
#define ivTTS_ROLE_XIAOFENG 4 /* Xiaofeng (male, Chinese) */
#define ivTTS_ROLE_YUFENG 4 /* Xiaofeng (male, Chinese) */
#define ivTTS_ROLE_SHERRI 5 /* Sherri (female, US English) */
#define ivTTS_ROLE_XIAOJIN 6 /* Xiaojin (female, Chinese) */
#define ivTTS_ROLE_NANNAN 7 /* Nannan (child, Chinese) */
#define ivTTS_ROLE_JINGER 8 /* Jinger (female, Chinese) */
#define ivTTS_ROLE_JIAJIA 9 /* Jiajia (girl, Chinese) */
#define ivTTS_ROLE_YUER 10 /* Yuer (female, Chinese) */
#define ivTTS_ROLE_XIAOQIAN 11 /* Xiaoqian (female, Chinese Northeast) */
#define ivTTS_ROLE_LAOMA 12 /* Laoma (male, Chinese) */
#define ivTTS_ROLE_BUSH 13 /* Bush (male, US English) */
#define ivTTS_ROLE_XIAORONG 14 /* Xiaorong (female, Chinese Szechwan) */
#define ivTTS_ROLE_XIAOMEI 15 /* Xiaomei (female, Cantonese) */
#define ivTTS_ROLE_ANNI 16 /* Anni (female, Chinese) */
#define ivTTS_ROLE_JOHN 17 /* John (male, US English) */
#define ivTTS_ROLE_ANITA 18 /* Anita (female, British English) */
#define ivTTS_ROLE_TERRY 19 /* Terry (female, US English) */
#define ivTTS_ROLE_CATHERINE 20 /* Catherine (female, US English) */
#define ivTTS_ROLE_TERRYW 21 /* Terry (female, US English Word) */
#define ivTTS_ROLE_XIAOLIN 22 /* Xiaolin (female, Chinese) */
#define ivTTS_ROLE_XIAOMENG 23 /* Xiaomeng (female, Chinese) */
#define ivTTS_ROLE_XIAOQIANG 24 /* Xiaoqiang (male, Chinese) */
#define ivTTS_ROLE_XIAOKUN 25 /* XiaoKun (male, Chinese) */
#define ivTTS_ROLE_JIUXU 51 /* Jiu Xu (male, Chinese) */
#define ivTTS_ROLE_DUOXU 52 /* Duo Xu (male, Chinese) */
#define ivTTS_ROLE_XIAOPING 53 /* Xiaoping (female, Chinese) */
#define ivTTS_ROLE_DONALDDUCK 54 /* Donald Duck (male, Chinese) */
#define ivTTS_ROLE_BABYXU 55 /* Baby Xu (child, Chinese) */
#define ivTTS_ROLE_DALONG 56 /* Dalong (male, Cantonese) */
#define ivTTS_ROLE_TOM 57 /* Tom (male, US English) */
#define ivTTS_ROLE_USER 99 /* user defined */
/* constants for values of parameter ivTTS_PARAM_SPEAK_STYLE */
#define ivTTS_STYLE_PLAIN 0 /* plain speak style */
#define ivTTS_STYLE_NORMAL 1 /* normal speak style (default) */
/* constants for values of parameter ivTTS_PARAM_VOICE_SPEED */
/* the range of voice speed value is from -32768 to +32767 */
#define ivTTS_SPEED_MIN -32768 /* slowest voice speed */
#define ivTTS_SPEED_NORMAL 0 /* normal voice speed (default) */
#define ivTTS_SPEED_MAX +32767 /* fastest voice speed */
/* constants for values of parameter ivTTS_PARAM_VOICE_PITCH */
/* the range of voice tone value is from -32768 to +32767 */
#define ivTTS_PITCH_MIN -32768 /* lowest voice tone */
#define ivTTS_PITCH_NORMAL 0 /* normal voice tone (default) */
#define ivTTS_PITCH_MAX +32767 /* highest voice tone */
/* constants for values of parameter ivTTS_PARAM_VOLUME */
/* the range of volume value is from -32768 to +32767 */
#define ivTTS_VOLUME_MIN -32768 /* minimized volume */
#define ivTTS_VOLUME_NORMAL 0 /* normal volume */
#define ivTTS_VOLUME_MAX +32767 /* maximized volume (default) */
/* constants for values of parameter ivTTS_PARAM_VEMODE */
#define ivTTS_VEMODE_NONE 0 /* none */
#define ivTTS_VEMODE_WANDER 1 /* wander */
#define ivTTS_VEMODE_ECHO 2 /* echo */
#define ivTTS_VEMODE_ROBERT 3 /* robert */
#define ivTTS_VEMODE_CHROUS 4 /* chorus */
#define ivTTS_VEMODE_UNDERWATER 5 /* underwater */
#define ivTTS_VEMODE_REVERB 6 /* reverb */
#define ivTTS_VEMODE_ECCENTRIC 7 /* eccentric */
/* constants for values of parameter ivTTS_PARAM_USERMODE(ivTTS_PARAM_NAVIGATION_MODE) */
#define ivTTS_USE_NORMAL 0 /* synthesize in the Mode of Normal */
#define ivTTS_USE_NAVIGATION 1 /* synthesize in the Mode of Navigation */
#define ivTTS_USE_MOBILE 2 /* synthesize in the Mode of Mobile */
#define ivTTS_USE_EDUCATION 3 /* synthesize in the Mode of Education */
/* constants for values of parameter ivTTS_PARAM_READ_WORD */
#define ivTTS_READWORD_BY_WORD 2 /* say words by the way of word */
#define ivTTS_READWORD_BY_ALPHA 1 /* say words by the way of alpha */
#define ivTTS_READWORD_BY_AUTO 0 /* say words by the way of auto */
/* parameter change callback type */
typedef ivTTSErrID (ivProc ivTTSCB_ParamChange)(
ivPointer pParameter, /* [in] user callback parameter */
ivUInt32 nParamID, /* [in] parameter ID */
ivUInt32 nParamValue ); /* [in] parameter value */
/* progress callback type */
typedef ivTTSErrID (ivProc ivTTSCB_Progress)(
ivPointer pParameter, /* [in] user callback parameter */
ivUInt32 iProcBegin, /* [in] current processing position */
ivUInt32 nProcLen ); /* [in] current processing length */
/* input callback type */
typedef ivTTSErrID (ivProc ivTTSCB_Input)(
ivPointer pParameter, /* [in] user callback parameter */
ivPointer pText, /* [out] input text buffer */
ivSize ivPtr pnSize ); /* [in/out] input text size */
/* output callback type */
typedef ivTTSErrID (ivProc ivTTSCB_Output)(
ivPointer pParameter, /* [in] user callback parameter */
ivUInt16 nCode, /* [in] output data code */
ivCPointer pcData, /* [in] output data buffer */
ivSize nSize ); /* [in] output data size */
/* parameter change callback type */
typedef ivTTSErrID (ivProc ivTTSCB_Event)(
ivPointer pParameter, /* [in] user callback parameter */
ivUInt32 nEventID, /* [in] parameter ID */
ivUInt32 nValue ); /* [in] parameter value */
/* constants for values of parameter nEventID */
#define ivTTS_EVENT_SLEEP 0x0100 /* sleep */
#define ivTTS_EVENT_PLAYSTART 0x0101 /* start playing */
#define ivTTS_EVENT_SWITCHCONTEXT 0x0102 /* context switch */
/* constants for values of parameter wCode */
#define ivTTS_CODE_PCM8K16B 0x0208 /* PCM 8K 16bit */
#define ivTTS_CODE_PCM11K16B 0x020B /* PCM 11K 16bit */
#define ivTTS_CODE_PCM16K16B 0x0210 /* PCM 16K 16bit */
/*
* PARAMETER STRUCTURES
*/
/* parameters for voice effect amplify */
typedef struct tagIsTTSVEAmplifyParam TIsTTSVEAmplifyParam;
struct tagIsTTSVEAmplifyParam
{
ivUInt16 m_nPeriod; /* 1-2000ms */
ivUInt8 m_fAmpMin; /* 0-100% */
ivUInt8 m_fAmpMax; /* 0-100% */
};
/* parameters for voice effect echo */
typedef struct tagIsTTSVEEchoParam TIsTTSVEEchoParam;
struct tagIsTTSVEEchoParam
{
ivUInt8 m_fInitDecay; /* 0-100% */
ivUInt8 m_fDecay; /* 0-100% */
ivUInt16 m_nDelay; /* 1-2000ms */
};
/* parameters for voice effectVE reverb */
typedef struct tagIsTTSVEReverbParam TIsTTSVEReverbParam;
struct tagIsTTSVEReverbParam
{
ivUInt8 m_fInitDecay; /* 0-100% */
ivUInt8 m_nFilters; /* 1-16 */
ivUInt8 m_fDecay[16]; /* 0-100% */
ivUInt8 m_nDelay[16]; /* 1-100ms */
};
/* parameters for voice effect chrous */
typedef struct tagIsTTSVEChrousParam TIsTTSVEChrousParam;
struct tagIsTTSVEChrousParam
{
ivUInt8 m_fInitDecay; /* 0-100% */
ivUInt8 m_fInitRatio; /* 0-100% */
ivUInt8 m_nDelayMin; /* 1-40ms */
ivUInt8 m_nDelayMax; /* 1-40ms */
ivUInt8 m_nFilters; /* 1-16 */
ivUInt8 m_nFilterFreq; /* 1-50Hz */
ivUInt8 m_nFilterFreqDelta; /* 1-50Hz */
};
/* parameters for voice effect pitch */
typedef struct tagIsTTSVEPitchParam TIsTTSVEPitchParam;
struct tagIsTTSVEPitchParam
{
ivUInt8 m_fDeltaPitch; /* 0-90% */
ivUInt16 m_nPeriod; /* 1-20000ms */
};
/* get pcm data */
ivTTSErrID ivCall ivTTS_GetData(
ivHTTS hTTS, /* [in] handle to an instance */
ivPointer pData, /* [in] pointer of pcm data buffer */
ivSize ivPtr pSize ); /* [in/out] data size */
/* Label text with symbol */
ivTTSErrID ivCall ivTTS_SymbolLabel(
ivHTTS hTTS, /* [in] handle to an instance */
ivCPointer pText, /* [in] pointer of the text buffer */
ivSize nTextLen, /* [in] size of the text buffer */
ivCPointer pSymbol, /* [in] pointer of the symbol buffer */
ivSize nSymbolLen, /* [in] size of the symbol buffer */
ivPointer pOut, /* [out] pointer of the output buffer */
ivPUInt32 pnOutLen, /* [in], max size of the output buffer[out] actually used size of the output buffer */
ivBool bTone /* [in], if the symbols have tone */
);
#ifdef __cplusplus
}
#endif
#endif /* !IFLYTEK_VOICE__TTS__H */

View File

@@ -0,0 +1,9 @@
/* SDK ID */
#ifndef AISOUND_5_0_SDK_CONSISTENCE_ALL_H
#define AISOUND_5_0_SDK_CONSISTENCE_ALL_H
#define AISOUND_SDK_USERID_16K ((ivCStrA)"\x65\x37\x38\x38\x66\x63\x33\x66\x35\x39\x32\x63\x34\x63\x36\x61\x61\x39\x62\x33\x36\x64\x32\x62\x36\x36\x65\x61\x38\x33\x31\x31")
#define AISOUND_SDK_USERID_8K ((ivCStrA)"\x65\x33\x32\x36\x35\x39\x63\x30\x61\x39\x34\x32\x34\x30\x38\x61\x39\x65\x66\x65\x66\x61\x61\x66\x30\x32\x39\x62\x65\x65\x32\x00")
#endif /* !AISOUND_SDK_CONSISTENCE__H */

View File

@@ -0,0 +1,815 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS compiler ARMCC (ARM compiler V5) header file
* @version V5.0.2
* @date 13. February 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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 __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* CMSIS compiler control architecture macros */
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
#define __ARM_ARCH_6M__ 1
#endif
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
#define __ARM_ARCH_7M__ 1
#endif
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
#define __ARM_ARCH_7EM__ 1
#endif
/* __ARM_ARCH_8M_BASE__ not applicable */
/* __ARM_ARCH_8M_MAIN__ not applicable */
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __declspec(noreturn)
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __enable_irq(); */
#define __enable_irq() __set_PRIMASK(0)
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __disable_irq(); */
#define __disable_irq() __set_PRIMASK(1)
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1U);
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#else
(void)fpscr;
#endif
}
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order in signed short value
\details Reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return(result);
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

View File

@@ -0,0 +1,361 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.0.2
* @date 13. February 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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 __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* ARM Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
#ifndef __FORCEINLINE
#define __FORCEINLINE __forceinline
#endif
#define __GET_RETURN_ADDRESS() __return_address()
/*
* ARM Compiler 6 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
#ifndef __FORCEINLINE
#define __FORCEINLINE __attribute__((always_inline)) inline
#endif
#define __GET_RETURN_ADDRESS() __builtin_return_address(0)
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#include <cmsis_iar.h>
/* CMSIS compiler control architecture macros */
#if (__CORE__ == __ARM6M__) || (__CORE__ == __ARM6SM__)
#ifndef __ARM_ARCH_6M__
#define __ARM_ARCH_6M__ 1
#endif
#elif (__CORE__ == __ARM7M__)
#ifndef __ARM_ARCH_7M__
#define __ARM_ARCH_7M__ 1
#endif
#elif (__CORE__ == __ARM7EM__)
#ifndef __ARM_ARCH_7EM__
#define __ARM_ARCH_7EM__ 1
#endif
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __noreturn
#endif
#ifndef __USED
#define __USED __root
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED __packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
__packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
// Workaround for missing __CLZ intrinsic in
// various versions of the IAR compilers.
// __IAR_FEATURE_CLZ__ should be defined by
// the compiler that supports __CLZ internally.
#if (defined (__ARM_ARCH_6M__)) && (__ARM_ARCH_6M__ == 1) && (!defined (__IAR_FEATURE_CLZ__))
__STATIC_INLINE uint32_t __CLZ(uint32_t data)
{
if (data == 0u) { return 32u; }
uint32_t count = 0;
uint32_t mask = 0x80000000;
while ((data & mask) == 0)
{
count += 1u;
mask = mask >> 1u;
}
return (count);
}
#endif
/*
* TI ARM Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

View File

@@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.2
* @date 19. April 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

View File

@@ -0,0 +1,123 @@
/****************************************************************************
*
* Copy right: 2017-, Copyrigths of AirM2M Ltd.
* File name: CommonTypedef.h
* Description: Common type define file
* History: 08/23/2017 Originated by Yunfei Li
*
****************************************************************************/
#ifndef _COMMON_TYPEDEF_H
#define _COMMON_TYPEDEF_H
#ifndef PHY_PC_SIM
#include "cmsis_compiler.h"
#else
#define __FORCEINLINE __inline
typedef unsigned long uint32_t;
#endif
//#define PUBLIC_CMCC_EDRX_DEBUG 1
/*****************************************************************************
armcc definition
char 8 1 (byte-aligned) 0 to 255 (unsigned) by default.
C128 to 127 (signed) when compiled with
--signed_chars.
signed char 8 1 (byte-aligned) <20>C128 to 127
unsigned char 8 1 (byte-aligned) 0 to 255
(signed) short 16 2 (halfword-aligned) <20>C32,768 to 32,767
unsigned short 16 2 (halfword-aligned) 0 to 65,535
(signed) int 32 4 (word-aligned) <20>C2,147,483,648 to 2,147,483,647
unsigned int 32 4 (word-aligned) 0 to 4,294,967,295
(signed) long 32 4 (word-aligned) <20>C2,147,483,648 to 2,147,483,647
unsigned long 32 4 (word-aligned) 0 to 4,294,967,295
(signed) long long 64 8 (doubleword-aligned) <20>C9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
unsigned long long 64 8 (doubleword-aligned) 0 to 18,446,744,073,709,551,615
float 32 4 (word-aligned) 1.175494351e-38 to 3.40282347e+38 (normalized values)
double 64 8 (doubleword-aligned) 2.22507385850720138e-308 to 1.79769313486231571e
+308 (normalized values)
long double 64 8 (doubleword-aligned) 2.22507385850720138e-308 to 1.79769313486231571e
+308 (normalized values)
wchar_t 16 2 (halfword-aligned) 0 to 65,535 by default.
32 4 (word-aligned) 0 to 4,294,967,295 when compiled with --wchar32.
All pointers 32 4 (word-aligned) Not applicable.
bool (C++ only) 8 1 (byte-aligned) false or true
_Bool (C only) 8 1 (byte-aligned) false or true
*****************************************************************************/
//#define VC_VERSION /* defined for windows, if undefined, unix or linux */
#ifndef VC_VERSION
typedef signed char INT8;
typedef unsigned char UINT8;
typedef signed short INT16;
typedef unsigned short UINT16;
typedef signed long INT32;
typedef unsigned long UINT32;
typedef long long INT64;
typedef unsigned long long UINT64;
#if (!defined PHY_PC_SIM)||(!defined PHY_PC_UNILOG)
typedef unsigned char BOOL;
#else
#define BOOL UINT8
#endif
typedef char CHAR;
#else
typedef signed char INT8;
typedef unsigned char UINT8;
typedef signed short INT16;
typedef unsigned short UINT16;
typedef signed long INT32;
typedef unsigned long UINT32;
typedef __int64 INT64;
typedef unsigned __int64 UINT64;
typedef unsigned char BOOL;
typedef char CHAR;
#endif //#ifndef VC_VERSION
typedef void ( *PhyCBFunc_T )(void* sigBody);
typedef struct
{
INT32 integer;
INT32 fwl;
} DCXODouble;
#ifndef FALSE
#define FALSE ((BOOL)0)
#endif
#ifndef TRUE
#define TRUE ((BOOL)1)
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef PNULL
#define PNULL ((void*) NULL)
#endif
#ifndef PPNULL
#define PPNULL ((void*)((void*) NULL))
#endif
#endif //#ifndef _COMMON_TYPEDEF_H

View File

@@ -0,0 +1,182 @@
/******************************************************************************
* @file mpu_armv7.h
* @brief CMSIS MPU API for ARMv7 MPU
* @version V5.0.2
* @date 09. June 2017
******************************************************************************/
/*
* Copyright (c) 2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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 ARM_MPU_ARMV7_H
#define ARM_MPU_ARMV7_H
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U)
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U)
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U)
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U)
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U)
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U)
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU)
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU)
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU)
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU)
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU)
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU)
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U)
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U)
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U)
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U)
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U)
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U)
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U)
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U)
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U)
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U)
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU)
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU)
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU)
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU)
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU)
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU)
#define ARM_MPU_AP_NONE 0u
#define ARM_MPU_AP_PRIV 1u
#define ARM_MPU_AP_URO 2u
#define ARM_MPU_AP_FULL 3u
#define ARM_MPU_AP_PRO 5u
#define ARM_MPU_AP_RO 6u
/** MPU Region Base Address Register Value
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress) ((BaseAddress & MPU_RBAR_ADDR_Msk) | (Region & MPU_RBAR_REGION_Msk) | (1UL << MPU_RBAR_VALID_Pos))
/**
* MPU Region Attribut and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
((DisableExec << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
((AccessPermission << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
((TypeExtField << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
((IsShareable << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
((IsCacheable << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
((IsBufferable << MPU_RASR_B_Pos) & MPU_RASR_B_Msk) | \
((SubRegionDisable << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
((Size << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
((1UL << MPU_RASR_ENABLE_Pos) & MPU_RASR_ENABLE_Msk)
/**
* Struct for a single MPU Region
*/
typedef struct _ARM_MPU_Region_t {
uint32_t RBAR; //!< The region base address register value (RBAR)
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DSB();
__ISB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
//SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable()
{
__DSB();
__ISB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
MPU->RNR = rnr;
MPU->RASR = 0u;
}
/** Configure an MPU region.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
{
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
{
MPU->RNR = rnr;
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Memcopy with strictly ordered memory access, e.g. for register targets.
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0u; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
{
orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*sizeof(ARM_MPU_Region_t)/4u);
}
#endif

View File

@@ -0,0 +1,7 @@
#define SDK_MAJOR_VERSION "001" // For Major version
#define SDK_MINOR_VERSION "013" // For minor version
#define SDK_RA_VERSION "xxx" // For jenkins release use
#define SDK_PATCH_VERSION "p001.002" // For patch verion, modify when patch release
#define EVB_MAJOR_VERSION "1"
#define EVB_MINOR_VERSION "0"
#define EC_CHIP_VERSION "EcChipVerEc618CoreAp"

View File

@@ -0,0 +1,105 @@
/**************************************************************************//**
* @file system_ARMCM3.h
* @brief CMSIS Device System Header File for
* ARMCM3 Device Series
* @version V5.00
* @date 02. March 2016
******************************************************************************/
/*
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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 SYSTEM_CATERPILLER_H
#define SYSTEM_CATERPILLER_H
/*----------------------------------------------------------------------------*
* INCLUDES *
*----------------------------------------------------------------------------*/
#include "commontypedef.h"
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*
* MACROS *
*----------------------------------------------------------------------------*/
#define XTAL (204800000U) /* Oscillator frequency */
#define DEFAULT_SYSTEM_CLOCK (XTAL)
#define SYSTICK_CLOCK (3250000)
/*----------------------------------------------------------------------------*
* DATA TYPE DEFINITION *
*----------------------------------------------------------------------------*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/*----------------------------------------------------------------------------*
* GLOBAL FUNCTIONS DECLEARATION *
*----------------------------------------------------------------------------*/
/**
\brief Setup the microcontroller system.
Initialize the System and update the SystemCoreClock variable.
*/
void SystemInit (void);
/**
\brief Update SystemCoreClock variable.
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
*/
void SystemCoreClockUpdate (void);
/**
\brief Save and set IRQ mask.
Close irq and save current IRQ mask.
*/
static __FORCEINLINE uint32_t SaveAndSetIRQMask(void)
{
uint32_t mask = __get_PRIMASK();
__disable_irq();
return mask;
}
/**
\brief Restore IRQ mask.
Restore IRQ mask and enable irq.
*/
static __FORCEINLINE void RestoreIRQMask(uint32_t mask)
{
__DSB();
__ISB();
__set_PRIMASK(mask);
}
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_CATERPILLER_H */

View File

@@ -0,0 +1,7 @@
#define SDK_MAJOR_VERSION "001" // For Major version
#define SDK_MINOR_VERSION "027" // For minor version
#define SDK_RA_VERSION "xxx" // For jenkins release use
#define SDK_PATCH_VERSION "000" // For patch verion, modify when patch release
#define EVB_MAJOR_VERSION "1"
#define EVB_MINOR_VERSION "0"

View File

@@ -0,0 +1,268 @@
#ifndef MEM_MAP_H
#define MEM_MAP_H
/*
AP flash layout, toatl 4MB
flash raw address: 0x00000000---0x00400000
flash xip address(from ap view): 0x00800000---0x00c00000
0x00000000 |---------------------------------|
| header1 8KB |
0x00002000 |---------------------------------|
| header2 8KB |
0x00004000 |---------------------------------|
| bl part1 32KB |
0x0000c000 |---------------------------------|
| bl part2 96KB |------OTA write
0x00024000 |---------------------------------|
| app img 2.5MB |------OTA write
0x002a4000 |---------------------------------|
| resv1 384KB |
0x00304000 |---------------------------------|
| fota 512KB |-----OTA download write
0x00384000 |---------------------------------|
| lfs 288KB |-----FS write
0x003cc000 |---------------------------------|
| softsim 64KB |-----SOFTSIM write
0x003dc000 |---------------------------------|
| rel_ap(factory) 16KB |-----factory write
0x003e0000 |---------------------------------|
| rel_ap 16KB |-----factory write
0x003e4000 |---------------------------------|
| hib backup 96KB |-----hib write
0x003fc000 |---------------------------------|
| plat config 16KB |-----similar as FS
0x00400000 |---------------------------------|
CP flash layout, toatl 1MB
flash raw address: 0x00000000---0x00100000
flash xip address(from cp view): 0x00800000---0x00900000
flash xip address(from ap view): 0x08800000---0x08900000
0x00000000 |---------------------------------|
| cp img 512KB |
0x00064000 |---------------------------------|
| resv 308KB |
0x000cd000 |---------------------------------|
| IP2 4KB |
0x000ce000 |---------------------------------|
| rel_cp(default) 100KB |
0x000e7000 |---------------------------------|
| rel_ap 100KB |
0x00100000 |---------------------------------|
*/
/* -------------------------------flash address define-------------------------*/
#define AP_VIEW_CPFLASH_XIP_ADDR (0x08800000)
#define AP_FLASH_XIP_ADDR (0x00800000)
//bl addr and size
#define BOOTLOADER_FLASH_LOAD_ADDR (0x00804000)
#ifdef __USER_CODE__
#define BOOTLOADER_FLASH_LOAD_SIZE (0x1e000)//120kB
#else
#define BOOTLOADER_FLASH_LOAD_SIZE (0x20000)//128kB
#endif
//ap image addr and size
#define AP_FLASH_LOAD_ADDR (0x00824000)
#ifdef __USER_CODE__
#define AP_FLASH_LOAD_SIZE (0x2E0000)//2.5MB + 384KB
#else
#define AP_FLASH_LOAD_SIZE (0x280000)//2.5MB
#endif
/*0x002a4000 -----0x00304000 RESERVRD 384KB*/
//fota addr and size
#define FLASH_FOTA_REGION_START (0x304000)
#define FLASH_FOTA_REGION_LEN (0x80000)//512KB
#define FLASH_FOTA_REGION_END (0x384000)
#ifdef __USER_CODE__
//fs addr and size
#define FLASH_FS_REGION_START (0x384000)
#define FLASH_FS_REGION_END (0x3cc000)
#define FLASH_FS_REGION_SIZE (FLASH_FS_REGION_END-FLASH_FS_REGION_START) // 352KB
#define FLASH_FDB_REGION_START (0x3cc000) //FDB 64KB
#define FLASH_FDB_REGION_END (0x3dc000)
//softsim addr and size
#define SOFTSIM_FLASH_PHYSICAL_BASEADDR (0xfcc000)
#define SOFTSIM_FLASH_MAX_SIZE (0x00000)//0KB
#else
#define FLASH_FS_REGION_START (0x384000)
#define FLASH_FS_REGION_END (0x3cc000)
#define FLASH_FS_REGION_SIZE (FLASH_FS_REGION_END-FLASH_FS_REGION_START) // 288KB
//softsim addr and size
#define SOFTSIM_FLASH_PHYSICAL_BASEADDR (0x3cc000)
#define SOFTSIM_FLASH_MAX_SIZE (0x10000)//64KB
#endif
//ap reliable addr and size
#define NVRAM_FACTORY_PHYSICAL_BASE (0x3dc000)
#define NVRAM_FACTORY_PHYSICAL_SIZE (0x4000)//16KB
#define NVRAM_PHYSICAL_BASE (0x3e0000)
#define NVRAM_PHYSICAL_SIZE (0x4000)//16KB
//hib bakcup addr and size
#define FLASH_MEM_BACKUP_ADDR (AP_FLASH_XIP_ADDR+0x3e4000)
#define FLASH_MEM_BACKUP_NONXIP_ADDR (FLASH_MEM_BACKUP_ADDR-AP_FLASH_XIP_ADDR)
#define FLASH_MEM_BLOCK_SIZE (0x6000)
#define FLASH_MEM_BLOCK_CNT (0x4)
#define FLASH_MEM_BACKUP_SIZE (0x18000)//96KB
//plat config addr and size
#define FLASH_MEM_PLAT_INFO_ADDR (AP_FLASH_XIP_ADDR+0x3fc000)
#define FLASH_MEM_PLAT_INFO_SIZE (0x1000)//4KB
#define FLASH_MEM_PLAT_INFO_NONXIP_ADDR (FLASH_MEM_PLAT_INFO_ADDR - AP_FLASH_XIP_ADDR)
#define FLASH_MEM_RESET_INFO_ADDR (AP_FLASH_XIP_ADDR+0x3fd000)
#define FLASH_MEM_RESET_INFO_SIZE (0x1000)//4KB
#define FLASH_MEM_RESET_INFO_NONXIP_ADDR (FLASH_MEM_RESET_INFO_ADDR - AP_FLASH_XIP_ADDR)
#define CP_FLASH_XIP_ADDR (0x00800000)
//cp img
#define CP_FLASH_LOAD_ADDR (0x00800000)
#define CP_FLASH_LOAD_SIZE (0x80000)//512KB
//for ramdump
#define CP_FLASH_RESV_ADDR (0x00880000)
//#define CP_FLASH_RESV_PHYSICAL_ADDR (0x80000)
#define CP_FLASH_RESV_SIZE (0x4d000)//308KB
//#define CP_FLASH_RESV_NUM_SECTOR (77)
#define FLASH_EXCEP_DUMP_ADDR (0x80000)
#define FLASH_EXCEP_DUMP_SECTOR_NUM (77)
#define CP_FLASH_IP2_ADDR (0x008cd000)
#define CP_FLASH_IP2_SIZE (0x1000)//4KB
//cp reliable addr and size, cp nvm write by ap
#define CP_NVRAM_FACTORY_PHYSICAL_BASE (0xce000)
#define CP_NVRAM_FACTORY_PHYSICAL_SIZE (0x19000)//100KB
#define CP_NVRAM_PHYSICAL_BASE (0xe7000)
#define CP_NVRAM_PHYSICAL_SIZE (0x19000)//100KB
//add for img merge tool,should fix as AP_xx/CP_xx/BL_xx, tool will extract img type from it
#define AP_IMG_MERGE_ADDR (0x00024000)
#define CP_IMG_MERGE_ADDR (0x00000000)
#define BL_IMG_MERGE_ADDR (0x00004000)
#define BLS_SEC_HAED_ADDR (0x0)
#define BLS_FLASH_LOAD_SIZE (0x2000)
#define SYS_SEC_HAED_ADDR (0x2000)
#define SYS_FLASH_LOAD_SIZE (0x2000)
/* -----------ram address define, TODO: need modify according to ram lauout-------------*/
//csmb start
#define CSMB_START_ADDR (0x0)
#define CSMB_END_ADDR (0x10000)
#define CSMB_PHY_AONMEM_ADDR (0xf000)
//csmb end
//msmb start
/*
0x00400000 |---------------------------------|
| LOAD_AP_FIRAM_MSMB |
|---------------------------------|
| LOAD_APOS |
|---------------------------------|
| LOAD_DRAM_BSP |
|---------------------------------|
| UNLOAD_SLPMEM |
|---------------------------------|
| LOAD_DRAM_SHARED |
0x00500000 |---------------------------------| <---MSMB_APMEM_END_ADDR
| LOAD_CP_FIRAM_MSMB |
|---------------------------------|
| LOAD_CPOS_IRAM |
|---------------------------------|
| UNLOAD_SLPMEM |
|---------------------------------|
| LOAD_CPDRAM_SHARED |
|---------------------------------|
| LOAD_CPDRAM_BSP |
0x0053D000 |---------------------------------| <---CP_AONMEMBACKUP_START_ADDR
| UNLOAD_CPAON |
0x0053E000 |---------------------------------| <---XP_SHAREINFO_BASE_ADDR
| LOAD_XP_SHAREDINFO |
0x0053F000 |---------------------------------| <---IPC_SHAREDMEM_START_ADDR
| LOAD_XP_IPCMEM |
0x00540000 | | <---MSMB_END_ADDR
*/
#define MSMB_START_ADDR (0x00400000)
#define MSMB_END_ADDR (0x00540000)
#define MSMB_APMEM_END_ADDR (0x00500000)
#define MSMB_CPMEM_START_ADDR (0x00500000)
#define MSMB_CPDATA_START_ADDR (0x0052C000)
#define CP_AONMEMBACKUP_START_ADDR (0x0053D000)
#define XP_SHAREINFO_BASE_ADDR (0x0053E000)
#define XP_DBGRESERVED_BASE_ADDR (0x0053EF00)
#define IPC_SHAREDMEM_START_ADDR (0x0053F000)
//msmb end
//asmb start
/*
0x00000000 |---------------------------------|
| bootcode |
0x00001000 |---------------------------------|
| LOAD_AP_PIRAM_ASMB |
|---------------------------------|
| LOAD_AP_FIRAM_ASMB |
0x0000C000 |---------------------------------|
| LOAD_RRCMEM |
0x0000D000 |---------------------------------|
| LOAD_FLASHMEM |
0x00010000 |---------------------------------|
*/
#define ASMB_START_ADDR (0x00000000)
#define ASMB_END_ADDR (0x00010000)
#define ASMB_IRAM_START_ADDR (0x00001000)
#define ASMB_RRCMEM_START_ADDR (0x0000C000)
#define ASMB_FLASHMEM_START_ADDR (0x0000D000)
//asmb end
#ifdef LOW_SPEED_SERVICE_ONLY
#define min_heap_size_threshold 0x19000
#define up_buf_start 0x4c3500
#else
#define min_heap_size_threshold 0x20000
#define up_buf_start 0x499000
#endif
// TODO: need re-design excption dump
#endif

View File

@@ -0,0 +1,36 @@
#ifndef BSP_CODECDRV_H
#define BSP_CODECDRV_H
#include "i2s.h"
typedef enum
{
ES8388, ///< Codec ES8388
NAU88C22, ///< Codec NAU88C22
ES7148, ///< Codec ES7148
ES7149, ///< Codec ES7149
ES8311, ///< Codec ES8311
}codecType_e;
typedef struct
{
uint8_t regAddr; ///< Register addr
uint16_t regVal; ///< Register value
}i2sI2cCfg_t;
/**
\brief Write value to codec via I2C.
\param[in] codecType The codec type you use.
\param[in] regAddr I2C register addr.
\param[in] regVal I2C register value that need to write.
\return
*/
void codecWriteVal(codecType_e codecType, uint8_t regAddr, uint16_t regVal);
uint8_t codecReadVal(codecType_e codecType, uint8_t regAddr);
//void codecCtrlVolume(codecType_e codecType, bool raise, uint8_t step);
#endif

View File

@@ -0,0 +1,77 @@
#ifndef BSP_H
#define BSP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "version.h"
#include "Driver_Common.h"
#include "Driver_I2C.h"
#include "Driver_SPI.h"
#include "Driver_USART.h"
#include "RTE_Device.h"
#include "pad.h"
#include "gpio.h"
#include "ic.h"
#include "dma.h"
#include "clock.h"
#define STRING_EOL "\r\n"
#define BOARD_NAME "EC618_EVK"
#define SDK_VERSION "EC618_SW_V"SDK_MAJOR_VERSION"."SDK_MINOR_VERSION"."SDK_PATCH_VERSION
#define EVB_VERSION "EC618_HW_V"EVB_MAJOR_VERSION"."EVB_MINOR_VERSION
#define VERSION_INFO "-- SDK Version: "SDK_VERSION" -- "STRING_EOL"-- EVB Version: "EVB_VERSION" -- "STRING_EOL
#define BSP_HEADER STRING_EOL"-- Board: "BOARD_NAME " -- "STRING_EOL \
VERSION_INFO \
"-- Compiled: "__DATE__" "__TIME__" -- "STRING_EOL
#define ATI_VERSION_INFO STRING_EOL"-- Board: "BOARD_NAME " -- "STRING_EOL \
"-- SDK Version: "SDK_VERSION" -- "STRING_EOL
#define SOFTVERSION "V"SDK_MAJOR_VERSION"."SDK_MINOR_VERSION"."SDK_PATCH_VERSION
#define CREATE_SYMBOL(name, port) name##port
/** @brief UART port index
* | UART port | Hardware Flow Control |
* |-----------|-----------------------|
* | UART0 | Y |
* | UART1 | Y |
* | UART2 | N |
*/
typedef enum usart_port
{
PORT_USART_0, /**< USART port 0. */
PORT_USART_1, /**< USART port 1. */
PORT_USART_2, /**< USART port 2. */
PORT_USART_MAX, /**< The total number of USART ports (invalid UART port number). */
PORT_USART_INVALID /**< USART invalid. */
} usart_port_t;
extern ARM_DRIVER_USART *UsartPrintHandle;
extern ARM_DRIVER_USART *UsartUnilogHandle;
extern ARM_DRIVER_USART *UsartAtCmdHandle;
/** @brief IRQ Callback functions
*/
typedef void (*IRQ_Callback_t)();
uint8_t* getBuildInfo(void);
uint8_t* getATIVersionInfo(void);
uint8_t* getVersionInfo(void);
void FlushUnilogOutput(void);
void SetUnilogUart(usart_port_t port, uint32_t baudrate, bool startRecv);
void BSP_CommonInit(void);
void setOSState(uint8_t state);
uint8_t * getDebugDVersion(void);
void delay_us(uint32_t us);
#ifdef __cplusplus
}
#endif
#endif /* BSP_H */

View File

@@ -0,0 +1,9 @@
#ifndef BF30A2_H
#define BF30A2_H
#define BF30A2_I2C_ADDR 0x6e
uint16_t bf30a2GetRegCnt(char* regName);
#endif

View File

@@ -0,0 +1,170 @@
#ifndef __CAMERA_DRV_H__
#define __CAMERA_DRV_H__
#include "cspi.h"
#include "sp0A39.h"
#include "sp0821.h"
#include "gc6123.h"
#include "gc032A.h"
#include "bf30a2.h"
#include "gc6153.h"
#ifdef __USER_CODE__
#ifndef CAM_CHAIN_COUNT
#define CAMERA_ENABLE_BF30A2 1
#define BF30A2_1SDR 1
#define CAM_CHAIN_COUNT CAM_8W
#endif
#endif
/**
\addtogroup cam_interface_gr
\{
*/
typedef struct
{
uint8_t regAddr; ///< Sensor I2C register address
uint8_t regVal; ///< Sensor I2C register value
}camI2cCfg_t;
typedef enum
{
LSB_MODE = 0, ///< Little endian
MSB_MODE = 1, ///< Big endian
}endianMode_e;
typedef enum
{
WIRE_1 = 0, ///< 1 wire
WIRE_2 = 1, ///< 2 wire
}wireNum_e;
typedef enum
{
SEQ_0 = 0, ///< rxd[0] 6 4 2 0
///< rxd[1] 7 5 3 1
SEQ_1 = 1, ///< rxd[1] 6 4 2 0
///< rxd[0] 7 5 3 1
}rxSeq_e;
typedef enum
{
CSPI_0 = 0,
CSPI_1 = 1,
}cspiInstance_e;
typedef enum
{
CSPI_START = 1, ///< cspi enable
CSPI_STOP = 0, ///< Cspi disable
}cspiStartStop_e;
typedef enum
{
CSPI_INT_ENABLE = 1, ///< cspi interrupt enable
CSPI_INT_DISABLE = 0, ///< Cspi interrupt disable
}cspiIntEnable_e;
typedef struct
{
endianMode_e endianMode; ///< Endian mode
wireNum_e wireNum; ///< Wire numbers
rxSeq_e rxSeq; ///< Bit sequence in 2 wire mode
uint8_t cpol;
uint8_t cpha;
uint8_t yOnly;
uint8_t rowScaleRatio;
uint8_t colScaleRatio;
uint8_t scaleBytes;
}camParamCfg_t;
typedef void (*camCbEvent_fn) (uint32_t event); ///< Camera callback event.
typedef void (*camIrq_fn)(void); ///< Camera irq
/**
\brief Init camera, include pinMux, and enable clock.
\param[in] dataAddr Mem addr to store picture.
\param[in] cb Indicate that a picture has been taken.
\return
*/
void camInit(void* dataAddr, camCbEvent_fn cb);
/**
\brief Receive the picture has been taken.
\param[out] dataIn The buffer which is used to store the picture.
\return
*/
void camRecv(uint8_t * dataIn);
/**
\brief Init sensor's registers.
\return
*/
void camRegCfg(void);
/**
\brief Write some parameters into the sensor.
\param[in] regInfo Sensor I2C addr and value.
\return
*/
void camWriteReg(camI2cCfg_t* regInfo);
/**
\brief Read from the sensor's I2C address.
\param[in] regAddr Sensor's I2C register address.
\return
*/
uint8_t camReadReg(uint8_t regAddr);
/**
\brief Start or stop Camera controller.
\param[in] startStop If true, start camera controller. If false, stop camera controller.
\return
*/
void camStartStop(cspiStartStop_e startStop);
/**
\brief Register irq for cspi.
\param[in] instance cspi0 or cspi1.
\param[in] irqCb irq cb.
\return
*/
void camRegisterIRQ(cspiInstance_e instance, camIrq_fn irqCb);
/**
\brief Get cspi status.
\param[in] instance cspi0 or cspi1.
\return
*/
uint32_t camGetCspiStats(cspiInstance_e instance);
/**
\brief Clear cspi interrupt status.
\param[in] instance cspi0 or cspi1.
\param[in] mask which bit needs to clear.
\return
*/
void camClearIntStats(cspiInstance_e instance, uint32_t mask);
/**
\brief Set memory addr which is used to store picture of camera.
\param[in] dataAddr data addr.
\return
*/
void camSetMemAddr(uint32_t dataAddr);
/**
\brief Enable or disable interrupt of cspi.
\param[in] intEnable interrupt enable or not.
\return
*/
void cspiIntEnable(cspiIntEnable_e intEnable);
/** \} */
#endif

View File

@@ -0,0 +1,9 @@
#ifndef GC032A_H
#define GC032A_H
#define GC032A_I2C_ADDR 0x21
uint16_t gc032aGetRegCnt(char* regName);
#endif

View File

@@ -0,0 +1,9 @@
#ifndef GC6123_H
#define GC6123_H
#define GC6123_I2C_ADDR 0x40
uint16_t gc6123GetRegCnt(char* regName);
#endif

View File

@@ -0,0 +1,9 @@
#ifndef GC6153_H
#define GC6153_H
#define GC6153_I2C_ADDR 0x40
uint16_t gc6153GetRegCnt(char* regName);
#endif

View File

@@ -0,0 +1,36 @@
#ifndef __I2C_GPIO_H__
#define __I2C_GPIO_H__
#include "stdio.h"
#include "string.h"
#include "ec618.h"
#include "bsp.h"
// sda pin definition. gpio16
#define SDA_GPIO_INSTANCE (1)
#define SDA_GPIO_PIN (0)
#define SDA_GPIO_ADDR (31)
#define SDA_PAD_ALT_FUNC (PAD_MUX_ALT0)
// scl pin definition. gpio17
#define SCL_GPIO_INSTANCE (1)
#define SCL_GPIO_PIN (1)
#define SCL_GPIO_ADDR (32)
#define SCL_PAD_ALT_FUNC (PAD_MUX_ALT0)
#define I2C_SDA_0 do {GPIO_pinWrite(SDA_GPIO_INSTANCE, 1 << SDA_GPIO_PIN, 0);}while(0)
#define I2C_SDA_1 do {GPIO_pinWrite(SDA_GPIO_INSTANCE, 1 << SDA_GPIO_PIN, 1 << SDA_GPIO_PIN);}while(0)
#define I2C_SCL_0 do {GPIO_pinWrite(SCL_GPIO_INSTANCE, 1 << SCL_GPIO_PIN, 0);}while(0)
#define I2C_SCL_1 do {GPIO_pinWrite(SCL_GPIO_INSTANCE, 1 << SCL_GPIO_PIN, 1 << SCL_GPIO_PIN);}while(0)
void i2cGpioInit();
uint8_t i2cReadByte();
void i2cWritebyte(uint8_t byte);
void i2cStop();
void i2cStart();
void i2cAck();
#endif

View File

@@ -0,0 +1,9 @@
#ifndef SP0821_H
#define SP0821_H
#define SP0821_I2C_ADDR 0x43
uint16_t sp0821GetRegCnt(char* regName);
#endif

View File

@@ -0,0 +1,9 @@
#ifndef SP0A39_H
#define SP0A39_H
#define SP0A39_I2C_ADDR 0x21
uint16_t sp0a39GetRegCnt(char* regName);
#endif

View File

@@ -0,0 +1,96 @@
/****************************************************************************
*
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
* File name: eepRom.h
* Description: EC618 eepRom driver file
* History: Rev1.0 2020-12-17
*
****************************************************************************/
#ifndef _EEPROM_EC618_H
#define _EEPROM_EC618_H
#include "ec618.h"
#include "Driver_Common.h"
#include "oneWire.h"
/**
\addtogroup eepRom_interface_gr
\{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/** \brief ROM Operation Command */
#define ROM_READ_CMD 0x33
#define ROM_MATCH_CMD 0x55
#define ROM_SKIP_CMD 0xCC
#define ROM_SEARCH_CMD 0xF0
/** \brief Memory Operation Command */
#define MEM_READ_CMD 0xF0
#define SCRATCHPAD_READ_CMD 0xAA
#define SCRATCHPAD_WRITE_CMD 0x0F
#define SCRATCHPAD_COPY_CMD 0x55
/** \brief EEPROM Status */
#define EEPROMDRV_OK (0)
#define EEPROMDRV_RESET_ERR (-1)
#define EEPROMDRV_RESETPD_ERR (-2)
#define EEPROMDRV_ROMREAD_ERR (-3)
#define EEPROMDRV_ROMMATCH_ERR (-4)
#define EEPROMDRV_ROMSKIP_ERR (-5)
#define EEPROMDRV_ROMSEARCH_ERR (-6)
#define EEPROMDRV_MEMREAD_ERR (-7)
#define EEPROMDRV_SCRATCHPADREAD_ERR (-8)
#define EEPROMDRV_SCRATCHPADWRITE_ERR (-9)
#define EEPROMDRV_SCRATCHPADCOPY_ERR (-10)
/**
\fn int32_t eePromReadRom(uint8_t* romCode)
\brief EEPROM read ROM code
\param[out] romCode ROM infomation read back.
\return read ROM status
*/
int32_t eePromReadRom(uint8_t* romCode);
/**
\fn eePromReadMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
\brief EEPROM read memory.
\param[in] targetAddr The target address of EEPROM.
\param[in] len Length of this read.
\param[out] buffer Data read back.
\return read memory status
*/
int32_t eePromReadMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer);
/**
\fn int32_t eePromWriteMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
\brief EEPROM write memory
\param[in] targetAddr The target address of EEPROM.
\param[in] len Length of this write.
\param[in] buffer Data needs to write into memory.
\return Write memory status
*/
int32_t eePromWriteMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer);
void eepRomInit(OwModeSel_e mode);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,70 @@
#include "stdint.h"
#include "bsp.h"
#define SPI_INSTANCE SPI0
#define SPI_APB_CLOCK PCLK_SPI0
#define SPI_FUNC_CLOCK FCLK_SPI0
#define SPI_DMA_TX_REQID DMA_REQUEST_SPI0_TX // DMA SPI Request ID
#define LCD_DMA_DESCRIPTOR_CHAIN_NUM 20 // 30w pixel
#define LCD_TRANSFER_SIZE_ONCE 480//7680 // less than 8k
#define HEIGHT (129)
#define WIDTH (128)
#define SPI_BUS_SPEED (1000000) // 13M
#define SPI_FLAG_TIMEOUT (0x1000)
// SPI cs pin definition
#define CS_GPIO_INSTANCE (0)
#define CS_GPIO_PIN (8)
#define CS_GPIO_ADDR (23)
#define CS_PAD_ALT_FUNC (PAD_MUX_ALT0)
// SPI clk pin definition
#define CLK_GPIO_INSTANCE (0)
#define CLK_GPIO_PIN (11)
#define CLK_GPIO_ADDR (26)
#define CLK_PAD_ALT_FUNC (PAD_MUX_ALT1)
// SPI mosi pin definition
#define MOSI_GPIO_INSTANCE (0)
#define MOSI_GPIO_PIN (9)
#define MOSI_GPIO_ADDR (24)
#define MOSI_PAD_ALT_FUNC (PAD_MUX_ALT1)
// SPI miso pin definition
#define MISO_GPIO_INSTANCE (0)
#define MISO_GPIO_PIN (10)
#define MISO_GPIO_ADDR (25)
#define MISO_PAD_ALT_FUNC (PAD_MUX_ALT1)
// LCD rst pin definition
#define RST_GPIO_INSTANCE (1)
#define RST_GPIO_PIN (4)
#define RST_GPIO_ADDR (40)
#define RST_PAD_ALT_FUNC (PAD_MUX_ALT0)
// LCD ds pin definition
#define DS_GPIO_INSTANCE (1)
#define DS_GPIO_PIN (12)
#define DS_GPIO_ADDR (48)
#define DS_PAD_ALT_FUNC (PAD_MUX_ALT0)
// LCD en pin definition
#define EN_GPIO_INSTANCE (1)
#define EN_GPIO_PIN (5)
#define EN_GPIO_ADDR (41)
#define EN_PAD_ALT_FUNC (PAD_MUX_ALT0)
void st7571_init(void);
void displayPic_60x80(uint8_t *p);
void st7571CleanScreen(void);

View File

@@ -0,0 +1,68 @@
#include "stdint.h"
#include "bsp.h"
#define SPI_INSTANCE SPI0
#define SPI_APB_CLOCK PCLK_SPI0
#define SPI_FUNC_CLOCK FCLK_SPI0
#define SPI_DMA_TX_REQID DMA_REQUEST_SPI0_TX // DMA SPI Request ID
#define LCD_DMA_DESCRIPTOR_CHAIN_NUM 20 // 30w pixel
#define LCD_TRANSFER_SIZE_ONCE 480//7680 // less than 8k
#define SPI_BUS_SPEED (1000000) // 13M
#define SPI_FLAG_TIMEOUT (0x1000)
#define HEIGHT (320)
#define WIDTH (240)
#define RED (0xf800)
#define GREEN (0x07e0)
#define BLUE (0x001f)
#define YELLOW (0xffe0)
#define WHITE (0xffff)
#define BLACK (0x0000)
#define PURPLE (0xf81f)
// SPI cs pin definition
#define CS_GPIO_INSTANCE (0)
#define CS_GPIO_PIN (8)
#define CS_GPIO_ADDR (23)
#define CS_PAD_ALT_FUNC (PAD_MUX_ALT0)
// SPI clk pin definition
#define CLK_GPIO_INSTANCE (0)
#define CLK_GPIO_PIN (11)
#define CLK_GPIO_ADDR (26)
#define CLK_PAD_ALT_FUNC (PAD_MUX_ALT1)
// SPI mosi pin definition
#define MOSI_GPIO_INSTANCE (0)
#define MOSI_GPIO_PIN (9)
#define MOSI_GPIO_ADDR (24)
#define MOSI_PAD_ALT_FUNC (PAD_MUX_ALT1)
// SPI miso pin definition
#define MISO_GPIO_INSTANCE (0)
#define MISO_GPIO_PIN (10)
#define MISO_GPIO_ADDR (25)
#define MISO_PAD_ALT_FUNC (PAD_MUX_ALT1)
// LCD rst pin definition
#define RST_GPIO_INSTANCE (1)
#define RST_GPIO_PIN (1)
#define RST_GPIO_ADDR (32)
#define RST_PAD_ALT_FUNC (PAD_MUX_ALT0)
// LCD ds pin definition
#define DS_GPIO_INSTANCE (1)
#define DS_GPIO_PIN (0)
#define DS_GPIO_ADDR (31)
#define DS_PAD_ALT_FUNC (PAD_MUX_ALT0)
void st7789v2_init(void);

View File

@@ -0,0 +1,85 @@
#ifndef IMAGE_PROCESS_H
#define IMAGE_PROCESS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
#include "string.h"
#include "ec618.h"
#include "bsp.h"
#include <stdlib.h>
/**
\brief Convert yuv422 to rgb565, used in color screen.
\param[in] inbuf source memory.
\param[out] outbuf output memory.
\param[in] width source picture width.
\param[in] height source picture height.
\return
*/
void yuv422ToRgb565(const void* inbuf, void* outbuf, int width, int height);
/**
\brief Scale the picture. Now this api can only zoom out the picture.
\param[in] ratio Zoom out ratio.
\param[in] inPtr Data source.
\param[in] width Source data width.
\param[in] height Source data height.
\param[out] outPtr Output data address.
\return
*/
void scalePic(uint8_t ratio, uint8_t* inPtr, uint16_t width, uint16_t height, uint8_t *outPtr);
/**
\brief Clockwise rotate 90 degree.
\param[in,out] mem Data source.
\param[in] width Source picture width.
\param[in] height Source picture height.
\return
*/
void imageRotate(uint8_t* mem, uint32_t width, uint32_t height);
/**
\brief Organize the bytes as horizontal or vertical.
\param[in] inPut Src data.
\param[in] pageLen The pageNum you want for these data, this param is set by you.
\param[in] width The width you want for these data, this param is set by you.
\param[out] outPut Output buffer.
\param[in] horizotal These data you want to array them as horizontal or vertical.
\return
*/
void storeByteIntoArray(uint8_t *inPut, uint8_t pageLen, uint16_t width, uint8_t *outPut, bool horizotal);
/**
\brief Merge 8bytes into one byte, used in 1-bit LCD.
\param[in] p Src data.
\param[out] outPut Output buffer.
\param[in] width Source data width.
\param[out] height Source data height.
\param[in] horizotal Fetch the data by row or by column.
\param[in] inByteRevert Within the byte, positive or reverse the bit sequence.
\return index How many bytes has been returned, for debug use
*/
uint16_t merge8Bytes2OneByte(uint8_t* p, uint8_t *outPut, uint16_t width, uint16_t height, bool horizotal, bool inByteRevert);
/**
\brief Binary the source picture.
\param[in] inPut Src data.
\param[in] width Source picture width.
\param[in] height Source picture height.
\param[out] outPut Output buffer.
\return
*/
void calBinary(uint8_t* inPut, uint16_t width, uint16_t height, uint8_t* outPut);
#ifdef __cplusplus
}
#endif
#endif /* IMAGE_PROCESS_H */

View File

@@ -0,0 +1,114 @@
#ifndef BSP_LCD_H
#define BSP_LCD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stdio.h"
#include "string.h"
#include "ec618.h"
#include "bsp.h"
// Only need to choose which LCD you use
#define ST7789V2_ENABLE 0
#define ST7571_ENABLE 1
#if (ST7789V2_ENABLE)
#include "st7789v2.h"
#endif
#if (ST7571_ENABLE)
#include "st7571.h"
#endif
#define SPI SPI_INSTANCE
#define SPI_CS_LOW do {GPIO_pinWrite(SPI_CS_GPIO_INSTANCE, 1 << SPI_CS_GPIO_PIN, 0);}while(0)
#define SPI_CS_HIGH do {GPIO_pinWrite(SPI_CS_GPIO_INSTANCE, 1 << SPI_CS_GPIO_PIN, 1 << SPI_CS_GPIO_PIN);}while(0)
#define LCD_DS_LOW do {GPIO_pinWrite(LCD_DS_GPIO_INSTANCE, 1 << LCD_DS_GPIO_PIN, 0);}while(0)
#define LCD_DS_HIGH do {GPIO_pinWrite(LCD_DS_GPIO_INSTANCE, 1 << LCD_DS_GPIO_PIN, 1 << LCD_DS_GPIO_PIN);}while(0)
#define LCD_RST_LOW do {GPIO_pinWrite(LCD_RST_GPIO_INSTANCE, 1 << LCD_RST_GPIO_PIN, 0);}while(0)
#define LCD_RST_HIGH do {GPIO_pinWrite(LCD_RST_GPIO_INSTANCE, 1 << LCD_RST_GPIO_PIN, 1 << LCD_RST_GPIO_PIN);}while(0)
#define SPI_SEND_DATA(data) do {SPI->DR = data;}while(0)
#define SPI_READ_DATA (SPI->DR)
#define SPI_WAIT_TX_DONE do {}while(!((SPI->SR & (SPI_SR_BSY_Msk | SPI_SR_TFE_Msk)) == SPI_SR_TFE_Msk))
#define SPI_IS_BUSY do {}while((SPI->SR & SPI_SR_BSY_Msk) == SPI_SR_BSY_Msk)
#define SPI_START_DMA_CHANNEL(channel) do {*((uint32_t*)(0x4d1f0000 + (channel << 2))) |= 0x80000000;}while(0)
#define SPI_STOP_DMA_CHANNEL(channel) do {*((uint32_t*)(0x4d1f0000 + (channel << 2))) &= ~0x80000000;}while(0)
#define SPI_ENABLE_TX_DMA do {SPI->DMACR |= SPI_DMACR_TXDMAE_Msk;}while(0)
// Spi cs pin
#define SPI_CS_GPIO_INSTANCE (CS_GPIO_INSTANCE)
#define SPI_CS_GPIO_PIN (CS_GPIO_PIN)
#define SPI_CS_PAD_ADDR (CS_GPIO_ADDR)
#define SPI_CS_PAD_ALT_FUNC (CS_PAD_ALT_FUNC)
// Spi clk pin
#define SPI_CLK_GPIO_INSTANCE (CLK_GPIO_INSTANCE)
#define SPI_CLK_GPIO_PIN (CLK_GPIO_PIN)
#define SPI_CLK_PAD_ADDR (CLK_GPIO_ADDR)
#define SPI_CLK_PAD_ALT_FUNC (CLK_PAD_ALT_FUNC)
// Spi mosi pin
#define SPI_MOSI_GPIO_INSTANCE (MOSI_GPIO_INSTANCE)
#define SPI_MOSI_GPIO_PIN (MOSI_GPIO_PIN)
#define SPI_MOSI_PAD_ADDR (MOSI_GPIO_ADDR)
#define SPI_MOSI_PAD_ALT_FUNC (MOSI_PAD_ALT_FUNC)
// Spi miso pin
#define SPI_MISO_GPIO_INSTANCE (MISO_GPIO_INSTANCE)
#define SPI_MISO_GPIO_PIN (MISO_GPIO_PIN)
#define SPI_MISO_PAD_ADDR (MISO_GPIO_ADDR)
#define SPI_MISO_PAD_ALT_FUNC (MISO_PAD_ALT_FUNC)
// Lcd rst pin
#define LCD_RST_GPIO_INSTANCE (RST_GPIO_INSTANCE)
#define LCD_RST_GPIO_PIN (RST_GPIO_PIN)
#define LCD_RST_PAD_ADDR (RST_GPIO_ADDR)
#define LCD_RST_PAD_ALT_FUNC (RST_PAD_ALT_FUNC)
// Lcd ds pin
#define LCD_DS_GPIO_INSTANCE (DS_GPIO_INSTANCE)
#define LCD_DS_GPIO_PIN (DS_GPIO_PIN)
#define LCD_DS_PAD_ADDR (DS_GPIO_ADDR)
#define LCD_DS_PAD_ALT_FUNC (DS_PAD_ALT_FUNC)
#if (ST7571_ENABLE)
// Lcd en pin
#define LCD_EN_GPIO_INSTANCE (EN_GPIO_INSTANCE)
#define LCD_EN_GPIO_PIN (EN_GPIO_PIN)
#define LCD_EN_PAD_ADDR (EN_GPIO_ADDR)
#define LCD_EN_PAD_ALT_FUNC (EN_PAD_ALT_FUNC)
#endif
typedef void (*pTxCb)(uint32_t event);
uint8_t lcdReadData(void);
void lcdReadId(void);
void lcdWriteCmd(uint8_t cmd);
void lcdWriteData(uint8_t data);
void lcdInit(pTxCb txCb);
void mDelay(uint32_t mDelay);
//void lcdWriteData16(uint16_t data);
//void lcdDispColor(uint16_t color);
void lcdDispWindows(void);
//void lcdWriteDataDma(uint16_t color);
void lcdWriteSetup(uint8_t * dataBuf, uint16_t dataCnt);
void lcdWriteCtrl(bool startOrStop);
void lcdClearScreen();
void lcdDispPic(uint8_t * pic);
#ifdef __cplusplus
}
#endif
#endif /* BSP_LCD_H */

View File

@@ -0,0 +1,40 @@
#ifndef _NTC_H
#define _NTC_H
#ifdef __cplusplus
extern "C" {
#endif
/**
\brief Get NTC temperature
Vref(AIO1 output 1200000 uV)
v
|
|
+-+
| |
| | R = 10 Kohm
| |
+-+
|--------->(AIO2)
+-+
| |
| | Rntc
| |
+-+
|
-----
--- (GND)
-
\param[in] adcInputVoltage ADC input voltage in unit of uV
\return temperature in unit of mili degree centigrade
*/
int32_t ntcGetTemperature(int32_t adcInputVoltage);
#ifdef __cplusplus
}
#endif
#endif /* _NTC_H */

View File

@@ -0,0 +1,506 @@
/****************************************************************************
*
* Copy right: 2019-, Copyrigths of AirM2M Ltd.
* File name: plat_config.h
* Description: platform configuration header file
* History: Rev1.0 2019-01-18
* Rev1.1 2019-11-27 Reimplement file operations with OSA APIs(LFS wrapper), not directly using LFS APIs in case of file system replacement
* Rev1.2 2020-01-01 Separate plat config into two parts, FS and raw flash
*
****************************************************************************/
#ifndef _PLAT_CONFIG_H
#define _PLAT_CONFIG_H
#include "Driver_Common.h"
#include "cmsis_compiler.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define FS_PLAT_CONFIG_FILE_CURRENT_VERSION (0)
#define RAW_FLASH_PLAT_CONFIG_FILE_CURRENT_VERSION (1)
/** \brief config file header typedef */
__PACKED_STRUCT _config_file_header
{
uint16_t fileBodySize; /**< size of file body, in unit of byte */
uint8_t version; /**< file version, this field shall be updated when file structure is changed */
uint8_t checkSum; /**< check sum value of file body */
};
typedef struct _config_file_header config_file_header_t;
/** \brief typedef of platform configuration stored in fs */
typedef __PACKED_UNION _EPAT_atPortFrameFormat
{
uint32_t wholeValue;
__PACKED_STRUCT _config
{
uint32_t dataBits : 3;
uint32_t parity : 2;
uint32_t stopBits : 2;
uint32_t flowControl : 3;
} config;
} atPortFrameFormat_t;
// ulg port enum
typedef enum
{
PLAT_CFG_ULG_PORT_USB=0,
PLAT_CFG_ULG_PORT_UART,
PLAT_CFG_ULG_PORT_MIX,
PLAT_CFG_ULG_PORT_MAX
} PlatCfgUlgPort_e;
/** \brief typedef of platform configuration stored in fs */
typedef __PACKED_STRUCT _NVM_EPAT_plat_config
{
/** PM on/off flag
* valid value:
* 0x504D5544 -- PM is disabled, "PMUD"
* 0x504D5545 -- PM is enabled, "PMUE"
*/
uint32_t enablePM;
/** sleep mode
* valid value:
* 0 -- dummy
* 1 -- dummy
*/
uint8_t sleepMode;
/** wait n ms before sleep, when wakeup from pad
* valid value:
* 0 -- do not wait
* x -- wait x ms
*/
uint32_t slpWaitTime;
/** AT baudrate,for AP only
* should be equal to 'atPortBaudRate' in struct plat_config_raw_flash_t
*/
uint32_t atPortBaudRate;
/** AT port frame format*/
atPortFrameFormat_t atPortFrameFormat;
/** ECQSCLK config
* valid value:
* 0 -- ECQSCLK set to 0
* 1 -- ECQSCLK set to 1
*/
uint8_t ecSclkCfg;
} plat_config_fs_t;
/** \brief typedef of platform configuration stored in raw flash --old v0*/
__PACKED_STRUCT _plat_config_raw_flash_v0
{
/** action to perform when assert or hard fault occurs
* valid value:
* 0 -- dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
* 1 -- print necessary exception info then reset
* 2 -- dump full exception info to flash then reset
* 3 -- dump full exception info to flash and EPAT tool then reset
* 4 -- reset directly
* 10 -- enable uart help dump and dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
* 13 -- enable uart help dump and dump full exception info to flash and EPAT tool, and then reset
*/
uint8_t faultAction;
/** port select for dump info output when exception occurs
* valid value:
* 0,1,2,3,(4) -- specify which port
* 0xff -- disable this function
*/
uint8_t uartDumpPort;
/** WDT start/stop control
* valid value:
* 0 -- stop WDT
* 1 -- start WDT
*/
uint8_t startWDT;
/** unilog on/off flag
* valid value:
* 0 -- unilog is disabled
* 1 -- only sw log is enabled
* 2 -- All log is enabled
*/
uint8_t logControl;
/** uart baudrate for unilog output */
uint32_t uartBaudRate;
/** debug trace log level setting, refer to 'DebugTraceLevelType_e' */
uint32_t logLevel;
/** unilog output port select
* valid value:
* 0 -- USB
* 1 -- UART
* 2 -- MIX(for future use UART/USB dynamic select)
**/
PlatCfgUlgPort_e logPortSel;
/** RNDIS enum control
* valid value:
* 0 -- enable USB init and enum RNDIS
* 1 -- enable USB init but not enum RNDIS
* 2 -- disable USB init
*/
uint8_t usbCtrl;
/** usb software trace control
* valid value:
* 0 -- disable all usb software trace
* 1 -- enable all usb software trace
* others -- misc usb software trace
*/
uint8_t usbSwTrace;
/** USB sleep mask
* valid value:
* 0 -- usb should vote to enter sleep
* 1 -- do not consider usb vote before sleep
*/
uint8_t usbSlpMask;
/** USB sleep thd
* valid value:
* set the minimal time to sleep, when usbSlpMask=1
*/
uint16_t usbSlpThd;
/** pwrkey mode
* valid value:
* 1 power key mode
* 0 normal key mode
*/
uint8_t pwrKeyMode;
};
// fota urc port type
typedef enum
{
PLAT_CFG_FOTA_URC_PORT_USB=0,
PLAT_CFG_FOTA_URC_PORT_UART,
PLAT_CFG_FOTA_URC_PORT_MAXTYPE
} PlatCfgFotaUrcPortType_e;
#define PLAT_CFG_FOTA_URC_USB_PORT_IDX_MIN 0
#define PLAT_CFG_FOTA_URC_USB_PORT_IDX_MAX 2
#define PLAT_CFG_FOTA_URC_UART_PORT_IDX_MIN 0
#define PLAT_CFG_FOTA_URC_UART_PORT_IDX_MAX 1
#define PLAT_CFG_RAW_FLASH_RSVD_SIZE 21
/** \brief typedef of platform configuration stored in raw flash */
__PACKED_STRUCT _plat_config_raw_flash
{
/** action to perform when assert or hard fault occurs
* valid value:
* 0 -- dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
* 1 -- print necessary exception info then reset
* 2 -- dump full exception info to flash then reset
* 3 -- dump full exception info to flash and EPAT tool then reset
* 4 -- reset directly
* 10 -- enable uart help dump and dump full exception info to flash and EPAT tool then trapped in endless loop(while(1))
* 13 -- enable uart help dump and dump full exception info to flash and EPAT tool, and then reset
*/
uint8_t faultAction;
/** port select for dump info output when exception occurs
* valid value:
* 0,1,2,3,(4) -- specify which port
* 0xff -- disable this function
*/
uint8_t uartDumpPort;
/** WDT start/stop control
* valid value:
* 0 -- stop WDT
* 1 -- start WDT
*/
uint8_t startWDT;
/** unilog on/off flag
* valid value:
* 0 -- unilog is disabled
* 1 -- only sw log is enabled
* 2 -- All log is enabled
*/
uint8_t logControl;
/** uart baudrate for unilog output */
uint32_t uartBaudRate;
/** debug trace log level setting, refer to 'DebugTraceLevelType_e' */
uint32_t logLevel;
/** unilog output port select
* valid value:
* 0 -- USB
* 1 -- UART
* 2 -- MIX(for future use UART/USB dynamic select)
**/
PlatCfgUlgPort_e logPortSel;
/** RNDIS enum control
* valid value:
* 0 -- enable USB init and enum RNDIS
* 1 -- enable USB init but not enum RNDIS
* 2 -- disable USB init
*/
uint8_t usbCtrl;
/** usb software trace control
* valid value:
* 0 -- disable all usb software trace
* 1 -- enable all usb software trace
* others -- misc usb software trace
*/
uint8_t usbSwTrace;
/** USB sleep mask
* valid value:
* 0 -- usb should vote to enter sleep
* 1 -- do not consider usb vote before sleep
*/
uint8_t usbSlpMask;
/** USB sleep thd
* valid value:
* set the minimal time to sleep, when usbSlpMask=1
*/
uint16_t usbSlpThd;
/** pwrkey mode
* valid value:
* 1 power key mode
* 0 normal key mode
*/
uint8_t pwrKeyMode;
/** USB VBUS MODE Enable,Disable Flag
* valid value:
* 0 -- usb vbus mode disable
* 1 -- usb vbus mode enable
*/
uint8_t usbVBUSModeEn;
/** USB VBUS MODE Wakup Pad Index
* valid value:
* 0,1,2,3,4,5 PAD IDX FOR USB VBUS WKUP PAD
*/
uint8_t usbVBUSWkupPad;
/** USB NET IF SEL
* valid value:
* 0----RNDIS,default
* 1----ECM
*/
uint8_t usbNet;
/** USB VCOM EN bitmap
* valid value:
* bit0---vcom0
* bit1---vcom1
* ----
* ----
*/
uint8_t usbVcomEnBitMap;
/** AT/fotaURC baudrate, for AP & BL*/
uint32_t atPortBaudRate;
/** FOTA URC output port select
* valid value(Bit4-7):
* 0 -- USB
* 1 -- UART
**
* valid value(Bit0-3):
* 0-2 -- USB
* 0-1 -- UART
**/
uint8_t fotaUrcPortSel;
/** pmuInCdrx
* valid value:
* 0----
* 1----
*/
uint8_t pmuInCdrx;
/** slpLimitEn
* valid value:
* 0---- disable
* 1---- enable
*/
uint8_t slpLimitEn;
/** slpLimitTime
* valid value:
* 0---0xFFFFFFFF
*/
uint32_t slpLimitTime;
/* 'PLAT_CFG_RAW_FLASH_RSVD_SIZE' bytes rsvd for future */
uint8_t resv[PLAT_CFG_RAW_FLASH_RSVD_SIZE];
};
typedef struct _plat_config_raw_flash plat_config_raw_flash_t;//current
typedef struct _plat_config_raw_flash_v0 plat_config_raw_flash_v0_t;//old v0
/** \brief typedef of platform info layout stored in raw flash */
__PACKED_STRUCT _plat_info_layout
{
config_file_header_t header; /**< raw flash plat config header */
plat_config_raw_flash_t config; /**< raw flash plat config body */
uint32_t fsAssertCount; /**< count for monitoring FS assert, when it reaches specific number, FS region will be re-formated */
};
typedef struct _plat_info_layout plat_info_layout_t;
/** @brief List of platform configuration items used to set/get sepecific setting */
typedef enum _plat_config_id
{
PLAT_CONFIG_ITEM_FAULT_ACTION = 0, /**< faultAction item */
PLAT_CONFIG_ITEM_UART_DUMP_PORT, /**< uartDumpPort item */
PLAT_CONFIG_ITEM_START_WDT, /**< startWDT item */
PLAT_CONFIG_ITEM_LOG_CONTROL, /**< logControl item */
PLAT_CONFIG_ITEM_LOG_BAUDRATE, /**< uart baudrate for log output */
PLAT_CONFIG_ITEM_LOG_LEVEL, /**< logLevel item */
PLAT_CONFIG_ITEM_ENABLE_PM, /**< enablePM item */
PLAT_CONFIG_ITEM_SLEEP_MODE, /**< sleepMode item */
PLAT_CONFIG_ITEM_WAIT_SLEEP, /**< wait ms before sleep */
PLAT_CONFIG_ITEM_AT_PORT_BAUDRATE, /**< AT port baudrate */
PLAT_CONFIG_ITEM_AT_PORT_FRAME_FORMAT, /**< AT port frame format */
PLAT_CONFIG_ITEM_ECSCLK_CFG, /**< ECSCLK config */
PLAT_CONFIG_ITEM_LOG_PORT_SEL, /**< ULG output port select */
PLAT_CONFIG_ITEM_USB_CTRL, /**< USB control */
PLAT_CONFIG_ITEM_USB_SW_TRACE_FLAG, /**< USB control */
PLAT_CONFIG_ITEM_USB_SLEEP_MASK, /**< USB Sleep Vote Mask */
PLAT_CONFIG_ITEM_USB_SLEEP_THD, /**< USB Sleep Thread */
PLAT_CONFIG_ITEM_PWRKEY_MODE, /**< PWRKEY Mode */
PLAT_CONFIG_ITEM_USB_VBUS_MODE_EN, /**< USB VBUS MODE ENABLE, DISABLE*/
PLAT_CONFIG_ITEM_USB_VBUS_WKUP_PAD, /**< USB VBUS MODE WKUP PAD INDEX*/
PLAT_CONFIG_ITEM_USB_NET, /**< USB NET Select*/
PLAT_CONFIG_ITEM_USB_VCOM_EN_BMP, /**< USB VCOM Enabled Bitmap*/
PLAT_CONFIG_ITEM_FOTA_URC_PORT_SEL, /**< FOTA URC Port Select*/
PLAT_CONFIG_ITEM_PMUINCDRX, /**< PMUINCDRX Select*/
PLAT_CONFIG_ITEM_SLP_LIMIT_EN, /**< enable sleep time limit*/
PLAT_CONFIG_ITEM_SLP_LIMIT_TIME, /**< set maximum sleep time in mili second*/
PLAT_CONFIG_ITEM_TOTAL_NUMBER /**< total number of items */
} plat_config_id_t;
/*******************************************************************************
* API
******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/**
\fn void BSP_SavePlatConfigToFs(void)
\brief Save platform configuration into FS
\return void
*/
void BSP_SavePlatConfigToFs(void);
/**
\fn void BSP_LoadPlatConfigFromFs(void)
\brief Load platform configuration from FS
\return void
*/
void BSP_LoadPlatConfigFromFs(void);
/**
\fn plat_config_fs_t* BSP_GetFsPlatConfig(void)
\brief Get FS platform configuration variable pointer
\return pointer to internal platform configuration loaded from FS
*/
plat_config_fs_t* BSP_GetFsPlatConfig(void);
/**
\fn void BSP_SavePlatConfigToRawFlash(void)
\brief Save platform configuration into raw flash
\return void
*/
void BSP_SavePlatConfigToRawFlash(void);
/**
\fn void BSP_LoadPlatConfigFromRawFlash(void)
\brief Load platform configuration from raw flash
\return void
*/
void BSP_LoadPlatConfigFromRawFlash(void);
/**
\fn plat_config_raw_flash_t* BSP_GetRawFlashPlatConfig(void)
\brief Get raw flash platform configuration variable pointer
\return pointer to internal platform configuration loaded from raw flash
*/
plat_config_raw_flash_t* BSP_GetRawFlashPlatConfig(void);
/**
\fn uint32_t BSP_GetPlatConfigItemValue(plat_config_id_t id)
\brief Get value of specific platform configuration item
\param[in] id id of platform configuration item, \ref plat_config_id_t
\return value of current configuration item
*/
uint32_t BSP_GetPlatConfigItemValue(plat_config_id_t id);
/**
\fn void BSP_SetPlatConfigItemValue(plat_config_id_t id, uint32_t value)
\brief Set value of specific platform configuration item
\param[in] id id of platform configuration item, \ref plat_config_id_t
\param[in] value value of configuration item to set
\return void
*/
void BSP_SetPlatConfigItemValue(plat_config_id_t id, uint32_t value);
/**
\fn uint32_t BSP_GetFSAssertCount(void)
\brief Fetch current 'fsAssertCount' value from PLAT_INFO region
\return current fsAssertCount value
*/
uint32_t BSP_GetFSAssertCount(void);
/**
\fn void BSP_SetFSAssertCount(uint32_t value);
\brief Update 'fsAssertCount' value
\param[in] value new value assigned to 'fsAssertCount'
\return void
\note Internal use only on FS assert occurs
*/
void BSP_SetFSAssertCount(uint32_t value);
/**
\fn void BSP_SetFsPorDefaultValue(void);
\brief when por happened some data may retore to it's default
\return void
*/
void BSP_SetFsPorDefaultValue(void);
#ifdef __cplusplus
}
#endif
#endif /* _PLAT_CONFIG_H */

View File

@@ -0,0 +1,172 @@
#include "codecDrv.h"
void delay_us(uint32_t us);
extern ARM_DRIVER_I2C Driver_I2C0;
static ARM_DRIVER_I2C *i2cDrvInstance = &CREATE_SYMBOL(Driver_I2C, 0);
void codecI2cInit()
{
i2cDrvInstance->Initialize(NULL);
i2cDrvInstance->PowerControl(ARM_POWER_FULL);
i2cDrvInstance->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
i2cDrvInstance->Control(ARM_I2C_BUS_CLEAR, 0);
}
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2cCfg)
{
uint8_t cmd[2] = {0, 0};
uint8_t regAddr = i2cCfg->regAddr;
uint16_t regData = i2cCfg->regVal;
if (strcmp(codecName, "es8388") == 0)
{
cmd[0] = regAddr;
cmd[1] = regData & 0xff;
}
else if (strcmp(codecName, "NAU88C22") == 0)
{
cmd[0] = (regAddr << 1) | ((regData & 0x100) >> 8);
cmd[1] = regData & 0xff;
}
else if(strcmp(codecName, "es8311") == 0)
{
cmd[0] = regAddr;
cmd[1] = regData & 0xff;
}
i2cDrvInstance->MasterTransmit(slaveAddr, cmd, 2, false);
//delay_us(30 * 1000); // need to add delay in app layer which call it
}
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr)
{
uint8_t a;
a = regAddr;
uint8_t readData;
i2cDrvInstance->MasterTransmit(slaveAddr, (uint8_t *)&a, 1, true);
i2cDrvInstance->MasterReceive(slaveAddr, &readData, 1, false);
return readData;
}
uint16_t es8388GetFs(void);
uint16_t es8311GetFs(void);
uint16_t codecGetFs(codecType_e codecType)
{
switch (codecType)
{
case ES8388:
return es8388GetFs();
case NAU88C22:
return 1;
case ES7148:
return 1;
case ES7149:
return 1;
case ES8311:
return es8311GetFs();
}
return 0;
}
#if 0
/**
\fn void codecCtrlVolume(uint8_t raise, uint8_t step)
\brief Raise or decrease volume.
\param[in] codecType codec type.
\param[in] raise true means raise volume; false means decrease volume.
\param[in] step Raise or decrease vlume'samplitude everytime.
\return none.
*/
void codecCtrlVolume(codecType_e codecType, bool raise, uint8_t step)
{
i2sI2cCfg_t i2cCfg = {0,0,0};
switch (codecType)
{
case ES8388:
{
i2cCfg.regAddr = 0x1b;
raise? (i2cCfg.regVal += step) : (i2cCfg.regVal -= step);
i2cCfg.delayMs = 1;
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2cCfg); // register27. Digital part
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2cCfg); // register49. Analog part
return;
}
case NAU88C22:
return;
}
}
#endif
void codecWriteVal(codecType_e codecType, uint8_t regAddr, uint16_t regVal)
{
i2sI2cCfg_t i2cCfg;
i2cCfg.regAddr = regAddr;
i2cCfg.regVal = regVal;
switch (codecType)
{
case ES8388:
{
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2cCfg);
return;
}
case NAU88C22:
{
codecI2cWrite("NAU88C22", NAU88C22_IICADDR, (i2sI2cCfg_t*)&i2cCfg);
return;
}
case ES7148:
{
return;
}
case ES7149:
{
return;
}
case ES8311:
{
codecI2cWrite("es8311", ES8311_IICADDR, (i2sI2cCfg_t*)&i2cCfg);
return;
}
}
}
uint8_t codecReadVal(codecType_e codecType, uint8_t regAddr)
{
uint8_t dataRead = 0x55;
switch (codecType)
{
case ES8388:
{
dataRead = codecI2cRead(ES8388_IICADDR, regAddr);
break;
}
case ES8311:
{
dataRead = codecI2cRead(ES8311_IICADDR, regAddr);
break;
}
case ES7148:
case ES7149:
case NAU88C22:
break;
}
return dataRead;
}

View File

@@ -0,0 +1,153 @@
#include "i2s.h"
#define ES8311_FS_NUM 256
i2sI2cCfg_t es8311_regInfo[] =
{
{0x45,0x00},
{0x01,0x30},
{0x02,0x10},
//Ratio=MCLK/LRCK=25612M288-48K4M096-16K; 2M048-8K
{0x02,0x00},//MCLK DIV=1
{0x03,0x10},
{0x16,0x24},
{0x04,0x20},
{0x05,0x00},
{0x06,(0<<5) + 4 -1},//(0x06,(SCLK_INV<<5) + SCLK_DIV -1);
{0x07,0x00},
{0x08,0xFF},
{0x09,(0<<7) + 0x00 + (0x00<<2)},//(0x09,(DACChannelSel<<7) + Format + (Format_Len<<2));
{0x0A,0x00 + (0x00<<2)},//(0x0A,Format + (Format_Len<<2));
{0x0B,0x00},
{0x0C,0x00},
// {0x10,(0x1C*0) + (0x60*0x01) + 0x03}, //(0x10,(0x1C*DACHPModeOn) + (0x60*VDDA_VOLTAGE) + 0x03); //VDDA_VOLTAGE=1.8V close es8311MasterInit 3.3PWR setting
{0x10,(0x1C*0) + (0x60*0x00) + 0x03}, //(0x10,(0x1C*DACHPModeOn) + (0x60*VDDA_VOLTAGE) + 0x03); //VDDA_VOLTAGE=3.3V open es8311MasterInit 3.3PWR setting
{0x11,0x7F},
{0x00,0x80 + (0<<6)},//Slave Mode (0x00,0x80 + (MSMode_MasterSelOn<<6));//Slave Mode
{0x0D,0x01},
{0x01,0x3F + (0x00<<7)},//(0x01,0x3F + (MCLK<<7));
{0x14,(0<<6) + (1<<4) + 0},//选择CH1输入+30DB GAIN (0x14,(Dmic_Selon<<6) + (ADCChannelSel<<4) + ADC_PGA_GAIN);
{0x12,0x28},
{0x13,0x00 + (0<<4)}, //(0x13,0x00 + (DACHPModeOn<<4));
{0x0E,0x02},
{0x0F,0x44},
{0x15,0x00},
{0x1B,0x0A},
{0x1C,0x6A},
{0x37,0x48},
{0x44,(0 <<7)}, //(0x44,(ADC2DAC_Sel <<7));
{0x17,210},//(0x17,ADC_Volume);
{0x32,100},//(0x32,DAC_Volume);
};
uint16_t es8311GetRegCnt(char* regName)
{
if (strcmp(regName, "es8311_master") == 0)
{
return (sizeof(es8311_regInfo) / sizeof(es8311_regInfo[0]));
}
else if (strcmp(regName, "es8311_slave") == 0)
{
return (sizeof(es8311_regInfo) / sizeof(es8311_regInfo[0]));
}
return 0;
}
void codecI2cInit(void);
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2sI2cCfg);
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr);
void es8311MasterInit()
{
uint8_t dataRead = 0xff;
codecI2cInit();
for (int i = 0; i < es8311GetRegCnt("es8311_master"); i++)
{
codecI2cWrite("es8311", ES8311_IICADDR, (i2sI2cCfg_t*)&es8311_regInfo[i]);
delay_us(10000);
}
#if 1
for (int i = 0; i < es8311GetRegCnt("es8311_master"); i++)
{
dataRead = codecI2cRead(ES8311_IICADDR, es8311_regInfo[i].regAddr);
printf("reg = 0x%02x, val = 0x%02x\n", es8311_regInfo[i].regAddr, dataRead);
}
#endif
}
void es8311SlaveInit()
{
// uint8_t dataRead = 0xff;
es8311MasterInit();
i2sI2cCfg_t i2sI2cCfg;
i2sI2cCfg.regAddr = 0x80;
i2sI2cCfg.regVal = 0<<6; // Bit7 --> 1: master(default); 0: slave
codecI2cWrite("es8311", ES8311_IICADDR, (i2sI2cCfg_t*)&i2sI2cCfg);
#if 0
for (int i = 0; i < es8311GetRegCnt("es8311_slave"); i++)
{
dataRead = codecI2cRead(ES8311_IICADDR, es8311_regInfo[i].regAddr);
printf("reg = 0x%02x, val = 0x%02x\n", es8311_regInfo[i].regAddr, dataRead);
}
#endif
}
uint16_t es8311GetFs()
{
return ES8311_FS_NUM;
}
void es8311SetMode(i2sMode_e mode)
{
uint8_t val = 0;
switch(mode)
{
case MSB_MODE:
val = 0x0F;
break;
case I2S_MODE:
val = 0x0C;
break;
case LSB_MODE:
val = 0x0D;
break;
case PCM_MODE:
val = 0x2F;
break;
}
codecWriteVal(CODEC_ES8311, 0x09, val);
}

View File

@@ -0,0 +1,146 @@
#include "i2s.h"
#define ES8388_FS_NUM 256
i2sI2cCfg_t es8388_regInfo[] =
{
{0x00,0x80},
{0x00,0x06},
{0x02,0xf3},
{0x35,0xa0},
{0x36,0x08},
{0x08,0x84}, // Bit7: 1 means master(default); 0 means slave; 0x84: master 32bit; 0x86: master 16bit
{0x0d,0x02}, // 256 ratio
{0x18,0x02}, // 256 ratio
{0x07,0x7c},
{0x2b,0x80},
{0x2d,0x10},
{0x00,0x30},
{0x01,0x00},
{0x03,0x00},
{0x06,0xff},
{0x09,0x88}, // Analog PGA: +24dB
{0x0a,0xfc},
{0x0b,0x02},
{0x0c,0x0D}, // 0x0d: 16bit Left; 0x0c: 16bit I2S; 0x0e: 16bit Right; 0x0f: 16bit PCM;
{0x10,0x00}, // digital gain ADCL
{0x11,0x00}, // digital gain ADCR
{0x12,0x05},
{0x17,0x1B}, // 0x1b: 16bit Left; 0x19: 16bit I2S; 0x1d: 16bit Right; 0x1f: 16bit PCM;
{0x19,0x76},
{0x1a,0x45}, // digital gain DACL
{0x1b,0x00}, // digital gain DACR
{0x26,0x12},
{0x2e,0x00},
{0x2f,0x00},
{0x30,0x00},
{0x31,0x00},
{0x02,0x00},
{0x00,0x37},
{0x01,0x20},
{0x27,0xb8},
{0x2a,0xb8},
{0x04,0x3c},
{0x00,0x36},
{0x19,0x72},
{0x2e,0x1e},
{0x2f,0x1e},
{0x30,0x1e},
{0x31,0x1e},
};
uint16_t es8388GetRegCnt(char* regName)
{
if (strcmp(regName, "es8388_master") == 0)
{
return (sizeof(es8388_regInfo) / sizeof(es8388_regInfo[0]));
}
else if (strcmp(regName, "es8388_slave") == 0)
{
return (sizeof(es8388_regInfo) / sizeof(es8388_regInfo[0]));
}
return 0;
}
void codecI2cInit(void);
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2sI2cCfg);
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr);
void es8388MasterInit()
{
//uint8_t dataRead = 0xff;
codecI2cInit();
for (int i = 0; i < es8388GetRegCnt("es8388_master"); i++)
{
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&es8388_regInfo[i]);
//delay_us(10000);
}
#if 0
for (int i = 0; i < es8388GetRegCnt("es8388_master"); i++)
{
dataRead = codecI2cRead(ES8388_IICADDR, es8388_regInfo[i].regAddr);
printf("reg = 0x%02x, val = 0x%02x\n", es8388_regInfo[i].regAddr, dataRead);
}
#endif
}
void es8388SlaveInit()
{
//uint8_t dataRead = 0xff;
es8388MasterInit();
i2sI2cCfg_t i2sI2cCfg;
i2sI2cCfg.regAddr = 0x08;
i2sI2cCfg.regVal = 0<<7; // Bit7 --> 1: master(default); 0: slave
codecI2cWrite("es8388", ES8388_IICADDR, (i2sI2cCfg_t*)&i2sI2cCfg);
#if 0
for (int i = 0; i < es8388GetRegCnt("es8388_slave"); i++)
{
dataRead = codecI2cRead(ES8388_IICADDR, es8388_regInfo[i].regAddr);
printf("reg = 0x%02x, val = 0x%02x\n", es8388_regInfo[i].regAddr, dataRead);
}
#endif
}
uint16_t es8388GetFs()
{
return ES8388_FS_NUM;
}
void es8388SetMode(i2sMode_e mode)
{
uint8_t val = 0;
switch(mode)
{
case MSB_MODE:
val = 0x1b;
break;
case I2S_MODE:
val = 0x19;
break;
case LSB_MODE:
val = 0x1d;
break;
case PCM_MODE:
val = 0x1f;
break;
}
codecWriteVal(CODEC_ES8388, 0x17, val);
}

View File

@@ -0,0 +1,79 @@
#include "i2s.h"
#define NAU88C22_FS_NUM 256
i2sI2cCfg_t NAU88C22_slaveRegInfo[] =
{
{0x00,0x000},
{0x01,0x1FD},
{0x02,0x1BF},
{0x03,0x1EF},
//{0x04,0x008},
{0x06,0x000},
{0x0A,0x008},
//{0x0B,0x1FF},
//{0x0C,0x1FF},
{0x2C,0x033},
{0x2D,0x012},
{0x2E,0x012},
{0x32,0x001},
{0x33,0x001},
{0x34,0x139},
{0x35,0x139},
};
uint16_t NAU88C22GetRegCnt(char* regName)
{
if (strcmp(regName, "NAU88C22_slave") == 0)
{
return (sizeof(NAU88C22_slaveRegInfo) / sizeof(NAU88C22_slaveRegInfo[0]));
}
else if (strcmp(regName, "NAU88C22_master") == 0)
{
return (sizeof(NAU88C22_slaveRegInfo) / sizeof(NAU88C22_slaveRegInfo[0]));
}
return 0;
}
void codecI2cInit(void);
void codecI2cWrite(char* codecName, uint8_t slaveAddr, i2sI2cCfg_t* i2sI2cCfg);
uint8_t codecI2cRead(uint8_t slaveAddr, uint8_t regAddr);
void nau88c22MasterInit()
{
}
void nau88c22SlaveInit()
{
uint8_t dataRead = 0xff;
codecI2cInit();
for (int i = 0; i < NAU88C22GetRegCnt("NAU88C22_slave"); i++)
{
codecI2cWrite("NAU88C22", NAU88C22_IICADDR, (i2sI2cCfg_t*)&NAU88C22_slaveRegInfo[i]);
}
for (int i = 0; i < NAU88C22GetRegCnt("NAU88C22_slave"); i++)
{
dataRead = codecI2cRead(NAU88C22_IICADDR, NAU88C22_slaveRegInfo[i].regAddr);
printf("reg = 0x%02x, val = 0x%02x\n", NAU88C22_slaveRegInfo[i].regAddr, dataRead);
}
}
uint16_t NAU88C22GetFs()
{
return NAU88C22_FS_NUM;
}

View File

@@ -0,0 +1,323 @@
/****************************************************************************
*
* Copy right: 2018 Copyrigths of AirM2M Ltd.
* File name: bsp.c
* Description:
* History:
*
****************************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "Driver_Common.h"
#include "clock.h"
#include "bsp.h"
#include "system_ec618.h"
#include DEBUG_LOG_HEADER_FILE
#include "ec_string.h"
#include "mem_map.h"
#if FEATURE_CCIO_ENABLE
#include "uart_device.h"
#endif
#include "dbversion.h"
#include "clock.h"
#include "hal_adcproxy.h"
#include "apmu_external.h"
extern ARM_DRIVER_USART Driver_USART0;
extern ARM_DRIVER_USART Driver_USART1;
ARM_DRIVER_USART *UsartPrintHandle = NULL;
ARM_DRIVER_USART *UsartUnilogHandle = NULL;
ARM_DRIVER_USART *UsartAtCmdHandle = NULL;
static uint8_t OSState = 0; // OSState = 0 os not start, OSState = 1 os started
extern void trimAdcSetGolbalVar(void);
void BSP_InitUartDriver(ARM_DRIVER_USART *drvHandler,
ARM_POWER_STATE powerMode,
uint32_t settings,
uint32_t baudRate,
ARM_USART_SignalEvent_t cb_event)
{
if(drvHandler)
{
drvHandler->Initialize(cb_event);
drvHandler->PowerControl(powerMode);
drvHandler->Control(settings, baudRate);
}
}
void BSP_DeinitUartDriver(ARM_DRIVER_USART *drvHandler)
{
if(drvHandler)
{
drvHandler->PowerControl(ARM_POWER_OFF);
drvHandler->Uninitialize();
}
}
#if defined ( __GNUC__ )
/*
* retarget for _write implementation
* Parameter: ch: character will be out
*/
int io_putchar(int ch)
{
if (UsartPrintHandle != NULL)
UsartPrintHandle->SendPolling((uint8_t*)&ch, 1);
return 0;
}
/*
* retarget for _read implementation
* Parameter: ch: character will be read
*/
int io_getchar()
{
uint8_t ch = 0;
if (UsartPrintHandle != NULL)
UsartPrintHandle->Receive(&ch, 1);
return (ch);
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
if (UsartPrintHandle != NULL)
UsartPrintHandle->Receive(&ch, 1);
return (ch);
}
__attribute__((weak,noreturn))
void __aeabi_assert (const char *expr, const char *file, int line) {
printf("Assert, expr:%s, file: %s, line: %d\r\n", expr, file, line);
while(1);
}
void __assert_func(const char *filename, int line, const char *assert_func, const char *expr)
{
for(uint8_t i = 0; i<5; i++)
{
uniLogFlushOut();
ECPLAT_PRINTF(UNILOG_PLA_DRIVER, assert_func_1, P_ERROR, "Assert, expr:%s, file: %s, line: %d\r\n", expr, filename, line);
}
while(1);
}
#elif defined (__CC_ARM)
/*
* retarget for printf implementation
* Parameter: ch: character will be out
* f: not used
*/
int fputc(int ch, FILE *f)
{
if (UsartPrintHandle != NULL)
UsartPrintHandle->SendPolling((uint8_t*)&ch,1);
return 0;
}
/*
* retarget for scanf implementation
* Parameter: f: not used
*/
int fgetc(FILE *f)
{
uint8_t ch = 0;
if (UsartPrintHandle != NULL)
UsartPrintHandle->Receive(&ch,1);
return (ch);
}
__attribute__((weak,noreturn))
void __aeabi_assert (const char *expr, const char *file, int line) {
printf("Assert, expr:%s, file: %s, line: %d\r\n", expr, file, line);
while(1);
}
#endif
uint32_t GET_PMU_RAWFLASH_OFFSET(void)
{
return FLASH_MEM_BACKUP_ADDR;
}
void setOSState(uint8_t state)
{
OSState = state;
}
PLAT_PA_RAMCODE uint8_t getOSState(void) //1 os started. 0 no OS or OS not started yet
{
return OSState;
}
uint8_t* getBuildInfo(void)
{
return (uint8_t *)BSP_HEADER;
}
uint8_t* getVersionInfo(void)
{
return (uint8_t *)VERSION_INFO;
}
uint8_t* getATIVersionInfo(void)
{
return (uint8_t *)ATI_VERSION_INFO;
}
//move here since this is an common and opensource place
uint8_t* getDebugDVersion(void)
{
return (uint8_t*)DB_VERSION_UNIQ_ID;
}
#ifdef UINILOG_FEATURE_ENABLE
/**
\fn void logToolCommandHandle(uint8_t *atcmd_buffer, uint32_t len)
\brief handle downlink command sent from unilog tool EPAT
if need to handle more command in future, add command-handler table
\param[in] event UART event, note used in this function
\param[in] cmd_buffer command received from UART
\param[in] len command length
\returns void
*/
void logToolCommandHandle(uint32_t event, uint8_t *cmd_buffer, uint32_t len)
{
(void)event;
uint8_t * LogDbVserion=getDebugDVersion();
if(ec_strnstr((const char *)cmd_buffer, "^logversion", len))
{
ECPLAT_PRINTF(UNILOG_PLA_INTERNAL_CMD, get_log_version, P_SIG, "LOGVERSION:%s",LogDbVserion);
}
else
{
ECPLAT_PRINTF(UNILOG_PLA_STRING, get_log_version_1, P_ERROR, "%s", "invalid command from EPAT");
}
return;
}
/**
* unilog entity is removed for the reason of BSP small image.
* for more implementation details, pls refer to
* gCustSerlEntity[CUST_ENTITY_UNILOG] in ccio_provider.c
*/
/*
* set unilog uart port
* Parameter: port: for unilog
* Parameter: baudrate: uart baudrate
*/
#ifdef __USER_CODE__
void SetUnilogUartOrg(usart_port_t port, uint32_t baudrate, bool startRecv)
#else
void SetUnilogUart(usart_port_t port, uint32_t baudrate, bool startRecv)
#endif
{
ARM_POWER_STATE powerMode = ARM_POWER_FULL;
uint32_t ctrlSetting = ARM_USART_MODE_ASYNCHRONOUS | ARM_USART_DATA_BITS_8 | \
ARM_USART_PARITY_NONE | ARM_USART_STOP_BITS_1 | \
ARM_USART_FLOW_CONTROL_NONE;
if (port == PORT_USART_0)
{
#if (RTE_UART0)
UsartUnilogHandle = &CREATE_SYMBOL(Driver_USART, 0);
#endif
}
else if (port == PORT_USART_1)
{
#if (RTE_UART1)
UsartUnilogHandle = &CREATE_SYMBOL(Driver_USART, 1);
#endif
}
if (UsartUnilogHandle == NULL) return;
#ifdef FEATURE_CCIO_ENABLE
UartDevConf_t uartDevConf;
UartHwConf_t *uartHwConf = &uartDevConf.hwConf;
memset(&uartDevConf, 0, sizeof(UartDevConf_t));
uartHwConf->powerMode = powerMode;
uartHwConf->ctrlSetting = ctrlSetting;
uartHwConf->baudRate = baudrate;
uartDevConf.drvHandler = UsartUnilogHandle;
uartDevConf.mainUsage = CSIO_DT_DIAG;
uartDevConf.speedType = CCIO_ST_HIGH;
if(startRecv)
{
uartDevConf.bmCreateFlag = CCIO_TASK_FLAG_RX;
}
else
{
uartDevConf.bmCreateFlag = CCIO_TASK_FLAG_NONE;
}
uartDevCreate(port, &uartDevConf);
#else
BSP_InitUartDriver(UsartUnilogHandle, powerMode, ctrlSetting, baudrate, NULL);
#endif
}
void FlushUnilogOutput(void)
{
uniLogFlushOut();
if(UsartUnilogHandle == NULL)
return;
UsartUnilogHandle->Control(ARM_USART_CONTROL_FLUSH_TX, 0);
}
#endif
void BSP_CommonInit(void)
{
SystemCoreClockUpdate();
PAD_driverInit();
GPR_initialize();
trimAdcSetGolbalVar();
apmuInit();
//interrupt config
IC_PowupInit();
if(apmuGetAPBootFlag() == 0) // power on
{
apmuSetCPFastBoot(false); // set cp fast boot in case of cp dap wakeup
}
cpADCInit(); // enable adc ref output, need stable time
BOOT_TIMESTAMP_SET(1, 3);
}

View File

@@ -0,0 +1,121 @@
#include "cameraDrv.h"
camI2cCfg_t bf30a2_1sdrRegInfo[] =
{
{0xf2,0x01},//soft reset
{0xcf,0xb0},//power up
{0x12,0x20},//MTK:20 ZX:10 RDA:40
{0x15,0x80},
{0x6b,0x71},
{0x00,0x40},
{0x04,0x00},
{0x06,0x26},
{0x08,0x07},
{0x1c,0x12},
{0x20,0x20},
{0x21,0x20},
{0x34,0x02},
{0x35,0x02},
{0x36,0x21},
{0x37,0x13},
{0xca,0x23},
{0xcb,0x22},
{0xcc,0x89},
{0xcd,0x4c},
{0xce,0x6b},
{0xa0,0x8e},
{0x01,0x1b},
{0x02,0x1d},
{0x13,0x08},
{0x87,0x13},
{0x8b,0x08},
{0x70,0x1f},
{0x71,0x40},
{0x72,0x0a},
{0x73,0x62},
{0x74,0xa2},
{0x75,0xbf},
{0x76,0x02},
{0x77,0xcc},
{0x40,0x32},
{0x41,0x28},
{0x42,0x26},
{0x43,0x1d},
{0x44,0x1a},
{0x45,0x14},
{0x46,0x11},
{0x47,0x0f},
{0x48,0x0e},
{0x49,0x0d},
{0x4B,0x0c},
{0x4C,0x0b},
{0x4E,0x0a},
{0x4F,0x09},
{0x50,0x09},
{0x24,0x50},
{0x25,0x36},
{0x80,0x00},
{0x81,0x20},
{0x82,0x40},
{0x83,0x30},
{0x84,0x50},
{0x85,0x30},
{0x86,0xD8},
{0x89,0x45},
{0x8a,0x33},
{0x8f,0x81},
{0x91,0xff},
{0x92,0x08},
{0x94,0x82},
{0x95,0xfd},
{0x9a,0x20},
{0x9e,0xbc},
{0xf0,0x8f},
{0x51,0x06},
{0x52,0x25},
{0x53,0x2b},
{0x54,0x0F},
{0x57,0x2A},
{0x58,0x22},
{0x59,0x2c},
{0x23,0x33},
{0xa1,0x93},
{0xa2,0x0f},
{0xa3,0x2a},
{0xa4,0x08},
{0xa5,0x26},
{0xa7,0x80},
{0xa8,0x80},
{0xa9,0x1e},
{0xaa,0x19},
{0xab,0x18},
{0xae,0x50},
{0xaf,0x04},
{0xc8,0x10},
{0xc9,0x15},
{0xd3,0x0c},
{0xd4,0x16},
{0xee,0x06},
{0xef,0x04},
{0x55,0x34},
{0x56,0x9c},
{0xb1,0x98},
{0xb2,0x98},
{0xb3,0xc4},
{0xb4,0x0C},
{0xa0,0x8f},
{0x13,0x07},
};
uint16_t bf30a2GetRegCnt(char* regName)
{
if (strcmp(regName, "bf30a2_1sdr") == 0)
{
return (sizeof(bf30a2_1sdrRegInfo) / sizeof(bf30a2_1sdrRegInfo[0]));
}
return 0;
}

View File

@@ -0,0 +1,99 @@
#include "cameraDrv.h"
#include "quirc.h"
static volatile bool isTransferDone;
extern void delay_us(uint32_t);
struct quirc *qr;
uint8_t* pic0Internal = NULL;
static void camRecvCb(uint32_t event)
{
if(event & ARM_SPI_EVENT_TRANSFER_COMPLETE)
{
isTransferDone = true;
}
}
bool decodeBegin(uint8_t* result)
{
int num_codes=0, w, h;
struct quirc_code code;
struct quirc_data data;
quirc_decode_error_t err;
quirc_begin(qr, &w, &h);
quirc_end(qr);
num_codes = quirc_count(qr);
if (num_codes != 1)
{
return false;
}
quirc_extract(qr, 0, &code);
/* Decoding stage */
err = quirc_decode(&code, &data);
if (err)
{
return false;
//printf("D F2: %s\n", quirc_strerror(err));
}
else
{
memcpy(result, data.payload, data.payload_len);
return true;
//printf("Data: %s\n", data.payload);
}
}
void camPrepare(uint8_t* pic0)
{
pic0Internal = pic0;
// Camera register part
camRegCfg(); // Only need to init once
// Quirc part
qr = quirc_new();
quirc_init(qr, pic0, 320, 240);
}
bool camBegin(bool start, uint8_t* result)
{
uint32_t timeOut_ms = 5000;
if (start)
{
camInit(camRecvCb);
camStart(true);
camRecv(pic0Internal);
do
{
delay_us(1000);
}
while((isTransferDone == false) && --timeOut_ms);
}
else
{
camStart(false);
return true;
}
if (isTransferDone)
{
isTransferDone = false;
return decodeBegin(result);
}
else
{
// Error: camera doesn't take picture fail
return false;
}
}

View File

@@ -0,0 +1,403 @@
#include "cameraDrv.h"
extern cspiDrvInterface_t cspiDrvInterface0;
extern cspiDrvInterface_t cspiDrvInterface1;
extern camI2cCfg_t sp0A39Cfg[];
extern camI2cCfg_t sp0821Cfg[];
extern camI2cCfg_t gc6123Cfg[];
extern camI2cCfg_t gc032ACfg[];
extern camI2cCfg_t bf30a2Cfg[];
extern cspiCtrl_t cspiCtrl;
extern cspiIntCtrl_t cspiIntCtrl;
extern cspiDataFmt_t cspiDataFmt;
extern ARM_DRIVER_I2C Driver_I2C0;
static ARM_DRIVER_I2C *i2cDrvInstance = &CREATE_SYMBOL(Driver_I2C, 0);
#define EIGEN_CSPI(n) ((CSPI_TypeDef *) (MP_I2S0_BASE_ADDR + 0x1000*n))
#if (CAMERA_ENABLE_SP0A39)
#if (SP0A39_2SDR)
char* regName = "sp0a39_2sdr";
#elif (SP0A39_1SDR)
char* regName = "sp0a39_1sdr";
#endif
#elif (CAMERA_ENABLE_SP0821)
#if (SP0821_2SDR)
char* regName = "sp0821_2sdr";
#elif (SP0821_1SDR)
char* regName = "sp0821_1sdr";
#endif
#elif (CAMERA_ENABLE_GC6123)
#if (GC6123_2SDR)
char* regName = "gc6123_2sdr";
#elif (GC6123_1SDR)
char* regName = "gc6123_1sdr";
#endif
#elif (CAMERA_ENABLE_GC032A)
#if (GC032A_2SDR)
char* regName = "gc032a_2sdr";
#elif (GC032A_1SDR)
char* regName = "gc032a_1sdr";
#endif
#elif (CAMERA_ENABLE_BF30A2)
#if (BF30A2_1SDR)
char* regName = "bf30a2_1sdr";
#endif
#elif (CAMERA_ENABLE_GC6153)
#if (GC6153_1SDR)
char* regName = "gc6153_1sdr";
#endif
#endif
static uint8_t slaveAddr;
static uint16_t regCnt;
static camI2cCfg_t* regInfo = NULL;
#if (RTE_CSPI1 == 1)
static cspiDrvInterface_t *cspiDrv = &CREATE_SYMBOL(cspiDrvInterface, 1);
#else
static cspiDrvInterface_t *cspiDrv = &CREATE_SYMBOL(cspiDrvInterface, 0);
#endif
extern void delay_us(uint32_t us);
void findRegInfo(char* regName, uint8_t* slaveAddr, uint16_t* regCnt, camI2cCfg_t** regInfo)
{
if (strcmp(regName, "sp0a39_2sdr") == 0)
{
extern camI2cCfg_t sp0A39_2sdrRegInfo[];
*regInfo = sp0A39_2sdrRegInfo;
*slaveAddr = SP0A39_I2C_ADDR;
*regCnt = sp0a39GetRegCnt(regName);
}
else if (strcmp(regName, "sp0a39_1sdr") == 0)
{
extern camI2cCfg_t sp0A39_1sdrRegInfo[];
*regInfo = sp0A39_1sdrRegInfo;
*slaveAddr = SP0A39_I2C_ADDR;
*regCnt = sp0a39GetRegCnt(regName);
}
else if (strcmp(regName, "sp0821_2sdr") == 0)
{
extern camI2cCfg_t sp0821_2sdrRegInfo[];
*regInfo = sp0821_2sdrRegInfo;
*slaveAddr = SP0821_I2C_ADDR;
*regCnt = sp0821GetRegCnt(regName);
}
else if (strcmp(regName, "sp0821_1sdr") == 0)
{
extern camI2cCfg_t sp0821_1sdrRegInfo[];
*regInfo = sp0821_1sdrRegInfo;
*slaveAddr = SP0821_I2C_ADDR;
*regCnt = sp0821GetRegCnt(regName);
}
else if (strcmp(regName, "gc6123_2sdr") == 0)
{
extern camI2cCfg_t gc6123_2sdrRegInfo[];
*regInfo = gc6123_2sdrRegInfo;
*slaveAddr = GC6123_I2C_ADDR;
*regCnt = gc6123GetRegCnt(regName);
}
else if (strcmp(regName, "gc6123_1sdr") == 0)
{
extern camI2cCfg_t gc6123_1sdrRegInfo[];
*regInfo = gc6123_1sdrRegInfo;
*slaveAddr = GC6123_I2C_ADDR;
*regCnt = gc6123GetRegCnt(regName);
}
else if (strcmp(regName, "gc032a_2sdr") == 0)
{
extern camI2cCfg_t gc032A_2sdrRegInfo[];
*regInfo = gc032A_2sdrRegInfo;
*slaveAddr = GC032A_I2C_ADDR;
*regCnt = gc032aGetRegCnt(regName);
}
else if (strcmp(regName, "gc032a_1sdr") == 0)
{
extern camI2cCfg_t gc032A_1sdrRegInfo[];
*regInfo = gc032A_1sdrRegInfo;
*slaveAddr = GC032A_I2C_ADDR;
*regCnt = gc032aGetRegCnt(regName);
}
else if (strcmp(regName, "bf30a2_1sdr") == 0)
{
extern camI2cCfg_t bf30a2_1sdrRegInfo[];
*regInfo = bf30a2_1sdrRegInfo;
*slaveAddr = BF30A2_I2C_ADDR;
*regCnt = bf30a2GetRegCnt(regName);
}
else if (strcmp(regName, "gc6153_1sdr") == 0)
{
extern camI2cCfg_t gc6153_1sdrRegInfo[];
*regInfo = gc6153_1sdrRegInfo;
*slaveAddr = GC6153_I2C_ADDR;
*regCnt = gc6153GetRegCnt(regName);
}
}
void camI2cInit()
{
i2cDrvInstance->Initialize(NULL);
i2cDrvInstance->PowerControl(ARM_POWER_FULL);
i2cDrvInstance->Control(ARM_I2C_BUS_SPEED, ARM_I2C_BUS_SPEED_STANDARD);
i2cDrvInstance->Control(ARM_I2C_BUS_CLEAR, 0);
// Backup some info about this sensor
findRegInfo(regName, &slaveAddr, &regCnt, &regInfo);
}
void camI2cWrite(uint8_t slaveAddr, uint8_t regAddr, uint8_t regData, uint32_t num)
{
uint8_t tempBuffer[2];
tempBuffer[0] = regAddr;
tempBuffer[1] = regData;
i2cDrvInstance->MasterTransmit(slaveAddr, tempBuffer, num, false);
}
uint8_t camI2cRead(uint8_t slaveAddr, uint8_t regAddr)
{
uint8_t a;
a = regAddr;
uint8_t readData;
i2cDrvInstance->MasterTransmit(slaveAddr, (uint8_t *)&a, 1, true);
i2cDrvInstance->MasterReceive(slaveAddr, &readData, 1, false);
return readData;
}
uint8_t camReadReg(uint8_t regAddr)
{
uint8_t recvData;
recvData = camI2cRead(slaveAddr, regAddr);
return recvData;
}
void camWriteReg(camI2cCfg_t* regInfo)
{
camI2cWrite(slaveAddr, regInfo->regAddr, regInfo->regVal, 2);
}
void camRegCfg()
{
//uint8_t dataRead;
camI2cInit();
// Configure all the registers about this sensor
for (int i=0; i < regCnt; i++)
{
camI2cWrite(slaveAddr, regInfo[i].regAddr, regInfo[i].regVal, 2);
delay_us(10000); // delay 10ms
#if 0
dataRead = camI2cRead(slaveAddr, regInfo[i].regAddr);
printf("reg addr=0x%02x, reg val=0x%02x\n", regInfo[i].regAddr, dataRead);
delay_us(15000);
#endif
}
}
void camInterfaceCfg(camParamCfg_t* config)
{
cspiDataFmt.endianMode = config->endianMode;
cspiCtrl.rxWid = config->wireNum;
cspiCtrl.rxdSeq = config->rxSeq;
cspiCtrl.cpol = config->cpol;
cspiCtrl.cpha = config->cpha;
cspiCtrl.fillYonly = config->yOnly;
cspiCtrl.rowScaleRatio = config->rowScaleRatio;
cspiCtrl.colScaleRatio = config->colScaleRatio;
cspiCtrl.scaleBytes = config->scaleBytes;
}
void camSetMemAddr(uint32_t dataAddr)
{
cspiDrv->ctrl(CSPI_CTRL_MEM_ADDR , dataAddr); // register the recv memory
}
void camInit(void* dataAddr, cspiCbEvent_fn cb)
{
camResolution_e camResolution;
#if 0 // if used in os environment, use this api to adjust voltage
slpManNormalIOVoltSet(IOVOLT_3_00V);
#else // used in environment without os
// set all pin io to 2.7V since camera max voltage is 2.7V
GPR_clockEnable(PCLK_PMDIG);
*(uint32_t*)0x4d020018 = 1;
*(uint32_t*)0x4d040308 = 7; // 1:2.7V 7:3V
#endif
// Need to enable cspi first to make camera clock working
camParamCfg_t camParamCfg;
#if (CAMERA_ENABLE_SP0A39)
#if (SP0A39_2SDR)
camParamCfg.wireNum = WIRE_2;
#elif (SP0A39_1SDR)
camParamCfg.wireNum = WIRE_1;
#endif
camParamCfg.endianMode = LSB_MODE;
camParamCfg.rxSeq = SEQ_0;
camParamCfg.cpha = 1;
camParamCfg.cpol = 0;
camResolution = CAM_CHAIN_COUNT;
#elif (CAMERA_ENABLE_SP0821)
#if (SP0821_2SDR)
camParamCfg.wireNum = WIRE_2;
#elif (SP0821_1SDR)
camParamCfg.wireNum = WIRE_1;
#endif
camParamCfg.endianMode = LSB_MODE;
camParamCfg.rxSeq = SEQ_0;
camParamCfg.cpha = 1;
camParamCfg.cpol = 0;
camResolution = CAM_CHAIN_COUNT;
#elif (CAMERA_ENABLE_GC6123)
#if (GC6123_2SDR)
camParamCfg.wireNum = WIRE_2;
#elif (GC6123_1SDR)
camParamCfg.wireNum = WIRE_1;
#endif
camParamCfg.endianMode = LSB_MODE;
camParamCfg.rxSeq = SEQ_1;
camParamCfg.cpha = 1;
camParamCfg.cpol = 0;
camParamCfg.yOnly = 1;
camParamCfg.rowScaleRatio = 0;
camParamCfg.colScaleRatio = 0;
camParamCfg.scaleBytes = 0;
camResolution = CAM_CHAIN_COUNT;
#elif (CAMERA_ENABLE_GC032A)
#if (GC032A_2SDR)
camParamCfg.wireNum = WIRE_2;
#elif (GC032A_1SDR)
camParamCfg.wireNum = WIRE_1;
#endif
camParamCfg.endianMode = LSB_MODE;
camParamCfg.rxSeq = SEQ_0;
camParamCfg.cpha = 0;
camParamCfg.cpol = 0;
camResolution = CAM_CHAIN_COUNT;
if (camResolution == CAM_30W)
{
camParamCfg.yOnly = 0;
camParamCfg.rowScaleRatio = 0;
camParamCfg.colScaleRatio = 0;
camParamCfg.scaleBytes = 0;
}
else // CAM_8W
{
camParamCfg.yOnly = 1;
camParamCfg.rowScaleRatio = 1;
camParamCfg.colScaleRatio = 1;
camParamCfg.scaleBytes = 1;
}
#elif (CAMERA_ENABLE_BF30A2)
#if (BF30A2_1SDR)
camParamCfg.wireNum = WIRE_1;
#endif
camParamCfg.endianMode = LSB_MODE;
camParamCfg.rxSeq = SEQ_0;
camParamCfg.cpha = 0;
camParamCfg.cpol = 0;
camParamCfg.yOnly = 1;
camParamCfg.rowScaleRatio = 0;
camParamCfg.colScaleRatio = 0;
camParamCfg.scaleBytes = 0;
camResolution = CAM_CHAIN_COUNT;
#elif (CAMERA_ENABLE_GC6153)
#if (GC6153_1SDR)
camParamCfg.wireNum = WIRE_1;
#endif
camParamCfg.endianMode = LSB_MODE;
camParamCfg.rxSeq = SEQ_1;
camParamCfg.cpha = 1;
camParamCfg.cpol = 0;
camParamCfg.yOnly = 1;
camParamCfg.rowScaleRatio = 0;
camParamCfg.colScaleRatio = 0;
camParamCfg.scaleBytes = 0;
camResolution = CAM_CHAIN_COUNT;
#endif
camInterfaceCfg(&camParamCfg);
cspiDrv->ctrl(CSPI_CTRL_MEM_ADDR , (uint32_t)dataAddr); // register the recv memory
cspiDrv->init(cb);
cspiDrv->powerCtrl(CSPI_POWER_FULL);
cspiDrv->ctrl(CSPI_CTRL_DATA_FORMAT , 0); // control cspi
cspiDrv->ctrl(CSPI_CTRL_RXTOR , 0);
cspiDrv->ctrl(CSPI_CTRL_FRAME_INFO0 , 0);
cspiDrv->ctrl(CSPI_CTRL_INT_CTRL , 0);
cspiDrv->ctrl(CSPI_CTRL_CSPICTL , 0);
cspiDrv->ctrl(CSPI_CTRL_DMA_CTRL , 0);
cspiDrv->ctrl(CSPI_CTRL_RESOLUTION_SET , camResolution);
cspiDrv->ctrl(CSPI_CTRL_BUS_SPEED, (camFrequence_e)CAM_25_5_M); // cspi working frequency
}
void camStartStop(cspiStartStop_e startStop)
{
cspiDrv->ctrl(CSPI_CTRL_START_STOP , (uint32_t)startStop);
}
void cspiIntEnable(cspiIntEnable_e intEnable)
{
cspiIntCtrl.frameStartIntEn = intEnable;
cspiDrv->ctrl(CSPI_CTRL_INT_CTRL , 0); // cspi interrupt enable or disable
}
void camFlush()
{
cspiDrv->ctrl(CSPI_CTRL_FLUSH_RX_FIFO , 0); // flush rx fifo
}
void camRegisterIRQ(cspiInstance_e instance, camIrq_fn irqCb)
{
IRQn_Type irqNum;
if (instance == CSPI_0)
{
irqNum = PXIC0_I2S0_IRQn;
}
else
{
irqNum = PXIC0_I2S1_IRQn;
}
XIC_SetVector(irqNum, irqCb);
XIC_EnableIRQ(irqNum);
}
PLAT_FM_RAMCODE void camRecv(uint8_t * dataAddr)
{
cspiDrv->ctrl(CSPI_CTRL_MEM_ADDR , (uint32_t)dataAddr); // register the recv memory
cspiDrv->recv();
}
uint32_t camGetCspiStats(cspiInstance_e instance)
{
return EIGEN_CSPI(instance)->STAS;
}
void camClearIntStats(cspiInstance_e instance, uint32_t mask)
{
EIGEN_CSPI(instance)->STAS = mask;
}

View File

@@ -0,0 +1,666 @@
#include "cameraDrv.h"
camI2cCfg_t gc032A_2sdrRegInfo[] =
{
{0xf3,0x83},
{0xf5,0x0c},
{0xf7,0x01},// gavin 20160820
{0xf8,0x01},
{0xf9,0x4e},
{0xfa,0x10}, // gavin 20160820
{0xfc,0x02},
{0xfe,0x02},
{0x81,0x03},
{0xfe,0x00},
{0x77,0x64},
{0x78,0x40},
{0x79,0x60},
/*Analog&Cisctl*/
{0xfe,0x00},
{0x03,0x01},
{0x04,0xc2},
{0x05,0x01},
{0x06,0xb8},
{0x07,0x00},
{0x08,0x08},
{0x0a,0x00},
{0x0c,0x00},
{0x0d,0x01},
{0x0e,0xe8},
{0x0f,0x02},
{0x10,0x88},
{0x17,0x54},
{0x19,0x08},
{0x1a,0x0a},
{0x1f,0x40},
{0x20,0x30},
{0x2e,0x80},
{0x2f,0x2b},
{0x30,0x1a},
{0xfe,0x02},
{0x03,0x02},
{0x05,0xd7},
{0x06,0x60},
{0x08,0x80},
{0x12,0x89},
/*SPI*/
{0xfe,0x03},
{0x51,0x01},
{0x52,0x58}, // DDR Disable gavin 20160820
{0x53,0x24}, // Disable CRC
{0x54,0x20},
{0x55,0x00},
{0x59,0x10},
{0x5a,0x00},
{0x5b,0x80},
{0x5c,0x02},
{0x5d,0xe0},
{0x5e,0x01},
{0x64,0x04}, //SCK Always OFF , gavin 20160820
/*blk*/
{0xfe,0x00},
{0x18,0x02},
{0xfe,0x02},
{0x40,0x22},
{0x45,0x00},
{0x46,0x00},
{0x49,0x20},
{0x4b,0x3c},
{0x50,0x20},
{0x42,0x10},
/*isp*/
{0xfe,0x01},
{0x0a,0xc5},
{0x45,0x00},
{0xfe,0x00},
{0x40,0xff},
{0x41,0x25},
{0x42,0xcf},
{0x43,0x10},
{0x44,0x83},
{0x46,0x22},
{0x49,0x03},
{0x52,0x02},
{0x54,0x00},
{0xfe,0x02},
{0x22,0xf6},
/*Shading*/
{0xfe,0x01},
{0xc1,0x38},
{0xc2,0x4c},
{0xc3,0x00},
{0xc4,0x32},
{0xc5,0x24},
{0xc6,0x16},
{0xc7,0x08},
{0xc8,0x08},
{0xc9,0x00},
{0xca,0x20},
{0xdc,0x8a},
{0xdd,0xa0},
{0xde,0xa6},
{0xdf,0x75},
/*AWB*//*20170110*/
{0xfe, 0x01},
{0x7c, 0x09},
{0x65, 0x06},
{0x7c, 0x08},
{0x56, 0xf4},
{0x66, 0x0f},
{0x67, 0x84},
{0x6b, 0x80},
{0x6d, 0x12},
{0x6e, 0xb0},
{0xfe, 0x01},
{0x90, 0x00},
{0x91, 0x00},
{0x92, 0xf4},
{0x93, 0xd5},
{0x95, 0x0f},
{0x96, 0xf4},
{0x97, 0x2d},
{0x98, 0x0f},
{0x9a, 0x2d},
{0x9b, 0x0f},
{0x9c, 0x59},
{0x9d, 0x2d},
{0x9f, 0x67},
{0xa0, 0x59},
{0xa1, 0x00},
{0xa2, 0x00},
{0x86, 0x00},
{0x87, 0x00},
{0x88, 0x00},
{0x89, 0x00},
{0xa4, 0x00},
{0xa5, 0x00},
{0xa6, 0xd4},
{0xa7, 0x9f},
{0xa9, 0xd4},
{0xaa, 0x9f},
{0xab, 0xac},
{0xac, 0x9f},
{0xae, 0xd4},
{0xaf, 0xac},
{0xb0, 0xd4},
{0xb1, 0xa3},
{0xb3, 0xd4},
{0xb4, 0xac},
{0xb5, 0x00},
{0xb6, 0x00},
{0x8b, 0x00},
{0x8c, 0x00},
{0x8d, 0x00},
{0x8e, 0x00},
{0x94, 0x50},
{0x99, 0xa6},
{0x9e, 0xaa},
{0xa3, 0x0a},
{0x8a, 0x00},
{0xa8, 0x50},
{0xad, 0x55},
{0xb2, 0x55},
{0xb7, 0x05},
{0x8f, 0x00},
{0xb8, 0xb3},
{0xb9, 0xb6},
/*CC*/
{0xfe,0x01},
{0xd0,0x40},
{0xd1,0xf8},
{0xd2,0x00},
{0xd3,0xfa},
{0xd4,0x45},
{0xd5,0x02},
{0xd6,0x30},
{0xd7,0xfa},
{0xd8,0x08},
{0xd9,0x08},
{0xda,0x58},
{0xdb,0x02},
{0xfe,0x00},
/*Gamma*/
{0xfe,0x00},
{0xba,0x00},
{0xbb,0x04},
{0xbc,0x0a},
{0xbd,0x0e},
{0xbe,0x22},
{0xbf,0x30},
{0xc0,0x3d},
{0xc1,0x4a},
{0xc2,0x5d},
{0xc3,0x6b},
{0xc4,0x7a},
{0xc5,0x85},
{0xc6,0x90},
{0xc7,0xa5},
{0xc8,0xb5},
{0xc9,0xc2},
{0xca,0xcc},
{0xcb,0xd5},
{0xcc,0xde},
{0xcd,0xea},
{0xce,0xf5},
{0xcf,0xff},
/*Auto Gamma*/
{0xfe,0x00},
{0x5a,0x08},
{0x5b,0x0f},
{0x5c,0x15},
{0x5d,0x1c},
{0x5e,0x28},
{0x5f,0x36},
{0x60,0x45},
{0x61,0x51},
{0x62,0x6a},
{0x63,0x7d},
{0x64,0x8d},
{0x65,0x98},
{0x66,0xa2},
{0x67,0xb5},
{0x68,0xc3},
{0x69,0xcd},
{0x6a,0xd4},
{0x6b,0xdc},
{0x6c,0xe3},
{0x6d,0xf0},
{0x6e,0xf9},
{0x6f,0xff},
/*Gain*/
{0xfe,0x00},
{0x70,0x50},
/*AEC*/
{0xfe,0x00},
{0x4f,0x01},
{0xfe,0x01},
{0x0d,0x00},//08 add 20170110
{0x12,0xa0},
{0x13,0x3a},
{0x44,0x04},
{0x1f,0x30},
{0x20,0x40},
{0x26,0x9a},
{0x3e,0x20},
{0x3f,0x2d},
{0x40,0x40},
{0x41,0x5b},
{0x42,0x82},
{0x43,0xb7},
{0x04,0x0a},
{0x02,0x79},
{0x03,0xc0},
/*measure window*/
{0xfe,0x01},
{0xcc,0x08},
{0xcd,0x08},
{0xce,0xa4},
{0xcf,0xec},
/*DNDD*/
{0xfe,0x00},
{0x81,0xb8},
{0x82,0x12},
{0x83,0x0a},
{0x84,0x01},
{0x86,0x50},
{0x87,0x18},
{0x88,0x10},
{0x89,0x70},
{0x8a,0x20},
{0x8b,0x10},
{0x8c,0x08},
{0x8d,0x0a},
/*Intpee*/
{0xfe,0x00},
{0x8f,0xaa},
{0x90,0x9c},
{0x91,0x52},
{0x92,0x03},
{0x93,0x03},
{0x94,0x08},
{0x95,0x44},
{0x97,0x00},
{0x98,0x00},
/*ASDE*/
{0xfe,0x00},
{0xa1,0x30},
{0xa2,0x41},
{0xa4,0x30},
{0xa5,0x20},
{0xaa,0x30},
{0xac,0x32},
/*YCP*/
{0xfe,0x00},
{0xd1,0x3c},
{0xd2,0x3c},
{0xd3,0x38},
{0xd6,0xf4},
{0xd7,0x1d},
{0xdd,0x73},
{0xde,0x84},
{0xfe,0x00},
{0x05,0x01},
{0x06,0xad},
{0x07,0x00},
{0x08,0x10},
{0xfe,0x01},
{0x25,0x00},
{0x26,0x4d},
{0x27,0x01},
{0x28,0xce},
{0x29,0x03},
{0x2a,0x02},
{0x2b,0x03},
{0x2c,0x9c},
{0x2d,0x04},
{0x2e,0x36},
{0x2f,0x04},
{0x30,0xd0},
{0x31,0x05},
{0x32,0x6a},
{0x33,0x06},
{0x34,0x04},
{0xfe,0x00},
};
camI2cCfg_t gc032A_1sdrRegInfo[] =
{
{0xf3,0x83}, //sync_output_en data_output_en
{0xf5,0x0c},
{0xf7,0x01},
{0xf8,0x01},
{0xf9,0x4e},
{0xfa,0x30},
{0xfc,0x02},
{0xfe,0x02},
{0x81,0x03}, // doesn't show 0x81 addr
/*Analog*/
{0xfe,0x00},
{0x03,0x01}, // exposure high
{0x04,0xc2}, // exposure low
{0x05,0x01},
{0x06,0x91},
{0x07,0x00},
{0x08,0x10},
{0x0a,0x04},
{0x0c,0x04},
{0x0d,0x01},
{0x0e,0xe8}, // height: 488
{0x0f,0x02},
{0x10,0x88}, // width: 652 VGA: 640*480
{0x17,0x54},
{0x19,0x04},
{0x1a,0x0a},
{0x1f,0x40},
{0x20,0x30},
{0x2e,0x80},
{0x2f,0x2b},
{0x30,0x1a},
{0xfe,0x02},
{0x03,0x02},
{0x05,0xd7},
{0x06,0x60},
{0x08,0x80},
{0x12,0x89},
/*blk*/
{0xfe,0x00},
{0x18,0x02},
{0xfe,0x02},
{0x40,0x22},
{0x45,0x00},
{0x46,0x00},
{0x49,0x20},
{0x4b,0x3c},
{0x50,0x20},
{0x42,0x10},
/*isp*/
{0xfe,0x01},
{0x0a,0xc5},
{0x45,0x00},
{0xfe,0x00},
{0x40,0xff},
{0x41,0x25},
{0x42,0x83},
{0x43,0x10},
{0x44,0x83},
{0x46,0x26},
{0x49,0x03},
{0x4f,0x01},
{0xde,0x84},
{0xfe,0x02},
{0x22,0xf6},
/*Shading*/
{0xfe,0x00},
{0x77,0x65},
{0x78,0x40},
{0x79,0x52},
{0xfe,0x01},
{0xc1,0x3c},
{0xc2,0x50},
{0xc3,0x00},
{0xc4,0x32},
{0xc5,0x24},
{0xc6,0x16},
{0xc7,0x08},
{0xc8,0x08},
{0xc9,0x00},
{0xca,0x20},
{0xdc,0x7a},
{0xdd,0x7a},
{0xde,0xa6},
{0xdf,0x60},
/*AWB*/
{0xfe,0x01},
{0x7c,0x09},
{0x65,0x06},
{0x7c,0x08},
{0x56,0xf4},
{0x66,0x0f},
{0x67,0x84},
{0x6b,0x80},
{0x6d,0x12},
{0x6e,0xb0},
{0x86,0x00},
{0x87,0x00},
{0x88,0x00},
{0x89,0x00},
{0x8a,0x00},
{0x8b,0x00},
{0x8c,0x00},
{0x8d,0x00},
{0x8e,0x00},
{0x8f,0x00},
{0x90,0xef},
{0x91,0xe1},
{0x92,0x0c},
{0x93,0xef},
{0x94,0x65},
{0x95,0x1f},
{0x96,0x0c},
{0x97,0x2d},
{0x98,0x20},
{0x99,0xaa},
{0x9a,0x3f},
{0x9b,0x2c},
{0x9c,0x5f},
{0x9d,0x3e},
{0x9e,0xaa},
{0x9f,0x67},
{0xa0,0x60},
{0xa1,0x00},
{0xa2,0x00},
{0xa3,0x0a},
{0xa4,0xb6},
{0xa5,0xac},
{0xa6,0xc1},
{0xa7,0xac},
{0xa8,0x55},
{0xa9,0xc3},
{0xaa,0xa4},
{0xab,0xba},
{0xac,0xa8},
{0xad,0x55},
{0xae,0xc8},
{0xaf,0xb9},
{0xb0,0xd4},
{0xb1,0xc3},
{0xb2,0x55},
{0xb3,0xd8},
{0xb4,0xce},
{0xb5,0x00},
{0xb6,0x00},
{0xb7,0x05},
{0xb8,0xd6},
{0xb9,0x8c},
/*CC*/
{0xfe,0x01},
{0xd0,0x40},
{0xd1,0xf8},
{0xd2,0x00},
{0xd3,0xfa},
{0xd4,0x45},
{0xd5,0x02},
{0xd6,0x30},
{0xd7,0xfa},
{0xd8,0x08},
{0xd9,0x08},
{0xda,0x58},
{0xdb,0x02},
{0xfe,0x00},
/*Gamma*/
{0xfe,0x00},
{0xba,0x00},
{0xbb,0x04},
{0xbc,0x0a},
{0xbd,0x0e},
{0xbe,0x22},
{0xbf,0x30},
{0xc0,0x3d},
{0xc1,0x4a},
{0xc2,0x5d},
{0xc3,0x6b},
{0xc4,0x7a},
{0xc5,0x85},
{0xc6,0x90},
{0xc7,0xa5},
{0xc8,0xb5},
{0xc9,0xc2},
{0xca,0xcc},
{0xcb,0xd5},
{0xcc,0xde},
{0xcd,0xea},
{0xce,0xf5},
{0xcf,0xff},
/*Auto Ga*/
{0xfe,0x00},
{0x5a,0x08},
{0x5b,0x0f},
{0x5c,0x15},
{0x5d,0x1c},
{0x5e,0x28},
{0x5f,0x36},
{0x60,0x45},
{0x61,0x51},
{0x62,0x6a},
{0x63,0x7d},
{0x64,0x8d},
{0x65,0x98},
{0x66,0xa2},
{0x67,0xb5},
{0x68,0xc3},
{0x69,0xcd},
{0x6a,0xd4},
{0x6b,0xdc},
{0x6c,0xe3},
{0x6d,0xf0},
{0x6e,0xf9},
{0x6f,0xff},
/*Gain*/
{0xfe,0x00},
{0x70,0x50},
/*AEC*/
{0xfe,0x00},
{0x4f,0x01},
{0xfe,0x01},
{0x12,0xa0},
{0x13,0x3a},
{0x44,0x04},
{0x1f,0x30},
{0x20,0x40},
{0x26,0x14},
{0x27,0x01},
{0x28,0xf4},
{0x29,0x02},
{0x2a,0x3a},
{0x2b,0x02},
{0x2c,0xac},
{0x2d,0x02},
{0x2e,0xf8},
{0x2f,0x0b},
{0x30,0x6e},
{0x31,0x0e},
{0x32,0x70},
{0x33,0x12},
{0x34,0x0c},
{0x3c,0x00},
{0x3e,0x20},
{0x3f,0x2d},
{0x40,0x40},
{0x41,0x5b},
{0x42,0x82},
{0x43,0xb7},
{0x04,0x0a},
{0x02,0x79},
{0x03,0xc0},
/*measure*/
{0xcc,0x08},
{0xcd,0x08},
{0xce,0xa4},
{0xcf,0xec},
/*DNDD*/
{0xfe,0x00},
{0x81,0xb8},
{0x82,0x12},
{0x83,0x0a},
{0x84,0x01},
{0x86,0x50},
{0x87,0x18},
{0x88,0x10},
{0x89,0x70},
{0x8a,0x20},
{0x8b,0x10},
{0x8c,0x08},
{0x8d,0x0a},
/*Intpee*/
{0xfe,0x00},
{0x8f,0xaa},
{0x90,0x9c},
{0x91,0x52},
{0x92,0x03},
{0x93,0x03},
{0x94,0x08},
{0x95,0x44},
{0x97,0x00},
{0x98,0x00},
/*ASDE*/
{0xfe,0x00},
{0xa1,0x30},
{0xa2,0x41},
{0xa4,0x30},
{0xa5,0x20},
{0xaa,0x30},
{0xac,0x32},
/*YCP*/
{0xfe,0x00},
{0xd1,0x3c},
{0xd2,0x3c},
{0xd3,0x38},
{0xd6,0xf4},
{0xd7,0x1d},
{0xdd,0x73},
{0xde,0x84},
/*SPI*/
{0xfe,0x03}, // registers in REGF3
{0x51,0x01},
{0x52,0x0a}, // Y: 266
{0x53,0x20}, // ֻ<><D6BB>2bit<69><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x20?
{0x54,0x20}, // X: 0x220 = 544
{0x55,0x00},
{0x59,0x10},
{0x5a,0x00}, // sync format<61><74>
{0x5b,0x80},
{0x5c,0x02}, // image width<74><68>640
{0x5d,0xe0},
{0x5e,0x01}, // image height<68><74>480
};
uint16_t gc032aGetRegCnt(char* regName)
{
if (strcmp(regName, "gc032a_2sdr") == 0)
{
return (sizeof(gc032A_2sdrRegInfo) / sizeof(gc032A_2sdrRegInfo[0]));
}
else if (strcmp(regName, "gc032a_1sdr") == 0)
{
return (sizeof(gc032A_1sdrRegInfo) / sizeof(gc032A_1sdrRegInfo[0]));
}
return 0;
}

View File

@@ -0,0 +1,360 @@
#include "cameraDrv.h"
camI2cCfg_t gc6123_2sdrRegInfo[] =
{
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xf1, 0x07}, //output enable
{0xf4, 0x00},
//{0xf7, 0x00},
//{0xfa, 0x00},
{0xfc, 0x16}, //clock enable
{0xfe , 0x00},
{0x08, 0x02}, //col start
{0x09, 0x01}, //window height
{0x0a, 0x48},
{0x0b, 0x00}, //window width
{0x0c, 0xf4},
{0x10, 0x48}, //sh_width
{0x11, 0x1d}, //tx_width
{0x14, 0x14}, //dark CFA
{0x15, 0x0a}, //sdark
{0x16, 0x04}, //AD pipe number
{0x18, 0xc2}, //rowsg_gap
{0x1a, 0x17}, //clk_delay_en
{0x1b, 0x1a}, //20121107 comv_r solve FPN-W/18 //70/adclk mode
{0x1c, 0x49}, //txhigh_en
{0x1d, 0xb0}, //vref
{0x1e, 0x52}, //20131231/53//20130306/52 //20121107 solve OBI/51 //ADC_r
//{0x1f, 0x3f},
/////////////////////////////////////////////////////
////////////////////// ISP //////////////////////
/////////////////////////////////////////////////////
{0x20,0x5e},
{0x21,0x38}, //autogray
{0x22,0x92}, //20121107 auto_DD_en/82 //02
{0x24,0xa2}, //output_format
{0x26,0x03},
{0x27,0x90}, //clock gating
{0x28,0x8c},
{0x38,0x80}, //crop
{0x3b,0x01},
{0x3c,0x40},
{0x3d,0x00},
{0x3e,0xf0},
/////////////////////////////////////////////////////
////////////////////// BLK //////////////////////
/////////////////////////////////////////////////////
{0x2a, 0x65}, //2f/BLK row select
{0x2c, 0x40}, //global offset
/////////////////////////////////////////////////////
////////////////////// GAIN /////////////////////
/////////////////////////////////////////////////////
{0x3f, 0x12}, //20/global gain
/////////////////////////////////////////////////////
////////////////////// DNDD /////////////////////
/////////////////////////////////////////////////////
{0x50, 0x45},
{0x52, 0x4f}, //6c/DN b
{0x53, 0x81}, //a5/DN C
{0x58, 0x6f}, //20121107 dark_th 64
{0xc3, 0x96}, //00
/////////////////////////////////////////////////////
////////////////////// ASDE /////////////////////
/////////////////////////////////////////////////////
{0xac, 0xb5},
{0x5c, 0x80}, //60/OT_th
/////////////////////////////////////////////////////
///////////////////// INTPEE ////////////////////
/////////////////////////////////////////////////////
{0x63, 0x03}, //04/edge effect
{0x65, 0x23}, //43/42/edge max/min
/////////////////////////////////////////////////////
///////////////////// GAMMA /////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
////////////////////// CC ///////////////////////
/////////////////////////////////////////////////////
{0x66, 0x13},
{0x67, 0x26},
{0x68, 0x07},
{0x69, 0xf5},
{0x6a, 0xea},
{0x6b, 0x21},
{0x6c, 0x21},
{0x6d, 0xe4},
{0x6e, 0xfb},
/////////////////////////////////////////////////////
////////////////////// YCP //////////////////////
/////////////////////////////////////////////////////
{0x81, 0x48}, //38//cb
{0x82, 0x48}, //38//cr
{0x83, 0x4b}, //40/luma contrast
{0x84, 0x80}, //90/contrast center
{0x85, 0x00}, //06/luma offset
{0x86, 0xfb}, //skin cb
{0x87, 0x1d}, //skin cr
{0x88, 0x18}, //skin radius
{0x8d, 0x78}, //38/edge dec sa
{0x8e, 0x25}, //autogray
/////////////////////////////////////////////////////
////////////////////// AEC //////////////////////
/////////////////////////////////////////////////////
{0xa4, 0x01},
{0x9e, 0x01}, // increase fps
{0x9f, 0x90}, // 0x1c
{0xa0, 0x10},
{0x90, 0x4a}, //0a //48
{0x92, 0x40}, //40/target Y
{0xa2, 0x40}, //max_post_gain
{0xa3, 0x80}, //max_pre_gain
/////////////////////////////////////////////////////
////////////////////// AWB //////////////////////
/////////////////////////////////////////////////////
{0xb0, 0xf8}, //f5/RGB high low
{0xb1, 0x24}, //18/Y to C
{0xb3, 0x20}, //0d/C max
{0xb4, 0x2d}, //22/C inter
{0xb5, 0x1b}, //22/C inter
{0xb6, 0x2e}, //C inter2
{0xb7, 0x18}, //40/C inter3
{0xb8, 0x13}, //20/number limit
{0xb9, 0x33},
{0xba, 0x21},
{0xbb, 0x61}, //42/speed & margin
{0xbf, 0x68}, //78/b limit
{0x4c, 0x08},
{0x4d, 0x06},
{0x4e, 0x7b},
{0x4f, 0xa0},
{0xfe, 0x02},
{0x01, 0x03},
{0x02, 0x02}, //LSB & Falling edge sample
//{0x03, 0x20}, //1-wire
{0x04, 0x20}, //[4] master_outformat
{0x05, 0x00},
{0x09, 0x00}, //Reverse the high<->low byte.
{0x0a, 0x00}, //Data ID, 0x00-YUV422, 0x01-RGB565
{0x13, 0xf0},
/////////////////////////////////////////////////////
///////////////////// 2-wire ////////////////////
/////////////////////////////////////////////////////
{0x03, 0x25}, //20
{0xfd, 0x04},
{0xf1, 0x07}, //00
/////////////////////////////////////////////////////
///////////////////// 1-wire ////////////////////
/////////////////////////////////////////////////////
//{0x03, 0x20}, //20
//{0xfd, 0x00}, //00
//{0xf1, 0x05},
{0xfe, 0x00},
};
camI2cCfg_t gc6123_1sdrRegInfo[] =
{
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xf1, 0x07}, //output enable
{0xf4, 0x00},
//{0xf7, 0x00},
//{0xfa, 0x00},
{0xfc, 0x16}, //clock enable
{0xfe , 0x00},
{0x08, 0x02}, //col start
{0x09, 0x01}, //window height
{0x0a, 0x48},
{0x0b, 0x00}, //window width
{0x0c, 0xf4},
{0x10, 0x48}, //sh_width
{0x11, 0x1d}, //tx_width
{0x14, 0x14}, //dark CFA
{0x15, 0x0a}, //sdark
{0x16, 0x04}, //AD pipe number
{0x18, 0xc2}, //rowsg_gap
{0x1a, 0x17}, //clk_delay_en
{0x1b, 0x1a}, //20121107 comv_r solve FPN-W/18 //70/adclk mode
{0x1c, 0x49}, //txhigh_en
{0x1d, 0xb0}, //vref
{0x1e, 0x52}, //20131231/53//20130306/52 //20121107 solve OBI/51 //ADC_r
//{0x1f, 0x3f},
/////////////////////////////////////////////////////
////////////////////// ISP //////////////////////
/////////////////////////////////////////////////////
{0x20,0x5e},
{0x21,0x38}, //autogray
{0x22,0x92}, //20121107 auto_DD_en/82 //02
{0x24,0xa2}, //output_format
{0x26,0x03},
{0x27,0x90}, //clock gating
{0x28,0x8c},
{0x38,0x80}, //crop
{0x3b,0x01},
{0x3c,0x40},
{0x3d,0x00},
{0x3e,0xf0},
/////////////////////////////////////////////////////
////////////////////// BLK //////////////////////
/////////////////////////////////////////////////////
{0x2a, 0x65}, //2f/BLK row select
{0x2c, 0x40}, //global offset
/////////////////////////////////////////////////////
////////////////////// GAIN /////////////////////
/////////////////////////////////////////////////////
{0x3f, 0x12}, //20/global gain
/////////////////////////////////////////////////////
////////////////////// DNDD /////////////////////
/////////////////////////////////////////////////////
{0x50, 0x45},
{0x52, 0x4f}, //6c/DN b
{0x53, 0x81}, //a5/DN C
{0x58, 0x6f}, //20121107 dark_th 64
{0xc3, 0x96}, //00
/////////////////////////////////////////////////////
////////////////////// ASDE /////////////////////
/////////////////////////////////////////////////////
{0xac, 0xb5},
{0x5c, 0x80}, //60/OT_th
/////////////////////////////////////////////////////
///////////////////// INTPEE ////////////////////
/////////////////////////////////////////////////////
{0x63, 0x03}, //04/edge effect
{0x65, 0x23}, //43/42/edge max/min
/////////////////////////////////////////////////////
///////////////////// GAMMA /////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
////////////////////// CC ///////////////////////
/////////////////////////////////////////////////////
{0x66, 0x13},
{0x67, 0x26},
{0x68, 0x07},
{0x69, 0xf5},
{0x6a, 0xea},
{0x6b, 0x21},
{0x6c, 0x21},
{0x6d, 0xe4},
{0x6e, 0xfb},
/////////////////////////////////////////////////////
////////////////////// YCP //////////////////////
/////////////////////////////////////////////////////
{0x81, 0x48}, //38//cb
{0x82, 0x48}, //38//cr
{0x83, 0x4b}, //40/luma contrast
{0x84, 0x80}, //90/contrast center
{0x85, 0x00}, //06/luma offset
{0x86, 0xfb}, //skin cb
{0x87, 0x1d}, //skin cr
{0x88, 0x18}, //skin radius
{0x8d, 0x78}, //38/edge dec sa
{0x8e, 0x25}, //autogray
/////////////////////////////////////////////////////
////////////////////// AEC //////////////////////
/////////////////////////////////////////////////////
{0xa4, 0x01},
{0x9e, 0x01}, // 0x02
{0x9f, 0x90}, // 0x1c
{0xa0, 0x10},
{0x90, 0x4a}, //0a //48
{0x92, 0x40}, //40/target Y
{0xa2, 0x40}, //max_post_gain
{0xa3, 0x80}, //max_pre_gain
/////////////////////////////////////////////////////
////////////////////// AWB //////////////////////
/////////////////////////////////////////////////////
{0xb0, 0xf8}, //f5/RGB high low
{0xb1, 0x24}, //18/Y to C
{0xb3, 0x20}, //0d/C max
{0xb4, 0x2d}, //22/C inter
{0xb5, 0x1b}, //22/C inter
{0xb6, 0x2e}, //C inter2
{0xb7, 0x18}, //40/C inter3
{0xb8, 0x13}, //20/number limit
{0xb9, 0x33},
{0xba, 0x21},
{0xbb, 0x61}, //42/speed & margin
{0xbf, 0x68}, //78/b limit
{0x4c, 0x08},
{0x4d, 0x06},
{0x4e, 0x7b},
{0x4f, 0xa0},
{0xfe, 0x02},
{0x01, 0x03},
{0x02, 0x02}, //LSB & Falling edge sample
//{0x03, 0x20}, //1-wire
{0x04, 0x20}, //[4] master_outformat
{0x05, 0x00},
{0x09, 0x00}, //Reverse the high<->low byte.
{0x0a, 0x00}, //Data ID, 0x00-YUV422, 0x01-RGB565
{0x13, 0xf0},
/////////////////////////////////////////////////////
///////////////////// 2-wire ////////////////////
/////////////////////////////////////////////////////
// {0x03, 0x25}, //20
// {0xfd, 0x04},
// {0xf1, 0x07}, //00
/////////////////////////////////////////////////////
///////////////////// 1-wire ////////////////////
/////////////////////////////////////////////////////
{0x03, 0x20}, //20
{0xfd, 0x00}, //00
{0xf1, 0x05},
{0xfe, 0x00},
};
uint16_t gc6123GetRegCnt(char* regName)
{
if (strcmp(regName, "gc6123_2sdr") == 0)
{
return (sizeof(gc6123_2sdrRegInfo) / sizeof(gc6123_2sdrRegInfo[0]));
}
else if (strcmp(regName, "gc6123_1sdr") == 0)
{
return (sizeof(gc6123_1sdrRegInfo) / sizeof(gc6123_1sdrRegInfo[0]));
}
return 0;
}

View File

@@ -0,0 +1,171 @@
#include "cameraDrv.h"
camI2cCfg_t gc6153_1sdrRegInfo[] =
{
// SYS
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xfe, 0xa0},
{0xfa, 0x11},
{0xfc, 0x00},
{0xf6, 0x00},
{0xfc, 0x12},
// ANALOG & CISCTL
{0xfe, 0x00},
{0x01, 0x40},
{0x02, 0x12},
{0x0d, 0x40},
{0x14, 0x7c}, // 0x7e
{0x16, 0x05}, // 0x05
{0x17, 0x18}, // 0x18
{0x1c, 0x31},
{0x1d, 0xbb},
{0x1f, 0x3f},
{0x73, 0x20},
{0x74, 0x71},
{0x77, 0x22},
{0x7a, 0x08},
{0x11, 0x18},
{0x13, 0x48},
{0x12, 0xc8},
{0x70, 0xc8},
{0x7b, 0x18},
{0x7d, 0x30},
{0x7e, 0x02},
{0xfe, 0x10},
{0xfe, 0x00},
{0xfe, 0x00},
{0xfe, 0x00},
{0xfe, 0x00},
{0xfe, 0x00},
{0xfe, 0x10},
{0xfe, 0x00},
{0x49, 0x61},
{0x4a, 0x40},
{0x4b, 0x58},
/*ISP*/
{0xfe, 0x00},
{0x39, 0x02},
{0x3a, 0x80},
{0x20, 0x7e},
{0x26, 0xa7},
/*BLK*/
{0x33, 0x10},
{0x37, 0x06},
{0x2a, 0x21},
/*GAIN*/
{0x3f, 0x16},
/*DNDD*/
{0x52, 0xa6},
{0x53, 0x81},
{0x54, 0x43},
{0x56, 0x78},
{0x57, 0xaa},
{0x58, 0xff},
/*ASDE*/
{0x5b, 0x60},
{0x5c, 0x50},
{0xab, 0x2a},
{0xac, 0xb5},
/*INTPEE*/
{0x5e, 0x06},
{0x5f, 0x06},
{0x60, 0x44},
{0x61, 0xff},
{0x62, 0x69},
{0x63, 0x13},
/*CC*/
{0x65, 0x13},
{0x66, 0x26},
{0x67, 0x07},
{0x68, 0xf5},
{0x69, 0xea},
{0x6a, 0x21},
{0x6b, 0x21},
{0x6c, 0xe4},
{0x6d, 0xfb},
/*YCP*/
{0x81, 0x3b}, // 0
{0x82, 0x3b}, // 0 : uyvy <20>ڰ<EFBFBD>
{0x83, 0x4b},
{0x84, 0x90},
{0x86, 0xf0},
{0x87, 0x1d},
{0x88, 0x16},
{0x8d, 0x74},
{0x8e, 0x25},
/*AEC*/
{0x90, 0x36},
{0x92, 0x43},
{0x9d, 0x32},
{0x9e, 0x81},
{0x9f, 0xf4},
{0xa0, 0xa0},
{0xa1, 0x04},
{0xa3, 0x2d},
{0xa4, 0x01},
/*AWB*/
{0xb0, 0xc2},
{0xb1, 0x1e},
{0xb2, 0x10},
{0xb3, 0x20},
{0xb4, 0x2d},
{0xb5, 0x1b},
{0xb6, 0x2e},
{0xb8, 0x13},
{0xba, 0x60},
{0xbb, 0x62},
{0xbd, 0x78},
{0xbe, 0x55},
{0xbf, 0xa0},
{0xc4, 0xe7},
{0xc5, 0x15},
{0xc6, 0x16},
{0xc7, 0xeb},
{0xc8, 0xe4},
{0xc9, 0x16},
{0xca, 0x16},
{0xcb, 0xe9},
{0x22, 0xf8},
/*SPI*/
{0xfe, 0x02},
{0x01, 0x01},
{0x02, 0x02},
{0x03, 0x20},
{0x04, 0x20},
{0x0a, 0x00},
{0x13, 0x10},
{0x24, 0x00},
{0x28, 0x03},
{0xfe, 0x00},
/*OUTPUT*/
{0xf2, 0x03},
{0xfe, 0x00},
};
uint16_t gc6153GetRegCnt(char* regName)
{
if (strcmp(regName, "gc6153_1sdr") == 0)
{
return (sizeof(gc6153_1sdrRegInfo) / sizeof(gc6153_1sdrRegInfo[0]));
}
return 0;
}

View File

@@ -0,0 +1,149 @@
#include "i2cGpio.h"
// We only act as I2C master
typedef enum
{
INPUT,
OUTPUT,
}pinDirection_e;
static void setSdaDirection(pinDirection_e direction)
{
GpioPinConfig_t config;
if (direction == INPUT)
{
config.pinDirection = GPIO_DIRECTION_INPUT;
config.misc.interruptConfig = GPIO_INTERRUPT_DISABLED;
GPIO_pinConfig(SDA_GPIO_INSTANCE, SDA_GPIO_PIN, &config);
}
else
{
config.pinDirection = GPIO_DIRECTION_OUTPUT;
//config.initOutput = 0;
GPIO_pinConfig(SDA_GPIO_INSTANCE, SDA_GPIO_PIN, &config);
}
}
void i2cStart()
{
I2C_SDA_1;
I2C_SCL_1;
delay_us(20);
I2C_SDA_0;
delay_us(19);
I2C_SCL_0;
}
void i2cStop()
{
setSdaDirection(OUTPUT);
I2C_SDA_0;
I2C_SCL_1;
delay_us(18);
I2C_SDA_1;
delay_us(18);
}
static uint32_t i2cSdaRead()
{
return (((((GPIO_TypeDef *) (MP_GPIO_BASE_ADDR + 0x1000*SDA_GPIO_INSTANCE))->DATA) >> SDA_GPIO_PIN) & 0x01);
}
void i2cWritebyte(uint8_t byte)
{
setSdaDirection(OUTPUT);
for (uint8_t i=0; i<8; i++)
{
I2C_SCL_0;
delay_us(18);
// Send data every bit
if (byte&0x80)
{
I2C_SDA_1;
}
else
{
I2C_SDA_0;
}
byte <<= 1;
I2C_SCL_1;
delay_us(18);
}
I2C_SCL_0;
delay_us(18);
I2C_SDA_1;
delay_us(18);
}
void i2cAck()
{
uint8_t i = 0;
setSdaDirection(INPUT);
I2C_SCL_1;
delay_us(18);
while ((i2cSdaRead()==1) && (i<255))
i++;
I2C_SCL_0;
delay_us(18);
setSdaDirection(OUTPUT);
}
uint8_t i2cReadByte()
{
uint8_t i, receveData = 0;
setSdaDirection(INPUT);
delay_us(18);
for (i = 0; i < 8; i++)
{
I2C_SCL_1;
delay_us(18);
receveData |= (i2cSdaRead() << (7-i));
I2C_SCL_0;
delay_us(18);
}
setSdaDirection(OUTPUT);
return receveData;
}
void i2cGpioInit()
{
PadConfig_t config;
PAD_getDefaultConfig(&config);
// scl pin
config.mux = SCL_PAD_ALT_FUNC;
PAD_setPinConfig(SCL_GPIO_ADDR, &config);
GpioPinConfig_t gpioCfg;
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
gpioCfg.misc.initOutput= 1;
GPIO_pinConfig(SCL_GPIO_INSTANCE, SCL_GPIO_PIN, &gpioCfg);
// sda pin
config.mux = SDA_PAD_ALT_FUNC;
PAD_setPinConfig(SDA_GPIO_ADDR, &config);
gpioCfg.pinDirection = GPIO_DIRECTION_OUTPUT;
gpioCfg.misc.initOutput= 1;
GPIO_pinConfig(SDA_GPIO_INSTANCE, SDA_GPIO_PIN, &gpioCfg);
}

View File

@@ -0,0 +1,349 @@
#include "cameraDrv.h"
camI2cCfg_t sp0821_2sdrRegInfo[] =
{
{0x30,0x01},
{0x32,0x00},
{0x03,0x00},
{0x04,0x96},
{0x24,0x13},
{0x9b,0x32},
{0xd7,0x00},
{0xc5,0xc7},
{0xc6,0xe2},
{0xe7,0x03},
{0x32,0x00},
{0x32,0x01},
{0x32,0x00},
{0xbf,0x0f},
{0xba,0x5a},
{0xbb,0x69},
{0xe7,0x00},
{0x32,0x07},
{0x31,0x03},
{0x19,0x04},
{0x2c,0x0f},
{0x2e,0x3c},
{0x30,0x01},
{0x28,0x2e},
{0x29,0x1f},
{0x0f,0x30},
{0x14,0xb0},
{0x38,0x50},
{0x39,0x52},
{0x3a,0x60},
{0x3b,0x10},
{0x3c,0xe0},
{0x85,0x01},
{0xe0,0x02},
{0xe5,0x60},
{0xf5,0x02},
{0xf1,0x03},
{0xf3,0x40},
{0x41,0x00},
{0x05,0x00},
{0x06,0x00},
{0x07,0x00},
{0x08,0x00},
{0x09,0x00},
{0x0a,0x34},
{0x0D,0x01},
{0xc8,0x10},
{0x29,0x1e},
{0xa2,0x26},
{0xa3,0x02},
{0xa4,0x32},
{0xa5,0x00},
{0xa8,0x32},
{0xa9,0x00},
{0xaa,0x01},
{0xab,0x00},
{0x4c,0x80},
{0x4d,0x80},
{0xa6,0xf0},
{0xa7,0x20},
{0xac,0xf0},
{0xad,0x20},
{0x8a,0x3e},
{0x8b,0x30},
{0x8c,0x2a},
{0x8d,0x26},
{0x8e,0x26},
{0x8f,0x24},
{0x90,0x24},
{0x91,0x22},
{0x92,0x22},
{0x93,0x22},
{0x94,0x20},
{0x95,0x20},
{0x96,0x20},
{0x17,0x88},
{0x18,0x80},
{0x4e,0x78},
{0x4f,0x78},
{0x58,0x8a},
{0x59,0xa8},
{0x5a,0x80},
{0xca,0x00},
{0x86,0x08},
{0x87,0x0f},
{0x88,0x30},
{0x89,0x45},
{0x9e,0x94},
{0x9f,0x88},
{0x97,0x84},
{0x98,0x88},
{0x99,0x74},
{0x9a,0x84},
{0xa0,0x7c},
{0xa1,0x78},
{0x9d,0x09},
{0xB1,0x04},
{0xb3,0x00},
{0x47,0x40},
{0xb8,0x04},
{0xb9,0x28},
{0x3f,0x18},
{0xc1,0xff},
{0xc2,0x40},
{0xc3,0xff},
{0xc4,0x40},
{0xc5,0xc7},
{0xc6,0xe2},
{0xc7,0xef},
{0xc8,0x10},
{0x50,0x2a},
{0x51,0x2a},
{0x52,0x2f},
{0x53,0xcf},
{0x54,0xd0},
{0x5c,0x1e},
{0x5d,0x21},
{0x5e,0x1a},
{0x5f,0xe9},
{0x60,0x98},
{0xcb,0x3f},
{0xcc,0x3f},
{0xcd,0x3f},
{0xce,0x85},
{0xcf,0xff},
{0x79,0x5a},
{0x7a,0xDC},
{0x7b,0x0A},
{0x7c,0xFD},
{0x7d,0x46},
{0x7e,0xFD},
{0x7f,0xFD},
{0x80,0xEF},
{0x81,0x54},
{0x1b,0x0a},
{0x1c,0x0f},
{0x1d,0x15},
{0x1e,0x15},
{0x1f,0x15},
{0x20,0x1f},
{0x21,0x2a},
{0x22,0x2a},
{0x56,0x49},
{0x1a,0x14},
{0x34,0x1f},
{0x82,0x10},
{0x83,0x00},
{0x84,0xff},
{0xd7,0x50},
{0xd8,0x1a},
{0xd9,0x20},
{0xc9,0x1f},
{0xbf,0x33},
{0xba,0x37},
{0xbb,0x38},
{0x19,0x04},
{0x34,0x1f},
{0x30,0x01},
{0x2e,0x2c},//0x29
{0x2c,0x0f},
};
camI2cCfg_t sp0821_1sdrRegInfo[] =
{
{0x30,0x01},
{0x32,0x00},
{0x03,0x00},
{0x04,0x96},
{0x24,0x13},
{0x9b,0x32},
{0xd7,0x00},
{0xc5,0xc7},
{0xc6,0xe2},
{0xe7,0x03},
{0x32,0x00},
{0x32,0x01},
{0x32,0x00},
{0xbf,0x0f},
{0xba,0x5a},
{0xbb,0x69},
{0xe7,0x00},
{0x32,0x07},
{0x31,0x03},
{0x19,0x04},
{0x2c,0x0f},
{0x2e,0x3c},
{0x30,0x01},
{0x28,0x2e},
{0x29,0x1f},
{0x0f,0x30},
{0x14,0xb0},
{0x38,0x50},
{0x39,0x52},
{0x3a,0x60},
{0x3b,0x10},
{0x3c,0xe0},
{0x85,0x01},
{0xe0,0x02},
{0xe5,0x60},
{0xf5,0x02},
{0xf1,0x03},
{0xf3,0x40},
{0x41,0x00},
{0x05,0x00},
{0x06,0x00},
{0x07,0x00},
{0x08,0x00},
{0x09,0x00},
{0x0a,0x34},
{0x0D,0x01},
{0xc8,0x10},
{0x29,0x1e},
{0xa2,0x26},
{0xa3,0x02},
{0xa4,0x32},
{0xa5,0x00},
{0xa8,0x32},
{0xa9,0x00},
{0xaa,0x01},
{0xab,0x00},
{0x4c,0x80},
{0x4d,0x80},
{0xa6,0xf0},
{0xa7,0x20},
{0xac,0xf0},
{0xad,0x20},
{0x8a,0x3e},
{0x8b,0x30},
{0x8c,0x2a},
{0x8d,0x26},
{0x8e,0x26},
{0x8f,0x24},
{0x90,0x24},
{0x91,0x22},
{0x92,0x22},
{0x93,0x22},
{0x94,0x20},
{0x95,0x20},
{0x96,0x20},
{0x17,0x88},
{0x18,0x80},
{0x4e,0x78},
{0x4f,0x78},
{0x58,0x8a},
{0x59,0xa8},
{0x5a,0x80},
{0xca,0x00},
{0x86,0x08},
{0x87,0x0f},
{0x88,0x30},
{0x89,0x45},
{0x9e,0x94},
{0x9f,0x88},
{0x97,0x84},
{0x98,0x88},
{0x99,0x74},
{0x9a,0x84},
{0xa0,0x7c},
{0xa1,0x78},
{0x9d,0x09},
{0xB1,0x04},
{0xb3,0x00},
{0x47,0x40},
{0xb8,0x04},
{0xb9,0x28},
{0x3f,0x18},
{0xc1,0xff},
{0xc2,0x40},
{0xc3,0xff},
{0xc4,0x40},
{0xc5,0xc7},
{0xc6,0xe2},
{0xc7,0xef},
{0xc8,0x10},
{0x50,0x2a},
{0x51,0x2a},
{0x52,0x2f},
{0x53,0xcf},
{0x54,0xd0},
{0x5c,0x1e},
{0x5d,0x21},
{0x5e,0x1a},
{0x5f,0xe9},
{0x60,0x98},
{0xcb,0x3f},
{0xcc,0x3f},
{0xcd,0x3f},
{0xce,0x85},
{0xcf,0xff},
{0x79,0x5a},
{0x7a,0xDC},
{0x7b,0x0A},
{0x7c,0xFD},
{0x7d,0x46},
{0x7e,0xFD},
{0x7f,0xFD},
{0x80,0xEF},
{0x81,0x54},
{0x1b,0x0a},
{0x1c,0x0f},
{0x1d,0x15},
{0x1e,0x15},
{0x1f,0x15},
{0x20,0x1f},
{0x21,0x2a},
{0x22,0x2a},
{0x56,0x49},
{0x1a,0x14},
{0x34,0x1f},
{0x82,0x10},
{0x83,0x00},
{0x84,0xff},
{0xd7,0x50},
{0xd8,0x1a},
{0xd9,0x20},
{0xc9,0x1f},
{0xbf,0x33},
{0xba,0x37},
{0xbb,0x38},
{0x19,0x04},
{0x34,0x1f},
{0x30,0x01},
{0x2e,0x2c},//0x29
{0x2c,0x0f},
};
uint16_t sp0821GetRegCnt(char* regName)
{
if (strcmp(regName, "sp0821_2sdr") == 0)
{
return (sizeof(sp0821_2sdrRegInfo) / sizeof(sp0821_2sdrRegInfo[0]));
}
else if (strcmp(regName, "sp0821_1sdr") == 0)
{
return (sizeof(sp0821_1sdrRegInfo) / sizeof(sp0821_1sdrRegInfo[0]));
}
return 0;
}

View File

@@ -0,0 +1,740 @@
#include "cameraDrv.h"
camI2cCfg_t sp0A39_2sdrRegInfo[] =
{
{0xfd,0x00},
{0x1d,0x25},
{0x31,0x04},
{0x32,0x01},
{0x30,0x01},
{0xfd,0x01},
{0x5d,0x01},
{0x34,0xe3},
{0x35,0x10},
{0xfd,0x00},
{0xf0,0xff},
{0xf1,0xff},
{0xf2,0xff},
{0xf3,0xff},
{0xfc,0x50},
{0xfd,0x00},
{0x03,0x00},
{0x04,0xf0},
{0x24,0x10},
{0xef,0x40},
{0x06,0x00},
{0x09,0x00},
{0x0a,0x46},
{0x10,0x07},
{0x11,0x04},
{0x16,0x01},
{0x19,0x22},
{0x1e,0x58},
{0x29,0x48},
{0x13,0x37},
{0x14,0x01},
{0x25,0x01},
{0x2a,0x06},
{0x27,0x01},
{0x54,0x00},
{0x55,0x10},
{0x58,0x38},
{0x5d,0x12},
{0x63,0x00},
{0x64,0x00},
{0x66,0x28},
{0x68,0x2a},
{0x72,0x3a},
{0x73,0x0a},
{0x75,0x48},
{0x76,0x0a},
{0x1f,0x77},
{0x20,0x07},
{0xfb,0x16},
{0xfd,0x01},
{0xf2,0x69},
{0xf7,0x28},
{0x02,0x10},
{0x03,0x01},
{0x06,0x28},
{0x08,0x01},
{0xfd,0x02},
{0xb8,0x50},
{0xb9,0xff},
{0xba,0x40},
{0xbb,0x45},
{0xbc,0xc0},
{0xbd,0x50},
{0xbe,0x80},
{0xbf,0x02},
{0xd0,0x80},
{0xd1,0x02},
{0xfd,0x01},
{0xc0,0x1f},
{0xc1,0x18},
{0xc2,0x15},
{0xc3,0x13},
{0xc4,0x13},
{0xc5,0x12},
{0xc6,0x12},
{0xc7,0x11},
{0xc8,0x11},
{0xc9,0x11},
{0xca,0x10},
{0xf3,0x10},
{0xf4,0x10},
{0xfd,0x01},
{0x04,0xff},
{0x05,0x10},
{0x0a,0x30},
{0x0b,0x10},
{0xfd,0x01},
{0xcb,0x38},
{0xcc,0x35},
{0xcd,0x03},
{0xce,0x05},
{0xfd,0x00},
{0xfb,0x16},
{0x35,0xaa},
{0xfd,0x01},
{0x1e,0x00},
{0x20,0x00},
{0x84,0x25},
{0x85,0x25},
{0x86,0x1f},
{0x87,0x23},
{0x88,0x1c},
{0x89,0x20},
{0x8a,0x1a},
{0x8b,0x15},
{0x8c,0x15},
{0x8d,0x1a},
{0x8e,0x0a},
{0x8f,0x13},
{0x90,0x13},
{0x91,0x00},
{0x92,0x0a},
{0x93,0x08},
{0x94,0x12},
{0x95,0x00},
{0x96,0x0a},
{0x97,0x08},
{0x98,0x15},
{0x99,0x00},
{0x9a,0x0a},
{0x9b,0x05},
{0xe8,0x20},
{0xe9,0x0f},
{0xea,0x00},
{0xfd,0x01},
{0xa4,0x00},
{0x0e,0x80},
{0x18,0x80},
{0x0f,0x20},
{0x10,0x90},
{0x11,0x80},
{0x12,0x80},
{0x13,0xa0},
{0x14,0x80},
{0x15,0x90},
{0x16,0x85},
{0x17,0x85},
{0x6e,0x00},
{0x6f,0x03},
{0x70,0x07},
{0x71,0x0d},
{0x72,0x17},
{0x73,0x29},
{0x74,0x3d},
{0x75,0x4f},
{0x76,0x5f},
{0x77,0x79},
{0x78,0x8c},
{0x79,0x9d},
{0x7a,0xa9},
{0x7b,0xb3},
{0x7c,0xbe},
{0x7d,0xc7},
{0x7e,0xd0},
{0x7f,0xd6},
{0x80,0xde},
{0x81,0xe4},
{0x82,0xe9},
{0x83,0xee},
{0xfd,0x02},
{0x09,0x06},
{0x0d,0x1a},
{0x1c,0x09},
{0x1d,0x03},
{0x1e,0x10},
{0x1f,0x06},
{0xfd,0x01},
{0x32,0x00},
{0xfd,0x02},
{0x26,0xcb},
{0x27,0xc2},
{0x10,0x00},
{0x11,0x00},
{0x18,0x17},
{0x19,0x36},
{0x2a,0x01},
{0x2b,0x10},
{0x28,0xf8},
{0x29,0x08},
{0x66,0x5F},
{0x67,0x7f},
{0x68,0xE0},
{0x69,0x10},
{0x69,0x10},
{0x6a,0xa6},
{0x7c,0x4A},
{0x7d,0x80},
{0x7e,0x00},
{0x7f,0x30},
{0x80,0xaa},
{0x70,0x32},
{0x71,0x60},
{0x72,0x30},
{0x73,0x5a},
{0x74,0xaa},
{0x6b,0xff},
{0x6c,0x50},
{0x6d,0x40},
{0x6e,0x60},
{0x6f,0x6a},
{0x61,0xff},
{0x62,0x27},
{0x63,0x51},
{0x64,0x7f},
{0x65,0x6a},
{0x75,0x80},
{0x76,0x09},
{0x77,0x02},
{0x0e,0x12},
{0x3b,0x09},
{0x48,0xea},
{0x49,0xfc},
{0x4a,0x05},
{0x02,0x00},
{0x03,0x88},
{0xf5,0xfe},
{0x22,0xfe},
{0x20,0xfe},
{0xf7,0xfe},
{0xfd,0x02},
{0xde,0x0f},
{0xcf,0x0a},
{0xd7,0x0a},
{0xd8,0x12},
{0xd9,0x14},
{0xda,0x1a},
{0xdc,0x07},
{0xe8,0x60},
{0xe9,0x40},
{0xea,0x40},
{0xeb,0x30},
{0xec,0x60},
{0xed,0x50},
{0xee,0x40},
{0xef,0x30},
{0xd3,0x30},
{0xd4,0xc0},
{0xd5,0x50},
{0xd6,0x0b},
{0xf0,0x7f},
{0xfd,0x01},
{0xb1,0xf0},
{0xfd,0x02},
{0xdc,0x07},
{0x05,0x08},
{0xfd,0x01},
{0x26,0x33},
{0x27,0x99},
{0x62,0xf0},
{0x63,0x80},
{0x64,0x80},
{0x65,0x20},
{0xfd,0x02},
{0xdd,0xff},
{0xfd,0x01},
{0xa8,0x00},
{0xa9,0x09},
{0xaa,0x09},
{0xab,0x0c},
{0xd3,0x00},
{0xd4,0x09},
{0xd5,0x09},
{0xd6,0x0c},
{0xcf,0xff},
{0xd0,0xf0},
{0xd1,0x80},
{0xd2,0x80},
{0xdf,0xff},
{0xe0,0xf0},
{0xe1,0xd0},
{0xe2,0x80},
{0xe3,0xff},
{0xe4,0xf0},
{0xe5,0xd0},
{0xe6,0x80},
{0xfd,0x02},
{0x15,0xe0},
{0x16,0x95},
{0xa0,0x9b},
{0xa1,0xe4},
{0xa2,0x01},
{0xa3,0xf2},
{0xa4,0x8f},
{0xa5,0xff},
{0xa6,0x01},
{0xa7,0xdb},
{0xa8,0xa4},
{0xac,0x80},
{0xad,0x21},
{0xae,0xdf},
{0xaf,0xf2},
{0xb0,0xa0},
{0xb1,0xee},
{0xb2,0xea},
{0xb3,0xd9},
{0xb4,0xbd},
{0xfd,0x01},
{0xb3,0xb0},
{0xb4,0x90},
{0xb5,0x70},
{0xb6,0x55},
{0xb7,0xb0},
{0xb8,0x90},
{0xb9,0x70},
{0xba,0x55},
{0xfd,0x01},
{0xbf,0xff},
{0x00,0x00},
{0xfd,0x01},
{0xa4,0x00},
{0xa5,0x1f},
{0xa6,0x50},
{0xa7,0x65},
{0xfd,0x02},
{0x30,0x38},
{0x31,0x40},
{0x32,0x40},
{0x33,0xd0},
{0x34,0x10},
{0x35,0x60},
{0x36,0x28},
{0x37,0x07},
{0x38,0x08},
{0xe6,0x8F},
{0xfd,0x01},
{0x1b,0x15},
{0x1c,0x1A},
{0x1d,0x0c},
{0xfd,0x01},
{0x32,0x15},
{0x33,0xef},
{0x36,0x10},
{0xf6,0xb0},
{0xf5,0x10},
{0xd7,0x3a},
{0xd8,0x10},
{0xd9,0x20},
{0xda,0x10},
{0xdb,0x7a},
{0xdc,0x3a},
{0xdd,0x30},
{0xde,0x30},
{0xe7,0x3a},
{0x9c,0xaa},
{0x9d,0xaa},
{0x9e,0x55},
{0x9f,0x55},
{0xfd,0x00},
{0x1c,0x00},
{0xfd,0x00},
{0xfd,0x00},
{0x30,0x0b},
{0x1c,0xdc},
{0x2c,0x1d}, // LSB
{0x2e,0xe1},
};
camI2cCfg_t sp0A39_1sdrRegInfo[] =
{
{0xfd,0x00},
{0x1d,0x25},
{0x31,0x04},
{0x32,0x01},
{0x30,0x01},
{0xfd,0x01},
{0x5d,0x01},
{0x34,0xe3},
{0x35,0x10},
{0xfd,0x00},
{0xf0,0xff},
{0xf1,0xff},
{0xf2,0xff},
{0xf3,0xff},
{0xfc,0x50},
{0xfd,0x00},
{0x03,0x03},
{0x04,0x6c},
{0x24,0x10},
{0xef,0x40},
{0x06,0x00},
{0x09,0x00},
{0x0a,0x80},
{0x10,0x07},
{0x11,0x04},
{0x16,0x01},
{0x19,0x22},
{0x1e,0x58},
{0x29,0x48},
{0x13,0x37},
{0x14,0x01},
{0x25,0x01},
{0x2a,0x06},
{0x27,0x01},
{0x54,0x00},
{0x55,0x10},
{0x58,0x38},
{0x5d,0x12},
{0x63,0x00},
{0x64,0x00},
{0x66,0x28},
{0x68,0x2a},
{0x72,0x3a},
{0x73,0x0a},
{0x75,0x48},
{0x76,0x0a},
{0x1f,0x77},
{0x20,0x07},
{0xfb,0x16},
{0xfd,0x01},
{0xf2,0x69},
{0xf7,0x97},
{0x02,0x08},
{0x03,0x01},
{0x06,0x8a},
{0x08,0x01},
{0xfd,0x02},
{0xb8,0x50},
{0xb9,0xff},
{0xba,0x40},
{0xbb,0x45},
{0xbc,0xc0},
{0xbd,0x50},
{0xbe,0xb8},
{0xbf,0x04},
{0xd0,0xb8},
{0xd1,0x04},
{0xfd,0x01},
{0xc0,0x1f},
{0xc1,0x18},
{0xc2,0x15},
{0xc3,0x13},
{0xc4,0x13},
{0xc5,0x12},
{0xc6,0x12},
{0xc7,0x11},
{0xc8,0x11},
{0xc9,0x11},
{0xca,0x10},
{0xf3,0x10},
{0xf4,0x10},
{0xfd,0x01},
{0x04,0xff},
{0x05,0x10},
{0x0a,0x30},
{0x0b,0x10},
{0xfd,0x01},
{0xcb,0x38},
{0xcc,0x35},
{0xcd,0x03},
{0xce,0x05},
{0xfd,0x00},
{0xfb,0x16},
{0x35,0xaa},
{0xfd,0x01},
{0x1e,0x00},
{0x20,0x00},
{0x84,0x25},
{0x85,0x25},
{0x86,0x1f},
{0x87,0x23},
{0x88,0x1c},
{0x89,0x20},
{0x8a,0x1a},
{0x8b,0x15},
{0x8c,0x15},
{0x8d,0x1a},
{0x8e,0x0a},
{0x8f,0x13},
{0x90,0x13},
{0x91,0x00},
{0x92,0x0a},
{0x93,0x08},
{0x94,0x12},
{0x95,0x00},
{0x96,0x0a},
{0x97,0x08},
{0x98,0x15},
{0x99,0x00},
{0x9a,0x0a},
{0x9b,0x05},
{0xe8,0x20},
{0xe9,0x0f},
{0xea,0x00},
{0xfd,0x01},
{0xa4,0x00},
{0x0e,0x80},
{0x18,0x80},
{0x0f,0x20},
{0x10,0x90},
{0x11,0x80},
{0x12,0x80},
{0x13,0xa0},
{0x14,0x80},
{0x15,0x90},
{0x16,0x85},
{0x17,0x85},
{0x6e,0x00},
{0x6f,0x03},
{0x70,0x07},
{0x71,0x0d},
{0x72,0x17},
{0x73,0x29},
{0x74,0x3d},
{0x75,0x4f},
{0x76,0x5f},
{0x77,0x79},
{0x78,0x8c},
{0x79,0x9d},
{0x7a,0xa9},
{0x7b,0xb3},
{0x7c,0xbe},
{0x7d,0xc7},
{0x7e,0xd0},
{0x7f,0xd6},
{0x80,0xde},
{0x81,0xe4},
{0x82,0xe9},
{0x83,0xee},
{0xfd,0x02},
{0x09,0x06},
{0x0d,0x1a},
{0x1c,0x09},
{0x1d,0x03},
{0x1e,0x10},
{0x1f,0x06},
{0xfd,0x01},
{0x32,0x00},
{0xfd,0x02},
{0x26,0xcb},
{0x27,0xc2},
{0x10,0x00},
{0x11,0x00},
{0x18,0x17},
{0x19,0x36},
{0x2a,0x01},
{0x2b,0x10},
{0x28,0xf8},
{0x29,0x08},
{0x66,0x5F},
{0x67,0x7f},
{0x68,0xE0},
{0x69,0x10},
{0x69,0x10},
{0x6a,0xa6},
{0x7c,0x4A},
{0x7d,0x80},
{0x7e,0x00},
{0x7f,0x30},
{0x80,0xaa},
{0x70,0x32},
{0x71,0x60},
{0x72,0x30},
{0x73,0x5a},
{0x74,0xaa},
{0x6b,0xff},
{0x6c,0x50},
{0x6d,0x40},
{0x6e,0x60},
{0x6f,0x6a},
{0x61,0xff},
{0x62,0x27},
{0x63,0x51},
{0x64,0x7f},
{0x65,0x6a},
{0x75,0x80},
{0x76,0x09},
{0x77,0x02},
{0x0e,0x12},
{0x3b,0x09},
{0x48,0xea},
{0x49,0xfc},
{0x4a,0x05},
{0x02,0x00},
{0x03,0x88},
{0xf5,0xfe},
{0x22,0xfe},
{0x20,0xfe},
{0xf7,0xfe},
{0xfd,0x02},
{0xde,0x0f},
{0xcf,0x0a},
{0xd7,0x0a},
{0xd8,0x12},
{0xd9,0x14},
{0xda,0x1a},
{0xdc,0x07},
{0xe8,0x60},
{0xe9,0x40},
{0xea,0x40},
{0xeb,0x30},
{0xec,0x60},
{0xed,0x50},
{0xee,0x40},
{0xef,0x30},
{0xd3,0x30},
{0xd4,0xc0},
{0xd5,0x50},
{0xd6,0x0b},
{0xf0,0x7f},
{0xfd,0x01},
{0xb1,0xf0},
{0xfd,0x02},
{0xdc,0x07},
{0x05,0x08},
{0xfd,0x01},
{0x26,0x33},
{0x27,0x99},
{0x62,0xf0},
{0x63,0x80},
{0x64,0x80},
{0x65,0x20},
{0xfd,0x02},
{0xdd,0xff},
{0xfd,0x01},
{0xa8,0x00},
{0xa9,0x09},
{0xaa,0x09},
{0xab,0x0c},
{0xd3,0x00},
{0xd4,0x09},
{0xd5,0x09},
{0xd6,0x0c},
{0xcf,0xff},
{0xd0,0xf0},
{0xd1,0x80},
{0xd2,0x80},
{0xdf,0xff},
{0xe0,0xf0},
{0xe1,0xd0},
{0xe2,0x80},
{0xe3,0xff},
{0xe4,0xf0},
{0xe5,0xd0},
{0xe6,0x80},
{0xfd,0x02},
{0x15,0xe0},
{0x16,0x95},
{0xa0,0x9b},
{0xa1,0xe4},
{0xa2,0x01},
{0xa3,0xf2},
{0xa4,0x8f},
{0xa5,0xff},
{0xa6,0x01},
{0xa7,0xdb},
{0xa8,0xa4},
{0xac,0x80},
{0xad,0x21},
{0xae,0xdf},
{0xaf,0xf2},
{0xb0,0xa0},
{0xb1,0xee},
{0xb2,0xea},
{0xb3,0xd9},
{0xb4,0xbd},
{0xfd,0x01},
{0xb3,0xb0},
{0xb4,0x90},
{0xb5,0x70},
{0xb6,0x55},
{0xb7,0xb0},
{0xb8,0x90},
{0xb9,0x70},
{0xba,0x55},
{0xfd,0x01},
{0xbf,0xff},
{0x00,0x00},
{0xfd,0x01},
{0xa4,0x00},
{0xa5,0x1f},
{0xa6,0x50},
{0xa7,0x65},
{0xfd,0x02},
{0x30,0x38},
{0x31,0x40},
{0x32,0x40},
{0x33,0xd0},
{0x34,0x10},
{0x35,0x60},
{0x36,0x28},
{0x37,0x07},
{0x38,0x08},
{0xe6,0x8F},
{0xfd,0x01},
{0x1b,0x15},
{0x1c,0x1A},
{0x1d,0x0c},
{0xfd,0x01},
{0x32,0x15},
{0x33,0xef},
{0x36,0x10},
{0xf6,0xb0},
{0xf5,0x10},
{0xd7,0x3a},
{0xd8,0x10},
{0xd9,0x20},
{0xda,0x10},
{0xdb,0x7a},
{0xdc,0x3a},
{0xdd,0x30},
{0xde,0x30},
{0xe7,0x3a},
{0x9c,0xaa},
{0x9d,0xaa},
{0x9e,0x55},
{0x9f,0x55},
{0xfd,0x00},
{0x1c,0x00},
{0xfd,0x00},
{0xfd,0x00},
{0x30,0x0c},
{0x1c,0xde},
{0x2c,0x1d}, //LSB
//{0x2c,0x15}, //MSB
{0x2e,0xf0},
};
uint16_t sp0a39GetRegCnt(char* regName)
{
if (strcmp(regName, "sp0a39_2sdr") == 0)
{
return (sizeof(sp0A39_2sdrRegInfo) / sizeof(sp0A39_2sdrRegInfo[0]));
}
else if (strcmp(regName, "sp0a39_1sdr") == 0)
{
return (sizeof(sp0A39_1sdrRegInfo) / sizeof(sp0A39_1sdrRegInfo[0]));
}
return 0;
}

View File

@@ -0,0 +1,315 @@
/****************************************************************************
*
* Copy right: 2020-, Copyrigths of AirM2M Ltd.
* File name: eepRom.c
* Description: EC618 eepRom ds2431 driver source file
* History: Rev1.0 2020-12-17
*
****************************************************************************/
#include "ec618.h"
#include "bsp.h"
#include "eepRom.h"
#include "oneWire.h"
#include "string.h"
#include "stdio.h"
extern void delay_us(uint32_t us);
static uint16_t crc16Maxim(uint8_t *data, uint16_t len)
{
uint8_t i;
uint16_t crc = 0;
while (len--)
{
crc ^= *data++;
for (i=0; i<8; ++i)
{
if (crc&1)
{
crc = (crc>>1) ^ 0xA001;
}
else
{
crc = crc>>1;
}
}
}
return ~crc;
}
int32_t writeScratchpad(uint8_t addr, uint8_t data[8])
{
uint8_t crcSrcData[11];
uint16_t crcCalResult;
uint8_t crcReadData[2];
if ((data == NULL) || (addr > 0x8F))
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
if (owResetPd() != 0)
{
return EEPROMDRV_RESET_ERR;
}
delay_us(140); // delay 200us
owWriteByte(ROM_SKIP_CMD);
owWriteByte(SCRATCHPAD_WRITE_CMD);
owWriteByte(addr);
owWriteByte(0x00);
crcSrcData[0] = SCRATCHPAD_WRITE_CMD; // before are right
crcSrcData[1] = addr;
crcSrcData[2] = 0x00;
for (int i=0; i<8; i++)
{
owWriteByte(data[i]);
crcSrcData[i+3] = data[i];
}
crcCalResult = crc16Maxim(crcSrcData, 11); // before are right
owReadByte(crcReadData);
owReadByte(crcReadData+1);
if (((crcReadData[1]<<8) | crcReadData[0]) != crcCalResult)
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
return EEPROMDRV_OK;
}
void readScratchpad(uint8_t dataBack[13])
{
if (owResetPd() != 0)
{
return;
}
delay_us(140); // delay 200us
owWriteByte(ROM_SKIP_CMD);
owWriteByte(SCRATCHPAD_READ_CMD);
// first 3 bytes are: TA1, TA2, ES; Then 8 bytes data; Last are 2 bytes crc
for (int i=0; i<13; i++)
{
owReadByte(dataBack+i);
}
}
int32_t copyScratchpad2Mem(uint16_t addr)
{
uint8_t readData;
if (owResetPd() != 0)
{
return EEPROMDRV_RESET_ERR;
}
delay_us(140); // delay 200us
owWriteByte(ROM_SKIP_CMD);
owWriteByte(SCRATCHPAD_COPY_CMD);
owWriteByte(addr);
owWriteByte(0x00);
owWriteByte(0x07);
delay_us(140); // delay 200us
owReadByte(&readData);
if (readData != 0xAA)
{
return EEPROMDRV_SCRATCHPADCOPY_ERR;
}
return EEPROMDRV_OK;
}
uint8_t dataBack[13]={0};
int32_t dataCmp(uint8_t targetAddr, uint8_t* buffer, uint8_t len)
{
// compare the data read from scratchpad
if (dataBack[0] != targetAddr)
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
if (dataBack[1] != 0)
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
if (dataBack[2] != 0x7)
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
for (int j=0; j<len; j++)
{
if (dataBack[j+3] != buffer[j])
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
}
return EEPROMDRV_OK;
}
int32_t eePromReadRom(uint8_t* romCode)
{
if (owResetPd() !=0)
{
return EEPROMDRV_RESET_ERR;
}
delay_us(140); // delay 200us
#if 0
uint8_t data = ROM_READ_CMD;
int i;
for (i=0; i<8; i++)
{
owWriteBit(data&0x01);
data >>=1;
}
uint8_t dataRead;
for (i=0; i<8; i++)
{
owReadBit(&dataRead);
dataRead <<=1;
}
#endif
#if 1
int32_t result = owWriteByte(ROM_READ_CMD);
if (result < 0)
{
return EEPROMDRV_ROMREAD_ERR;
}
for (int32_t i=0; i<8; i++)
{
owReadByte(romCode+i);
}
#endif
return EEPROMDRV_OK;
}
int32_t eePromReadMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
{
delay_us(3000); // wait unitl former write operations finish
if (owResetPd() != 0)
{
return EEPROMDRV_RESET_ERR;
}
delay_us(140); // delay 200us
if (owWriteByte(ROM_SKIP_CMD) < 0)
{
return EEPROMDRV_ROMREAD_ERR;
}
if (owWriteByte(MEM_READ_CMD) < 0)
{
return EEPROMDRV_ROMREAD_ERR;
}
// write addr low byte
if (owWriteByte(targetAddr) < 0)
{
return EEPROMDRV_ROMREAD_ERR;
}
// write addr high byte
if (owWriteByte(0) < 0)
{
return EEPROMDRV_ROMREAD_ERR;
}
for (int i=0; i<len; i++)
{
owReadByte(buffer+i);
}
return owResetPd();
}
int32_t writeSctStats;
int32_t eePromWriteMem(uint8_t targetAddr, uint8_t len, uint8_t* buffer)
{
uint8_t tmp[8];
int i, index=0;
if (owResetPd() != 0)
{
return EEPROMDRV_RESET_ERR;
}
if (targetAddr > 0x88)
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
while (len > 8)
{
for (i=0; i<8; i++)
{
tmp[i] = buffer[i+index];
}
len -= 8;
writeSctStats = writeScratchpad(targetAddr+index, tmp);
delay_us(3000);
readScratchpad(dataBack);
if (dataCmp(targetAddr+index, buffer+index, 8) != 0)
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
copyScratchpad2Mem(targetAddr+index);
delay_us(3000);
memset(dataBack, 0, 13);
index += 8;
}
for (i=0; i<len; i++)
{
tmp[i] = buffer[i+index];
}
memset(tmp+i, 1, 8-len);
delay_us(3000); // wait until eeprom store data finish
writeSctStats = writeScratchpad(targetAddr+index, tmp);
delay_us(3000);
readScratchpad(dataBack);
if (dataCmp(targetAddr+index, buffer+index, len) != 0)
{
return EEPROMDRV_SCRATCHPADWRITE_ERR;
}
copyScratchpad2Mem(targetAddr+index);
delay_us(30000); // wait until eeprom store data finish
if (owResetPd() != 0)
{
return EEPROMDRV_RESET_ERR;
}
return EEPROMDRV_OK;
}
void eepRomInit(OwModeSel_e mode)
{
owInit();
owSetMode(mode);
}

Some files were not shown because too many files have changed in this diff Show More