ifx_i2c_physical_layer.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. /**
  2. * MIT License
  3. *
  4. * Copyright (c) 2018 Infineon Technologies AG
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE
  23. *
  24. *
  25. * \file ifx_i2c_physical_layer.c
  26. *
  27. * \brief This file implements the IFX I2C Physical Layer.
  28. *
  29. * \addtogroup grIFXI2C
  30. * @{
  31. */
  32. /***********************************************************************************************************************
  33. * HEADER FILES
  34. **********************************************************************************************************************/
  35. #include "optiga/ifx_i2c/ifx_i2c_physical_layer.h"
  36. #include "optiga/pal/pal_os_event.h"
  37. /// @cond hidden
  38. /***********************************************************************************************************************
  39. * MACROS
  40. **********************************************************************************************************************/
  41. // Physical Layer Register addresses
  42. #define PL_REG_DATA (0x80)
  43. #define PL_REG_DATA_REG_LEN (0x81)
  44. #define PL_REG_I2C_STATE (0x82)
  45. #define PL_REG_BASE_ADDR (0x83)
  46. #define PL_REG_MAX_SCL_FREQU (0x84)
  47. #define PL_REG_SOFT_RESET (0x88)
  48. #define PL_REG_I2C_MODE (0x89)
  49. // Physical Layer Register lengths
  50. #define PL_REG_LEN_I2C_STATE (4)
  51. #define PL_REG_LEN_MAX_SCL_FREQU (4)
  52. #define PL_REG_LEN_I2C_MODE (2)
  53. #define PL_REG_LEN_DATA_REG_LEN (2)
  54. #define PL_REG_LEN_SOFT_RESET (2)
  55. #define PL_REG_LEN_BASE_ADDR (2)
  56. // Physical Layer State Register masks
  57. #define PL_REG_I2C_STATE_RESPONSE_READY (0x40)
  58. #define PL_REG_I2C_STATE_SOFT_RESET (0x08)
  59. // Physical Layer low level interface constants
  60. #define PL_ACTION_READ_REGISTER (0x01)
  61. #define PL_ACTION_WRITE_REGISTER (0x02)
  62. #define PL_I2C_CMD_WRITE (0x01)
  63. #define PL_I2C_CMD_READ (0x02)
  64. // Physical Layer high level interface constants
  65. #define PL_ACTION_WRITE_FRAME (0x01)
  66. #define PL_ACTION_READ_FRAME (0x02)
  67. #define PL_STATE_UNINIT (0x00)
  68. #define PL_STATE_INIT (0x01)
  69. #define PL_STATE_READY (0x02)
  70. #define PL_STATE_DATA_AVAILABLE (0x03)
  71. #define PL_STATE_RXTX (0x04)
  72. #define PL_STATE_SOFT_RESET (0x05)
  73. //Physical Layer negotiation constants
  74. #define PL_INIT_SET_DATA_REG_LEN (0x11)
  75. #define PL_INIT_GET_DATA_REG_LEN (0x22)
  76. #define PL_INIT_GET_FREQ_REG (0x33)
  77. #define PL_INIT_SET_FREQ_REG (0x44)
  78. #define PL_INIT_READ_FREQ (0x55)
  79. #define PL_INIT_VERIFY_FREQ (0x66)
  80. #define PL_INIT_AGREE_FREQ (0x77)
  81. #define PL_INIT_VERIFY_DATA_REG (0x88)
  82. #define PL_INIT_GET_STATUS_REG (0x99)
  83. #define PL_INIT_DONE (0xAA)
  84. #define PL_INIT_SET_FREQ_DEFAULT (0xBB)
  85. //Physical layer soft reset states
  86. #define PL_RESET_INIT (0xA1)
  87. #define PL_RESET_WRITE (0xA2)
  88. #define PL_RESET_STARTUP (0xA3)
  89. #define PL_REG_I2C_MODE_PERSISTANT (0x80)
  90. #define PL_REG_I2C_MODE_SM_FM (0x03)
  91. #define PL_REG_I2C_MODE_FM_PLUS (0x04)
  92. #define PL_SM_FM_MAX_FREQUENCY (0x190)
  93. #define PL_DEFAULT_FREQUENCY (0x64)
  94. #define PL_REG_BASE_ADDR_PERSISTANT (0x80)
  95. #define PL_REG_BASE_ADDR_VOLATILE (0x00)
  96. // Physical Layer Base Address Register mask
  97. #define PL_REG_I2C_BASE_ADDRESS_MASK (0x7F)
  98. // Setup debug log statements
  99. #if IFX_I2C_LOG_PL == 1
  100. #include "common/Log_api.h"
  101. #define LOG_PL(args...) ifx_debug_log(IFX_I2C_LOG_ID_PL, args)
  102. #else
  103. #define LOG_PL(...) //printf(__VA_ARGS__)
  104. #endif
  105. /***********************************************************************************************************************
  106. * ENUMS
  107. **********************************************************************************************************************/
  108. /***********************************************************************************************************************
  109. * DATA STRUCTURES
  110. ***********************************************************************************************************************/
  111. /***********************************************************************************************************************
  112. * GLOBAL
  113. ***********************************************************************************************************************/
  114. static host_lib_status_t pal_event_status;
  115. /***********************************************************************************************************************
  116. * LOCAL ROUTINES
  117. ***********************************************************************************************************************/
  118. /// Physical Layer low level interface function
  119. static void ifx_i2c_pl_read_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len);
  120. /// Physical Layer low level interface function
  121. static void ifx_i2c_pl_write_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len, const uint8_t* p_content);
  122. /// Physical Layer high level interface timer callback (Status register polling)
  123. static void ifx_i2c_pl_status_poll_callback(void *p_ctx);
  124. /// Physical Layer intermediate state machine (Negotiation with slave)
  125. static void ifx_i2c_pl_negotiation_event_handler(void *p_input_ctx);
  126. /// Physical Layer intermediate state machine(Set bit rate)
  127. static host_lib_status_t ifx_i2c_pl_set_bit_rate(ifx_i2c_context_t *p_ctx, uint16_t bitrate);
  128. /// Physical Layer intermediate state machine (soft reset)
  129. static void ifx_i2c_pl_soft_reset(ifx_i2c_context_t *p_ctx);
  130. /// Physical Layer high level interface state machine (read/write frames)
  131. static void ifx_i2c_pl_frame_event_handler(ifx_i2c_context_t *p_ctx,host_lib_status_t event);
  132. /// Physical Layer low level interface timer callback (I2C Nack/Busy polling)
  133. static void ifx_i2c_pal_poll_callback(void *p_ctx);
  134. /// Physical Layer low level guard time callback
  135. static void ifx_i2c_pl_guard_time_callback(void *p_ctx);
  136. /// Physical Layer low level interface state machine (read/write registers)
  137. static void ifx_i2c_pl_pal_event_handler(void *p_ctx, host_lib_status_t event);
  138. /// Physical layer low level event handler for set slave address
  139. static void ifx_i2c_pl_pal_slave_addr_event_handler(void *p_input_ctx, host_lib_status_t event);
  140. /// @endcond
  141. /***********************************************************************************************************************
  142. * API PROTOTYPES
  143. **********************************************************************************************************************/
  144. /// Physical Layer high level interface function
  145. host_lib_status_t ifx_i2c_pl_init(ifx_i2c_context_t *p_ctx,ifx_i2c_event_handler_t handler)
  146. {
  147. LOG_PL("[IFX-PL]: Init\n");
  148. p_ctx->pl.upper_layer_event_handler = handler;
  149. p_ctx->pl.frame_state = PL_STATE_UNINIT;
  150. p_ctx->pl.negotiate_state = PL_INIT_SET_FREQ_DEFAULT;
  151. p_ctx->p_pal_i2c_ctx->slave_address = p_ctx->slave_address;
  152. p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = (void*)ifx_i2c_pl_pal_event_handler;
  153. p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
  154. if(TRUE == p_ctx->do_pal_init)
  155. {
  156. // Initialize I2C driver
  157. if (PAL_STATUS_SUCCESS != pal_i2c_init(p_ctx->p_pal_i2c_ctx))
  158. {
  159. return IFX_I2C_STACK_ERROR;
  160. }
  161. }
  162. // Set Physical Layer internal state
  163. if(p_ctx->pl.request_soft_reset == (uint8_t)TRUE)
  164. {
  165. //Set the soft reset request to initial state to read register
  166. p_ctx->pl.request_soft_reset = PL_INIT_GET_STATUS_REG;
  167. p_ctx->pl.frame_state = PL_STATE_SOFT_RESET;
  168. }
  169. else
  170. {
  171. p_ctx->pl.frame_state = PL_STATE_INIT;
  172. }
  173. ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
  174. return IFX_I2C_STACK_SUCCESS;
  175. }
  176. /// Physical Layer high level interface function
  177. host_lib_status_t ifx_i2c_pl_send_frame(ifx_i2c_context_t *p_ctx,uint8_t* p_frame, uint16_t frame_len)
  178. {
  179. // Physical Layer must be idle, set requested action
  180. if (p_ctx->pl.frame_state != PL_STATE_INIT && p_ctx->pl.frame_state != PL_STATE_READY)
  181. {
  182. return IFX_I2C_STACK_ERROR;
  183. }
  184. p_ctx->pl.frame_action = PL_ACTION_WRITE_FRAME;
  185. // Store reference to frame for sending it later
  186. p_ctx->pl.p_tx_frame = p_frame;
  187. p_ctx->pl.tx_frame_len = frame_len;
  188. ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
  189. return IFX_I2C_STACK_SUCCESS;
  190. }
  191. /// Physical Layer high level interface function
  192. host_lib_status_t ifx_i2c_pl_receive_frame(ifx_i2c_context_t *p_ctx)
  193. {
  194. // Physical Layer must be idle, set requested action
  195. if (p_ctx->pl.frame_state != PL_STATE_INIT && p_ctx->pl.frame_state != PL_STATE_READY)
  196. {
  197. return IFX_I2C_STACK_ERROR;
  198. }
  199. p_ctx->pl.frame_action = PL_ACTION_READ_FRAME;
  200. ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
  201. return IFX_I2C_STACK_SUCCESS;
  202. }
  203. host_lib_status_t ifx_i2c_pl_write_slave_address(ifx_i2c_context_t *p_ctx, uint8_t slave_address, uint8_t persistent)
  204. {
  205. host_lib_status_t status = IFX_I2C_STACK_ERROR;
  206. app_event_handler_t * temp_upper_layer_event_handler;
  207. /// @cond hidden
  208. #define PAL_WRITE_INIT_STATUS (0x00FF)
  209. #define ADDRESS_OFFSET (0x02)
  210. #define BASE_ADDRESS_REG_OFFSET (0x00)
  211. #define MODE_OFFSET (0x01)
  212. /// @endcond
  213. //lint --e{611} suppress "void* function pointer is type casted to app_event_handler_t type"
  214. //ifx i2c wrapper api for setting slave address in synchronous. hence the event handler is backed up.
  215. temp_upper_layer_event_handler = (app_event_handler_t *)(p_ctx->p_pal_i2c_ctx->upper_layer_event_handler);
  216. //since the lower level APIs are asynchronous, a temporary event handler for set slave address is assigned
  217. p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = (void*)ifx_i2c_pl_pal_slave_addr_event_handler;
  218. p_ctx->pl.buffer[BASE_ADDRESS_REG_OFFSET] = PL_REG_BASE_ADDR;
  219. p_ctx->pl.buffer[MODE_OFFSET] = PL_REG_BASE_ADDR_VOLATILE;
  220. //supported base addresses are 0x00 - 0x7F. Hence 8th bit is ignored
  221. p_ctx->pl.buffer[ADDRESS_OFFSET] = slave_address & PL_REG_I2C_BASE_ADDRESS_MASK;
  222. p_ctx->pl.buffer_tx_len = 1 + PL_REG_LEN_BASE_ADDR;
  223. if(PL_REG_BASE_ADDR_VOLATILE != persistent)
  224. {
  225. p_ctx->pl.buffer[MODE_OFFSET] = PL_REG_BASE_ADDR_PERSISTANT;
  226. }
  227. p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
  228. while(p_ctx->pl.retry_counter)
  229. {
  230. pal_event_status = PAL_WRITE_INIT_STATUS;
  231. //lint --e{534} suppress "Return value is not required to be checked"
  232. pal_i2c_write(p_ctx->p_pal_i2c_ctx,p_ctx->pl.buffer, p_ctx->pl.buffer_tx_len);
  233. while(PAL_WRITE_INIT_STATUS == pal_event_status){};
  234. if(PAL_I2C_EVENT_SUCCESS == pal_event_status)
  235. {
  236. break;
  237. }
  238. p_ctx->pl.retry_counter--;
  239. pal_os_timer_delay_in_milliseconds(PL_POLLING_INVERVAL_US);
  240. }
  241. if(PAL_I2C_EVENT_SUCCESS == pal_event_status)
  242. {
  243. p_ctx->p_pal_i2c_ctx->slave_address = p_ctx->pl.buffer[ADDRESS_OFFSET];
  244. if(PL_REG_BASE_ADDR_VOLATILE != persistent)
  245. {
  246. p_ctx->slave_address = p_ctx->pl.buffer[ADDRESS_OFFSET];
  247. }
  248. status = IFX_I2C_STACK_SUCCESS;
  249. }
  250. //restoring the backed up event handler
  251. p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = temp_upper_layer_event_handler;
  252. /// @cond hidden
  253. #undef PAL_WRITE_INIT_STATUS
  254. #undef ADDRESS_OFFSET
  255. #undef BASE_ADDRESS_REG_OFFSET
  256. #undef MODE_OFFSET
  257. /// @endcond
  258. return status;
  259. }
  260. static void ifx_i2c_pl_read_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len)
  261. {
  262. LOG_PL("[IFX-PL]: Read register %x len %d\n", reg_addr, reg_len);
  263. // Prepare transmit buffer to write register address
  264. p_ctx->pl.buffer[0] = reg_addr;
  265. p_ctx->pl.buffer_tx_len = 1;
  266. // Set low level interface variables and start transmission
  267. p_ctx->pl.buffer_rx_len = reg_len;
  268. p_ctx->pl.register_action = PL_ACTION_READ_REGISTER;
  269. p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
  270. p_ctx->pl.i2c_cmd = PL_I2C_CMD_WRITE;
  271. //lint --e{534} suppress "Return value is not required to be checked"
  272. pal_i2c_write(p_ctx->p_pal_i2c_ctx,p_ctx->pl.buffer, p_ctx->pl.buffer_tx_len);
  273. }
  274. static void ifx_i2c_pl_write_register(ifx_i2c_context_t *p_ctx,uint8_t reg_addr, uint16_t reg_len, const uint8_t* p_content)
  275. {
  276. LOG_PL("[IFX-PL]: Write register %x len %d\n", reg_addr, reg_len);
  277. // Prepare transmit buffer to write register address and content
  278. p_ctx->pl.buffer[0] = reg_addr;
  279. memcpy(p_ctx->pl.buffer + 1, p_content, reg_len);
  280. p_ctx->pl.buffer_tx_len = 1 + reg_len;
  281. // Set Physical Layer low level interface variables and start transmission
  282. p_ctx->pl.register_action = PL_ACTION_WRITE_REGISTER;
  283. p_ctx->pl.retry_counter = PL_POLLING_MAX_CNT;
  284. p_ctx->pl.i2c_cmd = PL_I2C_CMD_WRITE;
  285. //lint --e{534} suppress "Return value is not required to be checked"
  286. pal_i2c_write(p_ctx->p_pal_i2c_ctx,p_ctx->pl.buffer, p_ctx->pl.buffer_tx_len);
  287. }
  288. static void ifx_i2c_pl_status_poll_callback(void *p_ctx)
  289. {
  290. LOG_PL("[IFX-PL]: Status poll Timer elapsed -> Read STATUS register\n");
  291. ifx_i2c_pl_read_register((ifx_i2c_context_t*)p_ctx,PL_REG_I2C_STATE, PL_REG_LEN_I2C_STATE);
  292. }
  293. static host_lib_status_t ifx_i2c_pl_set_bit_rate(ifx_i2c_context_t *p_ctx, uint16_t bitrate)
  294. {
  295. host_lib_status_t status;
  296. void* pal_ctx_upper_layer_handler;
  297. // Save upper layer context in pal
  298. pal_ctx_upper_layer_handler = p_ctx->p_pal_i2c_ctx->upper_layer_event_handler;
  299. // Pass context as NULL to avoid callback invocation
  300. p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = NULL;
  301. status = pal_i2c_set_bitrate(p_ctx->p_pal_i2c_ctx , bitrate);
  302. // Restore callback
  303. p_ctx->p_pal_i2c_ctx->upper_layer_event_handler = pal_ctx_upper_layer_handler;
  304. if(PAL_I2C_EVENT_SUCCESS != status)
  305. {
  306. if (p_ctx->pl.retry_counter--)
  307. {
  308. LOG_PL("[IFX-PL]: Set bit rate failed, Retry setting.\n");
  309. pal_os_event_register_callback_oneshot(ifx_i2c_pl_negotiation_event_handler,((void*)p_ctx),PL_POLLING_INVERVAL_US);
  310. status = IFX_I2C_STACK_BUSY;
  311. }
  312. else
  313. {
  314. status = IFX_I2C_STACK_ERROR;
  315. }
  316. }
  317. else
  318. {
  319. status = IFX_I2C_STACK_SUCCESS;
  320. }
  321. return status;
  322. }
  323. static void ifx_i2c_pl_negotiation_event_handler(void *p_input_ctx)
  324. {
  325. host_lib_status_t event = (uint8_t)IFX_I2C_STACK_ERROR;
  326. uint8_t continue_negotiation;
  327. ifx_i2c_context_t* p_ctx = (ifx_i2c_context_t*)p_input_ctx;
  328. uint8_t i2c_mode_value[2];
  329. uint8_t max_frame_size[2] = { (uint8_t)(p_ctx->frame_size >> 8), (uint8_t)(p_ctx->frame_size) };
  330. uint16_t buffer_len = 0;
  331. uint16_t slave_frequency;
  332. uint16_t slave_frame_len;
  333. uint8_t* p_buffer = NULL;
  334. do
  335. {
  336. continue_negotiation = FALSE;
  337. LOG_PL("[IFX-PL]: Negotiation started\n");
  338. switch(p_ctx->pl.negotiate_state)
  339. {
  340. // Set initial frequency to PL_DEFAULT_FREQUENCY to be able to negotiate with slave
  341. case PL_INIT_SET_FREQ_DEFAULT:
  342. {
  343. // Default frequency set to master
  344. event = ifx_i2c_pl_set_bit_rate(p_input_ctx,PL_DEFAULT_FREQUENCY);
  345. if(IFX_I2C_STACK_SUCCESS == event)
  346. {
  347. p_ctx->pl.negotiate_state = PL_INIT_GET_FREQ_REG;
  348. continue_negotiation = TRUE;
  349. }
  350. else if (IFX_I2C_STACK_ERROR == event)
  351. {
  352. p_ctx->pl.negotiate_state = PL_INIT_DONE;
  353. p_buffer = NULL;
  354. buffer_len = 0;
  355. }
  356. }
  357. break;
  358. // Read the current Max frequency supported by slave
  359. case PL_INIT_GET_FREQ_REG:
  360. {
  361. p_ctx->pl.negotiate_state = PL_INIT_SET_FREQ_REG;
  362. ifx_i2c_pl_read_register(p_ctx,PL_REG_MAX_SCL_FREQU, PL_REG_LEN_MAX_SCL_FREQU);
  363. }
  364. break;
  365. // Set the I2C mode register
  366. case PL_INIT_SET_FREQ_REG:
  367. {
  368. slave_frequency = (p_ctx->pl.buffer[2] << 8) | p_ctx->pl.buffer[3];
  369. i2c_mode_value[0] = PL_REG_I2C_MODE_PERSISTANT;
  370. if((p_ctx->frequency > PL_SM_FM_MAX_FREQUENCY)&&(slave_frequency<=PL_SM_FM_MAX_FREQUENCY))
  371. {
  372. //Change to FM+ mode if slave's current supported frequency is below user's requested frequency
  373. i2c_mode_value[1] = PL_REG_I2C_MODE_FM_PLUS;
  374. p_ctx->pl.negotiate_state = PL_INIT_READ_FREQ;
  375. ifx_i2c_pl_write_register(p_ctx,PL_REG_I2C_MODE, PL_REG_LEN_I2C_MODE, i2c_mode_value);
  376. }
  377. else if((p_ctx->frequency <= PL_SM_FM_MAX_FREQUENCY)&&(slave_frequency>PL_SM_FM_MAX_FREQUENCY))
  378. {
  379. //Change to SM&FM mode if slave's current supported frequency is above user's requested frequency
  380. i2c_mode_value[1] = PL_REG_I2C_MODE_SM_FM;
  381. p_ctx->pl.negotiate_state = PL_INIT_READ_FREQ;
  382. ifx_i2c_pl_write_register(p_ctx,PL_REG_I2C_MODE, PL_REG_LEN_I2C_MODE, i2c_mode_value);
  383. }
  384. else
  385. {
  386. p_ctx->pl.negotiate_state = PL_INIT_VERIFY_FREQ;
  387. continue_negotiation = TRUE;
  388. }
  389. }
  390. break;
  391. // After setting I2C mode register, read the slave's supported frequency
  392. case PL_INIT_READ_FREQ:
  393. {
  394. p_ctx->pl.negotiate_state = PL_INIT_VERIFY_FREQ;
  395. ifx_i2c_pl_read_register(p_ctx,PL_REG_MAX_SCL_FREQU, PL_REG_LEN_MAX_SCL_FREQU);
  396. }
  397. break;
  398. // Verify the requested frequency and slave's supported frequency
  399. case PL_INIT_VERIFY_FREQ:
  400. {
  401. slave_frequency = (p_ctx->pl.buffer[2] << 8) | p_ctx->pl.buffer[3];
  402. if(p_ctx->frequency > slave_frequency)
  403. {
  404. LOG_PL("[IFX-PL]: Unexpected frequency in MAX_SCL_FREQU\n");
  405. p_buffer = NULL;
  406. buffer_len = 0;
  407. p_ctx->pl.negotiate_state = PL_INIT_DONE;
  408. }
  409. else
  410. {
  411. p_ctx->pl.negotiate_state = PL_INIT_AGREE_FREQ;
  412. }
  413. continue_negotiation = TRUE;
  414. }
  415. break;
  416. // Frequency negotiated, Set frequency at master
  417. case PL_INIT_AGREE_FREQ:
  418. {
  419. // Frequency negotiation between master and slave is complete
  420. event = ifx_i2c_pl_set_bit_rate(p_input_ctx, p_ctx->frequency);
  421. if(IFX_I2C_STACK_SUCCESS == event)
  422. {
  423. p_ctx->pl.negotiate_state = PL_INIT_SET_DATA_REG_LEN;
  424. continue_negotiation = TRUE;
  425. }
  426. else if (IFX_I2C_STACK_ERROR == event)
  427. {
  428. p_ctx->pl.negotiate_state = PL_INIT_DONE;
  429. p_buffer = NULL;
  430. buffer_len = 0;
  431. }
  432. }
  433. break;
  434. // Start frame length negotiation by writing the requested frame length
  435. case PL_INIT_SET_DATA_REG_LEN:
  436. {
  437. p_ctx->pl.negotiate_state = PL_INIT_GET_DATA_REG_LEN;
  438. ifx_i2c_pl_write_register(p_ctx,PL_REG_DATA_REG_LEN, sizeof(max_frame_size), max_frame_size);
  439. }
  440. break;
  441. // Read the frame length to verify
  442. case PL_INIT_GET_DATA_REG_LEN:
  443. {
  444. p_ctx->pl.negotiate_state = PL_INIT_VERIFY_DATA_REG;
  445. ifx_i2c_pl_read_register(p_ctx,PL_REG_DATA_REG_LEN,PL_REG_LEN_DATA_REG_LEN);
  446. }
  447. break;
  448. // Check is slave accepted the new frame length
  449. case PL_INIT_VERIFY_DATA_REG:
  450. {
  451. p_ctx->pl.negotiate_state = PL_INIT_DONE;
  452. slave_frame_len = (p_ctx->pl.buffer[0] << 8) | p_ctx->pl.buffer[1];
  453. // Error if slave's frame length is more than requested frame length
  454. if(p_ctx->frame_size >= slave_frame_len)
  455. {
  456. p_ctx->frame_size = slave_frame_len;
  457. event = IFX_I2C_STACK_SUCCESS;
  458. }
  459. p_buffer = NULL;
  460. buffer_len = 0;
  461. continue_negotiation = TRUE;
  462. }
  463. break;
  464. case PL_INIT_DONE:
  465. {
  466. if(IFX_I2C_STACK_SUCCESS == event)
  467. {
  468. p_ctx->pl.frame_state = PL_STATE_READY;
  469. }
  470. else
  471. {
  472. p_ctx->pl.frame_state = PL_STATE_UNINIT;
  473. }
  474. // Negotiation between master and slave is complete
  475. p_ctx->pl.upper_layer_event_handler(p_ctx,event, p_buffer, buffer_len);
  476. }
  477. break;
  478. default:
  479. break;
  480. }
  481. }while(continue_negotiation);
  482. }
  483. static void ifx_i2c_pl_frame_event_handler(ifx_i2c_context_t *p_ctx,host_lib_status_t event)
  484. {
  485. uint16_t frame_size;
  486. if (event != IFX_I2C_STACK_SUCCESS)
  487. {
  488. p_ctx->pl.frame_state = PL_STATE_READY;
  489. // I2C read or write failed, report to upper layer
  490. p_ctx->pl.upper_layer_event_handler(p_ctx,event, 0, 0);
  491. }
  492. else
  493. {
  494. switch(p_ctx->pl.frame_state)
  495. {
  496. // Perform soft reset
  497. case PL_STATE_SOFT_RESET:
  498. {
  499. ifx_i2c_pl_soft_reset(p_ctx);
  500. }
  501. break;
  502. // Negotiate frame and frequency with slave
  503. case PL_STATE_INIT:
  504. {
  505. ifx_i2c_pl_negotiation_event_handler(p_ctx);
  506. }
  507. break;
  508. // Check status of slave data
  509. case PL_STATE_READY:
  510. {
  511. // Start polling status register
  512. p_ctx->pl.frame_state = PL_STATE_DATA_AVAILABLE;
  513. ifx_i2c_pl_read_register(p_ctx,PL_REG_I2C_STATE, PL_REG_LEN_I2C_STATE);
  514. }
  515. break;
  516. // Do read/write frame
  517. case PL_STATE_DATA_AVAILABLE:
  518. {
  519. // Read frame, if response is ready. Ignore busy flag
  520. if ((p_ctx->pl.frame_action == PL_ACTION_READ_FRAME)
  521. && (p_ctx->pl.buffer[0] & PL_REG_I2C_STATE_RESPONSE_READY))
  522. {
  523. frame_size = (p_ctx->pl.buffer[2] << 8) | p_ctx->pl.buffer[3];
  524. if ((frame_size > 0) && (frame_size <= p_ctx->frame_size))
  525. {
  526. p_ctx->pl.frame_state = PL_STATE_RXTX;
  527. ifx_i2c_pl_read_register(p_ctx,PL_REG_DATA, frame_size);
  528. }
  529. else
  530. {
  531. // Continue polling STATUS register if retry limit is not reached
  532. if ((pal_os_timer_get_time_in_milliseconds() - p_ctx->dl.frame_start_time) < p_ctx->dl.data_poll_timeout)
  533. {
  534. pal_os_event_register_callback_oneshot(ifx_i2c_pl_status_poll_callback, (void *)p_ctx, PL_DATA_POLLING_INVERVAL_US);
  535. }
  536. else
  537. {
  538. p_ctx->pl.frame_state = PL_STATE_READY;
  539. p_ctx->pl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_ERROR, 0, 0);
  540. }
  541. }
  542. }
  543. // Write frame is slave is not busy
  544. else if (p_ctx->pl.frame_action == PL_ACTION_WRITE_FRAME)
  545. {
  546. // Write frame if device is not busy, otherwise wait and poll STATUS again later
  547. p_ctx->pl.frame_state = PL_STATE_RXTX;
  548. ifx_i2c_pl_write_register(p_ctx,PL_REG_DATA, p_ctx->pl.tx_frame_len, (uint8_t*)p_ctx->pl.p_tx_frame);
  549. }
  550. // Continue checking the slave status register
  551. else
  552. {
  553. // Continue polling STATUS register if retry limit is not reached
  554. if ((pal_os_timer_get_time_in_milliseconds() - p_ctx->dl.frame_start_time) < p_ctx->dl.data_poll_timeout)
  555. {
  556. pal_os_event_register_callback_oneshot(ifx_i2c_pl_status_poll_callback, (void *)p_ctx, PL_DATA_POLLING_INVERVAL_US);
  557. }
  558. else
  559. {
  560. p_ctx->pl.frame_state = PL_STATE_READY;
  561. p_ctx->pl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_ERROR, 0, 0);
  562. }
  563. }
  564. }
  565. break;
  566. // Frame reading is complete
  567. case PL_STATE_RXTX:
  568. {
  569. // Writing/reading of frame to/from DATA register complete
  570. p_ctx->pl.frame_state = PL_STATE_READY;
  571. p_ctx->pl.upper_layer_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS, p_ctx->pl.buffer, p_ctx->pl.buffer_rx_len);
  572. }
  573. break;
  574. default:
  575. break;
  576. }
  577. }
  578. }
  579. static void ifx_i2c_pal_poll_callback(void *p_ctx)
  580. {
  581. ifx_i2c_context_t* p_local_ctx = (ifx_i2c_context_t *)p_ctx;
  582. if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_WRITE)
  583. {
  584. LOG_PL("[IFX-PL]: Poll Timer elapsed -> Restart TX\n");
  585. //lint --e{534} suppress "Return value is not required to be checked"
  586. pal_i2c_write(p_local_ctx->p_pal_i2c_ctx, p_local_ctx->pl.buffer, p_local_ctx->pl.buffer_tx_len);
  587. }
  588. else if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_READ)
  589. {
  590. LOG_PL("[IFX-PL]: Poll Timer elapsed -> Restart Read Register -> Start TX\n");
  591. //lint --e{534} suppress "Return value is not required to be checked"
  592. pal_i2c_read(p_local_ctx->p_pal_i2c_ctx,p_local_ctx->pl.buffer, p_local_ctx->pl.buffer_rx_len);
  593. }
  594. }
  595. static void ifx_i2c_pl_guard_time_callback(void *p_ctx)
  596. {
  597. ifx_i2c_context_t* p_local_ctx = (ifx_i2c_context_t*)p_ctx;
  598. if (p_local_ctx->pl.register_action == PL_ACTION_READ_REGISTER)
  599. {
  600. if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_WRITE)
  601. {
  602. LOG_PL("[IFX-PL]: GT done-> Start RX\n");
  603. p_local_ctx->pl.i2c_cmd = PL_I2C_CMD_READ;
  604. //lint --e{534} suppress "Return value is not required to be checked"
  605. pal_i2c_read(p_local_ctx->p_pal_i2c_ctx,p_local_ctx->pl.buffer, p_local_ctx->pl.buffer_rx_len);
  606. }
  607. else if (p_local_ctx->pl.i2c_cmd == PL_I2C_CMD_READ)
  608. {
  609. LOG_PL("[IFX-PL]: GT done -> REG is read\n");
  610. ifx_i2c_pl_frame_event_handler(p_local_ctx,IFX_I2C_STACK_SUCCESS);
  611. }
  612. }
  613. else if (p_local_ctx->pl.register_action == PL_ACTION_WRITE_REGISTER)
  614. {
  615. LOG_PL("[IFX-PL]: GT done -> REG written\n");
  616. ifx_i2c_pl_frame_event_handler(p_local_ctx,IFX_I2C_STACK_SUCCESS);
  617. }
  618. }
  619. static void ifx_i2c_pl_pal_event_handler(void *p_ctx, host_lib_status_t event)
  620. {
  621. ifx_i2c_context_t* p_local_ctx = (ifx_i2c_context_t*)p_ctx;
  622. switch (event)
  623. {
  624. case PAL_I2C_EVENT_ERROR:
  625. case PAL_I2C_EVENT_BUSY:
  626. // Error event usually occurs when the device is in sleep mode and needs time to wake up
  627. if (p_local_ctx->pl.retry_counter--)
  628. {
  629. LOG_PL("[IFX-PL]: PAL Error -> Continue polling\n");
  630. pal_os_event_register_callback_oneshot(ifx_i2c_pal_poll_callback,p_local_ctx,PL_POLLING_INVERVAL_US);
  631. }
  632. else
  633. {
  634. LOG_PL("[IFX-PL]: PAL Error -> Stop\n");
  635. ifx_i2c_pl_frame_event_handler(p_local_ctx,IFX_I2C_FATAL_ERROR);
  636. }
  637. break;
  638. case PAL_I2C_EVENT_SUCCESS:
  639. LOG_PL("[IFX-PL]: PAL Success -> Wait Guard Time\n");
  640. pal_os_event_register_callback_oneshot(ifx_i2c_pl_guard_time_callback,p_local_ctx,PL_GUARD_TIME_INTERVAL_US);
  641. break;
  642. default:
  643. break;
  644. }
  645. }
  646. static void ifx_i2c_pl_soft_reset(ifx_i2c_context_t *p_ctx)
  647. {
  648. uint8_t i2c_mode_value[2] = {0};
  649. switch(p_ctx->pl.request_soft_reset)
  650. {
  651. case PL_INIT_GET_STATUS_REG:
  652. p_ctx->pl.request_soft_reset = PL_RESET_WRITE;
  653. //Read the status register to check if soft reset is supported
  654. ifx_i2c_pl_read_register(p_ctx, PL_REG_I2C_STATE, PL_REG_LEN_I2C_STATE);
  655. break;
  656. case PL_RESET_WRITE:
  657. //Mask for soft reset bit(5th bit) from the 1st byte of status register
  658. p_ctx->pl.buffer[0] &= PL_REG_I2C_STATE_SOFT_RESET;
  659. if(p_ctx->pl.buffer[0] == PL_REG_I2C_STATE_SOFT_RESET)
  660. {
  661. p_ctx->pl.request_soft_reset = PL_RESET_STARTUP;
  662. //Write 88 register with 0 value
  663. ifx_i2c_pl_write_register(p_ctx, PL_REG_SOFT_RESET, PL_REG_LEN_SOFT_RESET, i2c_mode_value);
  664. }
  665. else
  666. {
  667. //Soft reset is not supported by the slave
  668. p_ctx->pl.frame_state = PL_STATE_UNINIT;
  669. ifx_i2c_pl_frame_event_handler(p_ctx, IFX_I2C_STACK_ERROR);
  670. }
  671. break;
  672. case PL_RESET_STARTUP:
  673. p_ctx->pl.request_soft_reset= PL_RESET_INIT;
  674. pal_os_event_register_callback_oneshot((register_callback)ifx_i2c_pl_soft_reset, (void *)p_ctx, STARTUP_TIME_MSEC);
  675. break;
  676. case PL_RESET_INIT:
  677. p_ctx->pl.frame_state = PL_STATE_INIT;
  678. ifx_i2c_pl_frame_event_handler(p_ctx,IFX_I2C_STACK_SUCCESS);
  679. break;
  680. default:
  681. break;
  682. }
  683. }
  684. //lint --e{715} suppress "This is used for synchromous implementation, hence p_ctx not used"
  685. //lint --e{818} suppress "This is ignored as upper layer handler function prototype requires this argument"
  686. static void ifx_i2c_pl_pal_slave_addr_event_handler(void *p_ctx, host_lib_status_t event)
  687. {
  688. pal_event_status = event;
  689. }