serial teste pulga to pulga

Revision:
1:10de89ea1f70
diff -r d32c60c1d9b5 -r 10de89ea1f70 Source/proculus_display.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/proculus_display.h	Sat May 02 03:01:56 2020 +0000
@@ -0,0 +1,581 @@
+
+/*
+@File name: proculus_display.h
+@Author Igor Ruschi Andrade E Lima <igor.lima@lsitec.org.br>
+@LSITEC
+*/
+
+//Insert Lincense Here
+
+#include "platform/platform.h"
+
+/******************************************************************************
+*                   Device SETUP
+******************************************************************************/
+
+//Time in ms to wait between the packet request and the display response
+#define SERIAL_DELAY 100 //100ms
+
+/*expected size of rx buffer, used only by irq. If baud rate is too high
+*consider increase the buffer size*/
+#define RX_BUFFER_SIZE 255
+
+//operation cycle period
+#define PROCULUS_OP_CYCLE_PERIOD 200
+
+
+/******************************************************************************
+*                       Proculus control register definitions
+******************************************************************************/
+#define VERSION_INFO 0x00
+#define CURRENT_BACKLIGHT 0x01
+#define ACTIVE_BUZZER 0x02
+#define PIC_ID_H 0x3
+#define PIC_ID_L 0x4
+#define TP_FLAG 0x5
+#define TP_STATUS 0x06
+#define TP_COORDINATES_H1 0x7
+#define TP_COORDINATES_H2 0x8
+#define TP_COORDINATES_H3 0x9
+#define TP_COORDINATES_L 0xA
+#define TP_ENABLE 0xB
+#define RUN_TIME_H1 0xC
+#define RUN_TIME_H2 0xD
+#define RUN_TIME_H3 0xE
+#define RUN_TIME_L 0xF
+#define OVERWRITE_CONFIG 0x1D
+#define READ_BACKLIGHT 0x1E
+#define OVERWRITE_RTC 0x1F
+#define RTC_VALUE_H1 0x20
+#define RTC_VALUE_H2 0x21
+#define RTC_VALUE_H3 0x22
+#define RTC_VALUE_H4 0x23
+#define RTC_VALUE_H5 0x24
+#define RTC_VALUE_H6 0x25
+#define RTC_VALUE_L 0x26
+#define TIMER_0_H 0x4A
+#define TIMER_0_L 0x4B
+#define TIMER_1 0x4C
+#define TIMER_2 0x4D
+#define TIMER_3 0x4E
+#define ACTIVATE_SOFT_CTRL 0x4F
+#define AUDIO_PLAY_STOP 0x50
+#define AUDIO_ID_H 0x51
+#define AUDIO_ID_L 0x52
+#define OVERWRITE_AUDIO_VOLUME 0X53
+#define AUDIO_VOLUME 0X54
+#define AUDIO_STATUS 0X55
+#define OVERWRITE_VIDEO 0X60
+#define VIDEO_MODE 0X61
+#define VIDEO_POSITION_H1 0X62
+#define VIDEO_POSITION_H2 0X63
+#define VIDEO_POSITION_H3 0X64
+#define VIDEO_POSITION_L 0X65
+#define VIDEO_ID_H 0X66
+#define VIDEO_ID_L 0X67
+#define OVERWRITE_VIDEO_VOLUME 0X68
+#define VIDEO_VOLUME 0X69
+#define VIDEO_PLAY_PAUSE 0X6A
+#define VIDEO_STOP 0X6B
+#define VIDEO_NEXT 0X6C
+#define VIDEO_PREVIOUS 0X6D
+#define VIDEO_STATUS 0X6E
+#define KEYBOARD_STATUS 0XE9
+#define ACTIVATE_CALIBRATION 0XEA
+#define CLEAN_TREND_CURVE 0XEB
+#define ACTIVE_RESET_H 0XEE 
+#define ACTIVE_RESET_H 0XEF
+
+/******************************************************************************
+*                       Proculus Operation Modes/CMD Definitions
+******************************************************************************/
+#define W_CTRL_REG 0x80
+#define R_CTRL_REG 0x81
+#define W_VP 0x82
+#define R_VP 0x83
+#define W_TREND_CURVE_BUFFER 0x84
+
+/******************************************************************************
+*                       Proculus CHANNELs definitions
+******************************************************************************/
+#define CHANNEL_0 0x1
+#define CHANNEL_1 0x2
+#define CHANNEL_2 0x4
+#define CHANNEL_3 0x8
+#define CHANNEL_4 0x10
+#define CHANNEL_5 0x20
+#define CHANNEL_6 0x40
+#define CHANNEL_7 0x80
+
+
+struct proculus_pkt {
+    uint8_t header_h;
+    uint8_t header_l;
+    uint8_t count;
+    uint8_t cmd;
+    uint16_t address;
+    uint8_t lenght; //only for read operations
+    uint8_t channel;//only for write trend curv
+    uint16_t *buffer;
+    uint8_t word_to_come;//it is not documented
+};
+/*
+#ifdef DEBUG_SERIAL
+int raw_to_string(char *raw, char *str, int size);
+int debug_puts(const char *str, int size);
+#endif
+
+int proculus_send_write_pkt(struct proculus_pkt pkt);
+int proculus_set_vp(uint8_t bc, uint16_t vp, uint16_t *data);
+int proculus_set_ctrl(uint8_t bc, uint16_t reg_addr, uint16_t *data);
+int proculus_get_ctrl(uint8_t bc, uint16_t vp, uint8_t lenght);
+int proculus_get_vp(uint8_t bc, uint16_t vp, uint8_t lenght);
+int serial_to_proculus_pkt(struct proculus_pkt *pkt);
+int get_vp_data(uint16_t vp, uint8_t lenght, uint16_t *data);
+int get_ctrl_data(uint16_t vp, uint8_t lenght, uint16_t *data);
+int start_touch_painel_calibration(void);
+int clear_trend_curve_buffer(uint8_t channel);
+int soft_control_activation(uint16_t control_code);
+int audio_ctrl(bool play, uint16_t id, uint16_t volume);
+int write_trend_buffer(uint8_t bc, const uint8_t channels, uint16_t *data);
+
+*/
+
+
+//define DEBUG_SERIAL for debug
+//#define DEBUG_SERIAL
+
+/*never define both DEBUG_RAW and DEBUG_ASCII at same time*/
+/*define DEBUG_RAW_SERIAL for raw data debug, only send and receive data between
+*display and MCU*/
+//#define DEBUG_RAW
+//define DEBUG_ASCII for ascii console debug
+//#define DEBUG_ASCII
+
+#ifdef DEBUG_SERIAL
+//RawSerial *debug_serial  = new RawSerial(P0_25,P0_6);
+char temp_str[255] = "init";
+
+int raw_to_string(char *raw, char *str, int size){
+    int i = 0;
+    char buffer[4];
+    strcpy(str, "_");
+    while(i < size){
+        sprintf(buffer, "x%x", raw[i]);
+        strcat(str,buffer);
+        //str[i] = buffer[0];
+        //str[i+1] = buffer[1];
+        i++;
+    }
+    return 0;
+}
+
+int debug_puts(const char *str, int size){
+    int i = 0;
+    while(i < size){
+        debug_serial->putc(str[i]);
+        i++;
+    }
+    return 0;
+}
+#endif //DEBUG_SERIAL
+
+/*****************************************************************************
+*                   GLOBAL SCOPE
+*****************************************************************************/
+RawSerial serial1(P0_25,P0_2);
+char serial_rx_buffer[RX_BUFFER_SIZE] = "init";
+int rx_to_rcv = 0;
+/*
+    *serial_puts: just send a string by serial serial1
+    *Description: The original mbed puts function will not work, it can't send 0x00
+*/
+int serial_puts(const char *str, int size){
+    int i = 0;
+    while(i < size){
+        serial1.putc(str[i]);
+        i++;
+    }
+    return 0;
+}
+
+/*****************************************************************************
+*                   BASIC PROCULUS PROTOCOL ROUTINEs 
+*****************************************************************************/
+
+int pkt_is_valid(proculus_pkt pkt){
+    if(pkt.header_h != 0x5A) return -1;
+    if(pkt.header_l != 0xA5) return -1;
+    if(pkt.count > 0xff) return -2;
+    if(pkt.cmd < 0x80 && pkt.cmd > 0x84) return -3;
+    if((pkt.cmd == 0x80 || pkt.cmd == 0x81) && pkt.address > 0xff) return -4;
+    if((pkt.cmd == 0x82 || pkt.cmd == 0x83) && pkt.address > 0xffff) return -5;
+    return 0;
+}
+
+
+int proculus_send_write_pkt(struct proculus_pkt pkt)
+{
+    char msg[4 + pkt.count];//count already take in a count cmd, address and buffer size
+    int i = 0, j = 0;
+    int ret;
+    //ret = pkt_is_valid(pkt);
+    //if(ret != 0)
+    //    return ret;
+    msg[0] = pkt.header_h;
+    msg[1] = pkt.header_l;
+    msg[2] = pkt.count;
+    msg[3] = pkt.cmd;
+    switch(pkt.cmd) {
+        case W_CTRL_REG:
+            msg[4] = (char)pkt.address;
+            i = 0;
+            while(i < pkt.count - 2) { //the address and cmd byte already gone
+                msg[i+5] = (char)pkt.buffer[i];
+                i++;
+            }
+            //rx_to_rcv = (5 + (pkt.count - 2));
+            break;
+        case W_VP:
+            msg[4] = (char)((pkt.address & 0xFF00) >> 8);
+            msg[5] = (char)(pkt.address & 0x00FF);
+            i = 0;
+            while(i < pkt.count - 3) { //the address and cmd byte already gone
+                if(i>0) {
+                    msg[i+6] = (char)((pkt.buffer[j] & 0xFF00) >> 8);
+                    msg[i+7] = (char)(pkt.buffer[j] & 0x00FF);
+                } else {
+                    msg[i+6] = (char)((pkt.buffer[i] & 0xFF00) >> 8);
+                    msg[i+7] = (char)(pkt.buffer[i] & 0x00FF);
+                }
+                i = i + 2;
+                j++;
+            }
+            break;
+        case W_TREND_CURVE_BUFFER:
+            msg[4] = pkt.channel;
+            i = 0;
+            while(i < pkt.count - 2) { //the address and cmd byte already gone
+                if(i>0) {
+                    msg[i+6] = (char)((pkt.buffer[j] & 0xFF00) >> 8);
+                    msg[i+7] = (char)(pkt.buffer[j] & 0x00FF);
+                } else {
+                    msg[i+6] = (char)((pkt.buffer[i] & 0xFF00) >> 8);
+                    msg[i+7] = (char)(pkt.buffer[i] & 0x00FF);
+                }
+                i = i + 2;
+                j++;
+            }
+            break;
+        case R_CTRL_REG:
+            msg[4] = (char)pkt.address;
+            msg[5] = (char)pkt.lenght;
+            //rx_to_rcv = 0x6 + pkt.lenght;
+            break;
+        case R_VP:
+            msg[4] = (char)((pkt.address & 0xFF00) >> 8);
+            msg[5] = (char)(pkt.address & 0x00FF);
+            msg[6] = (char)pkt.lenght;
+            rx_to_rcv = 0x7 + (pkt.lenght * 0x2);
+            break;
+        default:
+#ifdef DEBUG_ASCII
+            debug_serial->puts("Proculus CMD not supported");
+#endif
+            return -1;
+            break;
+    }
+    serial_puts(msg, (0x3 + pkt.count));
+#ifdef DEBUG_ASCII
+    char debug_msg[100];
+    raw_to_string(msg, debug_msg, 3 + pkt.count);
+    debug_serial->puts("send:");
+    debug_serial->puts(debug_msg);
+    debug_serial->puts("_|_");
+#endif    
+
+#ifdef DEBUG_RAW
+    //wait(SERIAL_DELAY/1000);
+    debug_puts(msg, 3 + pkt.count);
+#endif
+    return 0;
+}
+
+
+int proculus_set_vp(uint8_t bc, uint16_t vp, uint16_t *data){
+    struct proculus_pkt pkt;
+    pkt.header_h = 0x5A;
+    pkt.header_l = 0xA5;
+    pkt.cmd = W_VP;
+    pkt.count = bc;
+    pkt.address = vp;
+    pkt.buffer = data;
+    proculus_send_write_pkt(pkt);
+    return 0;
+}
+
+int proculus_set_ctrl(uint8_t bc, uint16_t reg_addr, uint16_t *data){
+    struct proculus_pkt pkt;
+    pkt.header_h = 0x5A;
+    pkt.header_l = 0xA5;
+    pkt.cmd = W_CTRL_REG;
+    pkt.count = bc;
+    pkt.address = reg_addr;
+    pkt.buffer = data;
+    proculus_send_write_pkt(pkt);
+    return 0;
+}
+
+int proculus_get_ctrl(uint8_t bc, uint16_t vp, uint8_t lenght){
+    struct proculus_pkt pkt;
+    pkt.header_h = 0x5A;
+    pkt.header_l = 0xA5;
+    pkt.cmd = R_CTRL_REG;
+    pkt.count = bc;
+    pkt.address = vp;
+    pkt.lenght = lenght;
+    proculus_send_write_pkt(pkt);
+    return 0;
+}
+
+/*proculus_get_vp
+*Description: send to proculus display the packet to request data in especific
+vp, it can read consecultives vps, stating from vp given.
+*/
+int proculus_get_vp(uint8_t bc, uint16_t vp, uint8_t lenght){
+    struct proculus_pkt pkt;
+    pkt.header_h = 0x5A;
+    pkt.header_l = 0xA5;
+    pkt.cmd = R_VP;
+    pkt.count = bc;
+    pkt.address = vp;
+    pkt.lenght = lenght;
+    proculus_send_write_pkt(pkt);
+    return 0;
+}
+
+/*
+*serial_to_proculus_pkt: get the data received in serial rx and translate
+*to proculus_pkt
+*@pkt is pointer to the struct to store datas
+*/
+int serial_to_proculus_pkt(char *serial_data, struct proculus_pkt *pkt){
+    
+    int i = 0, j = 0;
+    
+    pkt->header_h = serial_data[0];
+    pkt->header_l = serial_data[1];
+    pkt->count = serial_data[2];
+    pkt->cmd = serial_data[3];
+    if(pkt->cmd == R_CTRL_REG){
+        pkt->address = serial_data[4];
+        pkt->lenght = serial_data[5];
+        while(i < pkt->lenght){
+            pkt->buffer[i] = serial_data[6 + i];
+            i++;
+        }
+    }
+    else{
+        pkt->address = serial_data[4] << 8;
+        pkt->address |= serial_data[5];
+        pkt->lenght = serial_data[6];
+        while(i < pkt->lenght){
+            pkt->buffer[i] = serial_data[7 + j] << 8;
+            pkt->buffer[i] |= serial_data[8 + j];
+            i++;
+            j += 2;
+        }
+    }
+    return 0;
+}
+
+/*
+*serial_to_proculus_pkt: get the data received in serial rx and translate
+*to proculus_pkt
+*@pkt is pointer to the struct to store datas
+*/
+int serial_to_proculus_pkt_2(char *serial_data, struct proculus_pkt *pkt){
+    
+    int i = 0, j = 0;
+    
+    pkt->header_h = 0x5a;
+    pkt->header_l = serial_data[0];
+    pkt->count = serial_data[1];
+    pkt->cmd = serial_data[2];
+    if(pkt->cmd == R_CTRL_REG){
+        pkt->address = serial_data[3];
+        pkt->lenght = serial_data[4];
+        while(i < pkt->lenght){
+            pkt->buffer[i] = serial_data[5 + i];
+            i++;
+        }
+    }
+    else{
+        pkt->address = serial_data[3] << 8;
+        pkt->address |= serial_data[4];
+        pkt->lenght = serial_data[5];
+        while(i < pkt->lenght){
+            pkt->buffer[i] = serial_data[6 + j] << 8;
+            pkt->buffer[i] |= serial_data[7 + j];
+            i++;
+            j += 2;
+        }
+    }
+    return 0;
+}
+
+/*get_vp_data
+*Description: vp values without interrupt routine, if you are using interrupt
+do not use this function
+*/
+int get_vp_data(uint16_t vp, uint8_t lenght, uint16_t *data){
+        int i = 0;
+        struct proculus_pkt pkt;
+        pkt.buffer = data; //output data
+        proculus_get_vp(0x04, vp, lenght);
+        wait(SERIAL_DELAY/1000);
+        while(serial1.readable()){
+            serial_rx_buffer[i] = serial1.getc();
+            i++;
+        } 
+        serial_to_proculus_pkt(serial_rx_buffer,&pkt);
+        return 0;
+}
+
+/*get_crtl_data
+*Description: vp values without interrupt routine, if you are using interrupt
+do not use this function
+*/
+int get_ctrl_data(uint16_t vp, uint8_t lenght, uint16_t *data){
+        int i = 0;
+        struct proculus_pkt pkt;
+        pkt.buffer = data; //output data
+        proculus_get_ctrl(0x03, vp, lenght);
+        wait(SERIAL_DELAY/1000);
+        while(serial1.readable()){
+            serial_rx_buffer[i] = serial1.getc();
+            i++;
+        } 
+        serial_to_proculus_pkt(serial_rx_buffer, &pkt);
+        return 0;
+}
+
+/*****************************************************************************
+*                       SUPORT FUNCTIONS
+*****************************************************************************/
+
+
+/*start_touch_painel_calibration
+*Description: to start the touchscreen calibration routine
+*/
+int start_touch_painel_calibration(){
+    uint16_t data[1];
+    data[0] = 0x5A; 
+    proculus_set_ctrl(0x3, ACTIVATE_CALIBRATION, data);
+    return 0;   
+}
+
+/*clear_trend_curve_buffer
+*Description: use to clean especific trend curve buffers
+@channel: channel to clean the trend curve buffer, 0 < channel <= 7 clean the especific 
+channel. channel > 7 clean all channels
+*/
+int clear_trend_curve_buffer(uint8_t channel){
+    uint16_t data[1];
+    if(channel > 7)
+        data[0] = 0x55;
+    else
+        data[0] = 0x56 + channel; 
+    proculus_set_ctrl(0x3, CLEAN_TREND_CURVE, data); 
+    return 0;
+}
+
+/*soft_control_activation
+*Description: active software control to given control_code, you must to be in
+*same screen of software control are.
+@control_code: the software control code to be active0x00-0xFF
+*/
+int soft_control_activation(uint16_t control_code){
+    uint16_t data[1];
+    data[0] = control_code;
+    proculus_set_ctrl(0x3, ACTIVATE_SOFT_CTRL, data); 
+    return 0;    
+}
+
+/*audio_ctrl
+*Description, routine to full control the audio play, always update the volume
+@play: true will play the id audio, false will pause the audio
+@id: the audio id range[0x0000 - 0x0FFF)
+@volume: volume control, 0x40 = 100%, 0x00 = 0%
+*/
+int audio_ctrl(bool play, uint16_t id, uint16_t volume){
+    uint16_t data[4];
+    if(play)
+        data[0] = 0x5B;
+    else
+        data[0] = 0x5C;
+    data[1] = (id & 0xFF00) >> 8;
+    data[2] = id & 0x00FF;
+    data[3] = 0x5A;//always update volume
+    data[4] = volume;
+    proculus_set_ctrl(0x7, AUDIO_PLAY_STOP, data); 
+    return 0;
+}
+
+/*write_trend_buffer
+*Description: Write trend curve buffer, writes data into one or more trend curve
+*buffer channels.
+*@bc: byte counter = (CMD size = 1byte + ch size = 1byte + data size = nbytes),
+*to send 5bytes in data, the bc will be 0x7
+*@channels, you choose the channel to write combining flags CHANNEL_X,
+*for example, to write in channel 3 and 4 at same command, just use
+*channels = CHANNEL_3 | CHANNEL4
+*@*data: pointer to the buffer where the datas are. If you are writing in
+*multiple channels, the data is alternated between channels. Example:
+*if channels are (CHANNEL_1 | CHANNEL2), data should be like data[0] -> ch1
+*data[1] -> ch2, data[2] ->ch1 and so on...
+*/
+int write_trend_buffer(uint8_t bc, const uint8_t channels, uint16_t *data){
+    struct proculus_pkt pkt;
+    pkt.header_h = 0x5A;
+    pkt.header_l = 0xA5;
+    pkt.cmd = W_TREND_CURVE_BUFFER;
+    pkt.count = bc;
+    pkt.channel = channels;
+    pkt.buffer = data;
+    proculus_send_write_pkt(pkt);
+    return 0;
+}
+
+
+int jump_to_screen(uint16_t screen_num){
+    uint16_t data[1];
+    data[0] = (screen_num & 0xFF00) >> 8;
+    data[1] = (screen_num & 0x00FF);
+    wait(PROCULUS_OP_CYCLE_PERIOD/1000);
+    proculus_set_ctrl(0x4, PIC_ID_H, data);
+    return 0;
+}
+
+int get_screen(uint16_t *data){
+    get_ctrl_data(PIC_ID_H, 0x2, data);
+    return 0;
+}
+
+
+/*specific routine to get the screen at rx irq routine*/
+/*int get_screen_at_irq(){
+    int i = 0;
+    //strcpy(serial_rx_buffer, "");
+    //while(serial1.readable()){//clean anything in buffer before send cmd
+    //    serial_rx_buffer[i] = serial1.getc();
+    //    i++;
+    //}
+    //serial1.attach(0);
+    //while(rx_to_rcv);
+    //wait(0.500);
+    proculus_get_ctrl(0x3, PIC_ID_H, 0x2);
+    //serial1.attach(&serial_rx_irq);
+    return 0;    
+}*/
+