Merge branch 'dev'

# Conflicts:
#	README.md
This commit is contained in:
gx_ma
2024-08-09 10:40:35 +08:00
2201 changed files with 25348 additions and 670214 deletions

View File

@@ -1,22 +0,0 @@
<a name="v2.0.0"></a>
## [v2.0.0] - 2024-01-31
### 新增功能
- 支持netty mqtt broker ([#1]())
- 支持多种编码协议管理([#2]())
- 支持emqx5.0([#3]())
### 功能优化
- 设备列表卡片优化,设备详情页面优化
- 物模型功能优化
- 产品管理功能优化
### 代码重构
- java项目代码目录重新调整
- 消息网关重构
### 其他事务
- 新增Git提交规范([#Git提交规范](https://gitee.com/kerwincui/wumei-smart/blob/master/doc/Git%E6%8F%90%E4%BA%A4%E8%A7%84%E8%8C%83.md))
- 新增贡献者指南([#贡献者指南](https://gitee.com/kerwincui/wumei-smart/blob/master/doc/%E8%B4%A1%E7%8C%AE%E8%80%85%E6%8C%87%E5%8D%97.md))
- 新增功能规划([#功能规划](https://gitee.com/kerwincui/wumei-smart/blob/master/RoadMap.md))
- 修改项目AGPL3协议商用授权说明

View File

@@ -54,6 +54,7 @@ services:
- 8080:8080 - 8080:8080
- 1883:1883 - 1883:1883
- 8083:8083 - 8083:8083
- 5061:5061/udp
privileged: true privileged: true
networks: networks:
network: network:
@@ -61,6 +62,7 @@ services:
depends_on: depends_on:
- redis - redis
- mysql - mysql
- zlmedia
volumes: volumes:
- /var/data/java/fastbee-admin.jar:/server.jar - /var/data/java/fastbee-admin.jar:/server.jar
- /var/data/java/uploadPath:/uploadPath - /var/data/java/uploadPath:/uploadPath
@@ -89,5 +91,31 @@ services:
- /var/data/nginx/nginx.conf:/etc/nginx/nginx.conf - /var/data/nginx/nginx.conf:/etc/nginx/nginx.conf
- /var/data/nginx:/var/log/nginx - /var/data/nginx:/var/log/nginx
zlmedia:
image: zlmediakit/zlmediakit:master
container_name: zlmedia
privileged: true
restart: always
ports:
- 8082:80
- 8443:443
- 554:554
- 1935:1935
- 8000:8000
- 30000-30100:30000-30100/udp
expose:
- "80"
- "443"
- "554"
- "1935"
volumes:
- /var/data/zlmedia/logs:/opt/media/bin/log
- /var/data/zlmedia/data/www:/opt/media/bin/www
- /var/data/zlmedia/conf/config.ini:/opt/media/conf/config.ini
- /var/data/zlmedia/conf/default.pem:/opt/media/bin/default.pem
networks:
network:
ipv4_address: 177.7.0.15

File diff suppressed because one or more lines are too long

View File

@@ -1,68 +1,63 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIGujCCBaKgAwIBAgIQCEZHO+Au3dO0pmMgFV+CXDANBgkqhkiG9w0BAQsFADBf MIIGBzCCBO+gAwIBAgIQCGG3iG/dY+eL5UtirWmOUjANBgkqhkiG9w0BAQsFADBy
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg
d3cuZGlnaWNlcnQuY29tMR4wHAYDVQQDExVHZW9UcnVzdCBDTiBSU0EgQ0EgRzEw SW5jLjEdMBsGA1UECxMURG9tYWluIFZhbGlkYXRlZCBTU0wxHTAbBgNVBAMTFFRy
HhcNMjEwNzI2MDAwMDAwWhcNMjIwODI1MjM1OTU5WjB+MQswCQYDVQQGEwJDTjES dXN0QXNpYSBUTFMgUlNBIENBMB4XDTIyMDIwNjAwMDAwMFoXDTIzMDIwNTIzNTk1
MBAGA1UECAwJ5bm/5Lic55yBMRIwEAYDVQQHDAnmt7HlnLPluIIxMDAuBgNVBAoM OVowGTEXMBUGA1UEAxMOaW90Lnd1bWVpLmxpdmUwggEiMA0GCSqGSIb3DQEBAQUA
J+a3seWcs+W4guWTgemBk+mkkOmlrueuoeeQhuaciemZkOWFrOWPuDEVMBMGA1UE A4IBDwAwggEKAoIBAQC5x9cHl/vT7myCbHR7pIDgauBUsHoszqKYt0jeKGM6v5IR
AwwMKi5waW4tZGFvLmNuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA JPoyfYlm4GpM/6aEQR8dx6N0lwwkHxFwahiymW0/aN5xpCRdVD0CKoJLBsvnFqGF
rMBuC6MXRP7NaP5ux7nZmuOy2wKY6xWk/i2POrfGSnX0IeY7phoGliH2EBa+UyCA W9hZU+Rrhg8Usx2AADWpG4w4fiLCLabkxnQcIWnQC6be56A7RyVYmjbQtTUb/L6T
rj5B960UYDkpAmh5uCmDOO1Zs4VPwdoyj+OA6Up/LJXVg/txFvZfDkpk7lTjAQz4 TdKiKDbmEmCHxuN/aiv55TLy83dVEx+ev17jv6Ngr+pg93fT5bSAYNTS8TTvnqH8
OcYXxv+iMxDkpEnnlLRsUlUs2JdQUAXEzjwlKVVUqzEZ+9QY+BLb88bDQEBjaE4+ p50BC+M20yJLl/Ek8FfkaKpV0+bv+D/3TEqS8+GQPOEK9Ka3feH1PM/kKUXI9OAZ
JH95/oRJAby3OH/AXljswh0VUbj3S8pAbiI6f8xoWSn9mjPSGIlABYDgWma2T0RD fDcoPFeT7ihg4+OSUVrJGwvOfrVb/pWjlfAV43c3AgMBAAGjggLwMIIC7DAfBgNV
9F7sbY7JS/1njPA67i8vzVRMnpkMvYLt4a2qG1THUpFysmT0R2OOb8DlOZiPhnZk HSMEGDAWgBR/05nzoEcOMQBWViKOt8ye3coBijAdBgNVHQ4EFgQU0HxkNj7X8O9Q
xEvUGeDx8y34FSucWLQTvwIDAQABo4IDUTCCA00wHwYDVR0jBBgwFoAUkZ9eMRWu vR3M6Pf0YsU0DL8wGQYDVR0RBBIwEIIOaW90Lnd1bWVpLmxpdmUwDgYDVR0PAQH/
EJ+tYMH3wcyqSDQvDCYwHQYDVR0OBBYEFDrSDW+dz8TXCfrIPED7lQX1IGM5MCMG BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA+BgNVHSAENzA1
A1UdEQQcMBqCDCoucGluLWRhby5jboIKcGluLWRhby5jbjAOBgNVHQ8BAf8EBAMC MDMGBmeBDAECATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNv
BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGA1UdHwRuMGwwNKAy bS9DUFMwgZIGCCsGAQUFBwEBBIGFMIGCMDQGCCsGAQUFBzABhihodHRwOi8vc3Rh
oDCGLmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9HZW9UcnVzdENOUlNBQ0FHMS5j dHVzZS5kaWdpdGFsY2VydHZhbGlkYXRpb24uY29tMEoGCCsGAQUFBzAChj5odHRw
cmwwNKAyoDCGLmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9HZW9UcnVzdENOUlNB Oi8vY2FjZXJ0cy5kaWdpdGFsY2VydHZhbGlkYXRpb24uY29tL1RydXN0QXNpYVRM
Q0FHMS5jcmwwPgYDVR0gBDcwNTAzBgZngQwBAgIwKTAnBggrBgEFBQcCARYbaHR0 U1JTQUNBLmNydDAJBgNVHRMEAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgA
cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMG8GCCsGAQUFBwEBBGMwYTAhBggrBgEF dgDoPtDaPvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAX7N75LSAAAEAwBH
BQcwAYYVaHR0cDovL29jc3AuZGNvY3NwLmNuMDwGCCsGAQUFBzAChjBodHRwOi8v MEUCIFKefXNeH1To/AIRaEUHVc5kOBSVI8BDN8saxPGnzB9qAiEA3/oovbYcivLU
Y3JsLmRpZ2ljZXJ0LWNuLmNvbS9HZW9UcnVzdENOUlNBQ0FHMS5jcnQwDAYDVR0T 86zUnzG6CdUH+ONguG+BVJ/i3jkyC5AAdgA1zxkbv7FsV78PrUxtQsu7ticgJlHq
AQH/BAIwADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYARqVV63X6kSAwtaKJ P+Eq76gDwzvWTAAAAX7N75JxAAAEAwBHMEUCIQDexxT78ln6N02VsH4ly9Yun4Ph
afTzfREsQXS+/Um4havy/HD+bUcAAAF64K3X/QAABAMARzBFAiBOmRovvmyKDMxG kiMCRr+SzMGm9gJ30AIgJCpBK78lTS+COyGSeOX4BW1B7RcqBIgLYw7w1qFAv4IA
fA3H6aFk/x8ce6THZVe4bTW4gEDDJwIhANKatQg5dedqYI78Fevo3ZEUEYUyMB1V dgCzc3cH4YRQ+GOG1gWp3BEJSnktsWcMC4fc8AMOeTalmgAAAX7N75KfAAAEAwBH
ml1AajGZm/ebAHcAUaOw9f0BeZxWbbg3eI8MpHrMGyfL956IQpoN/tSLBeUAAAF6 MEUCIQC7GgkmWavuRWqxnqXrIRWkO/Oymi6DqHNIapUcetzrVAIgDZ4MbK3enmTG
4K3YDgAABAMASDBGAiEAmVXJCrNphalqawzCGHqLOHIbDUEH0S2mXOG/4jpQsKgC xLKmHusnM9lkgJIt61T7ZKOzwBDPAyswDQYJKoZIhvcNAQELBQADggEBACkK1DUd
IQDxC3C/aVX/D8CRj3py4OvD3PSkmP5+ZtvLsZDYEliYQQB2AEHIyrHfIkZKEMah xyjzJffk4ol3wykJ9M3Lcmb/FEoBbGpKCa552MY6I6haMcYSeDsGGQhlS+MTPBrp
OglCh15OMYsbA+vrS8do8JBilgb2AAABeuCt15EAAAQDAEcwRQIhANIAPeLjWGRz py2LVpf9LJWqZW2TGi31/QOolYw1TjNlEZVb85Gmd6kxV0HyQ5OUdqaJisFl5HMQ
Qm11rXG9VeBazY520LJ39puYjr4ovR4tAiBwU9cJ5esSS6hOtLrSkhLCeg4i3isp 1S0edM2AQ/G2jMyL9ykMCFqCvrtmC9llf4+R4scS8iBBodi96vnof9lldHk3mXjx
w30Hn1D77Um2UzANBgkqhkiG9w0BAQsFAAOCAQEAGPOc0d869d9C1YkbdSBwJtoh cDH8vMjRSoOAx/piMQc3k0jSZW3MLxmucRD8UrRGNJ5ELZ4UQwgVBaVvH06pfSKV
BMkf2RFlPSIlGUacELN6gSHP37CIe7CVcwTAS+bDUGRtTD5+8loa96pbLoloEqfD MMfPnVvI+a6yb6yUbvqNnvefemoOVozrO2TO79bsxV6MNmH2zHW1OMFdh7z4i78a
7Z7js9LE8anXazye/4W81ko3lThUq9PO0B+udKWWrhhD9wC9sfj5u22ruUN/8oyJ gLY94u7QW6jim24=
OeMIYj5Xi8RTFH1QgXtg3BX3oKgRWPsib+1BgLQQgchsV709DhlT1oAI4x69JL57
K5m5eVyK5eY3Y93+5GEQLxMhxJPpBbDbsieBHvvFzZ9sFxRLSW6YlRYPKcCMd80a
+uHNq69hXv4ZBkmoJV9PI7NJDD1e6RmRYj1v9vMarM2rhcL4yYZ1y7LiT5BkkA==
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIFGjCCBAKgAwIBAgIQCgRw0Ja8ihLIkKbfgm7sSzANBgkqhkiG9w0BAQsFADBh MIIErjCCA5agAwIBAgIQBYAmfwbylVM0jhwYWl7uLjANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xOTA2MjAxMjI3NThaFw0yOTA2MjAxMjI3NThaMF8xCzAJBgNVBAYTAlVT QTAeFw0xNzEyMDgxMjI4MjZaFw0yNzEyMDgxMjI4MjZaMHIxCzAJBgNVBAYTAkNO
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMR0wGwYDVQQL
b20xHjAcBgNVBAMTFUdlb1RydXN0IENOIFJTQSBDQSBHMTCCASIwDQYJKoZIhvcN ExREb21haW4gVmFsaWRhdGVkIFNTTDEdMBsGA1UEAxMUVHJ1c3RBc2lhIFRMUyBS
AQEBBQADggEPADCCAQoCggEBALFJ+j1KeZVG4jzgQob23lQ8PJUNhY31ufZihuUx U0EgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgWa9X+ph+wAm8
hYc6HSU4Lw0fxfA43a9DpJl74M3E6F1ZRBOfJ+dWnaiyYD0PxRIQd4wJisti4Uad Yh1Fk1MjKbQ5QwBOOKVaZR/OfCh+F6f93u7vZHGcUU/lvVGgUQnbzJhR1UV2epJa
vz61IYY/oQ/Elxk/X7GFDquYuxCSyBdHtTVMXCxFSvQ2C/7jWZFDfGGKKNoQSiJy e+m7cxnXIKdD0/VS9btAgwJszGFvwoqXeaCqFoP71wPmXjjUwLT70+qvX4hdyYfO
wDe8iiHbUOakLMmXmOTZyWJnFdR/TH5YNTiMKCNUPHAleG4IigGxDyL/gbwrdDNi JcjeTz5QKtg8zQwxaK9x4JT9CoOmoVdVhEBAiD3DwR5fFgOHDwwGxdJWVBvktnoA
bDA4lUNhD0xNvPjQ8BNKqm5HWDvirUuHdC+4hpi0GJO34O3iiRV16YmWTuVFNboU zjdTLXDdbSVC5jZ0u8oq9BiTDv7jAlsB5F8aZgvSZDOQeFrwaOTbKWSEInEhnchK
LDZ0+PQtctJnatpuZKPGyKX6jCpPvzzPw/EhNDlpEdrYHZMCAwEAAaOCAc4wggHK ZTD1dz6aBlk1xGEI5PZWAnVAba/ofH33ktymaTDsE6xRDnW97pDkimCRak6CEbfe
MB0GA1UdDgQWBBSRn14xFa4Qn61gwffBzKpINC8MJjAfBgNVHSMEGDAWgBQD3lA1 3dXw6OV5AgMBAAGjggFPMIIBSzAdBgNVHQ4EFgQUf9OZ86BHDjEAVlYijrfMnt3K
VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYB AYowHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQD
BQUHAwEGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wMQYIKwYBBQUHAQEEJTAj AgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAG
MCEGCCsGAQUFBzABhhVodHRwOi8vb2NzcC5kY29jc3AuY24wRAYDVR0fBD0wOzA5 AQH/AgEAMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au
oDegNYYzaHR0cDovL2NybC5kaWdpY2VydC1jbi5jb20vRGlnaUNlcnRHbG9iYWxS ZGlnaWNlcnQuY29tMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj
b290Q0EuY3JsMIHOBgNVHSAEgcYwgcMwgcAGBFUdIAAwgbcwKAYIKwYBBQUHAgEW ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwTAYDVR0gBEUwQzA3Bglg
HGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYoGCCsGAQUFBwICMH4MfEFu hkgBhv1sAQIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29t
eSB1c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBjb25zdGl0dXRlcyBhY2NlcHRhbmNl L0NQUzAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBAK3dVOj5dlv4MzK2i233
IG9mIHRoZSBSZWx5aW5nIFBhcnR5IEFncmVlbWVudCBsb2NhdGVkIGF0IGh0dHBz lDYvyJ3slFY2X2HKTYGte8nbK6i5/fsDImMYihAkp6VaNY/en8WZ5qcrQPVLuJrJ
Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9ycGEtdWEwDQYJKoZIhvcNAQELBQADggEBABfg DSXT04NnMeZOQDUoj/NHAmdfCBB/h1bZ5OGK6Sf1h5Yx/5wR4f3TUoPgGlnU7EuP
eXrxIrtlixBv+KMDeqKxtNJbZiLDzJBkGCd4HI63X5eS6BElJBn6mI9eYVrr7qOL ISLNdMRiDrXntcImDAiRvkh5GJuH4YCVE6XEntqaNIgGkRwxKSgnU3Id3iuFbW9F
Tp7WiO02Sf1Yrpaz/ePSjZ684o89UAGpxOfbgVSMvo/a07n/220jUWLxzaJhQNLu UQ9Qqtb1GX91AJ7i4153TikGgYCdwYkBURD8gSVe8OAco6IfZOYt/TEwii1Ivi1C
lACXwwWsxYf8twP8glkoIHnUUNTlhsyyl1ZzvVC4bDpI4hC6QkJGync1MNqYSMj8 qnuUlWpsF1LdQNIdfbW3TSe0BhQa7ifbVIfvPWHYOu3rkg1ZeMo6XRU9B4n5VyJY
tZbhQNw3HdSmcTO0Nc/J/pK2VZc6fFbKBgspmzdHc6jMKG2t4lisXEysS3wPcg0a RmE=
Nfr1Odl5+myh3MnMK08f6pTXvduLz+QZiIh8IYL+Z6QWgTZ9e2jnV8juumX1I8Ge
7cZdtNnTCB8hFfwGLUA=
-----END CERTIFICATE----- -----END CERTIFICATE-----

View File

@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEArMBuC6MXRP7NaP5ux7nZmuOy2wKY6xWk/i2POrfGSnX0IeY7 MIIEpAIBAAKCAQEAucfXB5f70+5sgmx0e6SA4GrgVLB6LM6imLdI3ihjOr+SEST6
phoGliH2EBa+UyCArj5B960UYDkpAmh5uCmDOO1Zs4VPwdoyj+OA6Up/LJXVg/tx Mn2JZuBqTP+mhEEfHcejdJcMJB8RcGoYspltP2jecaQkXVQ9AiqCSwbL5xahhVvY
FvZfDkpk7lTjAQz4OcYXxv+iMxDkpEnnlLRsUlUs2JdQUAXEzjwlKVVUqzEZ+9QY WVPka4YPFLMdgAA1qRuMOH4iwi2m5MZ0HCFp0Aum3uegO0clWJo20LU1G/y+k03S
+BLb88bDQEBjaE4+JH95/oRJAby3OH/AXljswh0VUbj3S8pAbiI6f8xoWSn9mjPS oig25hJgh8bjf2or+eUy8vN3VRMfnr9e47+jYK/qYPd30+W0gGDU0vE0756h/Ked
GIlABYDgWma2T0RD9F7sbY7JS/1njPA67i8vzVRMnpkMvYLt4a2qG1THUpFysmT0 AQvjNtMiS5fxJPBX5GiqVdPm7/g/90xKkvPhkDzhCvSmt33h9TzP5ClFyPTgGXw3
R2OOb8DlOZiPhnZkxEvUGeDx8y34FSucWLQTvwIDAQABAoIBAAdXly9bCCZZ8540 KDxXk+4oYOPjklFayRsLzn61W/6Vo5XwFeN3NwIDAQABAoIBAAnFGydQlFNAYh93
9vDGklwStcuFib0VsQSCKGZx4LVrdZI3RQbwCW86FElmXg9BM2O0dUmy8bAnqpMi waZw78Adjr+Vak9p7H4YgXIBcLp5sZ5KMggutuecnKqA9UpWPGMuCQgMG3zYz2t4
oGgjKfBlp6+8lVsDP62wsqe3qQraqpxIauvZ65WIGrZ42LxDskBQwTpakdwJXMTE gOT/kZG4m54hUjJASFcRUjnM2TNFauge/OExurz211sw0jfVivziMH0WERDiIrk8
Xoy9Ollcq2JG1BZo/sG9+d2O3EfGS/yCb0PemXMN+1L3Lds4LaVbWhkJTvRMYpQU QIXsMerZegSV7MTBSJMAxSozpV/b0xVbzdZPRuo2IuM/kQWL/efYiwpAAJvzI4Ph
m4wdRnAoKW1GKhFy9mvZ70HROPgmZ+jJkj63ZiOQyIpH1XlM6POdJCJx70ppZ6PP AWvLi/Xz8MBsM47G+wQJKEeYmaHdFAXkgz3d2JljJNKZHcOPClPpupQ5bv9oqvFn
ckjwvaV7wrrIYxK/tIWfDk4V+VxMc5tFJtjrNB/FwDAqBm9ltT1LjfN/j/cpQtZ7 B5ze4FF3KhZenJQOFTx7fjmQaIBpgdRMHpGK/tYR7hbpgLdYORDqD8gUBOEoeB6i
xk3kKSkCgYEA2Zo9tOMGdU/1lOZJ2MGQ2kRAeNfcgA/ZA7FlIAoqMc52/OrIiO4u FKIZXykCgYEA/7FOjgvRQ9cJWZYtVXjqByqM3LnDhKg9alhgjs9Cr4bE5X45r4yu
oAWJ5VkQNhgXazbEMl8ifI3fnSCcEjIcL3zVqIdFAeTOv+Wg1quK/TVENiG1uVnc mIxqCuQ8BEiNFj1LvoAkk2DgUI2ggFrPF8XpuV9qr05vKMbHmBavjqIn0dVujf7e
Kr/YCbuD0DLXgZ/Szm0+dwYxcRHb5oHpsE0XNl0mEpQUnCbxrSYOKNsCgYEAyzwk gw1OVdyWFc0SUFAQKtvQwXj+9ktNreyuEknWEL8c4X4XHsFvNS27AS8CgYEAugEE
bXczNjx90phzbIYqHG7LmZvWWKa7mqISL8RvyXhhzy9fXoBKhUtkC6XazYaYCO6F RGSjloJGMBo7wikJ+HpWYH05GDnx77sF16JTJurl4PH4zEDvmDgjexq6AEzXiwHC
mvSRT9BT/sRV9YgoOONHxscNMv7I2mKg8R6TDIFS/tq3E4A35YMvbVo4k/LfzExZ zxAH/zB5xG2joLkifAcrFOqskjmbok626H48b7l+mtmD8kUSG+by6wCoPY2Uxj9O
FKis6KuUfnA216++CaVAfIRTLSHsO4K2Hw6wE+0CgYEAimB3lSw50yhB96pqk5ik Mrm3SOzcsEH2Dl17JHZFtXz1Fl6tPyrH0eH0mHkCgYEA+Y836cI0/G68THkcRCkg
UOjORwqegiGR07Nfp3xPUNUG/dcgJ1Ov+rsK8fotQPkZC2kMYyv0dliSNw2hskCD 2d+43pJc93QxhUM+8wPtxV3XfVpmuSWpH3Ek6v56aX/aXJN1AzkU+dd6+IRS3BRF
g/9Sr5U14PpsL8QK//ierl7NPc86DOCEDftpmubP7/ok6Z2FJRh7fJ1Hm6vLt04u vqFHjstHWFVIf1cMZi/2J1OzY8VaAzN4QBbTl1AWGK8wKb0LGpmzNbJ/vyoeZhv0
GZssg7nAmFfqs1JgpcdpgbkCgYAOo+F35TtSL99ceVDvQ2brL2wJP7mcHz6qb/xh hhsU2QF/EcM8k6MehJvewrcCgYBYsH1pYxdBf9KZwxh1Zv4TFboz/eGIdLCwn1uU
ZoQq/joFg8MZ+qHjoj+tux/c6FIxaoVDWVTSbA5w7tHGYy2Kk4zLG/Gud74eRTaU yxic+OotjRMVyWy1Byeb3k2MMRehd3B9LOazPlkBWUnpK/2OaBiZu6AXhRJ5nNDI
yAANyY8h/r1rcTQVm3KiLPqgZcGLZQCRxWjXRezngsvgk69b4ISZs6qOOMBctRjL INEOcMM2cLrifR66YS+48DJIT0b+FFdkBnuncRF1la4OgXJjG2X3uKJgTTqMYQiw
efJjLQKBgFGdU3jg/+MctfR7N2yj3DHfPw6eya+yCjuY01S5E0oEJSE3yiLw7vPQ Qe5P+QKBgQC3ndKhFgqEsBEpyuavqrJd7erFfx5iwKHDRJcokeLm/jf9e5GFx1zF
kHeyZ5cEXD9y7VTCsfuYqsEwxKViBRc8xyyS7kYEEORLz/sAVU2V3TN7aKVinrEn m6Ni+7FabGYjJ+y1DJgYUCsxZN22Hb0YFvPJYoTSlZTahW5Mxp1/4WcFGidxWcCJ
MnKh1m2n4wno3AE4huJFbPuXqJO3iUkfhIuLkCFyZtEd72JFO9ns q+HL3QrU53S2eE4/H5W+oWtVV54xMxEPMRm8M0fiZDjBXTEOZAeZ4A==
-----END RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,193 @@
; auto-generated by mINI class {
[api]
apiDebug=1
defaultSnap=./www/logo.png
downloadRoot=./www
secret=JbGSW0jtsUnH4CP7M757z8L5AZucnUiG
snapRoot=./www/snap/
[cluster]
origin_url=
retry_count=3
timeout_sec=15
[ffmpeg]
bin=/usr/bin/ffmpeg
cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s
log=./ffmpeg/ffmpeg.log
restart_sec=0
snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s
[general]
broadcast_player_count_changed=0
check_nvidia_dev=1
enableVhost=0
enable_ffmpeg_log=0
flowThreshold=64
maxStreamWaitMS=15000
mediaServerId=fastbee
mergeWriteMS=0
resetWhenRePlay=1
streamNoneReaderDelayMS=20000
unready_frame_cache=100
wait_add_track_ms=3000
wait_track_ready_ms=10000
[hls]
broadcastRecordTs=0
deleteDelaySec=10
fastRegister=0
fileBufSize=65536
segDelay=0
segDur=2
segKeep=0
segNum=3
segRetain=5
[hook]
alive_interval=60.0
enable=1
on_flow_report=http://java:8080/zlmhook/on_flow_report
on_http_access=http://java:8080/zlmhook/on_http_access
on_play=http://java:8080/zlmhook/on_play
on_publish=http://java:8080/zlmhook/on_publish
on_record_mp4=http://127.0.0.1:18081/zlmhook/on_record_mp4
on_record_ts=
on_rtp_server_timeout=http://java:8080/zlmhook/on_rtp_server_timeout
on_rtsp_auth=
on_rtsp_realm=
on_send_rtp_stopped=http://java:8080/zlmhook/on_send_rtp_stopped
on_server_exited=http://java:8080/zlmhook/on_server_exited
on_server_keepalive=http://java:8080/zlmhook/on_server_keepalive
on_server_started=http://java:8080/zlmhook/on_server_started
on_shell_login=
on_stream_changed=http://java:8080/zlmhook/on_stream_changed
on_stream_none_reader=http://java:8080/zlmhook/on_stream_none_reader
on_stream_not_found=http://java:8080/zlmhook/on_stream_not_found
retry=1
retry_delay=3.0
stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4
timeoutSec=20
[http]
allow_cross_domains=1
allow_ip_range=
charSet=utf-8
dirMenu=1
forbidCacheSuffix=
forwarded_ip_header=
keepAliveSecond=30
maxReqSize=40960
notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit(git hash:56d3032/2024-06-29T11:33:17+08:00,branch:master,build time:2024-06-29T13:41:26)</center></body></html>
port=80
rootPath=./www
sendBufSize=65536
sslport=443
virtualPath=
[multicast]
addrMax=239.255.255.255
addrMin=239.0.0.0
udpTTL=64
[protocol]
add_mute_audio=1
auto_close=0
continue_push_ms=15000
enable_audio=1
enable_fmp4=1
enable_hls=1
enable_hls_fmp4=0
enable_mp4=0
enable_rtmp=1
enable_rtsp=1
enable_ts=1
fmp4_demand=0
hls_demand=0
hls_save_path=./www
modify_stamp=2
mp4_as_player=0
mp4_max_second=3600
mp4_save_path=./www
paced_sender_ms=0
rtmp_demand=0
rtsp_demand=0
ts_demand=0
[record]
appName=record
enableFmp4=0
fastStart=0
fileBufSize=65536
fileRepeat=0
sampleMS=500
[rtc]
externIP=
maxNackMS=5000
max_bitrate=0
min_bitrate=0
nackIntervalRatio=1.0
nackMaxCount=15
nackMaxMS=3000
nackMaxSize=2048
nackRtpSize=8
port=8000
preferredCodecA=PCMA,PCMU,opus,mpeg4-generic
preferredCodecV=H264,H265,AV1,VP9,VP8
rembBitRate=0
rtpCacheCheckInterval=100
start_bitrate=0
tcpPort=8000
timeoutSec=15
[rtmp]
directProxy=1
enhanced=0
handshakeSecond=15
keepAliveSecond=15
port=1935
sslport=0
[rtp]
audioMtuSize=600
h264_stap_a=1
lowLatency=0
rtpMaxSize=10
videoMtuSize=1400
[rtp_proxy]
dumpDir=
gop_cache=1
h264_pt=98
h265_pt=99
opus_pt=100
port=10000
port_range=30000-30103
ps_pt=96
rtp_g711_dur_ms=100
timeoutSec=5
udp_recv_socket_buffer=41943040
[rtsp]
authBasic=0
directProxy=1
handshakeSecond=15
keepAliveSecond=15
lowLatency=0
port=554
rtpTransportType=-1
sslport=0
[shell]
maxReqSize=1024
port=0
[srt]
latencyMul=4
pktBufSize=8192
port=9000
timeoutSec=5
; } ---

View File

@@ -0,0 +1,89 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAjTFnNz2btUHR/K8TegU2n06lXsQuW4AfsMGthBLvnz2zdgL2
uVxfRCuleoRpECEV9I80ibTXAJlouRLbnhLHto8gzyLeQue9/DtxTEGcS7y2aMha
0wAoUcOBv7tAITSnFepGHXoYgyU7HOCvn96U1bzqLTOhxOCH/xy003dwoEC7+Pjl
dsWs/16cpvYiZV/dZvzDDKIpHSIvQy1whi6N0SDpzz/ncThn1z8xcJDx0I1jVR76
juP7TttbyhqJkO+fOlLn4yP9K5wZ/dPFJn2+bQRCrzGc4SM7J5YOq8ckTTTbZtSp
9yPpm7O5QyfdzePhOpRrjWroLsqaDOPV2UQlzwIDAQABAoIBADCWTh8P19vdnR3X
v5uPXLcgkL7WQt+g7Qbd91CKVaRWTsHvDilGVNA4Ntc85oyy3gPNHfa/YPdnU0bQ
6vtwGgLEKTWumY6rgdDhQcFMmLTlaV4QiFSw6q8MWMN6c/yZSmA7wMoXAIVs0/VB
ip44sb4Fpw5MBMCjxZjwL3fP09WJPlUqx09vVo7eH8rFwLBikmn982IzRigAx1I8
TX0wkdqvv33MSxBXPMQIrwPqjf2arxWFzb6vp6yolYbMZtgORF9gznWABRy3oY50
9jFkTkbxZFlSMVuF7nlM0WJj5Q9/IelBqpozODWUVvB+6inCqkxNLkbh0ISbpXWC
16gUZfUCgYEAxWo3FRNBrNXhVD5h2N4ApyUXkZ5UYIY5zbsHEJCrPjooh9uHu9kh
xXh5v11J/7TV9BfwLZ4qRbDBH4fq0DKEOXOZRLY5Lo4KbrYmlEDCabuJdmwwHeGh
S5K37F5z/+zPz9KWkKN+9Rg32xdLxh0969O77GnvuBrhzASpVsF6ZFMCgYEAtxf1
eVg4Kxzuy0AWs+CisSVQc+5CbZ9teKA5fli2EVSmL5dsrKatVTIDghudJgQTU6cr
zP9I20K11jeqIoK5saQXH3CzogN6aDuKssq4rDbvVSZ09Zry6N1WMz9GPe31zEYw
sdU1w7vUw+l3unFfWOP4oZm0MH+na61V1YohCRUCgYANlp0J/1RS8DndUZnskoNa
/eucY1iNeE+8QHZhBoQy+U/W4h56qJxxejRvHp28UxczAP7QNQXV3C++2t0nzYJa
bgGLwDs5YB+JtVH8fGSlYHo6w4GgXOp8SDIOvAWiBQvc0zL367kOZ8dYdkcJ8PNV
KzLROA1/D6KhJ2T8ir7A7wKBgQCjVVxGw8xXqZfc+W9HSD3aic8bnJDl+jNOSKEB
dWH2U+1sx0jLPGWketlmV/v4zenv1lHcrl/wObK9RysfXj8JmbiG86NMBI5OLc+t
b+sOtnMLIyNzdqb71Xfwf6HJ3V5IvNTzz6AG3KkRnFSSnlDQm45RmyyDl11jUV4h
APg3gQKBgBzFeuKWnaTZz1FQBr5Ytl9gtxBRMl+49jtkqyzErJYFHe0MTWeD/1xj
mEC/7UERYWhIQF1L4ah6c0QkecR3F1s9/IYK/QHsnSJFwRyFuMas6StCERsDq5oQ
GWpXAmw7JTa8OYwxVjORdXY25Iwv6rEr6iUYBWZrkhoWYBySWpSZ
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIGAjCCBOqgAwIBAgIQAiXv68Xco/vd9YeB4g3HLjANBgkqhkiG9w0BAQsFADBu
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
RFYgVExTIENBIC0gRzEwHhcNMjIwOTE4MDAwMDAwWhcNMjMwOTE4MjM1OTU5WjAh
MR8wHQYDVQQDExZkZWZhdWx0LnpsbWVkaWFraXQuY29tMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAjTFnNz2btUHR/K8TegU2n06lXsQuW4AfsMGthBLv
nz2zdgL2uVxfRCuleoRpECEV9I80ibTXAJlouRLbnhLHto8gzyLeQue9/DtxTEGc
S7y2aMha0wAoUcOBv7tAITSnFepGHXoYgyU7HOCvn96U1bzqLTOhxOCH/xy003dw
oEC7+PjldsWs/16cpvYiZV/dZvzDDKIpHSIvQy1whi6N0SDpzz/ncThn1z8xcJDx
0I1jVR76juP7TttbyhqJkO+fOlLn4yP9K5wZ/dPFJn2+bQRCrzGc4SM7J5YOq8ck
TTTbZtSp9yPpm7O5QyfdzePhOpRrjWroLsqaDOPV2UQlzwIDAQABo4IC5zCCAuMw
HwYDVR0jBBgwFoAUVXRPsnJP9WC6UNHX5lFcmgGHGtcwHQYDVR0OBBYEFPnRZrfz
q/QAf5u4Xp4eGWvhMdvfMCEGA1UdEQQaMBiCFmRlZmF1bHQuemxtZWRpYWtpdC5j
b20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjA+BgNVHSAENzA1MDMGBmeBDAECATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3
LmRpZ2ljZXJ0LmNvbS9DUFMwgYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEoGCCsGAQUFBzAChj5odHRwOi8vY2Fj
ZXJ0cy5kaWdpY2VydC5jb20vRW5jcnlwdGlvbkV2ZXJ5d2hlcmVEVlRMU0NBLUcx
LmNydDAJBgNVHRMEAjAAMIIBfwYKKwYBBAHWeQIEAgSCAW8EggFrAWkAdgDoPtDa
PvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAYNQt3JvAAAEAwBHMEUCIEaO
G4ffzzaE6OMqiu6PUr+Y+wO2tsXCkGt1jt04Ix1qAiEAhNZwqFACieds1ZbY3r/p
wlF3iFbhqp+kNfPzon7kwc8AdgA1zxkbv7FsV78PrUxtQsu7ticgJlHqP+Eq76gD
wzvWTAAAAYNQt3JVAAAEAwBHMEUCIBOErqyKvihAEKItLWG/Plgtxh/hCTMsE+t5
+MfsAQLCAiEA76d50S4iy1wxya+8IUASVlKStaHNqBkJAS+Oadxs2sMAdwCzc3cH
4YRQ+GOG1gWp3BEJSnktsWcMC4fc8AMOeTalmgAAAYNQt3LIAAAEAwBIMEYCIQC/
kfFCpwF76sw/Qx3sxR8b3srW+Ds0k/6VrIIDZcYV5gIhAKkLmuyeDvzulp0y4f0t
GDgIN/OoURq6CuHA67UJlsWzMA0GCSqGSIb3DQEBCwUAA4IBAQB0BwVxPRihSdPJ
FUPLQ+ClHy9O/UisnRD7NadQQtbcMXn6L9Lwd0f2la0ytLQAKHADOZDA08KfQ5qW
B19OeQOlTwp2nhY2ZvoLEG+paeh0gYxIgD76APnd/m3g2H7GeW144ymjPcZRoldj
ZKYSdzStJJIFYXzL3FR9wjkMc4xOEes/IY5PFtj8OT8CFf7zl0R7L2Vcw9RGYi9u
vLjGwwJW9kXTX8UlKXFyjJN0ZyrmxBQHq5uNtigx8xy6HtMnPsc58tp1IqitIELp
HIur2XrRPBJA5XtpDg3AE8bXhRTM8oFMPL0UoSFWyWRYGgBo1Msc10dpXPtmbgIc
pPW8w+2c
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEqjCCA5KgAwIBAgIQAnmsRYvBskWr+YBTzSybsTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xNzExMjcxMjQ2MTBaFw0yNzExMjcxMjQ2MTBaMG4xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPeP6wkab41dyQh6mKc
oHqt3jRIxW5MDvf9QyiOR7VfFwK656es0UFiIb74N9pRntzF1UgYzDGu3ppZVMdo
lbxhm6dWS9OK/lFehKNT0OYI9aqk6F+U7cA6jxSC+iDBPXwdF4rs3KRyp3aQn6pj
pp1yr7IB6Y4zv72Ee/PlZ/6rK6InC6WpK0nPVOYR7n9iDuPe1E4IxUMBH/T33+3h
yuH3dvfgiWUOUkjdpMbyxX+XNle5uEIiyBsi4IvbcTCh8ruifCIi5mDXkZrnMT8n
wfYCV6v6kDdXkbgGRLKsR4pucbJtbKqIkUGxuZI2t7pfewKRc5nWecvDBZf3+p1M
pA8CAwEAAaOCAU8wggFLMB0GA1UdDgQWBBRVdE+yck/1YLpQ0dfmUVyaAYca1zAf
BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYw
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAK3Gp6/aGq7aBZsxf/oQ+TD/B
SwW3AU4ETK+GQf2kFzYZkby5SFrHdPomunx2HBzViUchGoofGgg7gHW0W3MlQAXW
M0r5LUvStcr82QDWYNPaUy4taCQmyaJ+VB+6wxHstSigOlSNF2a6vg4rgexixeiV
4YSB03Yqp2t3TeZHM9ESfkus74nQyW7pRGezj+TC44xCagCQQOzzNmzEAP2SnCrJ
sNE2DpRVMnL8J6xBRdjmOsC3N6cQuKuRXbzByVBjCqAA8t1L0I+9wXJerLPyErjy
rMKWaBFLmfK/AHNF4ZihwPGOc7w6UHczBZXH5RFzJNnww+WnKuTPI0HfnVH8lg==
-----END CERTIFICATE-----

View File

@@ -1,157 +0,0 @@
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
String randomName="wumei-device"+(String)random(1000);
const char *ap_ssid =randomName.c_str();
const char *ap_password = ""; //开放式网络
char sta_ssid[32] = {0};
char sta_password[64] = {0};
char sta_user_id[32] = {0};
IPAddress local_IP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
void initApConfig();
void initWebServer();
void handleConfig();
void handleStatus();
void handleNotFound();
ESP8266WebServer server(80);
void setup(void)
{
//打开串行端口:
Serial.begin(115200);
// AP模式
initApConfig();
// web服务
initWebServer();
}
void loop(void)
{
// Web服务端
server.handleClient();
}
/**
* AP模式
*/
void initApConfig()
{
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);
}
/**
* 初始化webserver配置
*/
void initWebServer()
{
server.on("/status", HTTP_GET, handleStatus);
server.on("/config", HTTP_POST, handleConfig);
server.onNotFound(handleNotFound);
server.enableCORS(true);
server.begin();
printMsg("HTTP服务已启动");
}
/**
* 连接WIFI
*/
void connectWifi()
{
printMsg("连接WIFI");
WiFi.begin(sta_ssid, sta_password);
int cnt = 0;
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
cnt++;
Serial.print(".");
if (cnt >= 30)
{
printMsg("设备连接WIFI超时请重新配网");
return;
}
}
server.close();
WiFi.softAPdisconnect(false);
printMsg("Http服务和热点已关闭设备已连接WIFI");
}
/**
* 检测设备状态
*/
void handleStatus(){
server.send(200, "text/plain;charset=utf-8", "AP配网已准备就绪");
}
/**
* 配网:下发配置信息
*/
void handleConfig()
{
printMsg("进入配网......");
// wifi名称、wifi密码、用户编号
if (server.hasArg("SSID") && server.hasArg("password") && server.hasArg("userId"))
{
strcpy(sta_ssid, server.arg("SSID").c_str());
strcpy(sta_password, server.arg("password").c_str());
strcpy(sta_user_id, server.arg("userId").c_str());
printMsg("收到WIFI名称" + (String)sta_ssid);
printMsg("收到WIFI密码" + (String)sta_password);
printMsg("收到用户编号:" + (String)sta_user_id);
}
else
{
printMsg("配网必须传递用户编号、WIFI名称和WIFI密码,配网失败");
server.send(500, "text/plain;charset=utf-8", "配网必须传递用户编号、WIFI名称和WIFI密码配网失败");
return;
}
// 可选字段
if (server.hasArg("deviceNum"))
{
printMsg("收到设备编号:" + server.arg("deviceNum"));
}
if (server.hasArg("extra"))
{
printMsg("收到补充信息:" + server.arg("extra"));
}
// TODO 可增加设备连接WIFI测试
server.send(200, "text/plain;charset=utf-8", "设备已更新WIFI配置开始连接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", "请求的地址找不到或无法访问");
}
}
//打印提示信息
void printMsg(String msg)
{
Serial.print("\r\n[");
Serial.print(millis());
Serial.print("ms]");
Serial.print(msg);
}

View File

@@ -1,7 +0,0 @@
{
"port": "COM3",
"configuration": "FlashFreq=80,UploadSpeed=921600",
"board": "esp32:esp32:nano32",
"output": "./build",
"sketch": "Arduino-Esp32.ino"
}

View File

@@ -1,85 +0,0 @@
/***********************************************************
* author: LaoHuang
* create: 2022-04-14
* emailrememberyousaid@163.com
* source:https://github.com/kerwincui/wumei-smart
* board:esp32 版本 1.0.6
***********************************************************/
#include "Helper.h"
long lastMqttConn; // 上次mqtt连接时间
long lastPublishMonitor; // 上次发布监测数据时间
long lastTimerMonitor; // 上次定时发布监测数据
/**
* 启动
*/
void setup()
{
//打开串行端口:
Serial.begin(115200);
printMsg("wumei smart device starting...");
connectWifi();
connectMqtt();
}
/**
* 循环执行
*/
void loop()
{
// Wifi掉线重连
if (WiFi.status() != WL_CONNECTED)
{
connectWifi();
}
// 非阻塞Mqtt重连间隔30秒
if (WiFi.status() == WL_CONNECTED)
{
long now = millis();
if (!mqttClient.connected())
{
if (now - lastMqttConn > 30000)
{
lastMqttConn = now;
connectMqtt();
}
}
else
{
mqttClient.loop();
}
}
// 非阻塞发布实时监测数据,间隔默认1秒
if(WiFi.status() == WL_CONNECTED && monitorCount>0){
long now = millis();
if (now - lastPublishMonitor > monitorInterval)
{
lastPublishMonitor = now;
monitorCount--;
publishMonitor();
}
}
// 非阻塞定时上报测试用60秒发布一次
if(WiFi.status() == WL_CONNECTED){
long now = millis();
if (now - lastTimerMonitor > 60000)
{
lastTimerMonitor = now;
printMsg("执行定时上报");
// 发布事件
publishEvent();
// 发布时钟同步
publishNtp();
// 发布属性(监测值)
String msg=randomPropertyData();
publishProperty(msg);
}
}
}

View File

@@ -1,137 +0,0 @@
#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

@@ -1,79 +0,0 @@
/*
* Copyright (c) 2013 Adam Rudd.
* See LICENSE for more information
*/
#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

@@ -1,555 +0,0 @@
/***********************************************************
* author: LaoHuang
* create: 2022-04-14
* emailrememberyousaid@163.com
* source:https://github.com/kerwincui/wumei-smart
* board:esp32 版本1.0.6
***********************************************************/
#include "Helper.h"
String g_time;
WiFiClient wifiClient;
PubSubClient mqttClient;
float rssi = 0;
char wumei_iv[17] = "wumei-smart-open";
int monitorCount = 0;
long monitorInterval = 1000;
//==================================== 这是需要配置的项 ===============================
// Wifi配置
char *wifiSsid = "wifi-ssid";
char *wifiPwd = "wifi-password";
// 设备信息配置
String deviceNum = "D6329VL54419L1Y0";
String userId = "1";
String productId = "2";
float firmwareVersion = 1.0;
// 经度和纬度可选,如果产品使用设备定位,则必须传
float latitude=0;
float longitude=0;
// Mqtt配置
char *mqttHost = "wumei.live";
int mqttPort = 1883;
char *mqttUserName = "wumei-smart";
char *mqttPwd = "P5FJKZJHIR82GNB2";
char mqttSecret[17] = "K63C4EA3AI5TER97";
// 产品启用授权码,则授权码不能为空
String authCode="";
// NTP地址用于获取时间,可选的修改为自己部署项目的地址)
String ntpServer = "http://wumei.live:8080/iot/tool/ntp?deviceSendTime=";
//====================================================================================
// 订阅的主题
String prefix = "/" + productId + "/" + deviceNum;
String sInfoTopic = prefix + "/info/get";
String sOtaTopic = prefix + "/ota/get";
String sNtpTopic = prefix + "/ntp/get";
String sPropertyTopic = prefix + "/property/get";
String sFunctionTopic = prefix + "/function/get";
String sPropertyOnline = prefix + "/property-online/get";
String sFunctionOnline = prefix + "/function-online/get";
String sMonitorTopic = prefix + "/monitor/get";
// 发布的主题
String pInfoTopic = prefix + "/info/post";
String pNtpTopic = prefix + "/ntp/post";
String pPropertyTopic = prefix + "/property/post";
String pFunctionTopic = prefix + "/function/post";
String pMonitorTopic = prefix + "/monitor/post";
String pEventTopic = prefix + "/event/post";
// 物模型-属性处理
void processProperty(String payload)
{
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, payload);
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(payload);
}
// 物模型-功能处理
void processFunction(String payload)
{
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, payload);
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);
}
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)
{
String msg = randomPropertyData();
printMsg("订阅到上报监测数据指令,上报数据:");
printMsg(msg);
publishProperty(msg);
}
}
// 最后发布功能,服务端订阅存储(重要)
publishFunction(payload);
}
// Mqtt回调
void callback(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, 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, sInfoTopic.c_str()) == 0)
{
printMsg("订阅到设备信息...");
// 发布设备信息
publishInfo();
}
else if (strcmp(topic, 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;
}
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, sPropertyTopic.c_str()) == 0 || strcmp(topic, sPropertyOnline.c_str()) == 0)
{
printMsg("订阅到属性指令...");
processProperty(data);
}
else if (strcmp(topic, sFunctionTopic.c_str()) == 0 || strcmp(topic, sFunctionOnline.c_str()) == 0)
{
printMsg("订阅到功能指令...");
processFunction(data);
}
else if (strcmp(topic, 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"];
}
}
// 连接wifi
void connectWifi()
{
printMsg("连接 ");
Serial.print(wifiSsid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifiSsid, wifiPwd);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
printMsg("WiFi连接成功");
printMsg("IP地址: ");
Serial.print(WiFi.localIP());
}
// 连接mqtt
void connectMqtt()
{
printMsg("连接Mqtt服务器...");
// 生成mqtt认证密码(设备加密认证密码加密格式为mqtt密码 & 过期时间 & 授权码,其中授权码为可选)
String password = generationPwd();
String encryptPassword = encrypt(password, mqttSecret, wumei_iv);
printMsg("密码(已加密)" + encryptPassword);
mqttClient.setClient(wifiClient);
mqttClient.setServer(mqttHost, mqttPort);
mqttClient.setCallback(callback);
mqttClient.setBufferSize(1024);
mqttClient.setKeepAlive(10);
//连接 设备mqtt客户端Id格式为认证类型(E=加密、S=简单) & 设备编号 & 产品ID & 用户ID
String clientId = "E&" + deviceNum + "&" + productId +"&" + userId;
bool connectResult = mqttClient.connect(clientId.c_str(), mqttUserName, encryptPassword.c_str());
if (connectResult)
{
printMsg("连接成功");
// 订阅(OTA、NTP、属性、功能、实时监测、信息)
mqttClient.subscribe(sInfoTopic.c_str(), 1);
mqttClient.subscribe(sOtaTopic.c_str(), 1);
mqttClient.subscribe(sNtpTopic.c_str(), 1);
mqttClient.subscribe(sPropertyTopic.c_str(), 1);
mqttClient.subscribe(sFunctionTopic.c_str(), 1);
mqttClient.subscribe(sPropertyOnline.c_str(), 1);
mqttClient.subscribe(sFunctionOnline.c_str(), 1);
mqttClient.subscribe(sMonitorTopic.c_str(), 1);
printMsg("订阅主题:" + sInfoTopic);
printMsg("订阅主题:" + sOtaTopic);
printMsg("订阅主题:" + sNtpTopic);
printMsg("订阅主题:" + sPropertyTopic);
printMsg("订阅主题:" + sFunctionTopic);
printMsg("订阅主题:" + sPropertyOnline);
printMsg("订阅主题:" + sFunctionOnline);
printMsg("订阅主题:" + sMonitorTopic);
// 发布设备信息
publishInfo();
}
else
{
printMsg("连接失败, rc=");
Serial.print(mqttClient.state());
}
}
// 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);
mqttClient.publish(pInfoTopic.c_str(), output.c_str());
}
// 2.发布时钟同步信,用于获取当前时间(可选)
void publishNtp()
{
StaticJsonDocument<128> doc;
doc["deviceSendTime"] = millis();
printMsg("发布NTP信息:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
mqttClient.publish(pNtpTopic.c_str(), output.c_str());
}
// 3.发布属性
void publishProperty(String msg)
{
printMsg("发布属性:" + msg);
mqttClient.publish(pPropertyTopic.c_str(), msg.c_str());
}
// 4.发布功能
void publishFunction(String msg)
{
printMsg("发布功能:" + msg);
mqttClient.publish(pFunctionTopic.c_str(), msg.c_str());
}
// 5.发布事件
void publishEvent()
{
// 匹配云端的事件
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);
mqttClient.publish(pEventTopic.c_str(), output.c_str());
}
// 6.发布实时监测数据
void publishMonitor()
{
String msg = randomPropertyData();
// 发布为实时监测数据,不会存储
printMsg("发布实时监测数据:" + msg);
mqttClient.publish(pMonitorTopic.c_str(), msg.c_str());
}
// 随机生成监测值
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;
}
// 生成密码
String generationPwd()
{
String jsonTime = getTime();
printMsg("getTime()= " + jsonTime);
// 128字节内存池容量
StaticJsonDocument<128> doc;
// 解析JSON
DeserializationError error = deserializeJson(doc, jsonTime);
if (error)
{
printMsg("Json解析失败");
Serial.print(error.f_str());
return "";
}
// 获取当前时间
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);
return password;
}
// HTTP获取时间
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)
{
g_time = http.getString();
printMsg("获取时间成功data:");
Serial.print(g_time);
return g_time;
}
}
else
{
printMsg("获取时间失败error:");
Serial.printf(http.errorToString(httpCode).c_str());
}
http.end();
}
else
{
printMsg("连接Http失败");
}
delay(500);
}
return "1672524366000";
}
//打印提示信息
void printMsg(String msg)
{
Serial.print("\r\n[");
Serial.print(millis());
Serial.print("ms]");
Serial.print(msg);
}
// 控制指示灯闪烁
void blink()
{
printMsg("指示灯闪烁...");
pinMode(15, OUTPUT);
for (int i = 0; i < 2; i++)
{
digitalWrite(15, HIGH);
delay(200);
digitalWrite(15, LOW);
delay(200);
}
}
// 加密 (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];
uint8_t crypt_data[3 * 16] = {0};
memcpy(key, wumei_key, 16);
memcpy(iv, wumei_iv, 16);
memset(crypt_data, 0, 48);
len = n_blocks * 16;
// 加密
mbedtls_aes_context aes_ctx;
mbedtls_aes_init(&aes_ctx);
mbedtls_aes_setkey_enc(&aes_ctx, key, 128);
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, len, iv, data, crypt_data);
// Base64编码
char encoded_data[base64_enc_len(len)];
base64_encode(encoded_data, (char *)crypt_data, len);
return String(encoded_data);
}
// 解密 (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;
uint8_t n_padding = data[n_blocks * 16 - 1];
len = n_blocks * 16 - n_padding;
char plain_data[len + 1];
//密文空间
mbedtls_aes_context aes_ctx;
mbedtls_aes_init(&aes_ctx);
//设置解密密钥
mbedtls_aes_setkey_dec(&aes_ctx, key, 128);
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, 48, iv, (unsigned char *)encoded_data, (unsigned char *)plain_data);
mbedtls_aes_free(&aes_ctx);
// PKCS#7 Padding 填充
plain_data[len] = '\0';
return String(plain_data);
}

View File

@@ -1,79 +0,0 @@
/***********************************************************
* author: LaoHuang
* create: 2022-04-14
* emailrememberyousaid@163.com
* source:https://github.com/kerwincui/wumei-smart
* board:esp32 版本1.0.6
***********************************************************/
#ifndef _HELPER_H
#define _HELPER_H
#include <mbedtls/aes.h>
#include "Base64.h"
#include <WiFiClient.h>
//#include <Ethernet.h>
#include <HTTPClient.h>
#include <PubSubClient.h> // 版本2.8.0
#include <ArduinoJson.h> // 版本6.19.4
extern WiFiClient wifiClient;
extern PubSubClient mqttClient;
extern String deviceNum ; // 设备编号重要同时是Mqtt的clientId
extern String userId; // 用户ID
extern String productId; // 产品ID
extern float rssi; // 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85]
extern float firmwareVersion; // 固件版本
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 String ntpServer; // NTP服务地址用于获取当前时间
extern int monitorCount; // 发布监测数据的最大次数
extern long monitorInterval; // 发布监测数据的间隔默认1000毫秒
// 连接wifi
void connectWifi();
// 连接mqtt
void connectMqtt();
// Mqtt回调
void callback(char *topic, byte *payload, unsigned int length);
// 发布设备信息
void publishInfo();
// 发布时钟同步信息
void publishNtp();
// 发布事件
void publishEvent();
// 发布实时监测数据
void publishMonitor();
// 随机生成监测值
String randomPropertyData();
// 发布属性
void publishProperty(String msg);
// 发布功能
void publishFunction(String msg);
// 属性处理
void processProperty(String payload);
// 功能处理
void processFunction(String payload);
// 生成密码
String generationPwd();
// 获取时间
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);
//打印提示信息
void printMsg(String tips);
// 控制指示灯闪烁
void blink();
#endif

View File

@@ -1,120 +0,0 @@
/*********************************************************************
* 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 = "fastbee-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

@@ -1,28 +0,0 @@
/*********************************************************************
* 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

@@ -1,156 +0,0 @@
/*********************************************************************
* 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

@@ -1,29 +0,0 @@
/*********************************************************************
* 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

@@ -1,173 +0,0 @@
/*********************************************************************
* 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

@@ -1,84 +0,0 @@
/*********************************************************************
* 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

@@ -1,175 +0,0 @@
/*********************************************************************
* 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 = "";
char *wifiPwd = "";
char *userId = "1";
// 产品启用授权码,则授权码不能为空
char *authCode = "";
// 设备信息配置
char *deviceNum = "D1FJTWOT3HIB";
char *productId = "588";
float firmwareVersion = 1.0;
// 经度和纬度可选,如果产品使用设备定位,则必须传
float latitude = 0;
float longitude = 0;
// Mqtt配置
char *mqttHost = "fastbee.cn";
int mqttPort = 1883;
char *mqttUserName = "FastBee";
char *mqttPwd = "P63653937TRQ8F27";
char mqttSecret[17] = "KV52PPZ813EFCQD8";
// NTP地址用于获取时间,修改为自己部署项目的接口地址)
String ntpServer = "http://fastbee.cn: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

@@ -1,87 +0,0 @@
/*********************************************************************
* 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

@@ -1,127 +0,0 @@
/*********************************************************************
* 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();
}
ESP.wdtFeed(); // 喂软件看门狗,防止程序跑偏
}
/*
* 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

@@ -1,87 +0,0 @@
/*********************************************************************
* 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

@@ -1,29 +0,0 @@
/*********************************************************************
* 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

@@ -1,255 +0,0 @@
/*********************************************************************
* 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"] = "light_current";
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, "light_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

@@ -1,33 +0,0 @@
/*********************************************************************
* 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

@@ -1,120 +0,0 @@
/*********************************************************************
* 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

@@ -1,28 +0,0 @@
/*********************************************************************
* 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

@@ -1,156 +0,0 @@
/*********************************************************************
* 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

@@ -1,29 +0,0 @@
/*********************************************************************
* 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

@@ -1,173 +0,0 @@
/*********************************************************************
* 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

@@ -1,84 +0,0 @@
/*********************************************************************
* 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

@@ -1,175 +0,0 @@
/*********************************************************************
* 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 = (char*)"MERCURY100";
char *wifiPwd = (char*)"FastBee";
char *userId = (char*)"1";
// 产品启用授权码,则授权码不能为空
char *authCode = (char*)"";
// 设备信息配置
char *deviceNum = (char*)"D1PGLPG58K88";
char *productId = (char*)"96";
float firmwareVersion = 1.0;
// 经度和纬度可选,如果产品使用设备定位,则必须传
float latitude = 0;
float longitude = 0;
// Mqtt配置
char *mqttHost = (char*)"iot.fastbee.cn";
int mqttPort = 1883;
char *mqttUserName = (char*)"FastBee";
char *mqttPwd = (char*)"P467433O1MT8MXS2";
char mqttSecret[17] = "KWF32S3H95LH14LO";
// NTP地址用于获取时间,修改为自己部署项目的接口地址)
String ntpServer = "http://fastbee.cn: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

@@ -1,87 +0,0 @@
/*********************************************************************
* 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

@@ -1,126 +0,0 @@
/*********************************************************************
* 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

@@ -1,87 +0,0 @@
/*********************************************************************
* 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 + pPropertyTopic);
printMsg("消息:" + msg);
mqttClient.publish((prefix + pPropertyTopic).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

@@ -1,29 +0,0 @@
/*********************************************************************
* 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

@@ -1,509 +0,0 @@
/*********************************************************************
* 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("订阅到属性指令...");
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);
}
}
// 处理子设备的数据上报
processSubDeviceReport(id, value);
}
// 最后发布功能,服务端订阅存储(重要)
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

@@ -1,37 +0,0 @@
/*********************************************************************
* 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

View File

@@ -1,51 +0,0 @@
## 硬件端树莓派SDK说明
#### 一、运行环境
- Python 3.7.2 (其他python3的版本一般也可以)
- 开发板树莓派4b没有加入硬件相关代码安装好python3环境win下linux下都能运行
- 库 需要安装库
1. mqtt库
```
pip install paho-mqtt
```
2. ase加密库
```
# 前面两个卸载命令是为了防止一些安装环境问题
pip uninstall crypto
pip uninstall pycryptodome
pip install pycryptodome
```
3. 报错缺少xx库命令
```
pip install xx
```
#### 二、运行程序
```
python3 main_sdk.py
# 备注程序运行依赖aes.py文件保证该文件和main_sdk.py在同一目录
```
#### 三、开发参考资料:
- [Eclipse Paho MQTT Python Client 使用手册](https://www.cooooder.com/archives/20210303)
- [Python 实现AES加密](https://zhuanlan.zhihu.com/p/261694311)
- [python实现AES加密解密](https://blog.csdn.net/chouzhou9701/article/details/122019967)
- [使用python time()方法](http://www.py.cn/jishu/jichu/20424.html)
- [python 线程定时器Timer](https://zhuanlan.zhihu.com/p/91412537)
- [浅谈Python的格式化输出](https://www.jb51.net/article/225609.htm)
- [Python Request库入门](https://www.jianshu.com/p/d78982126318)
- [Python JSON ](https://www.runoob.com/python/python-json.html)
- [Python random() 函数 ](https://www.runoob.com/python/func-number-random.html)

View File

@@ -1,210 +0,0 @@
from Crypto.Cipher import AES
import base64
import binascii
# 数据类
class MData():
def __init__(self, data = b"",characterSet='utf-8'):
# data肯定为bytes
self.data = data
self.characterSet = characterSet
def saveData(self,FileName):
with open(FileName,'wb') as f:
f.write(self.data)
def fromString(self,data):
self.data = data.encode(self.characterSet)
return self.data
def fromBase64(self,data):
self.data = base64.b64decode(data.encode(self.characterSet))
return self.data
def fromHexStr(self,data):
self.data = binascii.a2b_hex(data)
return self.data
def toString(self):
return self.data.decode(self.characterSet)
def toBase64(self):
return base64.b64encode(self.data).decode() #decode()转成字符串形式,否则为字节型数据
def toHexStr(self):
return binascii.b2a_hex(self.data).decode()
def toBytes(self):
return self.data
def __str__(self):
try:
return self.toString()
except Exception:
return self.toBase64()
### 封装类
class AEScryptor():
def __init__(self,key,mode,iv = '',paddingMode= "NoPadding",characterSet ="utf-8"):
'''
构建一个AES对象
key: 秘钥,字节型数据
mode: 使用模式只提供两种AES.MODE_CBC, AES.MODE_ECB
iv iv偏移量字节型数据
paddingMode: 填充模式默认为NoPadding, 可选NoPaddingZeroPaddingPKCS5PaddingPKCS7Padding
characterSet: 字符集编码
'''
self.key = key
self.mode = mode
self.iv = iv
self.characterSet = characterSet
self.paddingMode = paddingMode
self.data = ""
def __ZeroPadding(self,data):
data += b'\x00'
while len(data) % 16 != 0:
data += b'\x00'
return data
def __StripZeroPadding(self,data):
data = data[:-1]
while len(data) % 16 != 0:
data = data.rstrip(b'\x00')
if data[-1] != b"\x00":
break
return data
def __PKCS5_7Padding(self,data):
needSize = 16-len(data) % 16
if needSize == 0:
needSize = 16
return data + needSize.to_bytes(1,'little')*needSize
def __StripPKCS5_7Padding(self,data):
paddingSize = data[-1]
return data.rstrip(paddingSize.to_bytes(1,'little'))
def __paddingData(self,data):
if self.paddingMode == "NoPadding":
if len(data) % 16 == 0:
return data
else:
return self.__ZeroPadding(data)
elif self.paddingMode == "ZeroPadding":
return self.__ZeroPadding(data)
elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
return self.__PKCS5_7Padding(data)
else:
print("不支持Padding")
def __stripPaddingData(self,data):
if self.paddingMode == "NoPadding":
return self.__StripZeroPadding(data)
elif self.paddingMode == "ZeroPadding":
return self.__StripZeroPadding(data)
elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
return self.__StripPKCS5_7Padding(data)
else:
print("不支持Padding")
def setCharacterSet(self,characterSet):
'''
设置字符集编码
characterSet: 字符集编码
'''
self.characterSet = characterSet
def setPaddingMode(self,mode):
'''
设置填充模式
mode: 可选NoPaddingZeroPaddingPKCS5PaddingPKCS7Padding
'''
self.paddingMode = mode
def decryptFromBase64(self,entext):
'''
从base64编码字符串编码进行AES解密
entext: 数据类型str
'''
mData = MData(characterSet=self.characterSet)
self.data = mData.fromBase64(entext)
return self.__decrypt()
def decryptFromHexStr(self,entext):
'''
从hexstr编码字符串编码进行AES解密
entext: 数据类型str
'''
mData = MData(characterSet=self.characterSet)
self.data = mData.fromHexStr(entext)
return self.__decrypt()
def decryptFromString(self,entext):
'''
从字符串进行AES解密
entext: 数据类型str
'''
mData = MData(characterSet=self.characterSet)
self.data = mData.fromString(entext)
return self.__decrypt()
def decryptFromBytes(self,entext):
'''
从二进制进行AES解密
entext: 数据类型bytes
'''
self.data = entext
return self.__decrypt()
def encryptFromString(self,data):
'''
对字符串进行AES加密
data: 待加密字符串数据类型为str
'''
self.data = data.encode(self.characterSet)
return self.__encrypt()
def __encrypt(self):
if self.mode == AES.MODE_CBC:
aes = AES.new(self.key,self.mode,self.iv)
elif self.mode == AES.MODE_ECB:
aes = AES.new(self.key,self.mode)
else:
print("不支持这种模式")
return
data = self.__paddingData(self.data)
enData = aes.encrypt(data)
return MData(enData)
def __decrypt(self):
if self.mode == AES.MODE_CBC:
aes = AES.new(self.key,self.mode,self.iv)
elif self.mode == AES.MODE_ECB:
aes = AES.new(self.key,self.mode)
else:
print("不支持这种模式")
return
data = aes.decrypt(self.data)
# mData = MData(self.__stripPaddingData(data),characterSet=self.characterSet)
# return mData()
return MData(self.__stripPaddingData(data),characterSet=self.characterSet)
if __name__ == '__main__':
key = b"1234567812345678"
iv = b"0000000000000000"
aes = AEScryptor(key,AES.MODE_CBC,iv,paddingMode= "ZeroPadding",characterSet='utf-8')
data = "好好学习"
rData = aes.encryptFromString(data)
print("密文:",rData.toBase64())
rData = aes.decryptFromBase64(rData.toBase64())
print("明文:",rData)
# ————————————————
# 版权声明本文为CSDN博主「Hello_wshuo」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。
# 原文链接https://blog.csdn.net/chouzhou9701/article/details/122019967

View File

@@ -1,351 +0,0 @@
# /***********************************************************
# * author: xiaoY [物美智能 wumei-smart]
# * create: 2022-05-10
# * emailqimint@outlook.com
# * source:https://github.com/kerwincui/wumei-smart
# * board:raspberry 4b
# ***********************************************************/
import time
import requests
import json
from aes import AEScryptor,AES
import paho.mqtt.client as mqtt
import random
import threading #导入线程模块,用作定时器
#################################################################
# 需要连接好外部网络
#################################################################
# 作为python的AES的iv,应该为16位字节型数据
wumei_iv = b"wumei-smart-open"
#发布监测数据的最大次数
monitorCount =5
# 发布监测数据的间隔默认5秒。 使用esp8266单片机时服务器传来的间隔单位为毫秒本程序由于定时运行需要的是秒将转化为秒如需毫秒运行自行更改程序
monitorInterval =5
# NTP地址用于获取时间,可选的修改为自己部署项目的地址)
ntpServer = "http://120.24.218.158:8080/iot/tool/ntp?deviceSendTime="
# 连接成功标志位
g_rc=-1
#全局变量,管理定时监测
global t2
# 设备信息配置
deviceNum = "DW43CI6RM8GMG23H"
userId = "1"
productId = "4"
firmwareVersion = "1.0"
# 经度和纬度可选,如果产品使用设备定位,则必须传
latitude=0
longitude=0
# Mqtt配置
mqttHost = "120.24.218.158"
mqttPort = 1883
mqttUserName = "wumei-smart"
mqttPwd = "P261I5G3RY3MCIGG"
# 作为python的AES的key,应该为16位字节型数据
mqttSecret = b"K2IB784BM0O01GG6"
# 产品启用授权码则authCode不能为空
authCode=""
# 订阅的主题
prefix = "/" + productId + "/" + deviceNum
sInfoTopic = prefix + "/info/get"
sOtaTopic = prefix + "/ota/get"
sNtpTopic = prefix + "/ntp/get"
sPropertyTopic = prefix + "/property/get"
sFunctionTopic = prefix + "/function/get"
sPropertyOnline = prefix + "/property-online/get"
sFunctionOnline = prefix + "/function-online/get"
sMonitorTopic = prefix + "/monitor/get"
# 发布的主题
pInfoTopic = prefix + "/info/post"
pNtpTopic = prefix + "/ntp/post"
pPropertyTopic = prefix + "/property/post"
pFunctionTopic = prefix + "/function/post"
pMonitorTopic = prefix + "/monitor/post"
pEventTopic = prefix + "/event/post"
# 初始化,连接 设备mqtt客户端Id格式为认证类型(E=加密、S=简单) & 设备编号 & 产品ID & 用户ID
clientId = "E&" + deviceNum + "&" + productId +"&" + userId
client=mqtt.Client(clientId)
#加密 (AES-CBC-128-pkcs5padding)
def encrypt(plain_data,wumei_key,wumei_iv):
aes=AEScryptor(wumei_key,AES.MODE_CBC,wumei_iv,paddingMode="PKCS5Padding",characterSet='utf-8')
rData=aes.encryptFromString(plain_data)
printMsg("密码(已加密)"+rData.toBase64())
return rData.toBase64()
#回调函数。当尝试与MQTT broker 建立连接时,触发该函数。
#client 是本次连接的客户端实例。
#userdata 是用户的信息,一般为空。但如果有需要,也可以通过 user_data_set 函数设置。
#flags 保存服务器响应标志的字典
#rc 是响应码。
# 0: 连接成功
# 1: 连接失败-不正确的协议版本
# 2: 连接失败-无效的客户端标识符
# 3: 连接失败-服务器不可用
# 4: 连接失败-错误的用户名或密码
# 5: 连接失败-未授权
# 6-255: 未定义.
#一般情况下我们只需要关注rc响应码是否为0就可以了。
def on_connect(client,userdata,flags,rc):
if rc==0:
printMsg("连接成功")
# 放在on_connect下可以保证重连重新订阅
# 订阅(OTA、NTP、属性、功能、实时监测)
client.subscribe(sInfoTopic, 1)
client.subscribe(sOtaTopic, 1)
client.subscribe(sNtpTopic, 1)
client.subscribe(sPropertyTopic, 1)
client.subscribe(sFunctionTopic, 1)
client.subscribe(sPropertyOnline, 1)
client.subscribe(sFunctionOnline, 1)
client.subscribe(sMonitorTopic, 1)
printMsg("订阅主题:" + sInfoTopic)
printMsg("订阅主题:" + sOtaTopic)
printMsg("订阅主题:" + sNtpTopic)
printMsg("订阅主题:" + sPropertyTopic)
printMsg("订阅主题:" + sFunctionTopic)
printMsg("订阅主题:" + sPropertyOnline)
printMsg("订阅主题:" + sFunctionOnline)
printMsg("订阅主题:" + sMonitorTopic)
# 发布设备信息
publishInfo()
global g_rc
g_rc=0
else:
printMsg("连接失败rc="+str(rc))
printMsg("3秒后重连...")
time.sleep(3)
connectMqtt()
# 物模型-属性处理
def processProperty(payload):
data=json.loads(payload)
for item in data:
# 匹配云端定义的属性(不包含属性中的监测数据)
id = item["id"]
value=item["value"]
printMsg(str(id)+":"+str(value))
# 最后发布属性,服务端订阅存储(重要)
publishProperty(json.dumps(data))
# 物模型-功能处理
def processFunction(payload):
data=json.loads(payload)
for item in data:
# 匹配云端定义的功能
id = item["id"]
value=item["value"]
if(id=="switch"):
printMsg("开关 switch"+ str(value))
elif(id=="gear"):
printMsg("档位 gear"+ str(value))
elif(id=="light_color"):
printMsg("灯光颜色 light_color"+ str(value))
elif(id=="message"):
printMsg("屏显消息 message"+ str(value))
elif(id=="report_monitor"):
msg=randomPropertyData();
printMsg("订阅到上报监测数据指令,上报数据:")
printMsg(msg)
publishProperty(msg)
# 最后发布属性,服务端订阅存储(重要)
publishProperty(json.dumps(data))
# 回调函数在客户端订阅的主题上接收到消息时调用“message”变量是一个MQTT消息描述所有消息特征
def on_message(client,userdata,msg):
printMsg("接收数据:"+msg.topic+" "+str(msg.payload))
if(msg.topic==sOtaTopic):
printMsg("订阅到设备升级指令...")
jsonData=json.loads(msg.payload)
newVersion = jsonData["version"]
downloadUrl = jsonData["downloadUrl"]
printMsg("固件版本:"+newVersion)
printMsg("下载地址:"+downloadUrl)
elif(msg.topic==sInfoTopic):
printMsg("订阅到设备信息指令...")
# 发布设备信息
publishInfo()
elif(msg.topic==sNtpTopic):
printMsg("订阅到NTP时间...");
jsonData=json.loads(msg.payload)
deviceSendTime = jsonData["deviceSendTime"]
serverSendTime = jsonData["serverSendTime"]
serverRecvTime = jsonData["serverRecvTime"]
deviceRecvTime = round(time.time()*1000)
now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2
printMsg("当前时间:"+str(round(now)))
elif(msg.topic==sPropertyTopic or msg.topic==sPropertyOnline):
printMsg("订阅到属性指令...")
processProperty(msg.payload)
elif(msg.topic==sFunctionTopic or msg.topic==sFunctionOnline):
printMsg("订阅到功能指令...")
processFunction(msg.payload)
elif(msg.topic==sMonitorTopic):
# python全局变量的使用
global t2
global monitorCount
global monitorInterval
printMsg("订阅到实时监测指令...")
jsonData=json.loads(msg.payload)
monitorCount = jsonData["count"]
monitorInterval = jsonData["interval"]/1000
t2.cancel()
t2=threading.Timer(monitorInterval,timing_publishMonitor)
t2.start()
# 1.发布设备信息
def publishInfo():
# rssi值 树莓派中暂时不处理wifi信号问题
# 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85]
# status值 1-未激活2-禁用3-在线4-离线)
doc={"rssi":1,"firmwareVersion":firmwareVersion,"status":3,"userId":userId,"longitude":longitude,"latitude":latitude,"summary":{"name":"device","chip":"esp8266","author":"kerwincui","version":1.6,"create":"2022 - 06 - 06"}}
# client.publish('raspberry/topic',payload=i,qos=0,retain=False)
jsonData=json.dumps(doc)
printMsg("发布设备信息:"+pInfoTopic+" "+jsonData)
client.publish(pInfoTopic,jsonData)
# 2.发布时钟同步信,用于获取当前时间(可选)
def publishNtp():
data={"deviceSendTime":round(time.time()*1000)}
jsonData=json.dumps(data)
printMsg("发布NTP信息"+jsonData)
client.publish(pNtpTopic,jsonData)
# 3.发布属性
# msg 接收格式json
def publishProperty(msg):
printMsg("发布属性:" + msg)
client.publish(pPropertyTopic, msg)
# 4.发布功能
def publishFunction( msg):
printMsg("发布功能:" + msg)
client.publish(pFunctionTopic, msg)
# 5.发布事件
def publishEvent():
objTmeperature={"id":"height_temperature","value":40,"remark":"温度过高警告"}
objException={"id":"exception","value":"异常消息消息内容XXXXXXXX","remark":"设备发生错误"}
data=[objTmeperature,objException]
jsonData=json.dumps(data)
printMsg("发布事件:"+jsonData)
client.publish(pEventTopic,jsonData)
# 6.发布实时监测数据
def publishMonitor():
msg=randomPropertyData()
# 发布为实时监测数据,不会存储
printMsg("发布实时监测数据:"+msg)
client.publish(pMonitorTopic,msg)
# 随机生成监测值
def randomPropertyData():
# 匹配云端定义的监测数据,随机数代替监测结果
# random.randint(0,10) #生成数据包括0,10
# random.uniform(30,60)生成数据为浮点型
objTmeperature={"id":"temperature","value":str(round(random.uniform(10,30),2)),"remark":""}
objHumidity={"id":"humidity","value":str(round(random.uniform(30,60),2)),"remark":""}
objCo2={"id":"co2","value":str(random.randint(400,1000)),"remark":""}
objBrightness={"id":"brightness","value":str(random.randint(1000,10000)),"remark":""}
printMsg("随机生成监测数据值:")
data=[objTmeperature,objHumidity,objCo2,objBrightness]
print(json.dumps(data))
return json.dumps(data)
#连接mqtt
def connectMqtt():
printMsg("连接Mqtt服务器")
# 生成mqtt认证密码(设备加密认证密码加密格式为mqtt密码 & 过期时间 & 授权码,其中授权码为可选)
password = generationPwd()
encryptPassword=encrypt(password,mqttSecret,wumei_iv)
client.username_pw_set(mqttUserName,encryptPassword)
client.on_connect=on_connect
client.on_message=on_message
client.connect(mqttHost,mqttPort,10)
#打印提示信息
def printMsg(msg):
print("[{}] {}".format(time.strftime("%Y-%m-%d %H:%M:%S"),msg))
# 生成密码
def generationPwd():
try:
doc=json.loads(getTime())
except:
printMsg("Json解析失败")
exit()
deviceSendTime = doc["deviceSendTime"]
serverSendTime = doc["serverSendTime"]
serverRecvTime = doc["serverRecvTime"]
deviceRecvTime = round(time.time()*1000)
now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2
expireTime = int(now + 1 * 60 * 60 * 1000)
# 密码加密格式为mqtt密码 & 过期时间 & 授权码(可选),如果产品启用了授权码就必须加上
password=""
if(authCode == ""):
password = mqttPwd + "&" + str(expireTime, 0)
else:
password = mqttPwd + "&" + str(expireTime, 0) + "&" + authCode
printMsg("密码(未加密):" + password)
return password
# HTTP获取时间
def getTime():
try:
r=requests.get(ntpServer+str(round(time.time()*1000)))
if(r.status_code>0):
if(r.status_code==200 or r.status_code==301):
printMsg("获取时间成功data:"+r.text)
return r.text
else:
printMsg("获取时间失败error:"+r.status_code)
except:
printMsg("连接Http失败")
# 定时上报属性
def timing_publishProperty():
printMsg("执行定时上报")
#发布事件
publishEvent()
#发布时钟同步
publishNtp()
# 发布属性(监测值)
msg=randomPropertyData()
publishProperty(msg)
t1=threading.Timer(60,timing_publishProperty)
t1.start()
# 定时上报监测数据
def timing_publishMonitor():
global monitorCount
monitorCount=monitorCount-1
printMsg("执行监测")
publishMonitor()
if(monitorCount>0):
t2=threading.Timer(monitorInterval,timing_publishMonitor)
t2.start()
if __name__ == '__main__':
connectMqtt()
client.loop_start()
printMsg("等待连接MQTT")
while(g_rc!=0):
print("-",end=" ")
time.sleep(1)
t1=threading.Timer(60,timing_publishProperty)
t1.setDaemon(True) #当主线程被关闭后,子线程也关闭
t1.start()
t2=threading.Timer(monitorInterval,timing_publishMonitor)
t2.setDaemon(True) #当主线程被关闭后,子线程也关闭
t2.start()
while True:
time.sleep(10) #定时上报、检测上报都是线程执行,主线程可以做自己的任务

View File

@@ -1,26 +0,0 @@
Eclipse Paho MQTT Python Client 使用手册
https://www.cooooder.com/archives/20210303
Python 实现AES加密
https://zhuanlan.zhihu.com/p/261694311
python实现AES加密解密
https://blog.csdn.net/chouzhou9701/article/details/122019967
使用python time()方法
http://www.py.cn/jishu/jichu/20424.html
python 线程定时器Timer
https://zhuanlan.zhihu.com/p/91412537
浅谈Python的格式化输出
https://www.jb51.net/article/225609.htm
Python Request库入门
https://www.jianshu.com/p/d78982126318
Python JSON
https://www.runoob.com/python/python-json.html
Python random() 函数
https://www.runoob.com/python/func-number-random.html

View File

@@ -1,37 +0,0 @@
## 硬件端合宙SDK说明
#### 一、运行环境
- vs code 仿真
- air724板子 在选择底层库pac文件时注意 支持float 类型
1. 在vs code 里面安装 luatIDE
2. 安装air724 usb 相关驱动
3. 使用luatools
以上均参考 https://doc.openluat.com/wiki/26?wiki_page_id=3063
#### 二、运行代码
1. 在vs code 下仿真调试
mainVscode.lua 复制为 main.lua
注释掉 WeiMeiApp.lua 里面与硬件相关的代码 如adc 温度等
在WuMeiTest.lua 文件里面 配置 产品ID MQTT 等信息
仿真调试
2. 在air724硬件上运行代码
mainAir724.lua 复制为 main.lua
取消 WeiMeiApp.lua 里面与硬件相关的代码注释 如adc 温度等
在WuMeiTest.lua 文件里面 配置 产品ID MQTT 等信息
用luatools 建立工程 需要加载 main.lua WeiMeiApp.lua WeiMeiComAuth.lua WeiMeiComInteraction.lua WuMeiTest.lua 文件 以及带float 类型的底层库
#### 三、代码文件说明
1. WeiMeiComAuth.lua 用于认证处理
支持 简单认证和加密认证
2. WeiMeiComInteraction.lua 用户交互
支持 信息 属性 功能 事件 监控
支持 设置定时上传 属性 功能 事件
3. WeiMeiApp.lua
主要开发在这个文件里面
对外提供 信息 属性 功能 事件 数据函数 改函数直接返回打包好的json 字符串

View File

@@ -1,83 +0,0 @@
--- 模块功能物美MQTT应用
-- @author 杜兴杰
-- @module 物美MQTT应用
-- @license MIT
-- @copyright 杜兴杰
-- @email 1066950103@qq.com
-- @release 2022.8.5
module(..., package.seeall)
local VERSION = "0.1"
local m_strUserId = "1"
local m_strLongitude = "0"
local m_strLatitude = "0"
local m_nTemperature = 25
--local m_nVoltval = 4.0
--模块温度返回回调函数
--@temp温度srting类型如果要对该值进行运算可以使用带float的固件将该值转为number
local function getTemperatureCb(temp)
m_nTemperature = temp
end
--- ADC读取测试
-- @return 无
-- @usage read()
local function read0()
--ADC0接口用来读取电压
local ADC_ID = 0
local adcval,voltval = adc.read(ADC_ID)
log.info("testAdc0.read",adcval,(voltval-(voltval%3))/3,voltval)
-- 输出计算得出的原始电压值
m_nVoltval = voltval/3 * 3127 / 1000
log.info("testAdc0.Vbat", m_nVoltval)
end
--2秒循环查询模块温度
sys.timerLoopStart(misc.getTemperature,1000,getTemperatureCb)
sys.timerLoopStart(read0,1000)
-- 开启对应的adc通道
adc.open(0)
function FunctionData()
local jsonStr = ""
end
function PropertyData()
local jsonData = {{
id= "temperature",
value= m_nTemperature ,
remark="温度信息"
},{
id= "voltage",
value= m_nVoltval,
remark="电压信息"
}}
local jsonStr = json.encode(jsonData)
return jsonStr
end
function InformationData()
local jsonData = {
rssi = net.getRssi(),
firmwareVersion = VERSION,
status = 3 ,
userId = m_strUserId ,
longitude = m_strLongitude ,
latitude = m_strLatitude,
summary = {
name= "device",
chip = "air724",
author = "duxingjie",
version=0.1,
create = "2022-08-07"
}
}
local jsonStr = json.encode(jsonData)
return jsonStr
end

View File

@@ -1,175 +0,0 @@
--- 模块功能物美MQTT认证
-- @author 杜兴杰
-- @module 物美MQTT通信
-- @license MIT
-- @copyright 杜兴杰
-- @email 1066950103@qq.com
-- @release 2022.8.4
module(..., package.seeall)
require"http"
require"utils"
require "common"
require"misc"
local m_strEncryptionMode
local m_strProductId
local m_strDeviceId
local m_strUserId
local m_strUser
local m_strPassword
local m_nTimeout
local m_strIp
local m_strDeviceAuthorizationCode = nil
local m_strProductPassword = nil
local m_InitCallback = nil
local m_strOutPassword
local m_strClientId
local m_nTimeSyncFlag
local function CreateCommunicationPassword()
if m_strEncryptionMode == "S" then
if nil == m_strDeviceAuthorizationCode then
m_strOutPassword = m_strPassword
else
m_strOutPassword = m_strPassword .. "&" .. m_strDeviceAuthorizationCode
end
return true
end
if m_strEncryptionMode == "E" then
m_strOutPassword = AesPassword()
return true
end
return false
end
local function Callback(nResult)
log.info("Callback" .. nResult)
if m_InitCallback ~= nil then
m_InitCallback(nResult)
end
end
local function ParameterCheck()
return true
end
local function FormatUnixTime2Date(unixTime)
if unixTime and unixTime >= 0 then
unixTime = unixTime /1000
local ntim = os.date("*t", unixTime)
return ntim
end
end
local function CreatedClientId()
m_strClientId = m_strEncryptionMode .. "&" .. m_strDeviceId .. "&" .. m_strProductId .. "&" .. m_strUserId
end
local function httpCallbackFun(result,prompt,head,body)
log.info("GetTimeHttp.cbFnc",result,prompt)
if result and body then
log.info("GetTimeHttp.cbFnc"..body.."bodyLen="..body:len())
local nDeviceRunTickMs = rtos.tick() * 5
local jsonObj = json.decode(body)
local nDeviceSendTime = jsonObj["deviceSendTime"]
local nServerSendTime = jsonObj["serverSendTime"]
local nServerRecvTime = jsonObj["serverRecvTime"]
local nSyncTime = (nServerRecvTime + nServerSendTime + nDeviceRunTickMs - nDeviceSendTime)/2
log.info("nSyncTime=" .. nSyncTime)
local tTime = FormatUnixTime2Date(nSyncTime)
log.info("tTime" .. tTime.year)
misc.setClock(tTime,nil)
--rtos.set_time(tTime.year,tTime.month,tTime.day,tTime.hour,tTime.min,tTime.sec)
--创建客户端ID
CreatedClientId()
--创建密码
CreateCommunicationPassword()
Callback(1)
m_nTimeSyncFlag = 1
end
end
function SyncTime()
local nDeviceRunTickMs = rtos.tick() * 5
local strUrl = "http://" .. m_strIp .. ":8080/iot/tool/ntp?deviceSendTime=" .. nDeviceRunTickMs
http.request("GET",strUrl,nil,nil,nil,nil,httpCallbackFun)
end
local function GetCurrentTime()
local tm = misc.getClock()
local nCurrentTime = os.time(tm)
return nCurrentTime
end
local function AesPassword()
local nCurrentTime = GetCurrentTime()
local nExpireTime = m_nTimeout + nCurrentTime
local strAesSource = nil
if nil == m_strDeviceAuthorizationCode then
strAesSource = m_strPassword .. "&" .. nExpireTime
else
strAesSource = m_strPassword .. "&" .. nExpireTime .. "&" .. m_strDeviceAuthorizationCode
end
--加密内容: mqtt密码 & expireTime & 授权码(可选)
--加密模式CBC填充方式Pkcs5Padding密钥1234567890123456密钥长度128 bit偏移量1234567890666666
encodeStr = crypto.aes_encrypt("CBC","PKCS5",strAesSource,m_strProductPassword,"wumei-smart-open")
log.info("AesPassword strAesSource" .. strAesSource .. " encodeStr " .. encodeStr )
encodeStr = crypto.base64_encode(encodeStr,slen(encodeStr))
log.info("AesPassword strAesSource" .. strAesSource .. " encodeStrbase64 " .. encodeStr )
return encodeStr
end
--- mqtt认证初始化
-- @string strEncryptionMode,string类型,认证类型S=简单认证E=加密认证
-- @string strProductId,string类型物美里面定义的产品ID
-- @string strDeviceId,string类型设备ID 一般用imei
-- @string strUserId,string类型用户ID
-- @string strUser,string类型用户
-- @string strPassword,string类型密码
-- @number nTimeout,number类型延迟秒为单位
-- @string strIp,string类型Ip
-- @string strDeviceAuthorizationCode,string类型 设备认证码 不用不填
-- @string strProductPassword,string类型 产品密码
-- @return nil
function Init(strEncryptionMode,strProductId,strDeviceId,strUserId,strUser,strPassword,nTimeout,strIp,strDeviceAuthorizationCode,strProductPassword,callback)
m_strEncryptionMode = strEncryptionMode
m_strProductId = strProductId
m_strDeviceId = strDeviceId
m_strUserId = strUserId
m_strUser = strUser
m_strPassword = strPassword
m_nTimeout = nTimeout
m_strIp = strIp
if nil == strDeviceAuthorizationCode then
m_strDeviceAuthorizationCode = strDeviceAuthorizationCode
end
if nil == strProductPassword then
m_strProductPassword = strProductPassword
end
m_nTimeSyncFlag = 0
m_InitCallback = callback
--if ParameterCheck() == false then
-- Callback(0)
-- end
SyncTime()
end
function GetUser()
return m_strUser
end
function GetPassword()
return m_strOutPassword
end
function GetClientId()
return m_strClientId
end
function GetIP()
return m_strIp
end

View File

@@ -1,289 +0,0 @@
--- 模块功能物美MQTT交互
-- @author 杜兴杰
-- @module 物美MQTT通信
-- @license MIT
-- @copyright 杜兴杰
-- @email 1066950103@qq.com
-- @release 2022.8.5
module(..., package.seeall)
local m_strProductId
local m_strDeviceNum
local m_tMessageQueue = {}
local m_callbackPropertyData = nil
local m_callbackFunctionData = nil
local m_callbackEventData = nil
local m_callbackDeviceInformationData = nil
local m_timePropertyId = 0
local m_timeFunctionId = 0
local m_timeEventId = 0
local m_nMonitorCount = 0
local m_nMonitorTime = 0
local m_timeMonitorId = 0
local function GetSubscriberDeviceInformation()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/info/get"
end
local function GetSubscriberDeviceInOta()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/ota/get"
end
local function GetSubscriberDeviceProperty()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/property/get"
end
local function GetSubscriberDevicePropertyOnline()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/property-online/get"
end
local function GetSubscriberDeviceFunction()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/function/get"
end
local function GetSubscriberDeviceFunctionOnline()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/function-online/get"
end
local function GetSubscriberDeviceMonitor()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/monitor/get"
end
local function GetSubscriberDeviceNtp()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/ntp/get"
end
local function GetPublishDeviceInformation()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/info/post"
end
local function GetPublishDeviceProperty()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/property/post"
end
local function GetPublishDeviceFunction()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/function/post"
end
local function GetPublishDeviceEvent()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/event/post"
end
local function GetPublishDeviceNtp()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/ntp/post"
end
local function GetPublishMonitorProperty()
return "/" .. m_strProductId .. "/" .. m_strDeviceNum .. "/monitor/post"
end
local function PropertyPush()
if m_callbackPropertyData ~= nil then
local strTopic = GetPublishDeviceProperty()
local strMessage = m_callbackPropertyData()
local nQos = 1
table.insert(m_tMessageQueue,{topic=strTopic,payload=strMessage,qosr=nQos})
log.info("------------------PropertyPush---------------")
end
end
local function FunctionPush()
if m_callbackFunctionData ~= nil then
local strTopic = GetPublishDeviceFunction()
local strMessage = m_callbackFunctionData()
local nQos = 1
table.insert(m_tMessageQueue,{topic=strTopic,payload=strMessage,qosr=nQos})
log.info("------------------FunctionPush---------------")
end
end
local function EventPush()
if m_callbackEventData ~= nil then
local strTopic = GetPublishDeviceEvent()
local strMessage = m_callbackEventData()
local nQos = 1
table.insert(m_tMessageQueue,{topic=strTopic,payload=strMessage,qosr=nQos})
log.info("------------------EventPush---------------")
end
end
local function MonitorPush()
if m_callbackPropertyData ~= nil then
local strTopic = GetPublishMonitorProperty()
local strMessage = m_callbackPropertyData()
local nQos = 1
table.insert(m_tMessageQueue,{topic=strTopic,payload=strMessage,qosr=nQos})
log.info("------------------MonitorPush---------------")
end
end
local function DeviceMonitorTimeCallback()
MonitorPush()
if m_nMonitorCount ~= 0 then
m_nMonitorCount = m_nMonitorCount -1
m_timeMonitorId = sys.timerStart(
DeviceMonitorTimeCallback
,m_nMonitorTime)
else
sys.timerStop(m_timeMonitorId)
m_timeMonitorId= 0
end
log.info("----m_nMonitorCount=" .. m_nMonitorCount)
end
local function DeviceInformationPush()
if m_callbackDeviceInformationData ~= nil then
local strTopic = GetPublishDeviceInformation()
local strMessage = m_callbackDeviceInformationData()
local nQos = 1
table.insert(m_tMessageQueue,{topic=strTopic,payload=strMessage,qosr=nQos})
end
end
--- mqtt交互初始化
-- @string strProductId,string类型,产品ID
-- @string strDeviceNum,string类型设备号 IMEI
-- @return nil
function Init(strProductId,strDeviceNum)
m_strProductId = strProductId
m_strDeviceNum = strDeviceNum
end
--- mqtt交互延时初始化
-- @return nil
function DelayInit()
DeviceInformationPush();
end
--- mqtt 获取待发送数据 一次取出一天且删除
-- @return bResult false 没有数据 true 有数据
-- @return strMessage 要发送的数据
-- @return strTopic 要发送的主题
-- @return nQos 发送消息级别
function GetData()
local bResult = false
local strMessage =""
local strTopic =""
local nQos = 0
if #m_tMessageQueue>0 then
local outMsg = table.remove(m_tMessageQueue,1)
bResult = true
strMessage = outMsg.payload
strTopic = outMsg.topic
nQos = outMsg.qosr
end
return bResult,strMessage,strTopic,nQos
end
--- mqtt 设置属性的获取获取函数,内部调用发送的时候会执行这个函数 这个函数外部实现
-- @function callback,函数类型, 数据函
function SetCallbackPropertyData(callback)
m_callbackPropertyData = callback
end
--- mqtt 设置功能的获取获取函数,内部调用发送的时候会执行这个函数 这个函数外部实现
-- @function callback,函数类型, 数据函
function SetCallbackFunctionData(callback)
m_callbackFunctionData = callback
end
--- mqtt 设置事件的获取获取函数,内部调用发送的时候会执行这个函数 这个函数外部实现
-- @function callback,函数类型, 数据函
function SetCallbackEventData(callback)
m_callbackEventData = callback
end
--- mqtt 设置设备信息获取函数,这个函数外部实现
-- @function callback,函数类型, 数据函
function SetCallbackInformationData(callback)
m_callbackDeviceInformationData = callback
end
--- mqtt 设置属性发布
-- @number nTime,数字类型, 0停止定时器 其他值开启定时器
function SetPropertyPush(nTime)
if m_timePropertyId ~= 0 then
sys.timerStop(m_timePropertyId)
m_timePropertyId = 0
end
if nTime~= 0 then
m_timePropertyId = sys.timerLoopStart(PropertyPush,nTime)
end
end
--- mqtt 设置功能发布
-- @number nTime,数字类型, 0停止定时器 其他值开启定时器
function SetFunctionPush(nTime)
if m_timeFunctionId ~= 0 then
sys.timerStop(m_timeFunctionId)
m_timeFunctionId = 0
end
if nTime~= 0 then
m_timeFunctionId = sys.timerLoopStart(FunctionPush,nTime)
end
end
--- mqtt 设置事件发布
-- @number nTime,数字类型, 0停止定时器 其他值开启定时器
function SetEventPush(nTime)
if m_timeEventId ~= 0 then
sys.timerStop(m_timeEventId)
m_timeEventId = 0
end
if nTime~= 0 then
m_timeEventId = sys.timerLoopStart(EventPush,nTime)
end
end
--- mqtt 获取要订阅的所有主题
-- @return tSubscriber,表类型, topic 主题 qos级别
function GetSubscriberAll()
local tSubscriber ={}
table.insert(tSubscriber,{topic=GetSubscriberDeviceInformation(),qos=1})
table.insert(tSubscriber,{topic=GetSubscriberDeviceProperty(),qos=1})
table.insert(tSubscriber,{topic=GetSubscriberDevicePropertyOnline(),qos=1})
table.insert(tSubscriber,{topic=GetSubscriberDeviceFunction(),qos=1})
table.insert(tSubscriber,{topic=GetSubscriberDeviceFunctionOnline(),qos=1})
table.insert(tSubscriber,{topic=GetSubscriberDeviceMonitor(),qos=1})
table.insert(tSubscriber,{topic=GetSubscriberDeviceNtp(),qos=1})
return tSubscriber
end
--- mqtt接受数据
-- @string topic,string类型,接收到的主题
-- @string message,string类型消息内容
-- @return nil
function OnRecvData(topic , message)
if topic == GetSubscriberDeviceInformation() then
DeviceInformationPush();
elseif topic == GetSubscriberDeviceInOta() then
local jsonObj = json.decode(message)
local strVersion = jsonObj["version"]
local strUrl = jsonObj["downloadUrl"]
elseif topic == GetSubscriberDeviceProperty() then
PropertyPush();
elseif topic == GetSubscriberDevicePropertyOnline() then
PropertyPush();
elseif topic == GetSubscriberDeviceFunction() then
FunctionPush();
elseif topic == GetSubscriberDeviceFunctionOnline() then
FunctionPush();
elseif topic == GetSubscriberDeviceMonitor() then
local jsonObj = json.decode(message)
m_nMonitorCount = jsonObj["count"]
m_nMonitorTime = jsonObj["interval"]
if m_timeMonitorId ~= 0 then
sys.timerStop(m_timeMonitorId)
m_timeMonitorId = 0
end
m_timeMonitorId = sys.timerStart(
DeviceMonitorTimeCallback
,m_nMonitorTime)
elseif topic == GetSubscriberDeviceNtp() then
log.info("--DeviceNtp---" .. message)
end
end

View File

@@ -1,133 +0,0 @@
--- 模块功能物美MQTT测试
-- @author 杜兴杰
-- @module 物美MQTT通信测试
-- @license MIT
-- @copyright 杜兴杰
-- @email 1066950103@qq.com
-- @release 2022.8.5
module(..., package.seeall)
require"WeiMeiComAuth"
require"WeiMeiComInteraction"
require"WeiMeiApp"
require"misc"
require"mqtt"
local ready = false
--物美配置参数相关配置
local m_strEncryptionMode = "S"
local m_strProductId = 220
local m_strDeviceId = nil
local m_strUserId = "1" -- admin
local m_strMqttUser = "wumei-smart"
local m_strMqttPassword = "PVMXS6V46205CAQ5"
local m_strProductPassword = "KC3169JOU816X5C0" --产品密码
local m_nMqttAuthenticationTimeout = 24*60*60*1000 --24小时
local m_strMqttIp = "wumei.live"
local m_strDeviceAuthorizationCode = "A25040D2E34B483DA371B5F9A315BB43" --设备授权码
local m_mqttClient = nil
local m_mqttFlag = 0
function AuthenticationResultCallback(nResult)
if nResult == 1 then
log.info("---AuthenticationResultCallback---ok")
WeiMeiComInteraction.Init(m_strProductId,m_strDeviceId)
m_mqttFlag = 1
end
end
local function MqttInit()
WeiMeiComAuth.Init(m_strEncryptionMode,m_strProductId,m_strDeviceId,m_strUserId,m_strMqttUser,m_strMqttPassword,m_nMqttAuthenticationTimeout,m_strMqttIp,m_strDeviceAuthorizationCode,m_strProductPassword,AuthenticationResultCallback)
end
-- 订阅所有主题
local function GetSubscriberAll()
local tSubscriber = WeiMeiComInteraction.GetSubscriberAll()
while #tSubscriber > 0 do
local ouSubscriber = table.remove(tSubscriber,1)
if m_mqttClient:subscribe({[ouSubscriber.topic]=ouSubscriber.qos}) == nil then
log.info("subscribe eeror ")
return false
end
end
return true
end
--- MQTT连接是否处于激活状态
-- @return 激活状态返回true非激活状态返回false
-- @usage mqttTask.isReady()
function isReady()
return ready
end
--启动MQTT客户端任务
sys.taskInit(
function()
local retryConnectCnt = 0
while true do
if not socket.isReady() then
retryConnectCnt = 0
--等待网络环境准备就绪超时时间是5分钟
sys.waitUntil("IP_READY_IND",300000)
end
if socket.isReady() then
m_strDeviceId = misc.getImei()
MqttInit()
while m_mqttFlag == 0 do
sys.wait(50)
end
--创建一个MQTT客户端
log.info("ClientId=" .. WeiMeiComAuth.GetClientId() )
log.info("User=" .. WeiMeiComAuth.GetUser() )
log.info("Password=" .. WeiMeiComAuth.GetPassword() )
log.info("Ip=" .. WeiMeiComAuth.GetIP() )
m_mqttClient = mqtt.client(WeiMeiComAuth.GetClientId(),600,WeiMeiComAuth.GetUser(),WeiMeiComAuth.GetPassword())
if m_mqttClient:connect(WeiMeiComAuth.GetIP(),1883,"tcp") then
retryConnectCnt = 0
ready = true
--订阅主题
if GetSubscriberAll() == true then
WeiMeiComInteraction.SetCallbackInformationData(WeiMeiApp.InformationData)
WeiMeiComInteraction.SetCallbackPropertyData(WeiMeiApp.PropertyData)
WeiMeiComInteraction.SetPropertyPush(1000*30) --30秒钟定时上传一次属性
WeiMeiComInteraction.DelayInit()
--循环处理接收和发送的数据
while true do
local result,data = m_mqttClient:receive(300,"APP_SOCKET_SEND_DATA")
if result or data=="timeout" or data=="APP_SOCKET_SEND_DATA" then
if result then
log.info("data.topic" .. data.topic .. "data.payload" .. data.payload)
WeiMeiComInteraction.OnRecvData(data.topic,data.payload);
end
else
break -- 出错了
end
result,strMessage,strTopic,nQos = WeiMeiComInteraction.GetData()
if result == true then
local mqttResult = m_mqttClient:publish(strTopic,strMessage,nQos)
if not mqttResult then
break
end
end
end
end
ready = false
else
retryConnectCnt = retryConnectCnt+1
end
--断开MQTT连接
m_mqttClient:disconnect()
if retryConnectCnt>=5 then link.shut() retryConnectCnt=0 end
sys.wait(5000)
else
--进入飞行模式20秒之后退出飞行模式
net.switchFly(true)
sys.wait(20000)
net.switchFly(false)
end
end
end
)

View File

@@ -1,32 +0,0 @@
## 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

@@ -1,32 +0,0 @@
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

@@ -1,32 +0,0 @@
# 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

@@ -1,21 +0,0 @@
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

@@ -1,604 +0,0 @@
/*
* 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

@@ -1,20 +0,0 @@
#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

@@ -1,181 +0,0 @@
#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

@@ -1,183 +0,0 @@
/*
* 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

@@ -1,175 +0,0 @@
/**
* @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

@@ -1,25 +0,0 @@
/**
* @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

@@ -1,70 +0,0 @@
/*
* 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

@@ -1,5 +0,0 @@
#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

@@ -1,62 +0,0 @@
/**
* @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

@@ -1,15 +0,0 @@
#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

@@ -1,356 +0,0 @@
#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

@@ -1,116 +0,0 @@
/**
* @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

@@ -1,191 +0,0 @@
/**
* @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

@@ -1,15 +0,0 @@
#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

@@ -1,9 +0,0 @@
/* 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

@@ -1,9 +0,0 @@
/* 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

@@ -1,388 +0,0 @@
/*--------------------------------------------------------------+
| |
| 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

@@ -1,77 +0,0 @@
/*--------------------------------------------------------------+
| |
| 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

@@ -1,451 +0,0 @@
/*--------------------------------------------------------------+
| |
| 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

@@ -1,9 +0,0 @@
/* 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

@@ -1,815 +0,0 @@
/**************************************************************************//**
* @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

@@ -1,361 +0,0 @@
/**************************************************************************//**
* @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

@@ -1,39 +0,0 @@
/**************************************************************************//**
* @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

@@ -1,123 +0,0 @@
/****************************************************************************
*
* 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

@@ -1,182 +0,0 @@
/******************************************************************************
* @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

@@ -1,7 +0,0 @@
#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

@@ -1,105 +0,0 @@
/**************************************************************************//**
* @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

@@ -1,7 +0,0 @@
#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

@@ -1,268 +0,0 @@
#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

@@ -1,36 +0,0 @@
#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

@@ -1,77 +0,0 @@
#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

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

View File

@@ -1,170 +0,0 @@
#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

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

View File

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

View File

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

View File

@@ -1,36 +0,0 @@
#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

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