Программный модуль для очистителя воздуха RAC-3706S. v.1.5
ПО является неотъемлемой частью очистителя воздуха RAC-3706S, отдельно потребителю не поставляется и эксплуатируется только в составе устройства.
////////////////////////////////////////////////////////////////
//RAC-3706S
//v1.5
//application.c
////////////////////////////////////////////////////////////////
#include "common.h"
#include "application.h"
#include "api.h"
#include "adc.h"
#include "clk.h"
#include "buz.h"
#include "keyb.h"
#include "display.h"
#include "nrf_soc.h"
#include "rtc1.h" //(ash)
////////////////////////////////////////////////////////////////
void RTC1_COMPARE3_Handler(void); //(ash)
////////////////////////////////////////////////////////////////
u16 TRC_VAR_TAB[]= {
325, // 0
320, // 1
315, // 2
310, // 3
305, // 4
300, // 5
295, // 6
290, // 7
285, // 8
280, // 9
275, // 10
272, // 11
269, // 12
266, // 13
263, // 14
260, // 15
257, // 16
254, // 17
251, // 18
248, // 19
245, // 20
243, // 21
241, // 22
239, // 23
237, // 24
235, // 25
233, // 26
231, // 27
229, // 28
227, // 29
225, // 30
223, // 31
221, // 32
219, // 33
217, // 34
215, // 35
213, // 36
211, // 37
209, // 38
207, // 39
205, // 40
203, // 41
201, // 42
199, // 43
197, // 44
195, // 45
193, // 46
191, // 47
189, // 48
187, // 49
185, // 50
184, // 51
183, // 52
182, // 53
181, // 54
180, // 55
179, // 56
178, // 57
177, // 58
176, // 59
175, // 60
174, // 61
173, // 62
172, // 63
171, // 64
170, // 65
169, // 66
168, // 67
167, // 68
166, // 69
165, // 70
164, // 71
163, // 72
162, // 73
161, // 74
160, // 75
159, // 76
158, // 77
157, // 78
156, // 79
155, // 80
154, // 81
153, // 82
152, // 83
151, // 84
150, // 85
149, // 86
148, // 87
147, // 88
146, // 89
145, // 90
144, // 91
143, // 92
142, // 93
141, // 94
140, // 95
139, // 96
138, // 97
137, // 98
136, // 99
135, // 100
134, // 101
133, // 102
132, // 103
131, // 104
130, // 105
129, // 106
128, // 107
127, // 108
126, // 109
125, // 110
124, // 111
123, // 112
122, // 113
121, // 114
120, // 115
119, // 116
118, // 117
117, // 118
116, // 119
115, // 120
114, // 121
113, // 122
112, // 123
111, // 124
110, // 125
109, // 126
108, // 127
107, // 128
106, // 129
105, // 130
104, // 131
103, // 132
102, // 133
101, // 134
100, // 135
99, // 136
98, // 137
97, // 138
96, // 139
95, // 140
94, // 141
93, // 142
92, // 143
91, // 144
90, // 145
89, // 146
88, // 147
87, // 148
86, // 149
85, // 150
84, // 151
83, // 152
82, // 153
81, // 154
80, // 155
79, // 156
78, // 157
77, // 158
76, // 159
75, // 160
74, // 161
73, // 162
72, // 163
71, // 164
70, // 165
69, // 166
68, // 167
67, // 168
66, // 169
65, // 170
63, // 171
61, // 172
59, // 173
57, // 174
55, // 175
53, // 176
51, // 177
49, // 178
47, // 179
45, // 180
43, // 181
41, // 182
39, // 183
37, // 184
35, // 185
33, // 186
31, // 187
29, // 188
27, // 189
25, // 190
23, // 191
21, // 192
19, // 193
17, // 194
15, // 195
13, // 196
11, // 197
9, // 198
7, // 199
5, // 200
};
u16 speedAtLevel[8] = {
0,
300, // 1
450, // 2
600, // 3
750, // 4
900, // 5
1300, // 6
1500 // ultraz
};
float dustSenseTab[6] = {
1.0, //no use
1.0, // 1
0.85, // 2
0.7, // 3
0.55, // 4
0.4 // 5
};
#define T_3S 30 // 30*100ms
#define T_6S 60 // 60*100ms
#define T_9S 90 // 90*100ms
#define MAX_TRC_VAR 200
#define MIN_TRC_VAR 20
#define MAX_FAN_SPEED 1500
#define MIN_FAN_SPEED 80
#define abs(x) ((x>0)?(x):(-x))
s16 fsErr1=0, fsErr2=0;
s8 indErr[11] = {0};
s16 indErr16;
u8 divVar;
u32 saveDataBuf[3]; //(jhb-add for save data to NVM )
u8 saveDataNecessary; //(jhb)-
u16 saveDataDlyTime; //(jhb)-
u8 saveDataFinished; //(jhb)-
///////////////////////////////////////////////////////////////
void simple_uart_config(uint8_t rts_pin_number, uint8_t txd_pin_number, uint8_t cts_pin_number, uint8_t rxd_pin_number, bool hwfc)
{
/** @snippet [Configure UART RX and TX pin] */
nrf_gpio_cfg_output(txd_pin_number);
nrf_gpio_cfg_input(rxd_pin_number, NRF_GPIO_PIN_NOPULL);
NRF_UART0->PSELTXD = txd_pin_number;
NRF_UART0->PSELRXD = rxd_pin_number;
/** @snippet [Configure UART RX and TX pin] */
NRF_UART0->CONFIG = 6;
if (hwfc)
{
nrf_gpio_cfg_output(rts_pin_number);
nrf_gpio_cfg_input(cts_pin_number, NRF_GPIO_PIN_NOPULL);
NRF_UART0->PSELCTS = cts_pin_number;
NRF_UART0->PSELRTS = rts_pin_number;
NRF_UART0->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos);
}
NRF_UART0->BAUDRATE = (UART_BAUDRATE_BAUDRATE_Baud19200<< UART_BAUDRATE_BAUDRATE_Pos);
NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
NRF_UART0->TASKS_STARTTX = 1;
NRF_UART0->TASKS_STARTRX = 0;
NRF_UART0->EVENTS_RXDRDY = 0;
// NRF_UART0->INTENSET = UART_INTENSET_RXDRDY_Set<<UART_INTENSET_RXDRDY_Pos;
NRF_UART0->INTENCLR = 0xfffff;
NVIC_ClearPendingIRQ(UART0_IRQn);
NVIC_SetPriority(UART0_IRQn, APP_IRQ_PRIORITY_LOW);
NVIC_EnableIRQ(UART0_IRQn);
}
void ApplyIO_Init()
{
nrf_gpio_cfg_sense_input(PIN_ZERO_INT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);
nrf_gpio_cfg_sense_input(PIN_SPEED, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);
NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Enabled << GPIOTE_INTENSET_PORT_Pos;
//---------------------------------------------------------------------------------
nrf_gpio_cfg_output(PIN_FAN);
nrf_gpio_cfg_output(PIN_ION);
nrf_gpio_cfg_output(PIN_BUZ);
nrf_gpio_cfg_output(PIN_DUST_AD_EN);
nrf_gpio_cfg_output(PIN_LED1);
nrf_gpio_cfg_output(PIN_LED2);
nrf_gpio_cfg_output(PIN_LED3);
//---------------------------------------------------------------------------------
nrf_gpio_cfg_input(KEYB_D, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(PIN_IR, NRF_GPIO_PIN_PULLUP); //(ash)
nrf_gpio_cfg_input(PIN_DUST_AD, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(PIN_DUST_SENSTIVE, NRF_GPIO_PIN_PULLUP); //(jhb)
// NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
// NVIC_ClearPendingIRQ(GPIOTE_IRQn);
// NVIC_EnableIRQ(GPIOTE_IRQn);
//=============================================================
// simple_uart_config(0, PIN_SDA, 0, PIN_NOT_USED, FALSE);
}
//(ash)
//void Rtc1_init()
//{
// NRF_CLOCK->TASKS_LFCLKSTART = 1;
// while(NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
// NRF_RTC1->PRESCALER = 0;
//
// NVIC_SetPriority(RTC1_IRQn, APP_IRQ_PRIORITY_HIGH);
// NVIC_ClearPendingIRQ(RTC1_IRQn);
// NVIC_EnableIRQ(RTC1_IRQn);
// NRF_RTC1->TASKS_START= 1;
//}
void ZERO_ISR()
{
volatile u32 counter;
u16 ccVar;
firstFallFlag = TRUE;
if(noSpeedSignalCnt <30) noSpeedSignalCnt++;
else {
fspdBk = 0;
fanSpeed = 0;
}
if(trcVar > MAX_TRC_VAR) trcVar = MAX_TRC_VAR;
ccVar = TRC_VAR_TAB[trcVar];
counter = NRF_RTC1->COUNTER;
counter += ccVar;
if(counter >= 0xFFFFFF) counter -= 0xFFFFFF;
if(trcVar <= MIN_TRC_VAR) {
nrf_gpio_pin_clear(PIN_FAN);
}else if(trcVar > (MAX_TRC_VAR - 3)) {
nrf_gpio_pin_set(PIN_FAN);
}else {
NRF_RTC1->EVENTS_COMPARE[3] = 0;
NRF_RTC1->CC[3] = counter;
NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE3_Enabled << RTC_INTENSET_COMPARE3_Pos;
}
}
static u32 lstCnt = 0;
volatile u32 cnt, spd;
void SPEED_ISR()
{
noSpeedSignalCnt = 0;
cnt = (NRF_RTC1->COUNTER);
spd = cnt;
if(cnt >= lstCnt) {
spd = cnt - lstCnt;
}else {
spd = cnt + 0xFFFFFF - lstCnt;
}
if(spd < 100) return;
spd = 327680/spd; // 32768 * 60/6 = 327680; UNIT RPM
if(spd > 32767) spd = 32767;
fspdBk = (fspdBk + spd)/2;
fanSpeed = (fspdBk + fanSpeed)/2;
lstCnt = cnt;
}
//(ash)void RTC1_IRQHandler(void)
void RTC1_COMPARE3_Handler(void) //(ash)
{
volatile u32 counter;
//(ash) if(NRF_RTC1->EVENTS_COMPARE[3]) {
NRF_RTC1->EVENTS_COMPARE[3] = 0;
//----------------------------------------------------
nrf_gpio_pin_set(PIN_FAN);
//--------------------------
if(firstFallFlag) {
firstFallFlag = 0;
counter = NRF_RTC1->COUNTER;
counter += 328;
if(counter >= 0xFFFFFF) counter -= 0xFFFFFF;
NRF_RTC1->CC[3] = counter; //interrupt at about 10ms later
}else {
NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE3_Enabled << RTC_INTENCLR_COMPARE3_Pos;
}
delay_10us(50);
nrf_gpio_pin_clear(PIN_FAN);
//(ash) }
}
const float pidTab[8][3] = {
// based on divVar = 5
0,0,0,
// Kp, Ki, Kd
15.0, 1.00, 10.0, // Speed Level 1
15.0, 1.00, 10.0, // Speed Level 2
15.0, 1.00, 10.0, // Speed Level 3
15.0, 1.00, 10.0, // Speed Level 4
15.0, 1.00, 10.0, // Speed Level 5
15.0, 1.00, 10.0, // Speed Level 6
15.0, 1.00, 10.0, // Speed Level 7
};
float ek, ek1, ek2;
float u, u1;
float Kp, Ki, Kd;
float ux;
u8 xo1, xo2, xo3, xo4;
void Pid_reset_allDat()
{
// Kp = 0;
// Ki = 0;
// Kd = 0;
u = 0;
u1 = 0;
ek = 0;
ek1 = 0;
ek2 = 0;
xo1 = 0;
xo2 = 0;
xo3 = 0;
xo4 = 0;
divVar = 5;
}
void Pid_K_Update()
{
if(fanSpeedLevel <8 ) {
Kp = pidTab[fanSpeedLevel][0];
Ki = pidTab[fanSpeedLevel][1];
Kd = pidTab[fanSpeedLevel][2];
}
}
void PidCtrl1()
{
float pErr=0;
float iErr=0;
float dErr=0;
ek = (float)((float)targetFanSpeed - (float)fanSpeed);
pErr = ek - ek1;
iErr = ek;
dErr = ek - ek1*2 + ek2;
ek2 = ek1;
ek1 = ek;
u = Kp*pErr + Ki*iErr + Kd*dErr + u1;
// if(fanSpeed==0 && u < -1000) u = 0;
if(u > 20000) u = 20000;
if(u< -2000) u= -2000;
u1 = u;
ux = u/100;
if(ux<=0) xo1 = 0;
else if(ux < MAX_TRC_VAR) xo1 = ux;
else xo1 = MAX_TRC_VAR;
xo2 = ((u16)xo1 + (u16)xo2)/2;
xo3 = ((u16)xo2 + (u16)xo3)/2;
xo4 = ((u16)xo3 + (u16)xo4)/2;
trcVar = xo2;
}
void FanSpeedControl()
{
static u8 div = 0;
if(++div < divVar) return;
div = 0;
if(targetFanSpeed < MIN_FAN_SPEED) {
trcVar = 0;
return;
}
if(targetFanSpeed > MAX_FAN_SPEED) targetFanSpeed = MAX_FAN_SPEED;
//-------------------------------------------------------------------------------------------
Pid_K_Update();
PidCtrl1();
}
////////////////////////////////////////////////////////////////
void Application_Init(void)
{
RTC1_SetCOMPARE3Handler(RTC1_COMPARE3_Handler); //(ash)
Clk_Init();
ApplyIO_Init();
Keyb_Init();
#ifdef REMOTE_IR
IR_Init();
#endif
//(ash)
NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
NVIC_ClearPendingIRQ(GPIOTE_IRQn);
NVIC_EnableIRQ(GPIOTE_IRQn);
//
//(ash) Rtc1_init();
Buz_Init();
Adc_init();
DisplayPinInit();
sysState = SYS_OFF;
timerOff_minute_set = timerOff_minute = 0; //(ash) timerOff_minute_set =
aqiHighSense = FALSE;
//(ash)
// fanSpeedLevel = FAN_OFF;
// handFspLevel = FAN_OFF;
// ionEnable = FALSE;
// targetFanSpeed = 0;
//(ash)
workingMode = MODE_HAND;
fanSpeedLevel = handFspLevel = FAN_SPD3;
ionEnable = TRUE;
rAQI = AQI_VERY_EXECLLENT;
InitDataFromFlash(); //replaced by jhb
if(workTime_seconds > (2000*3600)){
filterNeedReplace = TRUE;
}else {
filterNeedReplace = FALSE;
}
}
u16 miDivCnt = 0;
void TimeEvent(void)
{
if(flag_100ms) {
flag_100ms = FALSE;
//--------------------------------------
if(haltTime) haltTime--;
}
//===========================================
if(flag_500ms) {
flag_500ms = FALSE;
//-----------------------------------
}
//===========================================
if(flag_1s) {
flag_1s = FALSE;
miDivCnt++;
//GetTemp();
//---------------------------------------------
if(pairing) {
if(++pairStateCnt > 15) {
pairStateCnt = 0;
pairing = FALSE;
}
}
//------------------------------------
//------------------------------------
if(noUserActiveCnt < 120) noUserActiveCnt++;
//------------------------------------
if(waitTime) {
waitTime--;
if(waitTime ==0) {
}
}
//-----------------------------------------------
if(++second >= 60) {
second = 0;
//----------------------
if(timerOff_minute) {
if(--timerOff_minute ==0) {
sysState = SYS_OFF;
}
}
}
}
//----------------------------------------------------------------------------------------
if(miDivCnt >= (60*60)) { // 60 minute (ash) 5min->60min
miDivCnt = 0;
//-------------------------------
if(sysState == SYS_ON) { // only in working
if(filterNeedReplace == FALSE) {
workTime_seconds += 3600; //(ash) 300->3600
TrigSaveData(200); // 2秒后写入FLASH
}
//------------------------------------------
if(workTime_seconds > (3600*2000)){
if(filterNeedReplace == FALSE) {
Beep(3, 30);
}
filterNeedReplace = TRUE;
}else {
filterNeedReplace = FALSE;
}
}
}
//----------(lcx) add--------
if(setDustSenseLevel == FALSE && lstDustSenseLevel != dustSenseLevel) {
TrigSaveData(200); // 2秒后写入FLASH
lstDustSenseLevel = dustSenseLevel;
}
//---------------------------
}
void DustSenstiveCheck()
{
u8 pin;
static u8 divcnt1 = 0;
pin = nrf_gpio_pin_read(PIN_DUST_SENSTIVE);
if(pin ==0) {
if(++divcnt1 >= 50){
divcnt1 = 50;
aqiHighSense = TRUE;
}
}else {
if(divcnt1)divcnt1--;
else {
aqiHighSense = FALSE;
}
}
}
//------------------------------------------------------------------------------
// DUST DETECT
#define WORST_VAR (u16)351 //(488*3.6/5)
#define BEST_VAR (u16)58 //(488*0.6/5)
#define LEVEL_DEGREE (u16)49 //((WORST_VAR - BEST_VAR)/6)
u16 adbuf[6];
u16 dustVar;
u16 aqiLevelDegree;
extern u16 ad1;
void DustDetect()
{
u8 i;
u16 maxVar = 0;
static u16 dustVar_bk1=0, dustVar_bk2=0;
static u32 sum32 = 0;
static u8 cnt = 0;
nrf_gpio_pin_set(PIN_DUST_AD_EN);
for(i= 0; i<6; i++) {
AdConver();
adbuf[i] = ad1;
}
nrf_gpio_pin_clear(PIN_DUST_AD_EN);
//-----------------------------------------------------
for(i=0; i<6; i++) {
if(adbuf[i] > maxVar) maxVar = adbuf[i];
}
//-----------------------------------------------------------
//(JHB)
if(setDustSenseLevel == FALSE) { // (lcx) add
dustSenseFactor = dustSenseTab[dustSenseLevel];
}
aqiLevelDegree = LEVEL_DEGREE*dustSenseFactor; // (lcx) add
/*
if(aqiHighSense) { //以检测为准还是以设定为准??
aqiLevelDegree = LEVEL_DEGREE*0.7;
}else {
// (lcx) aqiLevelDegree = LEVEL_DEGREE;
aqiLevelDegree = LEVEL_DEGREE;
//aqiLevelDegree = LEVEL_DEGREE*dustSenseFactor; // (lcx) add
}
*/
//------------------------------------------------------------
sum32 += maxVar;
if(++cnt >= 200) {
cnt = 0;
dustVar_bk1 += (u16)(sum32/200);
sum32 = 0;
dustVar_bk1/=2;
dustVar_bk2 = (dustVar_bk2 + dustVar_bk1)/2;
dustVar = (dustVar + dustVar_bk2)/2;
//-----------------------------------------------------------
if(dustVar < BEST_VAR + (1*aqiLevelDegree)) {
rAQI = AQI_VERY_EXECLLENT;
}else if(dustVar < BEST_VAR + (2*aqiLevelDegree)) {
rAQI = AQI_EXECLLENT;
}else if(dustVar < BEST_VAR + (3*aqiLevelDegree)) {
rAQI = AQI_VERY_GOOD;
}else if(dustVar < BEST_VAR + (4*aqiLevelDegree)) {
rAQI = AQI_GOOD;
}else if(dustVar < BEST_VAR + (5*aqiLevelDegree)) {
rAQI = AQI_BAD;
}else if(dustVar < BEST_VAR + (6*aqiLevelDegree)) {
rAQI = AQI_VERY_BAD;
}
}
}
void OutPutCtrl(void)
{
if(sysState == SYS_OFF) {
targetFanSpeed = 0;
trcVar = 0;
Pid_reset_allDat();
nrf_gpio_pin_clear(PIN_ION);
nrf_gpio_pin_clear(PIN_FAN);
return;
}
targetFanSpeed = speedAtLevel[fanSpeedLevel];
if(ionEnable) nrf_gpio_pin_set(PIN_ION);
else nrf_gpio_pin_clear(PIN_ION);
}
////////////////////////////////////////////////////////////////
void Application(void)
{
if(sysState == SYS_OFF) {
return;
}
//==========================================
switch(workingMode) {
case MODE_HAND:
fanSpeedLevel = handFspLevel;
if(fanSpeedLevel > FAN_SPD6) fanSpeedLevel = FAN_SPD6;
break;
//----------------------------
case MODE_AUTO:
if(rAQI == AQI_VERY_EXECLLENT) fanSpeedLevel = FAN_SPD1;
if(rAQI == AQI_EXECLLENT) fanSpeedLevel = FAN_SPD2;
if(rAQI == AQI_VERY_GOOD) fanSpeedLevel = FAN_SPD3;
if(rAQI == AQI_GOOD) fanSpeedLevel = FAN_SPD4;
if(rAQI == AQI_BAD) fanSpeedLevel = FAN_SPD5;
if(rAQI == AQI_VERY_BAD) fanSpeedLevel = FAN_SPD6;
break;
//----------------------------
case MODE_SMOKE:
fanSpeedLevel = FAN_SPD6;
break;
//----------------------------
case MODE_NIGHT:
fanSpeedLevel = FAN_SPD1;
break;
//----------------------------
default: break;
}
//==========================================
if(workTime_seconds >= 2000*3600){
filterNeedReplace = TRUE;
}else filterNeedReplace = FALSE;
}
////////////////////////////////////////////////////////////////
//API for R4S
//The all Set...() functions return a true/false (Success/Fail) value
////////////////////////////////////////////////////////////////
//Get firmvare version
u16 API_GetVersion(void)
{
return FIRMWARE_VER;
}
bool API_On(void) //On device
{
if(sysState != SYS_OFF) return FALSE;
noUserActiveCnt = 0;
sysState = SYS_ON;
return TRUE;
}
bool API_Off(void) //Off device
{
if(sysState == SYS_OFF && !pairing) return FALSE;
timerOff_minute_set = timerOff_minute = 0; //(ash)
pairing = FALSE;
sysState = SYS_OFF;
return TRUE;
}
u8 API_GetState(void) //Get device state
{
u8 res;
if(sysState == SYS_OFF) res = API_OFF_STATE;
else {
res = API_WORK_STATE;
}
//(ash) if(errorId) res = API_ERROR_STATE;
if(pairing) res = API_PAIRING_STATE;
if(testMode) res = API_TEST_STATE;
return res;
}
bool API_SetMode(uint8_t mode) //Set mode
{
//(ash)
// if(sysState == SYS_OFF) return FALSE;
// if(mode == API_HAND_MODE) workingMode = MODE_HAND;
// if(mode == API_AUTO_MODE) workingMode = MODE_AUTO;
// if(mode == API_SMOKE_MODE) workingMode = MODE_SMOKE;
// if(mode == API_NIGHT_MODE) workingMode = MODE_NIGHT;
//
// return TRUE;
//(ash)
if(mode == API_HAND_MODE) {workingMode = MODE_HAND; return TRUE;}
if(mode == API_AUTO_MODE) {workingMode = MODE_AUTO; return TRUE;}
if(mode == API_SMOKE_MODE) {workingMode = MODE_SMOKE; return TRUE;}
if(mode == API_NIGHT_MODE) {
workingMode = MODE_NIGHT;
timerOff_minute_set = timerOff_minute = 0; //(ash 16.06.2015)
return TRUE;
}
return FALSE;
//
}
//Get mode
u8 API_GetMode(void)
{
//(ash)
// u8 res = API_HAND_MODE;
//
// if(sysState == SYS_ON) {
// if(workingMode == MODE_HAND) res = API_HAND_MODE;
// if(workingMode == MODE_AUTO) res = API_AUTO_MODE;
// if(workingMode == MODE_SMOKE) res = API_SMOKE_MODE;
// if(workingMode == MODE_NIGHT) res = API_NIGHT_MODE;
// }
//
// return res;
//(ash)
if(workingMode == MODE_HAND) return API_HAND_MODE;
if(workingMode == MODE_AUTO) return API_AUTO_MODE;
if(workingMode == MODE_SMOKE) return API_SMOKE_MODE;
if(workingMode == MODE_NIGHT) return API_NIGHT_MODE;
return API_HAND_MODE;
//
}
//Set speed
bool API_SetSpeed(u8 spdLevel)
{
//(ash)
// bool res = FALSE;
//
// if(sysState == SYS_ON) {
// if(spdLevel > FAN_SPD6) res = FALSE;
// else {
// fanSpeedLevel = spdLevel;
// res = TRUE;
// }
// }
// return res;
//(ash)
if(spdLevel == 0) return TRUE;
if(spdLevel > FAN_SPD6) return FALSE;
if(workingMode != MODE_HAND) return FALSE;
fanSpeedLevel = handFspLevel = spdLevel;
return TRUE;
//
}
//Get speed
u8 API_GetSpeed(void)
{
//(ash) if(sysState == SYS_OFF) return 0;
return fanSpeedLevel;
}
//Set work timer in hours
bool API_SetTimer(u8 hour)
{
//(ash) if(sysState == SYS_OFF) return FALSE;
//(ash) timerOff_minute = hour * 60; //
//(ash)
if(hour > 8) return FALSE;
timerOff_minute_set = hour * 60;
if(sysState == SYS_ON) timerOff_minute = timerOff_minute_set;
//
return TRUE;
}
//Get work timer in hours
u8 API_GetTimer(void)
{
//(ash)
// u8 res = 0;
//
// if(timerOff_minute==0) res = 0;
// else if(timerOff_minute <= 2*60) res = 2;
// else if(timerOff_minute <= 4*60) res = 4;
// else if(timerOff_minute <= 6*60) res = 6;
// else if(timerOff_minute <= 8*60) res = 8;
// return res;
return timerOff_minute_set / 60; //(ash)
}
u16 API_GetEndTime(void) //Get time to end of work in minutes
{
//(ash) if(sysState == SYS_OFF) return 0;
return timerOff_minute;
}
bool API_SetIon(u8 ionEn) //Set ionisation state (ON/OFF)
{
//(ash) if(sysState == SYS_OFF) return FALSE;
if(ionEn != 1 && ionEn != 0) return FALSE; //(ash)
if(workingMode == MODE_NIGHT) return FALSE; //(ash)
if(ionEn) ionEnable = 1;
else ionEnable = 0;
return TRUE;
}
u8 API_GetIon(void) //Get ionisation state (ON/OFF)
{
//(ash) if(sysState == SYS_OFF) return FALSE;
return ionEnable;
}
//(ash)
//Get air quality
u8 API_GetAirQuality(void)
{
return rAQI;
}
//
//Return a state of the unpairing flag
bool API_IsUnpairing(void)
{
return unpairingFlag;
}
//Clear unpairing flag
void API_ClrUnpairing(void)
{
unpairingFlag = FALSE;
}
u8 API_GetError(void) //Get error number (ash) u16->u8
{
return errorId;
}
////////////////////////////////////////////////////////////////
//
//(jhb)add
void InitDataFromFlash(void)
{
u8* volatile p;
u16 i = 0;
dustSenseLevel = *((u32 *)(FLASH_ADDR_dustSenseLevel)); //(lcx) add ---
workTime_seconds = *((u32 *)(FLASH_ADDR_totalTime)); //(ash) u16 -> u32
if((dustSenseLevel < DUST_SENSE_LEV1)||(dustSenseLevel > DUST_SENSE_LEV5)) {
dustSenseLevel = DUST_SENSE_LEV3;
i++;
}
dustSenseFactor = dustSenseTab[dustSenseLevel];
lstDustSenseLevel = dustSenseLevel;
//----------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
if(workTime_seconds == 0xffffffff) { // not initialed //(jhb) 0xffff -> 0xffffffff
workTime_seconds = 0;
i++;
}
if(i>0) {//need to write new initial value
u32 result;
do result = sd_flash_page_erase(FLASH_ADDR_totalTime/FLASH_PAGE_SIZE); while(result != NRF_SUCCESS);
do result = sd_flash_write((u32*)FLASH_ADDR_totalTime, &workTime_seconds, 1); while(result != NRF_SUCCESS);
do result = sd_flash_write((u32*)FLASH_ADDR_dustSenseLevel, &dustSenseLevel, 1); while(result != NRF_SUCCESS);
}
}
//------------------------------------------------------
//timeDly4Save 单位是10ms
void TrigSaveData(u16 timeDly4Save)
{
// saveDataBuf[0] = workTime_seconds;
// saveDataBuf[1] = dustSenseLevel;
saveDataDlyTime = timeDly4Save; // 3秒之后写入
saveDataNecessary = TRUE;
saveDataFinished = FALSE;
}
void UserDataSave2FlashProcess(void)
{
if(saveDataDlyTime){
saveDataDlyTime--;
return;
}
//--------------------------------------------------
if(saveDataNecessary != TRUE) return;
if(saveDataFinished == TRUE) return;
//--------------------------------------------------
{
u32 result;
//(lcx) u32 t32 = (u32)&saveDataBuf;
do result = sd_flash_page_erase(FLASH_ADDR_totalTime/FLASH_PAGE_SIZE); while(result != NRF_SUCCESS);
do result = sd_flash_write((u32*)FLASH_ADDR_totalTime, &workTime_seconds, 1); while(result != NRF_SUCCESS);
do result = sd_flash_write((u32*)FLASH_ADDR_dustSenseLevel, &dustSenseLevel, 1); while(result != NRF_SUCCESS);
saveDataFinished = TRUE;
saveDataNecessary = FALSE;
}
}