273 lines
4.7 KiB
C
273 lines
4.7 KiB
C
#include <nuvoton/functions.h>
|
|
#include <nuvoton/N76E003.h>
|
|
#include <nuvoton/Common.h>
|
|
#include <nuvoton/SFR_Macro.h>
|
|
#include <string.h>
|
|
|
|
#define M0 P03
|
|
#define M1 P04
|
|
#define M2 P01
|
|
|
|
#define RS485_DIR P05
|
|
|
|
#define OE P13
|
|
#define DS P14
|
|
#define SHCP P11
|
|
#define STCP P12
|
|
|
|
#define MAXCMD 64
|
|
|
|
unsigned char relay;
|
|
|
|
unsigned char crc;
|
|
|
|
unsigned char getchar1(void)
|
|
{
|
|
UINT8 c;
|
|
while (!RI);
|
|
c = SBUF;
|
|
RI = 0;
|
|
return (c);
|
|
}
|
|
|
|
int putchar1 (unsigned char c)
|
|
{
|
|
crc += c;
|
|
TI = 0;
|
|
SBUF = c;
|
|
while(TI==0);
|
|
return 0;
|
|
}
|
|
|
|
void sendpkt(unsigned char cmd, unsigned int len, unsigned char *buffer) {
|
|
unsigned int i;
|
|
|
|
crc = 0;
|
|
putchar1(0x55);
|
|
putchar1(0xAA);
|
|
putchar1(0x03);
|
|
putchar1(cmd);
|
|
putchar1(len >> 8);
|
|
putchar1(len & 0xFF);
|
|
|
|
for (i=0; i<len; i++) {
|
|
putchar1(buffer[i]);
|
|
}
|
|
putchar1(crc);
|
|
}
|
|
|
|
void load(void) {
|
|
OE = 0;
|
|
STCP = 0;
|
|
SHCP = 0;
|
|
|
|
DS = (relay & 0x01)? 1 : 0;
|
|
SHCP = 1;
|
|
SHCP = 0;
|
|
DS = (relay & 0x02)? 1 : 0;
|
|
SHCP = 1;
|
|
SHCP = 0;
|
|
DS = (relay & 0x04)? 1 : 0;
|
|
SHCP = 1;
|
|
SHCP = 0;
|
|
DS = (relay & 0x08)? 1 : 0;
|
|
SHCP = 1;
|
|
SHCP = 0;
|
|
DS = (relay & 0x10)? 1 : 0;
|
|
SHCP = 1;
|
|
SHCP = 0;
|
|
DS = (relay & 0x20)? 1 : 0;
|
|
SHCP = 1;
|
|
SHCP = 0;
|
|
DS = (relay & 0x40)? 1 : 0;
|
|
SHCP = 1;
|
|
SHCP = 0;
|
|
DS = (relay & 0x80)? 1 : 0;
|
|
|
|
SHCP = 1;
|
|
STCP = 1;
|
|
}
|
|
|
|
void tuya_receive (unsigned int len, unsigned char *buffer) {
|
|
unsigned char dpid;
|
|
unsigned char dtype;
|
|
unsigned int dlen;
|
|
|
|
if (len < 4) return;
|
|
dpid = buffer[0];
|
|
dtype = buffer[1];
|
|
dlen = buffer[2] << 8 + buffer[3];
|
|
|
|
switch(dpid) {
|
|
case 1:
|
|
relay = (relay & 0xFE) | (buffer[4] ? 1 : 0);
|
|
load();
|
|
break;
|
|
case 2:
|
|
relay = (relay & 0xFD) | (buffer[4] ? 2 : 0);
|
|
load();
|
|
break;
|
|
case 3:
|
|
relay = (relay & 0xFB) | (buffer[4] ? 4 : 0);
|
|
load();
|
|
break;
|
|
case 4:
|
|
relay = (relay & 0xF7) | (buffer[4] ? 8 : 0);
|
|
load();
|
|
break;
|
|
case 5:
|
|
relay = (relay & 0xEF) | (buffer[4] ? 0x10 : 0);
|
|
load();
|
|
break;
|
|
case 6:
|
|
relay = (relay & 0xDF) | (buffer[4] ? 0x20 : 0);
|
|
load();
|
|
break;
|
|
case 7:
|
|
relay = (relay & 0xBF) | (buffer[4] ? 0x40 : 0);
|
|
load();
|
|
break;
|
|
case 8:
|
|
relay = (relay & 0x7F) | (buffer[4] ? 0x80 : 0);
|
|
load();
|
|
break;
|
|
}
|
|
|
|
sendpkt(7, len, buffer);
|
|
}
|
|
|
|
void process(unsigned char cmd, unsigned int len, unsigned char *buffer) {
|
|
static unsigned char restart = 0;
|
|
|
|
switch (cmd) {
|
|
case 0: /* Heartbeat */
|
|
buffer[0] = restart;
|
|
restart = 1;
|
|
sendpkt(0, 1, buffer);
|
|
break;
|
|
case 1: /* Identify */
|
|
strcpy(buffer,"Nuovo");
|
|
len = strlen(buffer);
|
|
sendpkt(1, len, buffer);
|
|
break;
|
|
case 3: /* WIFI State */
|
|
sendpkt(3, 0, NULL);
|
|
break;
|
|
case 6: /* Set Command */
|
|
tuya_receive(len, buffer);
|
|
break;
|
|
case 8: /* Query Command */
|
|
break;
|
|
}
|
|
}
|
|
|
|
void recvpkt(void)
|
|
{
|
|
static unsigned char state = 0;
|
|
static unsigned char cmd;
|
|
static unsigned int len;
|
|
static unsigned char rcrc;
|
|
static unsigned char i;
|
|
static unsigned char command[MAXCMD];
|
|
|
|
if (RI) {
|
|
int inByte = getchar1();
|
|
switch (state) {
|
|
case 0:
|
|
if (inByte == 0x55) state++;
|
|
rcrc = 0;
|
|
break;
|
|
case 1:
|
|
if (inByte == 0xaa) state++; else state = 0;
|
|
break;
|
|
case 2:
|
|
if (inByte == 0) state++; else state = 0;
|
|
break;
|
|
case 3:
|
|
cmd = inByte;
|
|
state++;
|
|
break;
|
|
case 4:
|
|
len = inByte << 8;
|
|
state++;
|
|
break;
|
|
case 5:
|
|
len += inByte;
|
|
if (len < MAXCMD) state++; else state = 0;
|
|
if (len == 0) state++;
|
|
i = 0;
|
|
break;
|
|
case 6:
|
|
command[i] = inByte;
|
|
i++;
|
|
if (len == i) state++;
|
|
break;
|
|
case 7:
|
|
if (inByte == rcrc)
|
|
process(cmd, len, command);
|
|
state = 0;
|
|
break;
|
|
}
|
|
rcrc = rcrc + inByte;
|
|
}
|
|
}
|
|
|
|
void uart_loop() {
|
|
recvpkt();
|
|
}
|
|
|
|
void uart_init(UINT32 u32Baudrate) //T1M = 1, SMOD = 1
|
|
{
|
|
P06_PushPull_Mode;
|
|
P07_Input_Mode;
|
|
|
|
SCON = 0x50; //UART0 Mode1,REN=1,TI=1
|
|
TMOD |= 0x20; //Timer1 Mode1
|
|
|
|
set_SMOD; //UART0 Double Rate Enable
|
|
set_T1M;
|
|
clr_BRCK; //Serial port 0 baud rate clock source = Timer1
|
|
|
|
#ifdef FOSC_160000
|
|
TH1 = 256 - (1000000 / u32Baudrate + 1); /*16 MHz */
|
|
#endif
|
|
#ifdef FOSC_166000
|
|
TH1 = 256 - (1037500 / u32Baudrate); /*16.6 MHz */
|
|
#endif
|
|
set_TR1;
|
|
set_TI; //For printf function must setting TI = 1
|
|
}
|
|
|
|
int main()
|
|
{
|
|
uart_init(9600);
|
|
|
|
RS485_DIR = 0;
|
|
P05_PushPull_Mode;
|
|
|
|
/* Relays */
|
|
relay = 16;
|
|
|
|
M0 = 1;
|
|
M1 = 1;
|
|
M2 = 1;
|
|
|
|
P01_Quasi_Mode;
|
|
P03_Quasi_Mode;
|
|
P04_Quasi_Mode;
|
|
|
|
P11_PushPull_Mode;
|
|
P12_PushPull_Mode;
|
|
P13_PushPull_Mode;
|
|
P14_PushPull_Mode;
|
|
|
|
load();
|
|
|
|
OE = 0;
|
|
|
|
while (1)
|
|
{
|
|
uart_loop();
|
|
}
|
|
}
|
|
|