1 /**
2 * \file main.c
3 *
4 * \brief Example application main file. This application will toggle the led.
5 * The led toggling will be done inside an callback function, which
6 * will be called by Interrupt Service Routine. Interrupts are
7 * triggered manually and no external source is used to trigger
8 * interrupts.
9 *
10 */
12 /*
13 * Copyright (C) 2014-2019 Texas Instruments Incorporated - http://www.ti.com/
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the
25 * distribution.
26 *
27 * Neither the name of Texas Instruments Incorporated nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
50 #include <ti/drv/i2c/I2C.h>
51 #include <ti/drv/i2c/soc/I2C_soc.h>
52 #include <ti/drv/uart/UART_stdio.h>
54 #include "board.h"
55 #include "board_cfg.h"
56 #if defined(SOC_J721E)
57 #include "board_utils.h"
58 #endif
60 #if defined(SOC_J721E)
61 #include "diag_common_cfg.h"
62 #include <ti/csl/soc.h>
63 #endif
65 typedef struct pmic_data
66 {
67 uint8_t slaveAddr;
68 uint8_t i2cInstance;
69 uint8_t pmicIdReg;
70 uint8_t pmicIdPage;
71 uint8_t pmicReg;
72 uint8_t pmicVoltVal;
73 uint8_t pwdProtReg;
74 uint8_t pmicDevCtrl;
75 }pmic_data_t;
77 #if defined(SOC_J721E)
78 Board_I2cInitCfg_t boardI2cInitCfg = {0, BOARD_SOC_DOMAIN_WKUP, false};
79 #endif
80 int32_t numPmic = 0;
82 /********************************* *************************************
83 ************************** Internal functions ************************
84 **********************************************************************/
86 pmic_data_t* Get_PmicData(char *pBoardName);
88 extern const I2C_Config I2C_config[];
90 /* Board specific definitions */
91 #define I2C_INSTANCE (0U)
92 #if defined(SOC_J721E)
93 #define BOARD_NAME_LENGTH (16)
94 #else
95 #define BOARD_NAME_LENGTH (8)
96 #endif
98 /* TPS659037 Register values. */
99 #define TPS659037_I2C_SLAVE_ADDR (0x59U)
100 #define TPS659037_PMICID_REG (0x4FU)
101 #define TPS659037_PMIC_PAGEID (0x02U)
102 #define TPS659037_PMIC_REG (0x23U)
103 #define TPS659037_PMIC_VOLTAGE_VAL (0x44U)
105 /* TPS65910 Register values. */
106 #define TPS65910_I2C_SLAVE_ADDR (0x2D)
107 #define TPS65910_PMICID_REG (0x80)
108 #define TPS65910_PMIC_PAGEID (0x00U)
109 #define TPS65910_PMIC_REG (0x22U)
110 #define TPS65910_PMIC_VOLTAGE_VAL (0x27U)
111 #define TPS65910_PMIC_DEV_CTRL (0x3F)
113 #define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL (0x10u)
114 #define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_SHIFT (0x04u)
115 #define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_SR_I2C (0x0u)
116 #define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C (0x1u)
118 /* TPS65218 Register values. */
119 #define TPS65218_I2C_SLAVE_ADDR (0x24)
120 #define TPS65218_PMICID_REG (0x00U)
121 #define TPS65218_PMIC_PAGEID (0x00U)
122 #define TPS65218_PMIC_REG (0x16U)
123 #define TPS65218_PMIC_VOLTAGE_VAL (0x19U)
124 #define TPS65218_PWD_REG (0x10)
126 #define TPS65218_PROT_PWD (0x7DU)
128 /* TPS65917 Register value. */
129 #define TPS65917_I2C_SLAVE_ADDR (0x58U)
130 #define TPS65917_PMICID_REG (0x4FU)
131 #define TPS65917_PMIC_PAGEID (0x02U)
132 #define TPS65917_PMIC_REG (0x23U)
133 #define TPS65917_PMIC_VOLTAGE_VAL (0x44U)
135 /* TPS65941 Register value */
136 #define TPS65941_PMICA_I2C_SLAVE_ADDR (0x48U)
137 #define TPS65941_PMICB_I2C_SLAVE_ADDR (0x4CU)
138 #define TPS65941_PMICID_REG (0x01U)
139 #define TPS65941_PMIC_REG (0x0EU)
140 #define TPS65941_PMIC_VOLTAGE_VAL (0x41U)
142 /**********************************************************************
143 ************************** Global Variables **************************
144 **********************************************************************/
146 pmic_data_t tps65910 = {
147 TPS65910_I2C_SLAVE_ADDR,
148 I2C_INSTANCE,
149 TPS65910_PMICID_REG,
150 TPS65910_PMIC_PAGEID,
151 TPS65910_PMIC_REG,
152 TPS65910_PMIC_VOLTAGE_VAL,
153 0U,
154 TPS65910_PMIC_DEV_CTRL
155 };
157 pmic_data_t tps65218 = {
158 TPS65218_I2C_SLAVE_ADDR,
159 I2C_INSTANCE,
160 TPS65218_PMICID_REG,
161 TPS65218_PMIC_PAGEID,
162 TPS65218_PMIC_REG,
163 TPS65218_PMIC_VOLTAGE_VAL,
164 TPS65218_PWD_REG,
165 0U
166 };
168 pmic_data_t tps659037 = {
169 TPS659037_I2C_SLAVE_ADDR,
170 I2C_INSTANCE,
171 TPS659037_PMICID_REG,
172 TPS659037_PMIC_PAGEID,
173 TPS659037_PMIC_REG,
174 TPS659037_PMIC_VOLTAGE_VAL,
175 0U,
176 0U
177 };
179 pmic_data_t tps65917 = {
180 TPS65917_I2C_SLAVE_ADDR,
181 I2C_INSTANCE,
182 TPS65917_PMICID_REG,
183 TPS65917_PMIC_PAGEID,
184 TPS65917_PMIC_REG,
185 TPS65917_PMIC_VOLTAGE_VAL,
186 0U,
187 0U
188 };
190 pmic_data_t tps65941_pmicA = {
191 TPS65941_PMICA_I2C_SLAVE_ADDR,
192 I2C_INSTANCE,
193 TPS65941_PMICID_REG,
194 0U,
195 TPS65941_PMIC_REG,
196 TPS65941_PMIC_VOLTAGE_VAL,
197 0U,
198 0U
199 };
201 pmic_data_t tps65941_pmicB = {
202 TPS65941_PMICB_I2C_SLAVE_ADDR,
203 I2C_INSTANCE,
204 TPS65941_PMICID_REG,
205 0U,
206 TPS65941_PMIC_REG,
207 TPS65941_PMIC_VOLTAGE_VAL,
208 0U,
209 0U
210 };
212 void setPmicVoltage(I2C_Handle h, pmic_data_t *pPmicData, uint8_t val)
213 {
214 uint8_t tx[2];
215 I2C_Transaction t;
217 memset(&t, 0, sizeof(t));
218 t.slaveAddress = pPmicData->slaveAddr;
219 t.writeBuf = tx;
220 #if defined (SOC_AM437x)
221 /* Unlock the password protected register. */
222 tx[0] = pPmicData->pwdProtReg;
223 tx[1] = (pPmicData->pmicReg ^ TPS65218_PROT_PWD);
224 t.writeCount = 2;
225 I2C_transfer(h, &t);
226 /* Write the actual value. */
227 tx[0] = pPmicData->pmicReg;
228 tx[1] = val;
229 I2C_transfer(h, &t);
230 #else
231 t.writeCount = 2;
232 t.readCount = 0;
233 tx[0] = pPmicData->pmicReg;
234 tx[1] = val;
235 I2C_transfer(h, &t);
236 #endif
237 }
239 uint8_t readPmicVoltage(I2C_Handle h, uint8_t slaveAddr, uint8_t regOffset)
240 {
241 uint8_t tx[1];
242 uint8_t rx[1];
243 I2C_Transaction t;
245 memset(&t, 0, sizeof(t));
247 t.slaveAddress = slaveAddr;
248 t.writeBuf = tx;
249 t.writeCount = 1;
250 t.readBuf = rx;
251 t.readCount = 1;
252 tx[0] = regOffset;
253 I2C_transfer(h, &t);
254 return rx[0];
255 }
257 #if (defined (SOC_AM572x)) || (defined (SOC_AM571x)) || defined (SOC_AM574x)
258 uint32_t getPmicId(I2C_Handle h, pmic_data_t *pPmicData)
259 {
260 uint32_t val = 0;
261 uint8_t tx[2];
262 uint8_t rx[1];
263 uint8_t reg = pPmicData->pmicIdReg;
264 I2C_Transaction t;
266 memset(&t, 0, sizeof(t));
268 t.slaveAddress = pPmicData->slaveAddr;
269 t.writeBuf = tx;
270 t.writeCount = 2;
271 t.readBuf = rx;
272 t.readCount = 1;
273 tx[0] = reg;
274 tx[1] = pPmicData->pmicIdPage;
275 I2C_transfer(h, &t);
276 val |= (rx[0] << 24);
277 tx[0] = (reg + 1);
278 tx[1] = pPmicData->pmicIdPage;
279 I2C_transfer(h, &t);
280 val |= (rx[0] << 16);
281 tx[0] = (reg + 2);
282 tx[1] = pPmicData->pmicIdPage;
283 I2C_transfer(h, &t);
284 val |= (rx[0] << 8);
285 tx[0] = (reg + 3);
286 tx[1] = pPmicData->pmicIdPage;
287 I2C_transfer(h, &t);
288 val |= (rx[0] << 0);
289 return val;
290 }
291 #endif
293 #if (defined (SOC_AM437x)) || (defined (SOC_AM335x))
294 uint32_t getPmicId(I2C_Handle h, pmic_data_t *pPmicData)
295 {
296 uint8_t tx[2] = {0, 0};
297 uint8_t rx;
298 I2C_Transaction t;
300 memset(&t, 0, sizeof(t));
302 t.slaveAddress = pPmicData->slaveAddr;
303 t.writeBuf = tx;
304 t.readBuf = ℞
305 t.writeCount = 1;
306 t.readCount = 0;
308 /* Enable I2C access to the functional registers. */
309 #if defined (SOC_AM335x)
310 tx[0] = pPmicData->pmicDevCtrl;
311 rx = readPmicVoltage(h, pPmicData->slaveAddr, pPmicData->pmicDevCtrl);
312 rx |= (PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C << PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_SHIFT);
313 tx[1] = rx;
314 t.writeCount = 2;
315 rx = 0;
316 I2C_transfer(h, &t);
317 #endif
319 /* Read the PMIC ID register. */
320 tx[0] = pPmicData->pmicIdReg;
321 t.writeCount = 1;
322 t.readCount = 1;
323 I2C_transfer(h, &t);
325 return rx;
326 }
327 #endif
329 #if defined(SOC_J721E)
330 uint32_t getPmicId(I2C_Handle h, pmic_data_t *pPmicData)
331 {
332 uint32_t val = 0;
333 uint8_t tx[1];
334 uint8_t rx[1];
335 uint8_t reg = pPmicData->pmicIdReg;
336 I2C_Transaction t;
338 memset(&t, 0, sizeof(t));
340 if(pPmicData->slaveAddr == TPS65917_I2C_SLAVE_ADDR)
341 {
342 t.slaveAddress = (pPmicData->slaveAddr + 1);
343 }
344 else /* TPS65941 */
345 {
346 t.slaveAddress = pPmicData->slaveAddr;
347 }
348 t.writeBuf = tx;
349 t.writeCount = 1;
350 t.readBuf = rx;
351 t.readCount = 1;
352 tx[0] = reg;
353 I2C_transfer(h, &t);
354 val |= (rx[0] << 24);
356 if(pPmicData->slaveAddr == TPS65917_I2C_SLAVE_ADDR)
357 {
358 tx[0] = (reg + 1);
359 I2C_transfer(h, &t);
360 val |= (rx[0] << 16);
361 tx[0] = (reg + 2);
362 I2C_transfer(h, &t);
363 val |= (rx[0] << 8);
364 tx[0] = (reg + 3);
365 I2C_transfer(h, &t);
366 val |= (rx[0] << 0);
367 }
368 return val;
369 }
370 #endif
372 int pmic_test()
373 {
374 int ret = 0;
375 int i;
376 uint8_t voltage, val;
377 I2C_Params i2cParams;
378 I2C_Handle handle = NULL;
379 #if defined(SOC_J721E)
380 Board_IDInfo_v2 info = {0};
381 #else
382 Board_IDInfo boardInfo;
383 #endif
384 pmic_data_t *pPmicData;
385 int32_t stat = BOARD_SOK;
387 #if defined(SOC_J721E)
388 Board_setI2cInitConfig(&boardI2cInitCfg);
389 stat = Board_getIDInfo_v2(&info, BOARD_I2C_EEPROM_ADDR);
390 #else
391 stat = Board_getIDInfo(&boardInfo);
392 #endif
394 if(stat == BOARD_SOK)
395 {
396 #if defined(SOC_J721E)
397 pPmicData = Get_PmicData(info.boardInfo.boardName);
398 #else
399 pPmicData = Get_PmicData(boardInfo.boardName);
400 #endif
402 #if defined(SOC_J721E)
403 enableI2C(CSL_WKUP_I2C0_CFG_BASE);
404 #endif
405 for (i=0; I2C_config[i].fxnTablePtr != NULL; i++)
406 {
407 ((I2C_HwAttrs *)I2C_config[i].hwAttrs)->enableIntr = false;
408 }
410 I2C_init();
412 I2C_Params_init(&i2cParams);
414 handle = I2C_open(pPmicData->i2cInstance, &i2cParams);
416 UART_printf("\n*********************************************\n");
417 UART_printf ("* PMIC Test *\n");
418 UART_printf ("*********************************************\n");
419 #if defined(SOC_J721E)
420 while(numPmic)
421 {
422 #endif
423 val = pPmicData->pmicVoltVal;
424 UART_printf("Testing PMIC module... \n");
425 UART_printf("PMIC ID = 0x%08x\n", getPmicId(handle, pPmicData));
426 voltage = readPmicVoltage(handle, pPmicData->slaveAddr, pPmicData->pmicReg);
427 UART_printf("Initial PMIC voltage = 0x%x\n", voltage);
428 UART_printf("Setting PMIC voltage to 0x%x\n", val);
429 setPmicVoltage(handle, pPmicData, val);
430 UART_printf("done!\n");
431 UART_printf("PMIC voltage after = 0x%x\n", readPmicVoltage(handle, pPmicData->slaveAddr, pPmicData->pmicReg));
432 UART_printf("Setting PMIC voltage to original value\n");
433 setPmicVoltage(handle, pPmicData, voltage);
434 UART_printf("Final voltage value = 0x%x\n", readPmicVoltage(handle, pPmicData->slaveAddr, pPmicData->pmicReg));
435 #if defined(SOC_J721E)
436 pPmicData = &tps65941_pmicB;
437 numPmic--;
438 }
439 #endif
440 UART_printf("Test PASSED!\n");
441 I2C_close(handle);
442 }
443 return ret;
444 }
446 /* Fetch the PMIC data structure. */
447 pmic_data_t* Get_PmicData(char *pBoardName)
448 {
449 pmic_data_t *pPmicData = NULL;
451 /* Check if the board is GPEVM by comparing the string read from EEPROM. */
452 if (strncmp("AM572PM_", pBoardName, BOARD_NAME_LENGTH) == 0U)
453 {
454 pPmicData = &tps659037;
455 }
456 /* Check if the board is AM572xIDK by comparing the string read from EEPROM. */
457 else if (strncmp("AM572IDK", pBoardName, BOARD_NAME_LENGTH) == 0U)
458 {
459 pPmicData = &tps659037;
460 }
461 /* Check if the board is AM574xIDK by comparing the string read from EEPROM. */
462 else if (strncmp("AM574IDK", pBoardName, BOARD_NAME_LENGTH) == 0U)
463 {
464 pPmicData = &tps659037;
465 }
466 /* Check if the board is AM571xIDK by comparing the string read from EEPROM. */
467 else if (strncmp("AM571IDK", pBoardName, BOARD_NAME_LENGTH) == 0U)
468 {
469 pPmicData = &tps659037;
470 }
471 /* Check if the board is AM437x GPEVM by comparing the string read from EEPROM. */
472 else if (strncmp("AM43__GP", pBoardName, BOARD_NAME_LENGTH) == 0U)
473 {
474 pPmicData = &tps65218;
475 }
476 /* Check if the board is AM437x HSEVM by comparing the string read from EEPROM. */
477 else if (strncmp("AM43XXHS", pBoardName, BOARD_NAME_LENGTH) == 0U)
478 {
479 pPmicData = &tps65218;
480 }
481 /* Check if the board is SKAM437x by comparing the string read from EEPROM. */
482 else if (strncmp("AM43__SK", pBoardName, BOARD_NAME_LENGTH) == 0U)
483 {
484 pPmicData = &tps65218;
485 }
486 /* Check if the board is AM335x GPEVM by comparing the string read from EEPROM. */
487 else if (strncmp("A33515BB", pBoardName, BOARD_NAME_LENGTH) == 0U)
488 {
489 pPmicData = &tps65910;
490 }
491 /* Check if the board is BBBAM335x by comparing the string read from EEPROM. */
492 else if (strncmp("A335BNLT", pBoardName, BOARD_NAME_LENGTH) == 0U)
493 {
494 pPmicData = &tps65910;
495 }
496 /* Check if the board is ICEV2AM335x by comparing the string read from EEPROM. */
497 else if (strncmp("A335_ICE", pBoardName, BOARD_NAME_LENGTH) == 0U)
498 {
499 pPmicData = &tps65910;
500 }
501 /* Check if the board is SKAM335x by comparing the string read from EEPROM. */
502 else if (strncmp("A335X_SK", pBoardName, BOARD_NAME_LENGTH) == 0U)
503 {
504 pPmicData = &tps65910;
505 }
506 /* Check if the board is J721E SoM with Alt PMIC by comparing the string read from EEPROM. */
507 else if (strncmp("J721EX-PM1-SOM", pBoardName, BOARD_NAME_LENGTH) == 0U)
508 {
509 pPmicData = &tps65917;
510 numPmic = 1;
511 }
512 /* Check if the board is J721E SoM with Dual PMIC by comparing the string read from EEPROM. */
513 else if (strncmp("J721EX-PM2-SOM", pBoardName, BOARD_NAME_LENGTH) == 0U)
514 {
515 pPmicData = &tps65941_pmicA;
516 numPmic = 2;
517 }
518 else
519 {
520 /* If the board is not one of these, then the PmicData returns NULL. */
521 }
523 return pPmicData;
524 }
526 /*
527 * ======== main ========
528 */
529 int main(void)
530 {
531 Board_initCfg boardCfg;
532 #ifdef PDK_RAW_BOOT
533 boardCfg = BOARD_INIT_PINMUX_CONFIG |
534 BOARD_INIT_UART_STDIO;
535 #else
536 boardCfg = BOARD_INIT_UART_STDIO;
537 #endif
538 Board_init(boardCfg);
540 return pmic_test();
541 }
543 void AppDelay(uint32_t delayVal)
544 {
545 uint32_t cnt = 0;
546 while(cnt < delayVal)
547 {
548 asm("");
549 cnt++;
550 }
551 }