serial teste pulga to pulga

Source/proculus_display.h

Committer:
ruschigo
Date:
2020-05-03
Revision:
2:b39f5ce4d5bd
Parent:
1:10de89ea1f70

File content as of revision 2:b39f5ce4d5bd:


/*
@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;    
}*/