PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/src/common/STM32F10x/Utilities/STM32_EVAL/STM32100B_EVAL/stm32100b_eval_cec.c

https://github.com/denisacostaq/firmware-stm3210fx2
C | 1721 lines | 1057 code | 327 blank | 337 comment | 315 complexity | 6035e5bf28f080a4206cccb3040ad6e6 MD5 | raw file
Possible License(s): GPL-2.0
  1. /**
  2. ******************************************************************************
  3. * @file stm32100b_eval_cec.c
  4. * @author MCD Application Team
  5. * @version V4.1.0
  6. * @date 03/01/2010
  7. * @brief This file provides all the STM32100B-EVAL HDMI-CEC firmware functions.
  8. ******************************************************************************
  9. * @copy
  10. *
  11. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  12. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  13. * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  14. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  15. * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  16. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  17. *
  18. * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
  19. */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "stm32100b_eval_cec.h"
  22. /** @addtogroup Utilities
  23. * @{
  24. */
  25. /** @addtogroup STM32_EVAL
  26. * @{
  27. */
  28. /** @addtogroup STM32100B_EVAL
  29. * @{
  30. */
  31. /** @defgroup STM32100B_EVAL_CEC
  32. * @brief This file includes the CEC Stack driver for HDMI-CEC Module
  33. * of STM32100B-EVAL board.
  34. * @{
  35. */
  36. /** @defgroup STM32100B_EVAL_CEC_Private_Types
  37. * @{
  38. */
  39. /**
  40. * @}
  41. */
  42. /** @defgroup STM32100B_EVAL_CEC_Private_Defines
  43. * @{
  44. */
  45. /**
  46. * @}
  47. */
  48. /** @defgroup STM32100B_EVAL_CEC_Private_Macros
  49. * @{
  50. */
  51. /**
  52. * @}
  53. */
  54. /** @defgroup STM32100B_EVAL_CEC_Private_Variables
  55. * @{
  56. */
  57. __IO uint32_t ReceivedFrame = 0;
  58. __IO uint32_t SendFrame = 0;
  59. __IO uint32_t BufferCount = 0, TxCounter = 0, RxCounter = 0;
  60. __IO uint8_t BufferPointer[15];
  61. __IO uint32_t ReceiveStatus = 0;
  62. __IO uint32_t SendStatus = 0;
  63. __IO uint8_t TransErrorCode = 0;
  64. __IO uint8_t RecepErrorCode = 0;
  65. __IO uint8_t MyLogicalAddress = 0;
  66. __IO uint16_t MyPhysicalAddress = 0;
  67. __IO uint8_t DeviceType = 0;
  68. #ifdef HDMI_CEC_USE_DDC
  69. __IO uint8_t pBuffer[256];
  70. __IO uint16_t NumByteToRead = 255;
  71. #endif
  72. __IO uint8_t CECDevicesNumber = 0;
  73. HDMI_CEC_Message HDMI_CEC_TX_MessageStructPrivate;
  74. HDMI_CEC_Message HDMI_CEC_RX_MessageStructPrivate;
  75. HDMI_CEC_Message HDMI_CEC_TX_MessageStructure;
  76. __IO uint8_t FeatureOpcode = 0;
  77. __IO uint8_t AbortReason = 0;
  78. __IO uint8_t DeviceCount = 0;
  79. HDMI_CEC_Map HDMI_CEC_MapStruct;
  80. HDMI_CEC_Map HDMI_CEC_DeviceMap[14];
  81. /* CEC follower addresses */
  82. uint8_t* HDMI_CEC_Follower_String[13][2] =
  83. {
  84. {" TV ", "0"},
  85. {"Recording Device 1 ", "0"},
  86. {"Recording Device 2 ", "0"},
  87. {" Tuner 1 ", "0"},
  88. {" Playback Device 1 ", "0"},
  89. {" Audio System ", "0"},
  90. {" Tuner 2 ", "0"},
  91. {" Tuner 3 ", "0"},
  92. {" Playback Device 2 ", "0"},
  93. {"Recording Device 3 ", "0"},
  94. {" Tuner 4 ", "0"},
  95. {" Playback Device 3 ", "0"},
  96. {" Broadcast ", "1"}
  97. };
  98. /**
  99. * @}
  100. */
  101. /** @defgroup STM32100B_EVAL_CEC_Private_Function_Prototypes
  102. * @{
  103. */
  104. static HDMI_CEC_Error PhysicalAddressDiscovery(void);
  105. static HDMI_CEC_Error LogicalAddressAllocation(void);
  106. /**
  107. * @}
  108. */
  109. /** @defgroup STM32100B_EVAL_CEC_Private_Functions
  110. * @{
  111. */
  112. /**
  113. * @brief Initializes the HDMI CEC.
  114. * @param None
  115. * @retval HDMI_CEC_Error: CEC Error code
  116. */
  117. HDMI_CEC_Error HDMI_CEC_Init(void)
  118. {
  119. GPIO_InitTypeDef GPIO_InitStructure;
  120. CEC_InitTypeDef CEC_InitStructure;
  121. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  122. uint8_t sendcount = 0;
  123. #ifdef HDMI_CEC_USE_DDC
  124. I2C_InitTypeDef I2C_InitStructure;
  125. /* Enable CEC_I2C clocks */
  126. RCC_APB1PeriphClockCmd(HDMI_CEC_I2C_CLK, ENABLE);
  127. /* Enable CEC_I2C_GPIO and CEC_HPD_GPIO clocks */
  128. RCC_APB2PeriphClockCmd(HDMI_CEC_I2C_GPIO_CLK | HDMI_CEC_HPD_GPIO_CLK, ENABLE);
  129. #endif
  130. /* Enable CEC clocks */
  131. RCC_APB1PeriphClockCmd(RCC_APB1Periph_CEC, ENABLE);
  132. /* Enable CEC_LINE_GPIO clocks */
  133. RCC_APB2PeriphClockCmd(HDMI_CEC_LINE_GPIO_CLK, ENABLE);
  134. /* Configure CEC_LINE_GPIO as Output open drain */
  135. GPIO_InitStructure.GPIO_Pin = HDMI_CEC_LINE_PIN;
  136. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  137. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  138. GPIO_Init(HDMI_CEC_LINE_GPIO_PORT, &GPIO_InitStructure);
  139. #ifdef HDMI_CEC_USE_DDC
  140. /* Configure CEC_I2C_SCL_PIN and CEC_I2C_SDA_PIN as Output open drain */
  141. GPIO_InitStructure.GPIO_Pin = HDMI_CEC_I2C_SCL_PIN | HDMI_CEC_I2C_SDA_PIN;
  142. GPIO_Init(HDMI_CEC_I2C_GPIO_PORT, &GPIO_InitStructure);
  143. /* This configuration is only when the HDMI CEC is configured as source.
  144. The HDMI source has to provide the +5V Power signal to the sink.
  145. On STM32100B-EVAL borad, you have to solder the SB4 Solder bridge.
  146. Then, the source will wait for HPD signal to be asserted from the sink.
  147. Once the HPD signal is detected the source shall read the EDID structure
  148. throuhgh the DDC channel. */
  149. /* Configure CEC_HPD_GPIO as Input pull down */
  150. GPIO_InitStructure.GPIO_Pin = HDMI_CEC_HPD_PIN;
  151. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  152. GPIO_Init(HDMI_CEC_HPD_GPIO_PORT, &GPIO_InitStructure);
  153. /* This configuration is only when the HDMI CEC is configured as sink.
  154. The HDMI sink has to wait for the +5V Power signal from the source.
  155. On STM32100B-EVAL borad, SB4 Solder bridge should be open (default configuration).
  156. Then, the sink will assert the HPD signal to inform the source that the EDID
  157. is ready for read through DDC channel. In this implementation, the EDID structure
  158. is not implemented. */
  159. /* GPIO_InitStructure.GPIO_Pin = HDMI_CEC_HPD_PIN;
  160. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  161. GPIO_Init(HDMI_CEC_HPD_GPIO_PORT, &GPIO_InitStructure);
  162. HDMI_CEC_HPD_HIGH(); // Set the Hot plug detect signal */
  163. /* Enable CEC_I2C */
  164. I2C_Cmd(HDMI_CEC_I2C, ENABLE);
  165. /* I2C configuration */
  166. I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  167. I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  168. I2C_InitStructure.I2C_OwnAddress1 = HDMI_CEC_I2C_SLAVE_ADDRESS7;
  169. I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  170. I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  171. I2C_InitStructure.I2C_ClockSpeed = HDMI_CEC_I2C_CLOCK_SPEED;
  172. I2C_Init(HDMI_CEC_I2C, &I2C_InitStructure);
  173. #endif
  174. /* Physical Address discovery */
  175. errorstatus = PhysicalAddressDiscovery();
  176. if (errorstatus != HDMI_CEC_OK)
  177. {
  178. /* Device not connected (Physical Address lost) */
  179. return(errorstatus);
  180. }
  181. /* CEC DeInit */
  182. CEC_DeInit();
  183. /* Configure CEC */
  184. CEC_InitStructure.CEC_BitTimingMode = CEC_BitTimingStdMode;
  185. CEC_InitStructure.CEC_BitPeriodMode = CEC_BitPeriodStdMode;
  186. CEC_Init(&CEC_InitStructure);
  187. /* Set Prescaler value for APB1 clock = 24MHz */
  188. CEC_SetPrescaler(0x4AF);
  189. /* Enable CEC */
  190. CEC_Cmd(ENABLE);
  191. /* Logical Address Allocation */
  192. sendcount = 0;
  193. errorstatus = LogicalAddressAllocation();
  194. while ((errorstatus != HDMI_CEC_OK) && sendcount < 0x5)
  195. {
  196. sendcount++;
  197. errorstatus = LogicalAddressAllocation();
  198. }
  199. if (errorstatus != HDMI_CEC_OK)
  200. {
  201. /* Device Unregistred */
  202. return(errorstatus);
  203. }
  204. HDMI_CEC_CheckConnectedDevices();
  205. /* Set the CEC initiator address */
  206. CEC_OwnAddressConfig(MyLogicalAddress);
  207. /* Activate CEC interrupts associated to the set of RBTF,RERR, TBTF, TERR flags */
  208. CEC_ITConfig(ENABLE);
  209. /* Report physical address*/
  210. errorstatus = HDMI_CEC_ReportPhysicalAddress();
  211. sendcount = 0;
  212. while ((errorstatus != HDMI_CEC_OK) && sendcount < 0x5)
  213. {
  214. sendcount++;
  215. errorstatus = HDMI_CEC_ReportPhysicalAddress();
  216. }
  217. if (errorstatus != HDMI_CEC_OK)
  218. {
  219. /* Device Unregistred */
  220. return(errorstatus);
  221. }
  222. return errorstatus;
  223. }
  224. /**
  225. * @brief Transmit message by taking data from typedef struct CEC_Meassage
  226. * @param CEC_TX_MessageStructure: pointer to an CEC_Message structure that contains
  227. * the message to be sent.
  228. * @retval HDMI_CEC_Error: CEC Error code
  229. */
  230. HDMI_CEC_Error HDMI_CEC_TransmitMessage(HDMI_CEC_Message *HDMI_CEC_TX_MessageStructure)
  231. {
  232. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  233. __IO uint32_t count = 0, j = 0;
  234. SendFrame = 0;
  235. SendStatus = 0;
  236. TxCounter = 0;
  237. BufferCount = 0;
  238. HDMI_CEC_TX_MessageStructPrivate = *HDMI_CEC_TX_MessageStructure;
  239. /* Initialize BufferPointer */
  240. for (j = 0; j < 15; j++)
  241. {
  242. BufferPointer[j] = 0;
  243. }
  244. BufferPointer[0] = HDMI_CEC_TX_MessageStructPrivate.Opcode;
  245. for (BufferCount = 1; BufferCount < HDMI_CEC_TX_MessageStructPrivate.TxMessageLength + 1; BufferCount++)
  246. {
  247. BufferPointer[BufferCount] = HDMI_CEC_TX_MessageStructPrivate.Operande[BufferCount-1];
  248. }
  249. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  250. /* Write single Data in the TX Buffer to Transmit through the CEC peripheral */
  251. CEC_SendDataByte(HDMI_CEC_TX_MessageStructPrivate.Header);
  252. /* Initiate Message Transmission */
  253. CEC_StartOfMessage();
  254. while ((SendFrame == 0) && (count < HDMI_CEC_TIMEOUT_VALUE))
  255. {
  256. count++;
  257. }
  258. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  259. {
  260. errorstatus = HDMI_CEC_TIMEOUT;
  261. return(errorstatus);
  262. }
  263. if (SendStatus == 0)
  264. {
  265. errorstatus = (HDMI_CEC_Error) TransErrorCode;
  266. }
  267. return errorstatus;
  268. }
  269. /**
  270. * @brief Get the ESR register status.
  271. * @param None
  272. * @retval HDMI_CEC_Error: CEC Error code
  273. */
  274. HDMI_CEC_Error HDMI_CEC_GetErrorStatus (void)
  275. {
  276. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  277. /* Bit timing error case*/
  278. if (CEC_GetFlagStatus(CEC_FLAG_BTE) != RESET)
  279. {
  280. errorstatus = HDMI_CEC_BIT_TIMING;
  281. }
  282. /* Bit period error case */
  283. if (CEC_GetFlagStatus(CEC_FLAG_BPE) != RESET)
  284. {
  285. errorstatus = HDMI_CEC_BIT_PERIOD;
  286. }
  287. /* Recieve error case */
  288. if (CEC_GetFlagStatus(CEC_FLAG_RBTFE) != RESET)
  289. {
  290. errorstatus = HDMI_CEC_RX_BLOCK_FINISHED;
  291. }
  292. /* Start bit error case*/
  293. if (CEC_GetFlagStatus(CEC_FLAG_SBE) != RESET)
  294. {
  295. errorstatus = HDMI_CEC_START_BIT;
  296. }
  297. /* Acknowledge error case*/
  298. if (CEC_GetFlagStatus(CEC_FLAG_ACKE) != RESET)
  299. {
  300. errorstatus = HDMI_CEC_BLOCK_ACKNOWLEDGE;
  301. }
  302. /* Line error case */
  303. if (CEC_GetFlagStatus(CEC_FLAG_LINE) != RESET)
  304. {
  305. errorstatus = HDMI_CEC_LINE;
  306. }
  307. /* Transfert error case*/
  308. if (CEC_GetFlagStatus(CEC_FLAG_TBTFE) != RESET)
  309. {
  310. errorstatus = HDMI_CEC_TX_BLOCK_FINISHED;
  311. }
  312. /* Clear All errors */
  313. CEC_ClearFlag(CEC_FLAG_RERR);
  314. CEC_ClearFlag(CEC_FLAG_TERR);
  315. return errorstatus;
  316. }
  317. /**
  318. * @brief Allows to process all the interrupts that are high.
  319. * @param None
  320. * @retval None
  321. */
  322. void HDMI_CEC_ProcessIRQSrc(void)
  323. {
  324. /********************** Reception *********************************************/
  325. /* Check if a reception error occured */
  326. if (CEC_GetFlagStatus(CEC_FLAG_RERR))
  327. {
  328. /* Set receive status bit (Error) */
  329. ReceiveStatus = 0;
  330. ReceivedFrame = 1;
  331. RecepErrorCode = HDMI_CEC_GetErrorStatus();
  332. CEC_ClearFlag(CEC_FLAG_RERR | CEC_FLAG_RSOM | CEC_FLAG_REOM | CEC_FLAG_RBTF);
  333. }
  334. else if (CEC_GetFlagStatus(CEC_FLAG_RBTF))
  335. {
  336. /* Check if the byte received is the last one of the message */
  337. if (CEC_GetFlagStatus(CEC_FLAG_REOM))
  338. {
  339. HDMI_CEC_RX_MessageStructPrivate.Operande[RxCounter-1] = CEC_ReceiveDataByte();
  340. HDMI_CEC_RX_MessageStructPrivate.RxMessageLength = RxCounter;
  341. ReceiveStatus = SUCCESS;
  342. ReceivedFrame = 1;
  343. }
  344. /* Check if the byte received is a Header */
  345. else if (CEC_GetFlagStatus(CEC_FLAG_RSOM))
  346. {
  347. ReceiveStatus = 0;
  348. HDMI_CEC_RX_MessageStructPrivate.Header = CEC_ReceiveDataByte();
  349. RxCounter = 0;
  350. }
  351. /* Receive each byte except header in the reception buffer */
  352. else
  353. {
  354. if (RxCounter != 0)
  355. {
  356. HDMI_CEC_RX_MessageStructPrivate.Operande[RxCounter-1] = CEC_ReceiveDataByte();
  357. RxCounter++;
  358. }
  359. else
  360. {
  361. HDMI_CEC_RX_MessageStructPrivate.Opcode = CEC_ReceiveDataByte();
  362. RxCounter++;
  363. }
  364. }
  365. /* Clear all reception flags */
  366. CEC_ClearFlag(CEC_FLAG_RSOM | CEC_FLAG_REOM | CEC_FLAG_RBTF);
  367. }
  368. /********************** Transmission ******************************************/
  369. /* Check if a transmission error occured */
  370. if (CEC_GetFlagStatus(CEC_FLAG_TERR))
  371. {
  372. TransErrorCode = HDMI_CEC_GetErrorStatus();
  373. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  374. SendFrame = 1;
  375. SendStatus = 0;
  376. }
  377. /* Check if end of message bit is set in the data to be transmitted */
  378. else if (CEC_GetFlagStatus(CEC_FLAG_TEOM))
  379. {
  380. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_RBTF);
  381. CEC_EndOfMessageCmd(DISABLE);
  382. SendFrame = 1;
  383. SendStatus = SUCCESS;
  384. }
  385. /* Check if data byte has been sent */
  386. else if (CEC_GetFlagStatus(CEC_FLAG_TBTRF))
  387. {
  388. /* Set EOM bit if the byte to be transmitted is the last one of the TransmitBuffer */
  389. if (TxCounter == (HDMI_CEC_TX_MessageStructPrivate.TxMessageLength))
  390. {
  391. CEC_SendDataByte(BufferPointer[TxCounter]);
  392. TxCounter++;
  393. CEC_ClearFlag(CEC_FLAG_TBTRF);
  394. CEC_EndOfMessageCmd(ENABLE);
  395. }
  396. else
  397. {
  398. /* Put the byte in the TX Buffer */
  399. CEC_SendDataByte(BufferPointer[TxCounter]);
  400. TxCounter++;
  401. CEC_ClearFlag(CEC_FLAG_TBTRF);
  402. }
  403. }
  404. }
  405. /**
  406. * @brief Report physical address to all other devices thus allowing any
  407. device to create a map of the network.
  408. * @param None
  409. * @retval HDMI_CEC_Error: CEC Error code.
  410. */
  411. HDMI_CEC_Error HDMI_CEC_ReportPhysicalAddress(void)
  412. {
  413. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  414. HDMI_CEC_Message HDMI_CEC_TX_Message;
  415. HDMI_CEC_TX_Message.Header = ((MyLogicalAddress << 4) | 0xF);
  416. HDMI_CEC_TX_Message.Opcode = HDMI_CEC_OPCODE_REPORT_PHYSICAL_ADDRESS;
  417. HDMI_CEC_TX_Message.Operande[0] = MyPhysicalAddress >> 8;
  418. HDMI_CEC_TX_Message.Operande[1] = MyPhysicalAddress & 0xFF;
  419. HDMI_CEC_TX_Message.Operande[2] = DeviceType;
  420. HDMI_CEC_TX_Message.TxMessageLength = 0x03;
  421. errorstatus = HDMI_CEC_TransmitMessage(&HDMI_CEC_TX_Message);
  422. return errorstatus;
  423. }
  424. /**
  425. * @brief Handle CEC command receive callback.
  426. * When receiving the STANDBY Opcode commande, the system is entred in
  427. * Stop mode and when wakeup, the PLL is configured as system clock and
  428. * the HSI is selected as PLL source.
  429. * @param None
  430. * @retval None
  431. */
  432. void HDMI_CEC_CommandCallBack(void)
  433. {
  434. uint8_t i = 0, sendcount = 0;
  435. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  436. EXTI_InitTypeDef EXTI_InitStructure;
  437. switch (HDMI_CEC_RX_MessageStructPrivate.Opcode)
  438. {
  439. case HDMI_CEC_OPCODE_REPORT_PHYSICAL_ADDRESS:
  440. HDMI_CEC_MapStruct.PhysicalAddress_A = HDMI_CEC_RX_MessageStructPrivate.Operande[1] >> 4;
  441. HDMI_CEC_MapStruct.PhysicalAddress_B = HDMI_CEC_RX_MessageStructPrivate.Operande[1] & 0x0F;
  442. HDMI_CEC_MapStruct.PhysicalAddress_C = HDMI_CEC_RX_MessageStructPrivate.Operande[0] >> 4;
  443. HDMI_CEC_MapStruct.PhysicalAddress_D = HDMI_CEC_RX_MessageStructPrivate.Operande[0] & 0x0F;
  444. HDMI_CEC_MapStruct.LogicalAddress = (HDMI_CEC_RX_MessageStructPrivate.Header >> 0x4) & 0x0F;
  445. HDMI_CEC_MapStruct.DeviceType = HDMI_CEC_RX_MessageStructPrivate.Operande[2];
  446. HDMI_CEC_DeviceMap[DeviceCount] = HDMI_CEC_MapStruct;
  447. HDMI_CEC_Follower_String[(HDMI_CEC_DeviceMap[DeviceCount].LogicalAddress)][1] = "1";
  448. DeviceCount++;
  449. break;
  450. case HDMI_CEC_OPCODE_STANDBY:
  451. /* CEC Line */
  452. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);
  453. /* Configure the CEC Line as EXTI Line on Falling Edge */
  454. EXTI_ClearITPendingBit(EXTI_Line8);
  455. EXTI_InitStructure.EXTI_Line = EXTI_Line8;
  456. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  457. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  458. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  459. EXTI_Init(&EXTI_InitStructure);
  460. /* Request to enter Stop mode */
  461. PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
  462. /* Disable the CEC EXTI Line */
  463. EXTI_InitStructure.EXTI_LineCmd = DISABLE;
  464. EXTI_Init(&EXTI_InitStructure);
  465. /* Configure the PLL Source */
  466. RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_6);
  467. /* Enable PLL */
  468. RCC_PLLCmd(ENABLE);
  469. /* Wait till PLL is ready */
  470. while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  471. {
  472. }
  473. /* Select PLL as system clock source */
  474. RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  475. /* Wait till PLL is used as system clock source */
  476. while(RCC_GetSYSCLKSource() != 0x08)
  477. {
  478. }
  479. break;
  480. case HDMI_CEC_OPCODE_GET_CEC_VERSION:
  481. /* Send the Used CEC version */
  482. HDMI_CEC_TX_MessageStructPrivate.Header = ((MyLogicalAddress << 4) | HDMI_CEC_RX_MessageStructPrivate.Header >> 4);
  483. HDMI_CEC_TX_MessageStructPrivate.Opcode = HDMI_CEC_OPCODE_CEC_VERSION;
  484. HDMI_CEC_TX_MessageStructPrivate.Operande[0] = HDMI_CEC_VERSION; /* CEC Version */
  485. HDMI_CEC_TX_MessageStructPrivate.TxMessageLength = 0x01;
  486. errorstatus = HDMI_CEC_TransmitMessage(&HDMI_CEC_TX_MessageStructPrivate);
  487. /* Retransmit message until 5 time */
  488. while ((errorstatus != HDMI_CEC_OK) && sendcount < 0x5)
  489. {
  490. sendcount++;
  491. errorstatus = HDMI_CEC_TransmitMessage(&HDMI_CEC_TX_MessageStructPrivate);
  492. }
  493. break;
  494. case HDMI_CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
  495. /* Send the Physical address */
  496. errorstatus = HDMI_CEC_ReportPhysicalAddress();
  497. sendcount = 0;
  498. /* Retransmit message until 5 time */
  499. while ((errorstatus != HDMI_CEC_OK) && sendcount < 0x5)
  500. {
  501. sendcount++;
  502. errorstatus = HDMI_CEC_ReportPhysicalAddress();
  503. }
  504. break;
  505. case HDMI_CEC_OPCODE_FEATURE_ABORT:
  506. /* The device doesn't support the requested message type, or that it cannot
  507. execute it at the present time. */
  508. FeatureOpcode = HDMI_CEC_RX_MessageStructPrivate.Operande[0];
  509. AbortReason = HDMI_CEC_RX_MessageStructPrivate.Operande[1];
  510. break;
  511. case HDMI_CEC_OPCODE_GIVE_OSD_NAME:
  512. /* Send the OSD name = STM32100B CEC*/
  513. HDMI_CEC_TX_MessageStructPrivate.Header = ((MyLogicalAddress << 4) | HDMI_CEC_RX_MessageStructPrivate.Header >> 4);
  514. HDMI_CEC_TX_MessageStructPrivate.Opcode = HDMI_CEC_OPCODE_SET_OSD_NAME;
  515. /* STM32100B*/
  516. HDMI_CEC_TX_MessageStructPrivate.Operande[0] = 0x53;
  517. HDMI_CEC_TX_MessageStructPrivate.Operande[1] = 0x54;
  518. HDMI_CEC_TX_MessageStructPrivate.Operande[2] = 0x4D;
  519. HDMI_CEC_TX_MessageStructPrivate.Operande[3] = 0x33;
  520. HDMI_CEC_TX_MessageStructPrivate.Operande[4] = 0x32;
  521. HDMI_CEC_TX_MessageStructPrivate.Operande[5] = 0x31;
  522. HDMI_CEC_TX_MessageStructPrivate.Operande[6] = 0x30;
  523. HDMI_CEC_TX_MessageStructPrivate.Operande[7] = 0x30;
  524. HDMI_CEC_TX_MessageStructPrivate.Operande[8] = 0x42;
  525. HDMI_CEC_TX_MessageStructPrivate.Operande[9] = 0x20;
  526. /* CEC */
  527. HDMI_CEC_TX_MessageStructPrivate.Operande[10] = 0x43;
  528. HDMI_CEC_TX_MessageStructPrivate.Operande[11] = 0x45;
  529. HDMI_CEC_TX_MessageStructPrivate.Operande[12] = 0x43;
  530. HDMI_CEC_TX_MessageStructPrivate.TxMessageLength = 13;
  531. errorstatus = HDMI_CEC_TransmitMessage(&HDMI_CEC_TX_MessageStructPrivate);
  532. sendcount = 0;
  533. /* Retransmit message until 5 time */
  534. while ((errorstatus != HDMI_CEC_OK) && sendcount < 0x5)
  535. {
  536. sendcount++;
  537. errorstatus = HDMI_CEC_TransmitMessage(&HDMI_CEC_TX_MessageStructPrivate);
  538. }
  539. break;
  540. case HDMI_CEC_OPCODE_ROUTING_CHANGE:
  541. for (i = 0;i < 0x14;i++)
  542. {
  543. if ((HDMI_CEC_DeviceMap[i].PhysicalAddress_A == HDMI_CEC_RX_MessageStructPrivate.Operande[1] >> 4) &&
  544. (HDMI_CEC_DeviceMap[i].PhysicalAddress_B == HDMI_CEC_RX_MessageStructPrivate.Operande[1]&0x0F) &&
  545. (HDMI_CEC_DeviceMap[i].PhysicalAddress_C == HDMI_CEC_RX_MessageStructPrivate.Operande[0] >> 4) &&
  546. (HDMI_CEC_DeviceMap[i].PhysicalAddress_D == HDMI_CEC_RX_MessageStructPrivate.Operande[0]&0x0F))
  547. {
  548. HDMI_CEC_MapStruct.LogicalAddress = (HDMI_CEC_RX_MessageStructPrivate.Header >> 0x4) & 0x0F;
  549. HDMI_CEC_MapStruct.DeviceType = HDMI_CEC_RX_MessageStructPrivate.Operande[2];
  550. HDMI_CEC_DeviceMap[i] = HDMI_CEC_MapStruct;
  551. }
  552. }
  553. break;
  554. default:
  555. /* Send Abort feature*/
  556. HDMI_CEC_TX_MessageStructPrivate.Header = ((MyLogicalAddress << 4) | HDMI_CEC_RX_MessageStructPrivate.Header >> 4);
  557. HDMI_CEC_TX_MessageStructPrivate.Opcode = HDMI_CEC_OPCODE_FEATURE_ABORT;
  558. HDMI_CEC_TX_MessageStructPrivate.Operande[0] = 0x02; /* defines command to be performed */
  559. HDMI_CEC_TX_MessageStructPrivate.Operande[1] = HDMI_CEC_REFUSED; /* Reason for abort feature */
  560. HDMI_CEC_TX_MessageStructPrivate.TxMessageLength = 0x02;
  561. errorstatus = HDMI_CEC_TransmitMessage(&HDMI_CEC_TX_MessageStructPrivate);
  562. sendcount = 0;
  563. /* Retransmit message until 5 time */
  564. while ((errorstatus != HDMI_CEC_OK) && sendcount < 0x5)
  565. {
  566. sendcount++;
  567. errorstatus = HDMI_CEC_TransmitMessage(&HDMI_CEC_TX_MessageStructPrivate);
  568. }
  569. break;
  570. }
  571. }
  572. /**
  573. * @brief Check the connected CEC devices.
  574. * @param None
  575. * @retval HDMI_CEC_Error
  576. */
  577. HDMI_CEC_Error HDMI_CEC_CheckConnectedDevices(void)
  578. {
  579. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  580. uint32_t count = 0, i = 1;
  581. /*----------------------------- TV device ---------------------------*/
  582. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  583. CEC_EndOfMessageCmd(ENABLE);
  584. CEC_SendDataByte((MyLogicalAddress << 4) | 0x0);
  585. /* Start of message */
  586. CEC_StartOfMessage();
  587. /* Wait till the header message is sent */
  588. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  589. {
  590. count++;
  591. }
  592. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  593. {
  594. errorstatus = HDMI_CEC_TIMEOUT;
  595. return(errorstatus);
  596. }
  597. errorstatus = HDMI_CEC_GetErrorStatus();
  598. if (errorstatus == HDMI_CEC_OK)
  599. {
  600. HDMI_CEC_Follower_String[0][1] = "1";
  601. i++;
  602. errorstatus = HDMI_CEC_OK;
  603. }
  604. /* Clear CEC CSR register */
  605. CEC_ClearFlag(CEC_FLAG_TBTRF);
  606. CEC_EndOfMessageCmd(DISABLE);
  607. /*----------------------------- Recording device 1 ---------------------------*/
  608. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  609. CEC_EndOfMessageCmd(ENABLE);
  610. CEC_SendDataByte((MyLogicalAddress << 4) | 0x1);
  611. /* Start of message */
  612. CEC_StartOfMessage();
  613. /* Wait till the header message is sent */
  614. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  615. {
  616. count++;
  617. }
  618. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  619. {
  620. errorstatus = HDMI_CEC_TIMEOUT;
  621. return(errorstatus);
  622. }
  623. errorstatus = HDMI_CEC_GetErrorStatus();
  624. if (errorstatus == HDMI_CEC_OK)
  625. {
  626. HDMI_CEC_Follower_String[1][1] = "1";
  627. i++;
  628. errorstatus = HDMI_CEC_OK;
  629. }
  630. /* Clear CEC CSR register */
  631. CEC_ClearFlag(CEC_FLAG_TBTRF);
  632. CEC_EndOfMessageCmd(DISABLE);
  633. /*----------------------------- Recording device 2 ---------------------------*/
  634. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  635. CEC_EndOfMessageCmd(ENABLE);
  636. CEC_SendDataByte((MyLogicalAddress << 4) | 0x2);
  637. /* Start of message */
  638. CEC_StartOfMessage();
  639. /* Wait till the header message is sent */
  640. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  641. {
  642. count++;
  643. }
  644. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  645. {
  646. errorstatus = HDMI_CEC_TIMEOUT;
  647. return(errorstatus);
  648. }
  649. errorstatus = HDMI_CEC_GetErrorStatus();
  650. if (errorstatus == HDMI_CEC_OK)
  651. {
  652. HDMI_CEC_Follower_String[2][1] = "1";
  653. i++;
  654. errorstatus = HDMI_CEC_OK;
  655. }
  656. /* Clear CEC CSR register */
  657. CEC_ClearFlag(CEC_FLAG_TBTRF);
  658. CEC_EndOfMessageCmd(DISABLE);
  659. /*----------------------------- Tuner 1 ---------------------------*/
  660. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  661. CEC_EndOfMessageCmd(ENABLE);
  662. CEC_SendDataByte((MyLogicalAddress << 4) | 0x3);
  663. /* Start of message */
  664. CEC_StartOfMessage();
  665. /* Wait till the header message is sent */
  666. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  667. {
  668. count++;
  669. }
  670. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  671. {
  672. errorstatus = HDMI_CEC_TIMEOUT;
  673. return(errorstatus);
  674. }
  675. errorstatus = HDMI_CEC_GetErrorStatus();
  676. if (errorstatus == HDMI_CEC_OK)
  677. {
  678. HDMI_CEC_Follower_String[3][1] = "1";
  679. i++;
  680. errorstatus = HDMI_CEC_OK;
  681. }
  682. /* Clear CEC CSR register */
  683. CEC_ClearFlag(CEC_FLAG_TBTRF);
  684. CEC_EndOfMessageCmd(DISABLE);
  685. /*----------------------------- Playback device 1 ---------------------------*/
  686. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  687. CEC_EndOfMessageCmd(ENABLE);
  688. CEC_SendDataByte((MyLogicalAddress << 4) | 0x4);
  689. /* Start of message */
  690. CEC_StartOfMessage();
  691. /* Wait till the header message is sent */
  692. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  693. {
  694. count++;
  695. }
  696. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  697. {
  698. errorstatus = HDMI_CEC_TIMEOUT;
  699. return(errorstatus);
  700. }
  701. errorstatus = HDMI_CEC_GetErrorStatus();
  702. if (errorstatus == HDMI_CEC_OK)
  703. {
  704. HDMI_CEC_Follower_String[4][1] = "1";
  705. i++;
  706. errorstatus = HDMI_CEC_OK;
  707. }
  708. /* Clear CEC CSR register */
  709. CEC_ClearFlag(CEC_FLAG_TBTRF);
  710. CEC_EndOfMessageCmd(DISABLE);
  711. /*----------------------------- Audio system ---------------------------*/
  712. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  713. CEC_EndOfMessageCmd(ENABLE);
  714. CEC_SendDataByte((MyLogicalAddress << 4) | 0x5);
  715. /* Start of message */
  716. CEC_StartOfMessage();
  717. /* Wait till the header message is sent */
  718. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  719. {
  720. count++;
  721. }
  722. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  723. {
  724. errorstatus = HDMI_CEC_TIMEOUT;
  725. return(errorstatus);
  726. }
  727. errorstatus = HDMI_CEC_GetErrorStatus();
  728. if (errorstatus == HDMI_CEC_OK)
  729. {
  730. HDMI_CEC_Follower_String[5][1] = "1";
  731. i++;
  732. errorstatus = HDMI_CEC_OK;
  733. }
  734. /* Clear CEC CSR register */
  735. CEC_ClearFlag(CEC_FLAG_TBTRF);
  736. CEC_EndOfMessageCmd(DISABLE);
  737. /*----------------------------- Tuner 2 ---------------------------*/
  738. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  739. CEC_EndOfMessageCmd(ENABLE);
  740. CEC_SendDataByte((MyLogicalAddress << 4) | 0x6);
  741. /* Start of message */
  742. CEC_StartOfMessage();
  743. /* Wait till the header message is sent */
  744. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  745. {
  746. count++;
  747. }
  748. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  749. {
  750. errorstatus = HDMI_CEC_TIMEOUT;
  751. return(errorstatus);
  752. }
  753. errorstatus = HDMI_CEC_GetErrorStatus();
  754. if (errorstatus == HDMI_CEC_OK)
  755. {
  756. HDMI_CEC_Follower_String[6][1] = "1";
  757. i++;
  758. errorstatus = HDMI_CEC_OK;
  759. }
  760. /* Clear CEC CSR register */
  761. CEC_ClearFlag(CEC_FLAG_TBTRF);
  762. CEC_EndOfMessageCmd(DISABLE);
  763. /*----------------------------- Tuner 3 ---------------------------*/
  764. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  765. CEC_EndOfMessageCmd(ENABLE);
  766. CEC_SendDataByte((MyLogicalAddress << 4) | 0x7);
  767. /* Start of message */
  768. CEC_StartOfMessage();
  769. /* Wait till the header message is sent */
  770. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  771. {
  772. count++;
  773. }
  774. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  775. {
  776. errorstatus = HDMI_CEC_TIMEOUT;
  777. return(errorstatus);
  778. }
  779. errorstatus = HDMI_CEC_GetErrorStatus();
  780. if (errorstatus == HDMI_CEC_OK)
  781. {
  782. HDMI_CEC_Follower_String[7][1] = "1";
  783. i++;
  784. errorstatus = HDMI_CEC_OK;
  785. }
  786. /* Clear CEC CSR register */
  787. CEC_ClearFlag(CEC_FLAG_TBTRF);
  788. CEC_EndOfMessageCmd(DISABLE);
  789. /*----------------------------- Playback device 2 ---------------------------*/
  790. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  791. CEC_EndOfMessageCmd(ENABLE);
  792. CEC_SendDataByte((MyLogicalAddress << 4) | 0x8);
  793. /* Start of message */
  794. CEC_StartOfMessage();
  795. /* Wait till the header message is sent */
  796. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  797. {
  798. count++;
  799. }
  800. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  801. {
  802. errorstatus = HDMI_CEC_TIMEOUT;
  803. return(errorstatus);
  804. }
  805. errorstatus = HDMI_CEC_GetErrorStatus();
  806. if (errorstatus == HDMI_CEC_OK)
  807. {
  808. HDMI_CEC_Follower_String[8][1] = "1";
  809. i++;
  810. errorstatus = HDMI_CEC_OK;
  811. }
  812. /* Clear CEC CSR register */
  813. CEC_ClearFlag(CEC_FLAG_TBTRF);
  814. CEC_EndOfMessageCmd(DISABLE);
  815. /*----------------------------- Recording device 3 ---------------------------*/
  816. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  817. CEC_EndOfMessageCmd(ENABLE);
  818. CEC_SendDataByte((MyLogicalAddress << 4) | 0x9);
  819. /* Start of message */
  820. CEC_StartOfMessage();
  821. /* Wait till the header message is sent */
  822. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  823. {
  824. count++;
  825. }
  826. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  827. {
  828. errorstatus = HDMI_CEC_TIMEOUT;
  829. return(errorstatus);
  830. }
  831. errorstatus = HDMI_CEC_GetErrorStatus();
  832. if (errorstatus == HDMI_CEC_OK)
  833. {
  834. HDMI_CEC_Follower_String[9][1] = "1";
  835. i++;
  836. errorstatus = HDMI_CEC_OK;
  837. }
  838. /* Clear CEC CSR register */
  839. CEC_ClearFlag(CEC_FLAG_TBTRF);
  840. CEC_EndOfMessageCmd(DISABLE);
  841. /*----------------------------- Tuner 4 ---------------------------*/
  842. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  843. CEC_EndOfMessageCmd(ENABLE);
  844. CEC_SendDataByte((MyLogicalAddress << 4) | 0xA);
  845. /* Start of message */
  846. CEC_StartOfMessage();
  847. /* Wait till the header message is sent */
  848. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  849. {
  850. count++;
  851. }
  852. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  853. {
  854. errorstatus = HDMI_CEC_TIMEOUT;
  855. return(errorstatus);
  856. }
  857. errorstatus = HDMI_CEC_GetErrorStatus();
  858. if (errorstatus == HDMI_CEC_OK)
  859. {
  860. HDMI_CEC_Follower_String[10][1] = "1";
  861. i++;
  862. errorstatus = HDMI_CEC_OK;
  863. }
  864. /* Clear CEC CSR register */
  865. CEC_ClearFlag(CEC_FLAG_TBTRF);
  866. CEC_EndOfMessageCmd(DISABLE);
  867. /*----------------------------- Playback device 3 ---------------------------*/
  868. CEC_OwnAddressConfig(MyLogicalAddress); /* Own address = MyLogicalAddress */
  869. CEC_EndOfMessageCmd(ENABLE);
  870. CEC_SendDataByte((MyLogicalAddress << 4) | 0xB);
  871. /* Start of message */
  872. CEC_StartOfMessage();
  873. /* Wait till the header message is sent */
  874. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  875. {
  876. count++;
  877. }
  878. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  879. {
  880. errorstatus = HDMI_CEC_TIMEOUT;
  881. return(errorstatus);
  882. }
  883. errorstatus = HDMI_CEC_GetErrorStatus();
  884. if (errorstatus == HDMI_CEC_OK)
  885. {
  886. HDMI_CEC_Follower_String[11][1] = "1";
  887. i++;
  888. errorstatus = HDMI_CEC_OK;
  889. }
  890. /* Clear CEC CSR register */
  891. CEC_ClearFlag(CEC_FLAG_TBTRF);
  892. CEC_EndOfMessageCmd(DISABLE);
  893. CECDevicesNumber = i - 1;
  894. return errorstatus;
  895. }
  896. /**
  897. * @brief Physical address discovery.
  898. * @param None
  899. * @retval HDMI_CEC_Error: CEC Error code.
  900. */
  901. static HDMI_CEC_Error PhysicalAddressDiscovery(void)
  902. {
  903. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  904. #ifdef HDMI_CEC_USE_DDC
  905. uint32_t index = 0, i = 0;
  906. #endif
  907. /*------------------------------ Physical address discovery -----------------*/
  908. if (HDMI_CEC_ROOT == 0x1)
  909. {
  910. MyPhysicalAddress = 0x0000;
  911. /* The HDMI-CEC here is configured as sink or as a repeater. The configuration
  912. of the +5V power signal and the HPD should be well configured.
  913. Implement here the EDID Structure to be sent to the HDMI source.
  914. For more details please refer to the HDMI specification.
  915. The EDID structure should be sent to the device source using the DDC Channel
  916. and using the HPD signal. */
  917. }
  918. else
  919. {
  920. #ifdef HDMI_CEC_USE_DDC
  921. /* The HDMI-CEC here is configured as source or as a repeater. The configuration
  922. of the +5V power signal and the HPD should be well configured.
  923. The source should wait for HPD and then read the EDID structure. */
  924. while(GPIO_ReadInputDataBit(HDMI_CEC_HPD_GPIO_PORT, HDMI_CEC_HPD_PIN) == RESET)
  925. {
  926. }
  927. /* Wait for 100 ms after HPD was received */
  928. for(i = 0; i < 0x5FFFF; i++)
  929. {
  930. }
  931. /* Return the physical address using the I2C by reading the 2 bytes 24 and
  932. 25 form the EDID */
  933. /* Read the EDID Block 0 and EDID Block 1 at address 0xA0 */
  934. /*!< While the bus is busy */
  935. while(I2C_GetFlagStatus(HDMI_CEC_I2C, I2C_FLAG_BUSY))
  936. {
  937. }
  938. /*!< Send START condition */
  939. I2C_GenerateSTART(HDMI_CEC_I2C, ENABLE);
  940. /*!< Test on EV5 and clear it */
  941. while(!I2C_CheckEvent(HDMI_CEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  942. {
  943. }
  944. /*!< Send EEPROM address for write */
  945. I2C_Send7bitAddress(HDMI_CEC_I2C, 0xA0, I2C_Direction_Transmitter);
  946. /*!< Test on EV6 and clear it */
  947. while(!I2C_CheckEvent(HDMI_CEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  948. {
  949. }
  950. /*!< Send the EEPROM's internal address to read from: Only one byte address */
  951. I2C_SendData(HDMI_CEC_I2C, 0x00);
  952. /*!< Test on EV8 and clear it */
  953. while(!I2C_CheckEvent(HDMI_CEC_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  954. {
  955. }
  956. /*!< Send STRAT condition a second time */
  957. I2C_GenerateSTART(HDMI_CEC_I2C, ENABLE);
  958. /*!< Test on EV5 and clear it */
  959. while(!I2C_CheckEvent(HDMI_CEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  960. {
  961. }
  962. /*!< Send EEPROM address for read */
  963. I2C_Send7bitAddress(HDMI_CEC_I2C, 0xA1, I2C_Direction_Receiver);
  964. /*!< Test on EV6 and clear it */
  965. while(!I2C_CheckEvent(HDMI_CEC_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  966. {
  967. }
  968. /* While there is data to be read */
  969. while (NumByteToRead-- > 1)
  970. {
  971. while(I2C_CheckEvent(HDMI_CEC_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))
  972. {
  973. }
  974. for(i = 0; i < 0xFFF; i++)
  975. {
  976. }
  977. pBuffer[index++] = I2C_ReceiveData(HDMI_CEC_I2C);
  978. }
  979. /* Disable Acknowledgement */
  980. I2C_AcknowledgeConfig(HDMI_CEC_I2C, DISABLE);
  981. /* Send STOP Condition */
  982. I2C_GenerateSTOP(HDMI_CEC_I2C, ENABLE);
  983. while(I2C_CheckEvent(HDMI_CEC_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED));
  984. pBuffer[index] = I2C_ReceiveData(HDMI_CEC_I2C);
  985. /* Enable Acknowledgement to be ready for another reception */
  986. I2C_AcknowledgeConfig(HDMI_CEC_I2C, ENABLE);
  987. MyPhysicalAddress = ((pBuffer[138] << 8) | pBuffer[137]);
  988. #else
  989. MyPhysicalAddress = 0x1000;
  990. #endif
  991. }
  992. return errorstatus;
  993. }
  994. /**
  995. * @brief Allocate the logical address.
  996. * @param None
  997. * @retval HDMI_CEC_Error: CEC Error code.
  998. */
  999. static HDMI_CEC_Error LogicalAddressAllocation(void)
  1000. {
  1001. HDMI_CEC_Error errorstatus = HDMI_CEC_OK;
  1002. uint32_t count = 0;
  1003. /*------------------ Logical address allocation -----------------------------*/
  1004. /* Get the device type */
  1005. /* Device type = CEC_TV */
  1006. if (DeviceType == HDMI_CEC_TV)
  1007. {
  1008. if (HDMI_CEC_ROOT)
  1009. {
  1010. MyLogicalAddress = 0x00;
  1011. }
  1012. else
  1013. {
  1014. CEC_OwnAddressConfig(0xE); /* Own address = 0xE */
  1015. CEC_EndOfMessageCmd(ENABLE);
  1016. CEC_SendDataByte(0xEE);
  1017. /* Start of message */
  1018. CEC_StartOfMessage();
  1019. /* Wait till the polling message is sent */
  1020. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1021. {
  1022. count++;
  1023. }
  1024. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1025. {
  1026. errorstatus = HDMI_CEC_TIMEOUT;
  1027. return(errorstatus);
  1028. }
  1029. errorstatus = HDMI_CEC_GetErrorStatus();
  1030. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1031. {
  1032. MyLogicalAddress = 0x0E;
  1033. errorstatus = HDMI_CEC_OK;
  1034. }
  1035. else if (errorstatus == HDMI_CEC_OK)
  1036. {
  1037. MyLogicalAddress = 0x0F;
  1038. errorstatus = HDMI_CEC_DEVICE_UNREGISTRED;
  1039. }
  1040. }
  1041. /* Clear CEC CSR register */
  1042. CEC_ClearFlag(CEC_FLAG_TBTRF);
  1043. CEC_EndOfMessageCmd(DISABLE);
  1044. }
  1045. /* Device type = CEC_RECORDING */
  1046. if (DeviceType == HDMI_CEC_RECORDING)
  1047. {
  1048. CEC_OwnAddressConfig(0x1); /* Own address = 0x1 */
  1049. CEC_EndOfMessageCmd(ENABLE);
  1050. CEC_SendDataByte(0x11);
  1051. /* Start of message */
  1052. CEC_StartOfMessage();
  1053. /* Wait till the header message is sent */
  1054. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1055. {
  1056. count++;
  1057. }
  1058. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1059. {
  1060. errorstatus = HDMI_CEC_TIMEOUT;
  1061. return(errorstatus);
  1062. }
  1063. errorstatus = HDMI_CEC_GetErrorStatus();
  1064. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1065. {
  1066. MyLogicalAddress = 0x01;
  1067. errorstatus = HDMI_CEC_OK;
  1068. }
  1069. else if (errorstatus == HDMI_CEC_OK)
  1070. {
  1071. /* Clear CEC CSR register */
  1072. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1073. CEC_EndOfMessageCmd(DISABLE);
  1074. CEC_OwnAddressConfig(0x2); /* Own address = 0x2 */
  1075. CEC_EndOfMessageCmd(ENABLE);
  1076. CEC_SendDataByte(0x22);
  1077. /* Start of message */
  1078. CEC_StartOfMessage();
  1079. count = 0;
  1080. /* Wait till the header message is sent */
  1081. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1082. {
  1083. count++;
  1084. }
  1085. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1086. {
  1087. errorstatus = HDMI_CEC_TIMEOUT;
  1088. return(errorstatus);
  1089. }
  1090. errorstatus = HDMI_CEC_GetErrorStatus();
  1091. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1092. {
  1093. MyLogicalAddress = 0x02;
  1094. errorstatus = HDMI_CEC_OK;
  1095. }
  1096. else if (errorstatus == HDMI_CEC_OK)
  1097. {
  1098. /* Clear CEC CSR register */
  1099. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1100. CEC_EndOfMessageCmd(DISABLE);
  1101. CEC_OwnAddressConfig(0x9); /* Own address = 0x9 */
  1102. CEC_EndOfMessageCmd(ENABLE);
  1103. CEC_SendDataByte(0x99);
  1104. /* Start of message */
  1105. CEC_StartOfMessage();
  1106. count = 0;
  1107. /* Wait till the header message is sent */
  1108. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1109. {
  1110. count++;
  1111. }
  1112. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1113. {
  1114. errorstatus = HDMI_CEC_TIMEOUT;
  1115. return(errorstatus);
  1116. }
  1117. errorstatus = HDMI_CEC_GetErrorStatus();
  1118. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1119. {
  1120. MyLogicalAddress = 0x09;
  1121. errorstatus = HDMI_CEC_OK;
  1122. }
  1123. else if (errorstatus == HDMI_CEC_OK)
  1124. {
  1125. MyLogicalAddress = 0x0F;
  1126. errorstatus = HDMI_CEC_DEVICE_UNREGISTRED;
  1127. }
  1128. }
  1129. }
  1130. /* Clear CEC CSR register */
  1131. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1132. CEC_EndOfMessageCmd(DISABLE);
  1133. }
  1134. /* Device type = CEC_TUNER */
  1135. if (DeviceType == HDMI_CEC_TUNER)
  1136. {
  1137. CEC_OwnAddressConfig(0x3); /* Own address = 0x3 */
  1138. CEC_EndOfMessageCmd(ENABLE);
  1139. CEC_SendDataByte(0x33);
  1140. /* Start of message */
  1141. CEC_StartOfMessage();
  1142. count = 0;
  1143. /* Wait till the header message is sent */
  1144. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1145. {
  1146. count++;
  1147. }
  1148. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1149. {
  1150. errorstatus = HDMI_CEC_TIMEOUT;
  1151. return(errorstatus);
  1152. }
  1153. errorstatus = HDMI_CEC_GetErrorStatus();
  1154. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1155. {
  1156. MyLogicalAddress = 0x03;
  1157. errorstatus = HDMI_CEC_OK;
  1158. }
  1159. else if (errorstatus == HDMI_CEC_OK)
  1160. {
  1161. /* Clear CEC CSR register */
  1162. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1163. CEC_EndOfMessageCmd(DISABLE);
  1164. CEC_OwnAddressConfig(0x6); /* Own address = 0x6 */
  1165. CEC_EndOfMessageCmd(ENABLE);
  1166. CEC_SendDataByte(0x66);
  1167. /* Start of message */
  1168. CEC_StartOfMessage();
  1169. count = 0;
  1170. /* Wait till the header message is sent */
  1171. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1172. {
  1173. count++;
  1174. }
  1175. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1176. {
  1177. errorstatus = HDMI_CEC_TIMEOUT;
  1178. return(errorstatus);
  1179. }
  1180. errorstatus = HDMI_CEC_GetErrorStatus();
  1181. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1182. {
  1183. MyLogicalAddress = 0x06;
  1184. errorstatus = HDMI_CEC_OK;
  1185. }
  1186. else if (errorstatus == HDMI_CEC_OK)
  1187. {
  1188. /* Clear CEC CSR register */
  1189. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1190. CEC_EndOfMessageCmd(DISABLE);
  1191. CEC_OwnAddressConfig(0x7); /* Own address = 0x7 */
  1192. CEC_EndOfMessageCmd(ENABLE);
  1193. CEC_SendDataByte(0x77);
  1194. /* Start of message */
  1195. CEC_StartOfMessage();
  1196. count = 0;
  1197. /* Wait till the header message is sent */
  1198. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1199. {
  1200. count++;
  1201. }
  1202. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1203. {
  1204. errorstatus = HDMI_CEC_TIMEOUT;
  1205. return(errorstatus);
  1206. }
  1207. errorstatus = HDMI_CEC_GetErrorStatus();
  1208. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1209. {
  1210. MyLogicalAddress = 0x07;
  1211. errorstatus = HDMI_CEC_OK;
  1212. }
  1213. else if (errorstatus == HDMI_CEC_OK)
  1214. {
  1215. /* Clear CEC CSR register */
  1216. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1217. CEC_EndOfMessageCmd(DISABLE);
  1218. CEC_OwnAddressConfig(0xA); /* Own address = 0xA */
  1219. CEC_EndOfMessageCmd(ENABLE);
  1220. CEC_SendDataByte(0xAA);
  1221. /* Start of message */
  1222. CEC_StartOfMessage();
  1223. count = 0;
  1224. /* Wait till the header message is sent */
  1225. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1226. {
  1227. count++;
  1228. }
  1229. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1230. {
  1231. errorstatus = HDMI_CEC_TIMEOUT;
  1232. return(errorstatus);
  1233. }
  1234. errorstatus = HDMI_CEC_GetErrorStatus();
  1235. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1236. {
  1237. MyLogicalAddress = 0x0A;
  1238. errorstatus = HDMI_CEC_OK;
  1239. }
  1240. else if (errorstatus == HDMI_CEC_OK)
  1241. {
  1242. MyLogicalAddress = 0x0F;
  1243. errorstatus = HDMI_CEC_DEVICE_UNREGISTRED;
  1244. }
  1245. }
  1246. }
  1247. }
  1248. /* Clear CEC CSR register */
  1249. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1250. CEC_EndOfMessageCmd(DISABLE);
  1251. }
  1252. /* Device type = CEC_PLAYBACK */
  1253. if (DeviceType == HDMI_CEC_PLAYBACK)
  1254. {
  1255. CEC_OwnAddressConfig(0x4); /* Own address = 0x4 */
  1256. CEC_EndOfMessageCmd(ENABLE);
  1257. CEC_SendDataByte(0x44);
  1258. /* Start of message */
  1259. CEC_StartOfMessage();
  1260. count = 0;
  1261. /* Wait till the header message is sent */
  1262. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1263. {
  1264. count++;
  1265. }
  1266. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1267. {
  1268. errorstatus = HDMI_CEC_TIMEOUT;
  1269. return(errorstatus);
  1270. }
  1271. errorstatus = HDMI_CEC_GetErrorStatus();
  1272. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1273. {
  1274. MyLogicalAddress = 0x04;
  1275. errorstatus = HDMI_CEC_OK;
  1276. }
  1277. else if (errorstatus == HDMI_CEC_OK)
  1278. {
  1279. /* Clear CEC CSR register */
  1280. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1281. CEC_EndOfMessageCmd(DISABLE);
  1282. CEC_OwnAddressConfig(0x8); /* Own address = 0x8 */
  1283. CEC_EndOfMessageCmd(ENABLE);
  1284. CEC_SendDataByte(0x88);
  1285. /* Start of message */
  1286. CEC_StartOfMessage();
  1287. count = 0;
  1288. /* Wait till the header message is sent */
  1289. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1290. {
  1291. count++;
  1292. }
  1293. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1294. {
  1295. errorstatus = HDMI_CEC_TIMEOUT;
  1296. return(errorstatus);
  1297. }
  1298. errorstatus = HDMI_CEC_GetErrorStatus();
  1299. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1300. {
  1301. MyLogicalAddress = 0x08;
  1302. errorstatus = HDMI_CEC_OK;
  1303. }
  1304. else if (errorstatus == HDMI_CEC_OK)
  1305. {
  1306. /* Clear CEC CSR register */
  1307. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1308. CEC_EndOfMessageCmd(DISABLE);
  1309. CEC_OwnAddressConfig(0xB); /* Own address = 0xBB */
  1310. CEC_EndOfMessageCmd(ENABLE);
  1311. CEC_SendDataByte(0xBB);
  1312. /* Start of message */
  1313. CEC_StartOfMessage();
  1314. count = 0;
  1315. /* Wait till the header message is sent */
  1316. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1317. {
  1318. count++;
  1319. }
  1320. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1321. {
  1322. errorstatus = HDMI_CEC_TIMEOUT;
  1323. return(errorstatus);
  1324. }
  1325. errorstatus = HDMI_CEC_GetErrorStatus();
  1326. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1327. {
  1328. MyLogicalAddress = 0x0B;
  1329. errorstatus = HDMI_CEC_OK;
  1330. }
  1331. else if (errorstatus == HDMI_CEC_OK)
  1332. {
  1333. MyLogicalAddress = 0x0F;
  1334. errorstatus = HDMI_CEC_DEVICE_UNREGISTRED;
  1335. }
  1336. }
  1337. }
  1338. /* Clear CEC CSR register */
  1339. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1340. CEC_EndOfMessageCmd(DISABLE);
  1341. }
  1342. /* Device type = CEC Audio System */
  1343. if (DeviceType == HDMI_CEC_AUDIOSYSTEM)
  1344. {
  1345. CEC_OwnAddressConfig(0x5); /* Own address = 0x5 */
  1346. CEC_EndOfMessageCmd(ENABLE);
  1347. CEC_SendDataByte(0x55);
  1348. /* Start of message */
  1349. CEC_StartOfMessage();
  1350. count = 0;
  1351. /* Wait till the header message is sent */
  1352. while ((CEC_GetFlagStatus(CEC_FLAG_TBTRF) == RESET) && (CEC_GetFlagStatus(CEC_FLAG_TERR) == RESET) && (count < HDMI_CEC_TIMEOUT_VALUE))
  1353. {
  1354. count++;
  1355. }
  1356. if (count >= HDMI_CEC_TIMEOUT_VALUE)
  1357. {
  1358. errorstatus = HDMI_CEC_TIMEOUT;
  1359. return(errorstatus);
  1360. }
  1361. errorstatus = HDMI_CEC_GetErrorStatus();
  1362. if (errorstatus == HDMI_CEC_BLOCK_ACKNOWLEDGE)
  1363. {
  1364. MyLogicalAddress = 0x05;
  1365. errorstatus = HDMI_CEC_OK;
  1366. }
  1367. else if (errorstatus == HDMI_CEC_OK)
  1368. {
  1369. MyLogicalAddress = 0x0F;
  1370. errorstatus = HDMI_CEC_DEVICE_UNREGISTRED;
  1371. }
  1372. /* Clear CEC CSR register */
  1373. CEC_ClearFlag(CEC_FLAG_TBTRF | CEC_FLAG_TERR);
  1374. CEC_EndOfMessageCmd(DISABLE);
  1375. }
  1376. return errorstatus;
  1377. }
  1378. /**
  1379. * @}
  1380. */
  1381. /**
  1382. * @}
  1383. */
  1384. /**
  1385. * @}
  1386. */
  1387. /**
  1388. * @}
  1389. */
  1390. /**
  1391. * @}
  1392. */
  1393. /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/