1 /*********************************************************************
  2     FileName:           I2C.c
  3     Dependencies:       See #includes
  4     Processor:          PIC32MZ
  5     Hardware:           MainBrain32 rev 0.20
  6     Complier:       XC32 4.40, 4.45
  7     Author:         Larry Knight 2024
  8 
  9     Software License Agreement:
 10         This software is licensed under the Apache License Agreement
 11 
 12     Description:
 13         I2C code for capacitive touch display with FT5436 controller
 14         SCL frequency = 400KHz
 15         Address 0x38 (7-bit) or 0x70 (write) and 0x71 (read) (8-bit)
 16         5 touch points
 17     References:
 18         Understanding the I2C Bus - https://www.ti.com/lit/pdf/slva704 
 19         FocalTech Application Note for FT5426 - 5526 CTPM
 20         https://github.com/crystalfontz/CFAF320480C7-035Tx/blob/main/CFAF320480C7-035Tx/CFAF320480C7-035Tx.ino
 21         https://github.com/Bodmer/Touch_FT5436/blob/main/Touch_FT5436.cpp
 22 
 23     File Description:
 24 
 25     Change History:
 26 
 27 /***********************************************************************/
 28 
 29 #include <xc.h>
 30 #include <p32xxxx.h>
 31 #include <proc/p32mz2048efh100.h>
 32 #include <sys/attribs.h>
 33 #include <sys/kmem.h>
 34 #include <stdint.h> 
 35 #include <stdio.h>
 36 #include <stdlib.h>
 37 #include <string.h>
 38 #include <stdbool.h>
 39 #include "MainBrain.h"
 40 
 41 //Register addresses
 42 #define FT_REG_MODE 0x00                //Device mode, either WORKING or FACTORY
 43 #define FT_REG_NUMTOUCHES 0x02          //Number of touch points
 44 #define FT_REG_CALIBRATE 0x02           //Calibrate mode
 45 #define FT_TP1_REG (0X03)
 46 #define FT_TP2_REG (0X09)
 47 #define FT_REG_FACTORYMODE 0x40         //Factory mode
 48 #define FT_REG_THRESHHOLD 0x80          //Threshold for touch detection
 49 #define FT_REG_POINTRATE 0x88           //Point rate
 50 #define FT_ID_G_LIB_VERSION (0xA1)
 51 #define FT_REG_FIRMVERS 0xA6            //Firmware version
 52 #define FT_REG_CHIPID 0xA3              //Chip selecting
 53 #define FT_ID_G_MODE (0xA4)
 54 #define FT_REG_VENDID 0xA8              //FocalTech's panel ID
 55 #define NVM_ADDR_DATA_WR (0xD0)
 56 
 57 //FocalTech ID's
 58 #define FT6234_VENVID 0x79  // FocalTech's panel ID
 59 #define FT6236_VENDID 0x11  // FocalTech's panel ID
 60 #define FT5436_VENDID 0x79  // FocalTech's panel ID
 61 #define FT6206_CHIPID 0x06  // FT6206 ID
 62 #define FT6234_CHIPID 0x54  // FT6234 ID
 63 #define FT6236_CHIPID 0x36  // FT6236 ID
 64 #define FT5436_CHIPID 0x54  // FT5436 ID
 65 #define FT6236U_CHIPID 0x64 // FT6236U ID
 66 
 67 uint8_t address;
 68 uint32_t reg_data_buf;
 69 uint8_t read_buf[16];
 70 int wait_time = 10000;
 71 uint16_t scn_pos_x;
 72 
 73 uint16_t scn_Y;
 74 
 75 uint8_t MenuLevel = 0;
 76 uint8_t ButtonNum = 0;
 77 bool ExitButton = false;
 78 bool isActive = false;
 79 
 80 void FT5436_Write_Reg(uint8_t reg, int8_t reg_data);
 81 void FT5436_Read_Reg(uint8_t reg);
 82 void I2C_wait_for_idle(void);
 83 void I2C_start(void);
 84 void I2C_stop(void);
 85 void I2C_restart(void);
 86 void I2C_ack(void);
 87 void I2C_nack(void);
 88 void FT5436_Read(uint8_t num_bytes);
 89 
 90 void I2C_init()
 91 {    
 92     //FT5436 Device Address
 93     address = 0x38;
 94     
 95     //Touch Controller Reset
 96     TRISBbits.TRISB13 = 0;
 97     PORTBbits.RB13 = 1;
 98     
 99     //INT pin 
100     TRISDbits.TRISD0 = 1;
101     //PORTDbits.RD0 = 1;
102     
103     //RA2 - Pin 59 - SCL2
104     TRISAbits.TRISA2 = 1;
105     
106     //RA3 - Pin 60 - SDA2
107     TRISAbits.TRISA3 = 1;
108      
109     //Disable Slew Rate Control bit
110     //I2C2CONbits.DISSLW = 1;
111     
112     //BAUD rate - 400KHz
113     //set with the scope where one clock period is 2.5uS (400KHz)
114     I2C2BRG = 0x0069; 
115     
116     //I2C-2 Interrupt
117     IEC0bits.IC2IE = 1;
118     IFS0bits.IC2IF = 0;
119     
120     //Master
121     IPC37bits.I2C2MIP = 7;
122     IEC4bits.I2C2MIE = 0;
123     IFS4bits.I2C2MIF = 0;
124     
125     //Slave
126     IPC37bits.I2C2SIP = 7;
127     IEC4bits.I2C2SIE = 0;
128     IFS4bits.I2C2SIF = 0;
129             
130     //INT0 
131     IPC0bits.INT0IP = 7;
132     IEC0bits.INT0IE = 1;
133     IFS0bits.INT0IF = 0;
134     
135     //SDA Hold Time 0 = 100nS, 1 = 300nS
136     I2C2CONbits.SDAHT = 0;
137     
138     I2C2CONbits.PCIE = 1;
139 
140     //Enable module
141     I2C2CONbits.ON = 1;
142     
143     //RESET Touch Controller
144     //Should be low for 10mS
145     int i;
146     for(i=0;i<10000;i++)
147     {
148         PORTBbits.RB13 = 0;
149     }
150    
151     PORTBbits.RB13 = 1;
152     for(i=0;i<100000;i++);
153     
154     //Check for device present    
155     if(!Device_Present())
156     {
157         return;
158     }
159     
160     //Set mode
161     FT5436_Write_Reg(FT_REG_MODE, 0);
162     
163     //ID_G_MODE set interrupt
164         //0x00 - Polling Mode
165         //0x01 - Trigger Mode
166     FT5436_Write_Reg(FT_ID_G_MODE, 0x00);
167     
168     //Touch Threshold
169     FT5436_Write_Reg(FT_REG_THRESHHOLD, 20);
170 
171         //Reporting rate
172         FT5436_Write_Reg(FT_REG_POINTRATE, 12);   
173     
174     FT5436_Write_Reg(0x86, 0x0);
175 }
176 
177 //INT0 Interrupt handler
178 void __attribute__((vector(_EXTERNAL_0_VECTOR), interrupt(ipl7srs), nomips16)) INT0_Handler()
179 {
180     FT5436_Read(16);
181     
182     //Process the touch position
183     if(read_buf[2] > 0)
184     {
185         scn_pos_x = read_buf[5];
186         scn_pos_x = scn_pos_x << 8;
187         scn_pos_x = scn_pos_x + read_buf[6];
188 
189         scn_Y = read_buf[3] - 128;
190         scn_Y = scn_Y << 8;
191         scn_Y = scn_Y + read_buf[4];
192 
193         if(scn_Y > 320)
194         {
195             scn_Y = 320;
196         }
197 
198         scn_Y = 320 - scn_Y;
199         
200 //            hchar = 10;
201 //            vchar = 200;
202 //
203 //            Binary2ASCIIBCD(scn_pos_x);
204 //            WriteChar(hchar, vchar, d2, black, white);
205 //            WriteChar(hchar, vchar, d1, black, white);
206 //            WriteChar(hchar, vchar, d0, black, white);
207 //
208 //            WriteChar(hchar, vchar, ',', black, white);
209 //
210 //            Binary2ASCIIBCD(scn_Y);
211 //            WriteChar(hchar, vchar, d2, black, white);
212 //            WriteChar(hchar, vchar, d1, black, white);
213 //            WriteChar(hchar, vchar, d0, black, white);
214 
215         //Button1 pressed 20, 50, 150, 50
216         if((scn_pos_x > 30 && scn_pos_x < 200) && (scn_Y > 50 && scn_Y < 100))
217         {
218             if(ButtonNum == 0)
219             {
220                 ButtonNum = 1;
221             }
222         }
223         
224         //Button2 pressed 20, 125, 150, 50
225         if((scn_pos_x > 30 && scn_pos_x < 200) && (scn_Y > 125 && scn_Y < 175))
226         {
227             if(ButtonNum == 0)
228             {
229                 ButtonNum = 2;
230             }
231         }
232         
233         //Draw Screen 
234         if(DrawScreenOpen == true)
235         {
236             if((scn_pos_x > 10 && scn_pos_x < 100) && (scn_Y > 40 && scn_Y < 90))
237             {
238                 ButtonNum = 10;
239             }
240 
241         }
242         
243         //Exit Button
244         if((scn_pos_x > 170 && scn_pos_x < 320) && (scn_Y > 250 && scn_Y < 300))
245         {
246             if(ButtonNum > 0)
247             {
248                 ExitButton = true;
249             }
250         }
251     }
252     
253     IFS0bits.INT0IF = 0;
254 }
255 
256 bool Device_Present(void)
257 {
258     int i;
259     //******************************************************
260     //Now we have to determine if there is a device present
261     //The display is optional and should not be required
262     //******************************************************
263     I2C_start();
264     
265     //write to slave
266     I2C2TRN = 0x70;                         // Send slave address with Read/Write bit cleared
267     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
268     I2C_wait_for_idle();                    // Wait until I2C bus is idle
269 
270     //wait a finite amount of time then RETURN if not acknowledged by device
271     for(i=0;i<wait_time;i++)
272     {
273         if(I2C2STATbits.ACKSTAT == 0)
274         {
275             return true;
276             i = wait_time;           
277         }
278     }
279     if(I2C2STATbits.ACKSTAT == 1)
280     {
281         return false;
282     }   
283     //******************************************************
284 }
285 
286 //Writes a byte to the specified register
287 void FT5436_Write_Reg(uint8_t reg, int8_t reg_data)
288 {
289     I2C_start();
290     
291     //write to slave
292     I2C2TRN = 0x70;                         // Send slave address with Read/Write bit cleared
293     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
294     I2C_wait_for_idle();                    // Wait until I2C bus is idle
295     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received  
296 
297     I2C2TRN = reg;                          // Register
298     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
299     I2C_wait_for_idle();                    // Wait until I2C bus is idle
300     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received
301     
302     I2C2TRN = reg_data;                     // Register data
303     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
304     I2C_wait_for_idle();                    // Wait until I2C bus is idle
305     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received
306     
307     I2C_stop();
308     
309 }
310 
311 //Reads a byte from the specified register and stores it in reg_data_buf
312 void FT5436_Read_Reg(uint8_t reg)
313 {
314     I2C_start();
315     
316     //write to slave
317     I2C2TRN = 0x70;                         // Send slave address with Read/Write bit cleared
318     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
319     I2C_wait_for_idle();                    // Wait until I2C bus is idle
320     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received  
321 
322     I2C2TRN = reg;                          // Register
323     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
324     I2C_wait_for_idle();                    // Wait until I2C bus is idle
325     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received
326     
327     I2C_restart();
328     
329     //write to slave
330     I2C2TRN = 0x71;                         // Send slave address with Read/Write bit cleared
331     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
332     I2C_wait_for_idle();                    // Wait until I2C bus is idle
333     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received  
334 
335     I2C2CONbits.RCEN = 1;                   // Receive enable
336     while (I2C2CONbits.RCEN);               // Wait until RCEN is cleared (automatic)  
337     while (!I2C2STATbits.RBF);              // Wait until Receive Buffer is Full (RBF flag)  
338     reg_data_buf = I2C2RCV;                 // Retrieve value from I2C2RCV
339 
340     I2C_nack();
341     I2C_stop(); 
342 }
343 
344 //Reads 16 bytes from the device
345 void FT5436_Read(uint8_t num_bytes)
346 {
347     int i;
348     
349     //read at least 1 byte
350     if(!num_bytes)
351     {
352         num_bytes;
353     }
354     
355     //Send start condition
356     I2C_start();
357     
358     //write to slave
359     I2C2TRN = 0x70;                         // Send slave address with Read/Write bit cleared
360     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
361     I2C_wait_for_idle();                    // Wait until I2C bus is idle
362     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received  
363 
364     I2C2TRN = 0;                            // Device mode
365     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
366     I2C_wait_for_idle();                    // Wait until I2C bus is idle
367     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received
368     
369     I2C_restart();
370     
371     //Read from slave
372     I2C2TRN = 0x71;                         // Send slave address with Read/Write bit set
373     while (I2C2STATbits.TBF == 1);          // Wait until transmit buffer is empty
374     I2C_wait_for_idle();                    // Wait until I2C bus is idle
375     while (I2C2STATbits.ACKSTAT == 1);      // Wait until ACK is received  
376 
377     for(i=0;i<num_bytes;i++)
378     {
379         I2C2CONbits.RCEN = 1;                   // Receive enable
380         while (I2C2CONbits.RCEN);               // Wait until RCEN is cleared (automatic)  
381         while (!I2C2STATbits.RBF);              // Wait until Receive Buffer is Full (RBF flag)  
382         read_buf[i] = I2C2RCV;                 // Retrieve value from I2C2RCV
383         I2C_ack();
384     }
385     
386     I2C2CONbits.RCEN = 1;                   // Receive enable
387     while (I2C2CONbits.RCEN);               // Wait until RCEN is cleared (automatic)  
388     while (!I2C2STATbits.RBF);              // Wait until Receive Buffer is Full (RBF flag)  
389     read_buf[15] = I2C2RCV;                 // Retrieve value from I2C2RCV
390     
391     I2C_nack();
392     I2C_stop(); 
393 }
394 
395 //DRIVER FOUNDATION 
396 //Waits until the I2C peripheral is no longer doing anything  
397 void I2C_wait_for_idle(void)
398 {
399     while(I2C2CON & 0x1F); // Acknowledge sequence not in progress
400                                 // Receive sequence not in progress
401                                 // Stop condition not in progress
402                                 // Repeated Start condition not in progress
403                                 // Start condition not in progress
404     while(I2C2STATbits.TRSTAT); // Bit = 0 Master transmit is not in progress
405 }
406 
407 //Sends a start condition  
408 void I2C_start(void)
409 {
410     I2C_wait_for_idle();
411     I2C2CONbits.SEN = 1;
412     while (I2C2CONbits.SEN == 1);
413 }
414 
415 //Sends a stop condition  
416 void I2C_stop(void)
417 {
418     I2C_wait_for_idle();
419     I2C2CONbits.PEN = 1;
420 }
421 
422 //Sends a repeated start/restart condition
423 void I2C_restart(void)
424 {
425     I2C_wait_for_idle();
426     I2C2CONbits.RSEN = 1;
427     while (I2C2CONbits.RSEN == 1);
428 }
429 
430 //Sends an ACK condition
431 void I2C_ack(void)
432 {
433     I2C_wait_for_idle();
434     I2C2CONbits.ACKDT = 0; // Set hardware to send ACK bit
435     I2C2CONbits.ACKEN = 1; // Send ACK bit, will be automatically cleared by hardware when sent  
436     while(I2C2CONbits.ACKEN); // Wait until ACKEN bit is cleared, meaning ACK bit has been sent
437 }
438 
439 //Sends a NACK condition
440 void I2C_nack(void) // Acknowledge Data bit
441 {
442     I2C_wait_for_idle();
443     I2C2CONbits.ACKDT = 1; // Set hardware to send NACK bit
444     I2C2CONbits.ACKEN = 1; // Send NACK bit, will be automatically cleared by hardware when sent  
445     while(I2C2CONbits.ACKEN); // Wait until ACKEN bit is cleared, meaning NACK bit has been sent
446 }
447 
448 //Master Interrupt Handler
449 void __attribute__((vector(_I2C1_MASTER_VECTOR), interrupt(ipl7srs), nomips16)) I2C_Master_Handler()
450 {
451      
452     IFS4bits.I2C2MIF = 0;
453 }
454 
455 //Slave Interrupt Handler
456 void __attribute__((vector(_I2C2_SLAVE_VECTOR), interrupt(ipl7srs), nomips16)) I2C_Slave_Handler()
457 {
458     
459     IFS0bits.IC2IF = 0;
460 }