proculus_display_pulga
Diff: Source/proculus_display.h
- Revision:
- 1:2e4f9cb1c3e9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/proculus_display.h Mon Apr 27 17:40:57 2020 +0000 @@ -0,0 +1,499 @@ + +/* +@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 + + + + +/****************************************************************************** +* 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 + +#ifdef DEBUG_SERIAL +RawSerial *debug_serial = new RawSerial(P0_3,P0_29); +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 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; + 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++; + } + 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 = 6 + 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 = 7 + (pkt.lenght * 2); + break; + default: +#ifdef DEBUG_SERIAL + //char debug_msg[100]; + //debug_serial->puts("Proculus CMD not supported"); +#endif + return -1; + break; + } + serial_puts(msg, 3 + pkt.count); +#ifdef DEBUG_SERIAL + //debug_puts(msg, 3 + pkt.count); + 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 + 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(struct proculus_pkt *pkt){ + + int i = 0, j = 0; + + pkt->header_h = serial_rx_buffer[0]; + pkt->header_l = serial_rx_buffer[1]; + pkt->count = serial_rx_buffer[2]; + pkt->cmd = serial_rx_buffer[3]; + if(pkt->cmd == R_CTRL_REG){ + pkt->address = serial_rx_buffer[4]; + pkt->lenght = serial_rx_buffer[5]; + while(i < pkt->lenght){ + pkt->buffer[i] = serial_rx_buffer[6 + i]; + i++; + } + } + else{ + pkt->address = serial_rx_buffer[4] << 8; + pkt->address |= serial_rx_buffer[5]; + pkt->lenght = serial_rx_buffer[6]; + while(i < pkt->lenght){ + pkt->buffer[i] = serial_rx_buffer[7 + j] << 8; + pkt->buffer[i] |= serial_rx_buffer[8 + 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(&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(&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); + 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; +} +