proculus_display_pulga
Source/proculus_display.h
- Committer:
- ruschigo
- Date:
- 2020-04-27
- Revision:
- 1:2e4f9cb1c3e9
File content as of revision 1:2e4f9cb1c3e9:
/* @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; }